ratatui_ruby 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.builds/ruby-3.2.yml +2 -2
- data/.builds/ruby-3.3.yml +2 -2
- data/.builds/ruby-3.4.yml +2 -2
- data/.builds/ruby-4.0.0.yml +2 -2
- data/.pre-commit-config.yaml +1 -1
- data/AGENTS.md +3 -3
- data/CHANGELOG.md +77 -1
- data/LICENSES/LGPL-3.0-or-later.txt +304 -0
- data/LICENSES/MIT-0.txt +16 -0
- data/README.md +33 -5
- data/Rakefile +1 -1
- data/doc/concepts/application_architecture.md +44 -3
- data/doc/concepts/application_testing.md +43 -1
- data/doc/concepts/async.md +32 -2
- data/doc/concepts/custom_widgets.md +247 -0
- data/doc/concepts/event_handling.md +32 -3
- data/doc/concepts/interactive_design.md +32 -2
- data/doc/contributors/auditing/parity.md +7 -1
- data/doc/contributors/design/ruby_frontend.md +85 -1
- data/doc/contributors/design/rust_backend.md +67 -1
- data/doc/contributors/developing_examples.md +56 -2
- data/doc/contributors/documentation_style.md +20 -3
- data/doc/contributors/future_work.md +169 -0
- data/doc/contributors/index.md +1 -1
- data/doc/contributors/v1.0.0_blockers.md +19 -185
- data/doc/getting_started/quickstart.md +22 -4
- data/doc/getting_started/why.md +1 -1
- data/doc/index.md +2 -1
- data/doc/troubleshooting/debugging.md +32 -2
- data/doc/troubleshooting/terminal_limitations.md +8 -2
- data/doc/troubleshooting/tui_output.md +42 -0
- data/examples/app_all_events/README.md +14 -2
- data/examples/app_all_events/app.rb +1 -1
- data/examples/app_all_events/model/app_model.rb +1 -1
- data/examples/app_all_events/model/event_color_cycle.rb +1 -1
- data/examples/app_all_events/model/event_entry.rb +1 -1
- data/examples/app_all_events/model/msg.rb +1 -1
- data/examples/app_all_events/model/timestamp.rb +1 -1
- data/examples/app_all_events/update.rb +1 -1
- data/examples/app_all_events/view/app_view.rb +1 -1
- data/examples/app_all_events/view/controls_view.rb +1 -1
- data/examples/app_all_events/view/counts_view.rb +1 -1
- data/examples/app_all_events/view/live_view.rb +1 -1
- data/examples/app_all_events/view/log_view.rb +1 -1
- data/examples/app_all_events/view.rb +1 -1
- data/examples/app_color_picker/README.md +20 -2
- data/examples/app_color_picker/app.rb +1 -1
- data/examples/app_color_picker/clipboard.rb +1 -1
- data/examples/app_color_picker/color.rb +1 -1
- data/examples/app_color_picker/controls.rb +1 -1
- data/examples/app_color_picker/copy_dialog.rb +1 -1
- data/examples/app_color_picker/export_pane.rb +1 -1
- data/examples/app_color_picker/harmony.rb +1 -1
- data/examples/app_color_picker/input.rb +1 -1
- data/examples/app_color_picker/main_container.rb +1 -1
- data/examples/app_color_picker/palette.rb +1 -1
- data/examples/app_login_form/README.md +8 -2
- data/examples/app_login_form/app.rb +1 -1
- data/examples/app_stateful_interaction/README.md +2 -2
- data/examples/app_stateful_interaction/app.rb +71 -17
- data/examples/timeout_demo.rb +1 -1
- data/examples/verify_quickstart_dsl/README.md +6 -0
- data/examples/verify_quickstart_dsl/app.rb +3 -3
- data/examples/verify_quickstart_layout/README.md +6 -0
- data/examples/verify_quickstart_layout/app.rb +3 -3
- data/examples/verify_quickstart_lifecycle/README.md +6 -0
- data/examples/verify_quickstart_lifecycle/app.rb +3 -3
- data/examples/verify_readme_usage/README.md +6 -0
- data/examples/verify_readme_usage/app.rb +3 -3
- data/examples/widget_barchart/README.md +6 -0
- data/examples/widget_barchart/app.rb +2 -2
- data/examples/widget_block/README.md +7 -1
- data/examples/widget_block/app.rb +2 -2
- data/examples/widget_box/README.md +6 -0
- data/examples/widget_box/app.rb +9 -6
- data/examples/widget_calendar/README.md +6 -0
- data/examples/widget_calendar/app.rb +2 -2
- data/examples/widget_canvas/README.md +4 -0
- data/examples/widget_canvas/app.rb +2 -2
- data/examples/widget_cell/README.md +6 -0
- data/examples/widget_cell/app.rb +2 -3
- data/examples/widget_center/README.md +4 -0
- data/examples/widget_center/app.rb +2 -2
- data/examples/widget_chart/README.md +6 -0
- data/examples/widget_chart/app.rb +2 -2
- data/examples/widget_gauge/README.md +6 -0
- data/examples/widget_gauge/app.rb +2 -2
- data/examples/widget_layout_split/README.md +6 -0
- data/examples/widget_layout_split/app.rb +9 -3
- data/examples/widget_line_gauge/README.md +6 -0
- data/examples/widget_line_gauge/app.rb +2 -2
- data/examples/widget_list/README.md +6 -0
- data/examples/widget_list/app.rb +2 -2
- data/examples/widget_map/README.md +8 -2
- data/examples/widget_map/app.rb +2 -2
- data/examples/widget_overlay/README.md +7 -1
- data/examples/widget_overlay/app.rb +2 -2
- data/examples/widget_popup/README.md +6 -0
- data/examples/widget_popup/app.rb +2 -2
- data/examples/widget_ratatui_logo/README.md +6 -0
- data/examples/widget_ratatui_logo/app.rb +2 -3
- data/examples/widget_ratatui_mascot/README.md +6 -0
- data/examples/widget_ratatui_mascot/app.rb +2 -2
- data/examples/widget_rect/README.md +12 -0
- data/examples/widget_rect/app.rb +40 -26
- data/examples/widget_render/README.md +6 -0
- data/examples/widget_render/app.rb +2 -2
- data/examples/widget_render/app.rbs +41 -0
- data/examples/widget_rich_text/README.md +6 -0
- data/examples/widget_rich_text/app.rb +2 -2
- data/examples/widget_scroll_text/README.md +6 -0
- data/examples/widget_scroll_text/app.rb +2 -2
- data/examples/widget_scrollbar/README.md +6 -0
- data/examples/widget_scrollbar/app.rb +2 -2
- data/examples/widget_sparkline/README.md +6 -0
- data/examples/widget_sparkline/app.rb +2 -2
- data/examples/widget_style_colors/README.md +6 -0
- data/examples/widget_style_colors/app.rb +2 -2
- data/examples/widget_table/README.md +8 -2
- data/examples/widget_table/app.rb +2 -2
- data/examples/widget_tabs/README.md +6 -0
- data/examples/widget_tabs/app.rb +2 -2
- data/examples/widget_text_width/README.md +6 -0
- data/examples/widget_text_width/app.rb +4 -4
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/ext/ratatui_ruby/extconf.rb +2 -2
- data/ext/ratatui_ruby/src/events.rs +1 -0
- data/ext/ratatui_ruby/src/rendering.rs +1 -1
- data/ext/ratatui_ruby/src/style.rs +0 -8
- data/ext/ratatui_ruby/src/widgets/chart.rs +0 -118
- data/ext/ratatui_ruby/src/widgets/list_state.rs +36 -0
- data/lib/ratatui_ruby/buffer/cell.rb +34 -2
- data/lib/ratatui_ruby/buffer.rb +2 -2
- data/lib/ratatui_ruby/cell.rb +34 -2
- data/lib/ratatui_ruby/event/focus_gained.rb +26 -2
- data/lib/ratatui_ruby/event/focus_lost.rb +26 -2
- data/lib/ratatui_ruby/event/key/character.rb +18 -2
- data/lib/ratatui_ruby/event/key/media.rb +2 -2
- data/lib/ratatui_ruby/event/key/modifier.rb +10 -2
- data/lib/ratatui_ruby/event/key/navigation.rb +2 -2
- data/lib/ratatui_ruby/event/key/system.rb +2 -2
- data/lib/ratatui_ruby/event/key.rb +114 -2
- data/lib/ratatui_ruby/event/mouse.rb +42 -2
- data/lib/ratatui_ruby/event/none.rb +10 -2
- data/lib/ratatui_ruby/event/paste.rb +34 -2
- data/lib/ratatui_ruby/event/resize.rb +34 -2
- data/lib/ratatui_ruby/event/sync.rb +52 -0
- data/lib/ratatui_ruby/event.rb +32 -2
- data/lib/ratatui_ruby/frame.rb +74 -2
- data/lib/ratatui_ruby/layout/constraint.rb +193 -2
- data/lib/ratatui_ruby/layout/layout.rb +47 -2
- data/lib/ratatui_ruby/layout/rect.rb +403 -2
- data/lib/ratatui_ruby/layout.rb +2 -2
- data/lib/ratatui_ruby/list_state.rb +113 -2
- data/lib/ratatui_ruby/output_guard.rb +26 -3
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +2 -2
- data/lib/ratatui_ruby/schema/bar_chart.rb +50 -2
- data/lib/ratatui_ruby/schema/block.rb +21 -15
- data/lib/ratatui_ruby/schema/calendar.rb +2 -2
- data/lib/ratatui_ruby/schema/canvas.rb +10 -2
- data/lib/ratatui_ruby/schema/center.rb +10 -2
- data/lib/ratatui_ruby/schema/chart.rb +2 -28
- data/lib/ratatui_ruby/schema/clear.rb +10 -2
- data/lib/ratatui_ruby/schema/constraint.rb +58 -2
- data/lib/ratatui_ruby/schema/cursor.rb +10 -2
- data/lib/ratatui_ruby/schema/draw.rb +10 -2
- data/lib/ratatui_ruby/schema/gauge.rb +2 -2
- data/lib/ratatui_ruby/schema/layout.rb +18 -2
- data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
- data/lib/ratatui_ruby/schema/list.rb +10 -2
- data/lib/ratatui_ruby/schema/list_item.rb +10 -2
- data/lib/ratatui_ruby/schema/overlay.rb +10 -2
- data/lib/ratatui_ruby/schema/paragraph.rb +10 -2
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +2 -2
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +2 -2
- data/lib/ratatui_ruby/schema/rect.rb +58 -2
- data/lib/ratatui_ruby/schema/row.rb +10 -2
- data/lib/ratatui_ruby/schema/scrollbar.rb +2 -2
- data/lib/ratatui_ruby/schema/shape/label.rb +10 -2
- data/lib/ratatui_ruby/schema/sparkline.rb +10 -2
- data/lib/ratatui_ruby/schema/style.rb +18 -2
- data/lib/ratatui_ruby/schema/table.rb +2 -2
- data/lib/ratatui_ruby/schema/tabs.rb +2 -2
- data/lib/ratatui_ruby/schema/text.rb +34 -2
- data/lib/ratatui_ruby/scrollbar_state.rb +10 -2
- data/lib/ratatui_ruby/style/style.rb +18 -2
- data/lib/ratatui_ruby/style.rb +2 -2
- data/lib/ratatui_ruby/synthetic_events.rb +86 -0
- data/lib/ratatui_ruby/table_state.rb +10 -2
- data/lib/ratatui_ruby/terminal_lifecycle.rb +18 -3
- data/lib/ratatui_ruby/test_helper/event_injection.rb +62 -2
- data/lib/ratatui_ruby/test_helper/snapshot.rb +74 -9
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +98 -2
- data/lib/ratatui_ruby/test_helper/terminal.rb +50 -2
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +18 -2
- data/lib/ratatui_ruby/test_helper.rb +10 -2
- data/lib/ratatui_ruby/tui/buffer_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/canvas_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/core.rb +2 -2
- data/lib/ratatui_ruby/tui/layout_factories.rb +32 -2
- data/lib/ratatui_ruby/tui/state_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/style_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/text_factories.rb +2 -2
- data/lib/ratatui_ruby/tui/widget_factories.rb +2 -2
- data/lib/ratatui_ruby/tui.rb +11 -3
- data/lib/ratatui_ruby/version.rb +3 -3
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -2
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -2
- data/lib/ratatui_ruby/widgets/bar_chart.rb +58 -2
- data/lib/ratatui_ruby/widgets/block.rb +37 -15
- data/lib/ratatui_ruby/widgets/calendar.rb +2 -2
- data/lib/ratatui_ruby/widgets/canvas.rb +10 -2
- data/lib/ratatui_ruby/widgets/cell.rb +10 -2
- data/lib/ratatui_ruby/widgets/center.rb +10 -2
- data/lib/ratatui_ruby/widgets/chart.rb +2 -28
- data/lib/ratatui_ruby/widgets/clear.rb +10 -2
- data/lib/ratatui_ruby/widgets/cursor.rb +10 -2
- data/lib/ratatui_ruby/widgets/gauge.rb +16 -2
- data/lib/ratatui_ruby/widgets/line_gauge.rb +16 -2
- data/lib/ratatui_ruby/widgets/list.rb +41 -2
- data/lib/ratatui_ruby/widgets/list_item.rb +10 -2
- data/lib/ratatui_ruby/widgets/overlay.rb +10 -2
- data/lib/ratatui_ruby/widgets/paragraph.rb +10 -2
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -2
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -2
- data/lib/ratatui_ruby/widgets/row.rb +10 -2
- data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -2
- data/lib/ratatui_ruby/widgets/shape/label.rb +10 -2
- data/lib/ratatui_ruby/widgets/sparkline.rb +10 -2
- data/lib/ratatui_ruby/widgets/table.rb +62 -2
- data/lib/ratatui_ruby/widgets/tabs.rb +2 -2
- data/lib/ratatui_ruby/widgets.rb +2 -2
- data/lib/ratatui_ruby.rb +101 -9
- data/sig/examples/app_all_events/view.rbs +7 -1
- data/sig/examples/app_all_events/view_state.rbs +7 -1
- data/sig/examples/app_color_picker/app.rbs +5 -0
- data/sig/examples/app_stateful_interaction/app.rbs +7 -1
- data/sig/examples/verify_quickstart_dsl/app.rbs +7 -1
- data/sig/examples/verify_quickstart_lifecycle/app.rbs +7 -1
- data/sig/examples/verify_readme_usage/app.rbs +7 -1
- data/sig/examples/widget_block_demo/app.rbs +6 -0
- data/sig/examples/widget_box_demo/app.rbs +7 -1
- data/sig/examples/widget_calendar_demo/app.rbs +7 -1
- data/sig/examples/widget_cell_demo/app.rbs +7 -1
- data/sig/examples/widget_chart_demo/app.rbs +7 -1
- data/sig/examples/widget_gauge_demo/app.rbs +7 -1
- data/sig/examples/widget_layout_split/app.rbs +7 -1
- data/sig/examples/widget_line_gauge_demo/app.rbs +7 -1
- data/sig/examples/widget_list_demo/app.rbs +5 -0
- data/sig/examples/widget_map_demo/app.rbs +7 -1
- data/sig/examples/widget_popup_demo/app.rbs +7 -1
- data/sig/examples/widget_ratatui_logo_demo/app.rbs +7 -1
- data/sig/examples/widget_ratatui_mascot_demo/app.rbs +7 -1
- data/sig/examples/widget_rect/app.rbs +7 -1
- data/sig/examples/widget_render/app.rbs +7 -1
- data/sig/examples/widget_rich_text/app.rbs +7 -1
- data/sig/examples/widget_scroll_text/app.rbs +7 -1
- data/sig/examples/widget_scrollbar_demo/app.rbs +7 -1
- data/sig/examples/widget_sparkline_demo/app.rbs +7 -1
- data/sig/examples/widget_style_colors/app.rbs +7 -1
- data/sig/examples/widget_table_demo/app.rbs +7 -1
- data/sig/examples/widget_text_width/app.rbs +7 -1
- data/sig/ratatui_ruby/event.rbs +7 -1
- data/sig/ratatui_ruby/frame.rbs +15 -3
- data/sig/ratatui_ruby/list_state.rbs +11 -1
- data/sig/ratatui_ruby/ratatui_ruby.rbs +8 -2
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +7 -1
- data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +6 -0
- data/sig/ratatui_ruby/schema/bar_chart.rbs +6 -0
- data/sig/ratatui_ruby/schema/block.rbs +7 -1
- data/sig/ratatui_ruby/schema/calendar.rbs +6 -0
- data/sig/ratatui_ruby/schema/canvas.rbs +6 -0
- data/sig/ratatui_ruby/schema/center.rbs +6 -0
- data/sig/ratatui_ruby/schema/chart.rbs +6 -9
- data/sig/ratatui_ruby/schema/constraint.rbs +14 -0
- data/sig/ratatui_ruby/schema/cursor.rbs +6 -0
- data/sig/ratatui_ruby/schema/draw.rbs +6 -0
- data/sig/ratatui_ruby/schema/gauge.rbs +9 -1
- data/sig/ratatui_ruby/schema/layout.rbs +6 -0
- data/sig/ratatui_ruby/schema/line_gauge.rbs +9 -1
- data/sig/ratatui_ruby/schema/list.rbs +9 -1
- data/sig/ratatui_ruby/schema/list_item.rbs +7 -1
- data/sig/ratatui_ruby/schema/overlay.rbs +6 -0
- data/sig/ratatui_ruby/schema/paragraph.rbs +6 -0
- data/sig/ratatui_ruby/schema/ratatui_logo.rbs +6 -0
- data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +5 -0
- data/sig/ratatui_ruby/schema/rect.rbs +30 -0
- data/sig/ratatui_ruby/schema/row.rbs +7 -1
- data/sig/ratatui_ruby/schema/scrollbar.rbs +6 -0
- data/sig/ratatui_ruby/schema/sparkline.rbs +6 -0
- data/sig/ratatui_ruby/schema/style.rbs +7 -1
- data/sig/ratatui_ruby/schema/table.rbs +11 -1
- data/sig/ratatui_ruby/schema/tabs.rbs +6 -0
- data/sig/ratatui_ruby/schema/text.rbs +7 -1
- data/sig/ratatui_ruby/scrollbar_state.rbs +7 -1
- data/sig/ratatui_ruby/session.rbs +7 -1
- data/sig/ratatui_ruby/table_state.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/terminal.rbs +7 -1
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -1
- data/sig/ratatui_ruby/test_helper.rbs +7 -1
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/core.rbs +7 -1
- data/sig/ratatui_ruby/tui/layout_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/state_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/style_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/text_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui/widget_factories.rbs +7 -1
- data/sig/ratatui_ruby/tui.rbs +7 -1
- data/sig/ratatui_ruby/version.rbs +6 -0
- data/tasks/autodoc/examples.rb +1 -1
- data/tasks/autodoc/member.rb +1 -1
- data/tasks/autodoc/name.rb +1 -1
- data/tasks/bump/cargo_lockfile.rb +1 -1
- data/tasks/bump/changelog.rb +1 -1
- data/tasks/bump/header.rb +1 -1
- data/tasks/bump/history.rb +1 -1
- data/tasks/bump/links.rb +1 -1
- data/tasks/bump/manifest.rb +1 -1
- data/tasks/bump/ruby_gem.rb +1 -1
- data/tasks/bump/sem_ver.rb +1 -1
- data/tasks/bump/unreleased_section.rb +1 -1
- data/tasks/license/headers_md.rb +223 -0
- data/tasks/license/headers_rb.rb +210 -0
- data/tasks/license/license_utils.rb +130 -0
- data/tasks/license/snippets_md.rb +315 -0
- data/tasks/license/snippets_rdoc.rb +150 -0
- data/tasks/license.rake +91 -0
- data/tasks/rdoc_config.rb +1 -1
- data/tasks/resources/build.yml.erb +13 -7
- data/tasks/sourcehut.rake +3 -1
- data/tasks/terminal_preview/app_screenshot.rb +1 -1
- data/tasks/terminal_preview/crash_report.rb +1 -1
- data/tasks/terminal_preview/example_app.rb +1 -1
- data/tasks/terminal_preview/launcher_script.rb +1 -1
- data/tasks/terminal_preview/preview_collection.rb +1 -1
- data/tasks/terminal_preview/preview_timing.rb +1 -1
- data/tasks/terminal_preview/safety_confirmation.rb +1 -1
- data/tasks/terminal_preview/saved_screenshot.rb +1 -1
- data/tasks/terminal_preview/system_appearance.rb +1 -1
- data/tasks/terminal_preview/terminal_window.rb +1 -1
- data/tasks/terminal_preview/window_id.rb +1 -1
- data/tasks/website/index_page.rb +1 -1
- data/tasks/website/version.rb +1 -1
- data/tasks/website/version_menu.rb +1 -1
- data/tasks/website/versioned_documentation.rb +1 -1
- data/tasks/website/website.rb +1 -1
- metadata +15 -3
- data/doc/migration/v0_7_0.md +0 -236
|
@@ -78,6 +78,35 @@ impl RubyListState {
|
|
|
78
78
|
self.inner.borrow_mut().scroll_up_by(amount);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/// Selects the next item or the first one if no item is selected.
|
|
82
|
+
///
|
|
83
|
+
/// Note: until the list is rendered, the number of items is not known, so the index
|
|
84
|
+
/// is set to 0 and will be corrected when the list is rendered.
|
|
85
|
+
pub fn select_next(&self) {
|
|
86
|
+
self.inner.borrow_mut().select_next();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// Selects the previous item or the last one if no item is selected.
|
|
90
|
+
///
|
|
91
|
+
/// Note: until the list is rendered, the number of items is not known, so the index
|
|
92
|
+
/// is set to `usize::MAX` and will be corrected when the list is rendered.
|
|
93
|
+
pub fn select_previous(&self) {
|
|
94
|
+
self.inner.borrow_mut().select_previous();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/// Selects the first item.
|
|
98
|
+
pub fn select_first(&self) {
|
|
99
|
+
self.inner.borrow_mut().select_first();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// Selects the last item.
|
|
103
|
+
///
|
|
104
|
+
/// Note: until the list is rendered, the number of items is not known, so the index
|
|
105
|
+
/// is set to `usize::MAX` and will be corrected when the list is rendered.
|
|
106
|
+
pub fn select_last(&self) {
|
|
107
|
+
self.inner.borrow_mut().select_last();
|
|
108
|
+
}
|
|
109
|
+
|
|
81
110
|
/// Borrows the inner `ListState` mutably for rendering.
|
|
82
111
|
///
|
|
83
112
|
/// # Safety
|
|
@@ -98,6 +127,13 @@ pub fn register(ruby: &Ruby, module: magnus::RModule) -> Result<(), Error> {
|
|
|
98
127
|
class.define_method("offset", method!(RubyListState::offset, 0))?;
|
|
99
128
|
class.define_method("scroll_down_by", method!(RubyListState::scroll_down_by, 1))?;
|
|
100
129
|
class.define_method("scroll_up_by", method!(RubyListState::scroll_up_by, 1))?;
|
|
130
|
+
class.define_method("select_next", method!(RubyListState::select_next, 0))?;
|
|
131
|
+
class.define_method(
|
|
132
|
+
"select_previous",
|
|
133
|
+
method!(RubyListState::select_previous, 0),
|
|
134
|
+
)?;
|
|
135
|
+
class.define_method("select_first", method!(RubyListState::select_first, 0))?;
|
|
136
|
+
class.define_method("select_last", method!(RubyListState::select_last, 0))?;
|
|
101
137
|
Ok(())
|
|
102
138
|
}
|
|
103
139
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -18,11 +18,19 @@ module RatatuiRuby
|
|
|
18
18
|
#
|
|
19
19
|
# === Examples
|
|
20
20
|
#
|
|
21
|
+
#--
|
|
22
|
+
# SPDX-SnippetBegin
|
|
23
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
24
|
+
# SPDX-License-Identifier: MIT-0
|
|
25
|
+
#++
|
|
21
26
|
# cell = RatatuiRuby.get_cell_at(0, 0)
|
|
22
27
|
# cell.char # => "H"
|
|
23
28
|
# cell.fg # => :red
|
|
24
29
|
# cell.bold? # => true
|
|
25
30
|
#
|
|
31
|
+
#--
|
|
32
|
+
# SPDX-SnippetEnd
|
|
33
|
+
#++
|
|
26
34
|
class Cell
|
|
27
35
|
# The character displayed in the cell.
|
|
28
36
|
#
|
|
@@ -45,8 +53,16 @@ module RatatuiRuby
|
|
|
45
53
|
#
|
|
46
54
|
# === Example
|
|
47
55
|
#
|
|
56
|
+
#--
|
|
57
|
+
# SPDX-SnippetBegin
|
|
58
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
59
|
+
# SPDX-License-Identifier: MIT-0
|
|
60
|
+
#++
|
|
48
61
|
# Buffer::Cell.empty # => #<RatatuiRuby::Buffer::Cell char=" ">
|
|
49
62
|
#
|
|
63
|
+
#--
|
|
64
|
+
# SPDX-SnippetEnd
|
|
65
|
+
#++
|
|
50
66
|
def self.empty
|
|
51
67
|
new(symbol: " ", fg: nil, bg: nil, modifiers: [])
|
|
52
68
|
end
|
|
@@ -55,8 +71,16 @@ module RatatuiRuby
|
|
|
55
71
|
#
|
|
56
72
|
# === Example
|
|
57
73
|
#
|
|
74
|
+
#--
|
|
75
|
+
# SPDX-SnippetBegin
|
|
76
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
77
|
+
# SPDX-License-Identifier: MIT-0
|
|
78
|
+
#++
|
|
58
79
|
# Buffer::Cell.default # => #<RatatuiRuby::Buffer::Cell char=" ">
|
|
59
80
|
#
|
|
81
|
+
#--
|
|
82
|
+
# SPDX-SnippetEnd
|
|
83
|
+
#++
|
|
60
84
|
def self.default
|
|
61
85
|
empty
|
|
62
86
|
end
|
|
@@ -67,8 +91,16 @@ module RatatuiRuby
|
|
|
67
91
|
#
|
|
68
92
|
# === Example
|
|
69
93
|
#
|
|
94
|
+
#--
|
|
95
|
+
# SPDX-SnippetBegin
|
|
96
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
97
|
+
# SPDX-License-Identifier: MIT-0
|
|
98
|
+
#++
|
|
70
99
|
# Buffer::Cell.symbol("X") # => #<RatatuiRuby::Buffer::Cell symbol="X">
|
|
71
100
|
#
|
|
101
|
+
#--
|
|
102
|
+
# SPDX-SnippetEnd
|
|
103
|
+
#++
|
|
72
104
|
def self.symbol(symbol)
|
|
73
105
|
new(symbol:, fg: nil, bg: nil, modifiers: [])
|
|
74
106
|
end
|
data/lib/ratatui_ruby/buffer.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
data/lib/ratatui_ruby/cell.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -17,11 +17,19 @@ module RatatuiRuby
|
|
|
17
17
|
#
|
|
18
18
|
# === Examples
|
|
19
19
|
#
|
|
20
|
+
#--
|
|
21
|
+
# SPDX-SnippetBegin
|
|
22
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
23
|
+
# SPDX-License-Identifier: MIT-0
|
|
24
|
+
#++
|
|
20
25
|
# cell = RatatuiRuby.get_cell_at(0, 0)
|
|
21
26
|
# cell.char # => "H"
|
|
22
27
|
# cell.fg # => :red
|
|
23
28
|
# cell.bold? # => true
|
|
24
29
|
#
|
|
30
|
+
#--
|
|
31
|
+
# SPDX-SnippetEnd
|
|
32
|
+
#++
|
|
25
33
|
class Cell
|
|
26
34
|
# The character displayed in the cell.
|
|
27
35
|
#
|
|
@@ -44,8 +52,16 @@ module RatatuiRuby
|
|
|
44
52
|
#
|
|
45
53
|
# === Example
|
|
46
54
|
#
|
|
55
|
+
#--
|
|
56
|
+
# SPDX-SnippetBegin
|
|
57
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
58
|
+
# SPDX-License-Identifier: MIT-0
|
|
59
|
+
#++
|
|
47
60
|
# Cell.empty # => #<RatatuiRuby::Cell char=" ">
|
|
48
61
|
#
|
|
62
|
+
#--
|
|
63
|
+
# SPDX-SnippetEnd
|
|
64
|
+
#++
|
|
49
65
|
def self.empty
|
|
50
66
|
new(symbol: " ", fg: nil, bg: nil, modifiers: [])
|
|
51
67
|
end
|
|
@@ -54,8 +70,16 @@ module RatatuiRuby
|
|
|
54
70
|
#
|
|
55
71
|
# === Example
|
|
56
72
|
#
|
|
73
|
+
#--
|
|
74
|
+
# SPDX-SnippetBegin
|
|
75
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
76
|
+
# SPDX-License-Identifier: MIT-0
|
|
77
|
+
#++
|
|
57
78
|
# Cell.default # => #<RatatuiRuby::Cell char=" ">
|
|
58
79
|
#
|
|
80
|
+
#--
|
|
81
|
+
# SPDX-SnippetEnd
|
|
82
|
+
#++
|
|
59
83
|
def self.default
|
|
60
84
|
empty
|
|
61
85
|
end
|
|
@@ -66,8 +90,16 @@ module RatatuiRuby
|
|
|
66
90
|
#
|
|
67
91
|
# === Example
|
|
68
92
|
#
|
|
93
|
+
#--
|
|
94
|
+
# SPDX-SnippetBegin
|
|
95
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
96
|
+
# SPDX-License-Identifier: MIT-0
|
|
97
|
+
#++
|
|
69
98
|
# Cell.symbol("X") # => #<RatatuiRuby::Cell symbol="X">
|
|
70
99
|
#
|
|
100
|
+
#--
|
|
101
|
+
# SPDX-SnippetEnd
|
|
102
|
+
#++
|
|
71
103
|
def self.symbol(symbol)
|
|
72
104
|
new(symbol:, fg: nil, bg: nil, modifiers: [])
|
|
73
105
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -19,24 +19,48 @@ module RatatuiRuby
|
|
|
19
19
|
#
|
|
20
20
|
# === Example
|
|
21
21
|
#
|
|
22
|
+
#--
|
|
23
|
+
# SPDX-SnippetBegin
|
|
24
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
25
|
+
# SPDX-License-Identifier: MIT-0
|
|
26
|
+
#++
|
|
22
27
|
# if event.focus_gained?
|
|
23
28
|
# puts "Focus gained"
|
|
24
29
|
# end
|
|
30
|
+
#--
|
|
31
|
+
# SPDX-SnippetEnd
|
|
32
|
+
#++
|
|
25
33
|
class FocusGained < Event
|
|
26
34
|
# Returns true for FocusGained events.
|
|
27
35
|
#
|
|
36
|
+
#--
|
|
37
|
+
# SPDX-SnippetBegin
|
|
38
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
39
|
+
# SPDX-License-Identifier: MIT-0
|
|
40
|
+
#++
|
|
28
41
|
# event.focus_gained? # => true
|
|
29
42
|
# event.key? # => false
|
|
43
|
+
#--
|
|
44
|
+
# SPDX-SnippetEnd
|
|
45
|
+
#++
|
|
30
46
|
def focus_gained?
|
|
31
47
|
true
|
|
32
48
|
end
|
|
33
49
|
|
|
34
50
|
# Deconstructs the event for pattern matching.
|
|
35
51
|
#
|
|
52
|
+
#--
|
|
53
|
+
# SPDX-SnippetBegin
|
|
54
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
55
|
+
# SPDX-License-Identifier: MIT-0
|
|
56
|
+
#++
|
|
36
57
|
# case event
|
|
37
58
|
# in type: :focus_gained
|
|
38
59
|
# puts "Application gained focus"
|
|
39
60
|
# end
|
|
61
|
+
#--
|
|
62
|
+
# SPDX-SnippetEnd
|
|
63
|
+
#++
|
|
40
64
|
def deconstruct_keys(keys)
|
|
41
65
|
{ type: :focus_gained }
|
|
42
66
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -20,24 +20,48 @@ module RatatuiRuby
|
|
|
20
20
|
#
|
|
21
21
|
# === Example
|
|
22
22
|
#
|
|
23
|
+
#--
|
|
24
|
+
# SPDX-SnippetBegin
|
|
25
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
26
|
+
# SPDX-License-Identifier: MIT-0
|
|
27
|
+
#++
|
|
23
28
|
# if event.focus_lost?
|
|
24
29
|
# puts "Focus lost"
|
|
25
30
|
# end
|
|
31
|
+
#--
|
|
32
|
+
# SPDX-SnippetEnd
|
|
33
|
+
#++
|
|
26
34
|
class FocusLost < Event
|
|
27
35
|
# Returns true for FocusLost events.
|
|
28
36
|
#
|
|
37
|
+
#--
|
|
38
|
+
# SPDX-SnippetBegin
|
|
39
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
40
|
+
# SPDX-License-Identifier: MIT-0
|
|
41
|
+
#++
|
|
29
42
|
# event.focus_lost? # => true
|
|
30
43
|
# event.key? # => false
|
|
44
|
+
#--
|
|
45
|
+
# SPDX-SnippetEnd
|
|
46
|
+
#++
|
|
31
47
|
def focus_lost?
|
|
32
48
|
true
|
|
33
49
|
end
|
|
34
50
|
|
|
35
51
|
# Deconstructs the event for pattern matching.
|
|
36
52
|
#
|
|
53
|
+
#--
|
|
54
|
+
# SPDX-SnippetBegin
|
|
55
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
56
|
+
# SPDX-License-Identifier: MIT-0
|
|
57
|
+
#++
|
|
37
58
|
# case event
|
|
38
59
|
# in type: :focus_lost
|
|
39
60
|
# puts "Application lost focus"
|
|
40
61
|
# end
|
|
62
|
+
#--
|
|
63
|
+
# SPDX-SnippetEnd
|
|
64
|
+
#++
|
|
41
65
|
def deconstruct_keys(keys)
|
|
42
66
|
{ type: :focus_lost }
|
|
43
67
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -12,9 +12,17 @@ module RatatuiRuby
|
|
|
12
12
|
module Character
|
|
13
13
|
# Returns true if the key represents a single printable character.
|
|
14
14
|
#
|
|
15
|
+
#--
|
|
16
|
+
# SPDX-SnippetBegin
|
|
17
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
18
|
+
# SPDX-License-Identifier: MIT-0
|
|
19
|
+
#++
|
|
15
20
|
# RatatuiRuby::Event::Key.new(code: "a").text? # => true
|
|
16
21
|
# RatatuiRuby::Event::Key.new(code: "enter").text? # => false
|
|
17
22
|
# RatatuiRuby::Event::Key.new(code: "space").text? # => false ("space" is not 1 char, " " is)
|
|
23
|
+
#--
|
|
24
|
+
# SPDX-SnippetEnd
|
|
25
|
+
#++
|
|
18
26
|
def text?
|
|
19
27
|
@code.length == 1
|
|
20
28
|
end
|
|
@@ -24,10 +32,18 @@ module RatatuiRuby
|
|
|
24
32
|
# [Printable Characters]
|
|
25
33
|
# Returns the character itself (e.g., <tt>"a"</tt>, <tt>"1"</tt>, <tt>" "</tt>).
|
|
26
34
|
# [Special Keys]
|
|
35
|
+
#--
|
|
36
|
+
# SPDX-SnippetBegin
|
|
37
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
38
|
+
# SPDX-License-Identifier: MIT-0
|
|
39
|
+
#++
|
|
27
40
|
# Returns <tt>nil</tt> (e.g., <tt>"enter"</tt>, <tt>"up"</tt>, <tt>"f1"</tt>).
|
|
28
41
|
#
|
|
29
42
|
# RatatuiRuby::Event::Key.new(code: "a").char # => "a"
|
|
30
43
|
# RatatuiRuby::Event::Key.new(code: "enter").char # => nil
|
|
44
|
+
#--
|
|
45
|
+
# SPDX-SnippetEnd
|
|
46
|
+
#++
|
|
31
47
|
def char
|
|
32
48
|
text? ? @code : nil
|
|
33
49
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -66,9 +66,17 @@ module RatatuiRuby
|
|
|
66
66
|
#
|
|
67
67
|
# === Example
|
|
68
68
|
#
|
|
69
|
+
#--
|
|
70
|
+
# SPDX-SnippetBegin
|
|
71
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
72
|
+
# SPDX-License-Identifier: MIT-0
|
|
73
|
+
#++
|
|
69
74
|
# if event.modifier?
|
|
70
75
|
# # Handle solo modifier key press
|
|
71
76
|
# end
|
|
77
|
+
#--
|
|
78
|
+
# SPDX-SnippetEnd
|
|
79
|
+
#++
|
|
72
80
|
def modifier?
|
|
73
81
|
@kind == :modifier
|
|
74
82
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
module RatatuiRuby
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
#--
|
|
4
|
-
# SPDX-FileCopyrightText:
|
|
5
|
-
# SPDX-License-Identifier:
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
6
|
#++
|
|
7
7
|
|
|
8
8
|
require_relative "key/character"
|
|
@@ -27,21 +27,45 @@ module RatatuiRuby
|
|
|
27
27
|
# === Examples
|
|
28
28
|
#
|
|
29
29
|
# Using predicates:
|
|
30
|
+
#--
|
|
31
|
+
# SPDX-SnippetBegin
|
|
32
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
33
|
+
# SPDX-License-Identifier: MIT-0
|
|
34
|
+
#++
|
|
30
35
|
# if event.key? && event.ctrl? && event.code == "c"
|
|
31
36
|
# exit
|
|
32
37
|
# end
|
|
33
38
|
#
|
|
39
|
+
#--
|
|
40
|
+
# SPDX-SnippetEnd
|
|
41
|
+
#++
|
|
34
42
|
# Using symbol comparison:
|
|
43
|
+
#--
|
|
44
|
+
# SPDX-SnippetBegin
|
|
45
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
46
|
+
# SPDX-License-Identifier: MIT-0
|
|
47
|
+
#++
|
|
35
48
|
# if event == :ctrl_c
|
|
36
49
|
# exit
|
|
37
50
|
# end
|
|
38
51
|
#
|
|
52
|
+
#--
|
|
53
|
+
# SPDX-SnippetEnd
|
|
54
|
+
#++
|
|
39
55
|
# Using pattern matching:
|
|
56
|
+
#--
|
|
57
|
+
# SPDX-SnippetBegin
|
|
58
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
59
|
+
# SPDX-License-Identifier: MIT-0
|
|
60
|
+
#++
|
|
40
61
|
# case event
|
|
41
62
|
# in type: :key, code: "c", modifiers: ["ctrl"]
|
|
42
63
|
# exit
|
|
43
64
|
# end
|
|
44
65
|
#
|
|
66
|
+
#--
|
|
67
|
+
# SPDX-SnippetEnd
|
|
68
|
+
#++
|
|
45
69
|
# === Terminal Compatibility
|
|
46
70
|
#
|
|
47
71
|
# Some key combinations never reach your application. Terminal emulators intercept them for
|
|
@@ -90,9 +114,17 @@ module RatatuiRuby
|
|
|
90
114
|
|
|
91
115
|
# Returns true for Key events.
|
|
92
116
|
#
|
|
117
|
+
#--
|
|
118
|
+
# SPDX-SnippetBegin
|
|
119
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
120
|
+
# SPDX-License-Identifier: MIT-0
|
|
121
|
+
#++
|
|
93
122
|
# event.key? # => true
|
|
94
123
|
# event.mouse? # => false
|
|
95
124
|
# event.resize? # => false
|
|
125
|
+
#--
|
|
126
|
+
# SPDX-SnippetEnd
|
|
127
|
+
#++
|
|
96
128
|
def key?
|
|
97
129
|
true
|
|
98
130
|
end
|
|
@@ -104,8 +136,16 @@ module RatatuiRuby
|
|
|
104
136
|
# [modifiers]
|
|
105
137
|
# List of modifiers (Array<String>).
|
|
106
138
|
# [kind]
|
|
139
|
+
#--
|
|
140
|
+
# SPDX-SnippetBegin
|
|
141
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
142
|
+
# SPDX-License-Identifier: MIT-0
|
|
143
|
+
#++
|
|
107
144
|
# The key category (Symbol). One of: <tt>:standard</tt>, <tt>:function</tt>,
|
|
108
145
|
# <tt>:media</tt>, <tt>:modifier</tt>, <tt>:system</tt>. Defaults to <tt>:standard</tt>.
|
|
146
|
+
#--
|
|
147
|
+
# SPDX-SnippetEnd
|
|
148
|
+
#++
|
|
109
149
|
def initialize(code:, modifiers: [], kind: :standard)
|
|
110
150
|
@code = code.freeze
|
|
111
151
|
@modifiers = modifiers.map(&:freeze).sort.freeze
|
|
@@ -141,8 +181,16 @@ module RatatuiRuby
|
|
|
141
181
|
# [Standard]
|
|
142
182
|
# <tt>:enter</tt>, <tt>:backspace</tt>, <tt>:tab</tt>, <tt>:back_tab</tt>, <tt>:esc</tt>, <tt>:null</tt>
|
|
143
183
|
# [Navigation]
|
|
184
|
+
#--
|
|
185
|
+
# SPDX-SnippetBegin
|
|
186
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
187
|
+
# SPDX-License-Identifier: MIT-0
|
|
188
|
+
#++
|
|
144
189
|
# <tt>:up</tt>, <tt>:down</tt>, <tt>:left</tt>, <tt>:right</tt>, <tt>:home</tt>, <tt>:end</tt>,
|
|
145
190
|
# <tt>:page_up</tt>, <tt>:page_down</tt>, <tt>:insert</tt>, <tt>:delete</tt>
|
|
191
|
+
#--
|
|
192
|
+
# SPDX-SnippetEnd
|
|
193
|
+
#++
|
|
146
194
|
# [Function Keys]
|
|
147
195
|
# <tt>:f1</tt> through <tt>:f12</tt> (and beyond, e.g. <tt>:f24</tt>)
|
|
148
196
|
# [Lock Keys]
|
|
@@ -150,17 +198,41 @@ module RatatuiRuby
|
|
|
150
198
|
# [System Keys]
|
|
151
199
|
# <tt>:print_screen</tt>, <tt>:pause</tt>, <tt>:menu</tt>, <tt>:keypad_begin</tt>
|
|
152
200
|
# [Media Keys]
|
|
201
|
+
#--
|
|
202
|
+
# SPDX-SnippetBegin
|
|
203
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
204
|
+
# SPDX-License-Identifier: MIT-0
|
|
205
|
+
#++
|
|
153
206
|
# <tt>:play</tt>, <tt>:media_pause</tt>, <tt>:play_pause</tt>, <tt>:reverse</tt>, <tt>:stop</tt>,
|
|
154
207
|
# <tt>:fast_forward</tt>, <tt>:rewind</tt>, <tt>:track_next</tt>, <tt>:track_previous</tt>,
|
|
155
208
|
# <tt>:record</tt>, <tt>:lower_volume</tt>, <tt>:raise_volume</tt>, <tt>:mute_volume</tt>
|
|
209
|
+
#--
|
|
210
|
+
# SPDX-SnippetEnd
|
|
211
|
+
#++
|
|
156
212
|
# [Modifier Keys]
|
|
213
|
+
#--
|
|
214
|
+
# SPDX-SnippetBegin
|
|
215
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
216
|
+
# SPDX-License-Identifier: MIT-0
|
|
217
|
+
#++
|
|
157
218
|
# <tt>:left_shift</tt>, <tt>:left_control</tt>, <tt>:left_alt</tt>, <tt>:left_super</tt>,
|
|
158
219
|
# <tt>:left_hyper</tt>, <tt>:left_meta</tt>, <tt>:right_shift</tt>, <tt>:right_control</tt>,
|
|
159
220
|
# <tt>:right_alt</tt>, <tt>:right_super</tt>, <tt>:right_hyper</tt>, <tt>:right_meta</tt>,
|
|
160
221
|
# <tt>:iso_level3_shift</tt>, <tt>:iso_level5_shift</tt>
|
|
222
|
+
#--
|
|
223
|
+
# SPDX-SnippetEnd
|
|
224
|
+
#++
|
|
161
225
|
# [Characters]
|
|
226
|
+
#--
|
|
227
|
+
# SPDX-SnippetBegin
|
|
228
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
229
|
+
# SPDX-License-Identifier: MIT-0
|
|
230
|
+
#++
|
|
162
231
|
# <tt>:a</tt>, <tt>:b</tt>, <tt>:1</tt>, <tt>:space</tt>, etc.
|
|
163
232
|
#
|
|
233
|
+
#--
|
|
234
|
+
# SPDX-SnippetEnd
|
|
235
|
+
#++
|
|
164
236
|
# === Modifier Examples
|
|
165
237
|
#
|
|
166
238
|
# * <tt>:ctrl_c</tt>
|
|
@@ -183,8 +255,16 @@ module RatatuiRuby
|
|
|
183
255
|
# [Special Keys]
|
|
184
256
|
# Returns an empty string (e.g., <tt>"enter"</tt>, <tt>"up"</tt>, <tt>"f1"</tt> all return <tt>""</tt>).
|
|
185
257
|
# [Modifiers]
|
|
258
|
+
#--
|
|
259
|
+
# SPDX-SnippetBegin
|
|
260
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
261
|
+
# SPDX-License-Identifier: MIT-0
|
|
262
|
+
#++
|
|
186
263
|
# Returns the character if printable, ignoring modifiers unless they alter the character code itself.
|
|
187
264
|
# Note that <tt>ctrl+c</tt> typically returns <tt>"c"</tt> as the code, so +to_s+ will return <tt>"c"</tt>.
|
|
265
|
+
#--
|
|
266
|
+
# SPDX-SnippetEnd
|
|
267
|
+
#++
|
|
188
268
|
def to_s
|
|
189
269
|
if text?
|
|
190
270
|
@code
|
|
@@ -202,11 +282,19 @@ module RatatuiRuby
|
|
|
202
282
|
#
|
|
203
283
|
# Allows convenient checking for specific keys or key combinations:
|
|
204
284
|
#
|
|
285
|
+
#--
|
|
286
|
+
# SPDX-SnippetBegin
|
|
287
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
288
|
+
# SPDX-License-Identifier: MIT-0
|
|
289
|
+
#++
|
|
205
290
|
# event.ctrl_c? # => true if Ctrl+C
|
|
206
291
|
# event.enter? # => true if Enter
|
|
207
292
|
# event.shift_up? # => true if Shift+Up
|
|
208
293
|
# event.q? # => true if "q"
|
|
209
294
|
#
|
|
295
|
+
#--
|
|
296
|
+
# SPDX-SnippetEnd
|
|
297
|
+
#++
|
|
210
298
|
# The method name is converted to a symbol and compared against the event.
|
|
211
299
|
# This works for any key code or modifier+key combination.
|
|
212
300
|
#
|
|
@@ -214,18 +302,34 @@ module RatatuiRuby
|
|
|
214
302
|
#
|
|
215
303
|
# For convenience, generic predicates match both system and media variants:
|
|
216
304
|
#
|
|
305
|
+
#--
|
|
306
|
+
# SPDX-SnippetBegin
|
|
307
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
308
|
+
# SPDX-License-Identifier: MIT-0
|
|
309
|
+
#++
|
|
217
310
|
# event.pause? # => true for BOTH system "pause" AND "media_pause"
|
|
218
311
|
# event.play? # => true for "media_play"
|
|
219
312
|
# event.stop? # => true for "media_stop"
|
|
220
313
|
#
|
|
314
|
+
#--
|
|
315
|
+
# SPDX-SnippetEnd
|
|
316
|
+
#++
|
|
221
317
|
# This "Do What I Mean" behavior reduces boilerplate when you just want to
|
|
222
318
|
# respond to a conceptual action (e.g., "pause the playback") regardless of
|
|
223
319
|
# whether the user pressed a keyboard key or a media button.
|
|
224
320
|
#
|
|
225
321
|
# For strict matching, use the full predicate or compare the code directly:
|
|
226
322
|
#
|
|
323
|
+
#--
|
|
324
|
+
# SPDX-SnippetBegin
|
|
325
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
326
|
+
# SPDX-License-Identifier: MIT-0
|
|
327
|
+
#++
|
|
227
328
|
# event.media_pause? # => true ONLY for media pause
|
|
228
329
|
# event.code == "pause" # => true ONLY for system pause
|
|
330
|
+
#--
|
|
331
|
+
# SPDX-SnippetEnd
|
|
332
|
+
#++
|
|
229
333
|
def method_missing(name, *args, &block)
|
|
230
334
|
if name.to_s.end_with?("?")
|
|
231
335
|
key_name = name.to_s[0...-1]
|
|
@@ -259,12 +363,20 @@ module RatatuiRuby
|
|
|
259
363
|
|
|
260
364
|
# Deconstructs the event for pattern matching.
|
|
261
365
|
#
|
|
366
|
+
#--
|
|
367
|
+
# SPDX-SnippetBegin
|
|
368
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
369
|
+
# SPDX-License-Identifier: MIT-0
|
|
370
|
+
#++
|
|
262
371
|
# case event
|
|
263
372
|
# in type: :key, code: "c", modifiers: ["ctrl"]
|
|
264
373
|
# puts "Ctrl+C pressed"
|
|
265
374
|
# in type: :key, kind: :media
|
|
266
375
|
# puts "Media key pressed"
|
|
267
376
|
# end
|
|
377
|
+
#--
|
|
378
|
+
# SPDX-SnippetEnd
|
|
379
|
+
#++
|
|
268
380
|
def deconstruct_keys(keys)
|
|
269
381
|
{ type: :key, code: @code, modifiers: @modifiers, kind: @kind }
|
|
270
382
|
end
|