ratatui_ruby 0.7.4 → 0.9.0
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 +70 -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 +15 -175
- data/doc/getting_started/quickstart.md +35 -9
- 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 +127 -6
- 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 +13 -1
- data/examples/verify_quickstart_lifecycle/app.rb +10 -4
- 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 +3 -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/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.rb +26 -2
- data/lib/ratatui_ruby/frame.rb +74 -2
- data/lib/ratatui_ruby/layout/constraint.rb +58 -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 +171 -0
- 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/table_state.rb +10 -2
- data/lib/ratatui_ruby/terminal_lifecycle.rb +144 -0
- data/lib/ratatui_ruby/test_helper/event_injection.rb +34 -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 +116 -81
- 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 +6 -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 +9 -3
- 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
|
@@ -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,6 +17,11 @@ module RatatuiRuby
|
|
|
17
17
|
#
|
|
18
18
|
# === Examples
|
|
19
19
|
#
|
|
20
|
+
#--
|
|
21
|
+
# SPDX-SnippetBegin
|
|
22
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
23
|
+
# SPDX-License-Identifier: MIT-0
|
|
24
|
+
#++
|
|
20
25
|
# # Basic Text
|
|
21
26
|
# Paragraph.new(text: "Hello, World!")
|
|
22
27
|
#
|
|
@@ -30,6 +35,9 @@ module RatatuiRuby
|
|
|
30
35
|
#
|
|
31
36
|
# # Scrolling mechanism
|
|
32
37
|
# Paragraph.new(text: large_text, scroll: [scroll_y, 0])
|
|
38
|
+
#--
|
|
39
|
+
# SPDX-SnippetEnd
|
|
40
|
+
#++
|
|
33
41
|
class Paragraph < Data.define(:text, :style, :block, :wrap, :alignment, :scroll)
|
|
34
42
|
##
|
|
35
43
|
# :attr_reader: text
|
|
@@ -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
|
module RatatuiRuby
|
|
@@ -17,6 +17,11 @@ module RatatuiRuby
|
|
|
17
17
|
#
|
|
18
18
|
# === Examples
|
|
19
19
|
#
|
|
20
|
+
#--
|
|
21
|
+
# SPDX-SnippetBegin
|
|
22
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
23
|
+
# SPDX-License-Identifier: MIT-0
|
|
24
|
+
#++
|
|
20
25
|
# # Row with red background
|
|
21
26
|
# Row.new(cells: ["Error", "Something went wrong"], style: Style.new(bg: :red))
|
|
22
27
|
#
|
|
@@ -28,6 +33,9 @@ module RatatuiRuby
|
|
|
28
33
|
# ],
|
|
29
34
|
# height: 2
|
|
30
35
|
# )
|
|
36
|
+
#--
|
|
37
|
+
# SPDX-SnippetEnd
|
|
38
|
+
#++
|
|
31
39
|
class Row < Data.define(:cells, :style, :height, :top_margin, :bottom_margin)
|
|
32
40
|
##
|
|
33
41
|
# :attr_reader: cells
|
|
@@ -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
|
|
@@ -20,6 +20,11 @@ module RatatuiRuby
|
|
|
20
20
|
#
|
|
21
21
|
# === Examples
|
|
22
22
|
#
|
|
23
|
+
#--
|
|
24
|
+
# SPDX-SnippetBegin
|
|
25
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
26
|
+
# SPDX-License-Identifier: MIT-0
|
|
27
|
+
#++
|
|
23
28
|
# # Simple label
|
|
24
29
|
# Shape::Label.new(x: 0, y: 0, text: "Origin")
|
|
25
30
|
#
|
|
@@ -38,6 +43,9 @@ module RatatuiRuby
|
|
|
38
43
|
# Text::Span.new(content: "World", style: Style.new(fg: :blue))
|
|
39
44
|
# ])
|
|
40
45
|
# )
|
|
46
|
+
#--
|
|
47
|
+
# SPDX-SnippetEnd
|
|
48
|
+
#++
|
|
41
49
|
class Label < Data.define(:x, :y, :text, :style)
|
|
42
50
|
##
|
|
43
51
|
# :attr_reader: x
|
|
@@ -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
|
|
@@ -72,6 +72,11 @@ module RatatuiRuby
|
|
|
72
72
|
#
|
|
73
73
|
# === Examples
|
|
74
74
|
#
|
|
75
|
+
#--
|
|
76
|
+
# SPDX-SnippetBegin
|
|
77
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
78
|
+
# SPDX-License-Identifier: MIT-0
|
|
79
|
+
#++
|
|
75
80
|
# bar_set: {
|
|
76
81
|
# empty: " ",
|
|
77
82
|
# one_eighth: " ",
|
|
@@ -91,6 +96,9 @@ module RatatuiRuby
|
|
|
91
96
|
#
|
|
92
97
|
# # Array (9 items)
|
|
93
98
|
# bar_set: [" ", " ", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
|
|
99
|
+
#--
|
|
100
|
+
# SPDX-SnippetEnd
|
|
101
|
+
#++
|
|
94
102
|
|
|
95
103
|
BAR_KEYS = %i[empty one_eighth one_quarter three_eighths half five_eighths three_quarters seven_eighths full].freeze
|
|
96
104
|
|
|
@@ -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
|
|
@@ -24,6 +24,38 @@ module RatatuiRuby
|
|
|
24
24
|
#
|
|
25
25
|
# ruby examples/widget_table_flex/app.rb
|
|
26
26
|
class Table < Data.define(:header, :rows, :widths, :row_highlight_style, :highlight_symbol, :highlight_spacing, :column_highlight_style, :cell_highlight_style, :selected_row, :selected_column, :offset, :block, :footer, :flex, :style, :column_spacing)
|
|
27
|
+
##
|
|
28
|
+
# Highlight spacing: always show the spacing column.
|
|
29
|
+
HIGHLIGHT_ALWAYS = :always
|
|
30
|
+
##
|
|
31
|
+
# Highlight spacing: show spacing only when a row is selected (default).
|
|
32
|
+
HIGHLIGHT_WHEN_SELECTED = :when_selected
|
|
33
|
+
##
|
|
34
|
+
# Highlight spacing: never show the spacing column.
|
|
35
|
+
HIGHLIGHT_NEVER = :never
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Flex: use legacy column sizing.
|
|
39
|
+
FLEX_LEGACY = :legacy
|
|
40
|
+
##
|
|
41
|
+
# Flex: align columns to start.
|
|
42
|
+
FLEX_START = :start
|
|
43
|
+
##
|
|
44
|
+
# Flex: center columns.
|
|
45
|
+
FLEX_CENTER = :center
|
|
46
|
+
##
|
|
47
|
+
# Flex: align columns to end.
|
|
48
|
+
FLEX_END = :end
|
|
49
|
+
##
|
|
50
|
+
# Flex: space between columns.
|
|
51
|
+
FLEX_SPACE_BETWEEN = :space_between
|
|
52
|
+
##
|
|
53
|
+
# Flex: space around columns.
|
|
54
|
+
FLEX_SPACE_AROUND = :space_around
|
|
55
|
+
##
|
|
56
|
+
# Flex: space evenly between columns.
|
|
57
|
+
FLEX_SPACE_EVENLY = :space_evenly
|
|
58
|
+
|
|
27
59
|
##
|
|
28
60
|
# :attr_reader: header
|
|
29
61
|
# Header row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
|
|
@@ -138,6 +170,34 @@ module RatatuiRuby
|
|
|
138
170
|
column_spacing: Integer(column_spacing)
|
|
139
171
|
)
|
|
140
172
|
end
|
|
173
|
+
|
|
174
|
+
# Returns true if a row is selected.
|
|
175
|
+
#
|
|
176
|
+
# @return [Boolean]
|
|
177
|
+
def row_selected?
|
|
178
|
+
!selected_row.nil?
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Returns true if a column is selected.
|
|
182
|
+
#
|
|
183
|
+
# @return [Boolean]
|
|
184
|
+
def column_selected?
|
|
185
|
+
!selected_column.nil?
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Returns true if both a row and column are selected (a cell is selected).
|
|
189
|
+
#
|
|
190
|
+
# @return [Boolean]
|
|
191
|
+
def cell_selected?
|
|
192
|
+
row_selected? && column_selected?
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Returns true if the table has no rows.
|
|
196
|
+
#
|
|
197
|
+
# @return [Boolean]
|
|
198
|
+
def empty?
|
|
199
|
+
rows.empty?
|
|
200
|
+
end
|
|
141
201
|
end
|
|
142
202
|
end
|
|
143
203
|
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
|
data/lib/ratatui_ruby/widgets.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.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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 "ratatui_ruby/version"
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Core types (mirrors ratatui Rust crate)
|
|
11
11
|
require_relative "ratatui_ruby/layout" # Layout::Rect, Layout::Constraint, Layout::Layout
|
|
12
12
|
require_relative "ratatui_ruby/style" # Style::Style
|
|
13
13
|
require_relative "ratatui_ruby/widgets" # Widgets::Block, Widgets::Paragraph, etc.
|
|
@@ -24,6 +24,10 @@ require_relative "ratatui_ruby/list_state"
|
|
|
24
24
|
require_relative "ratatui_ruby/table_state"
|
|
25
25
|
require_relative "ratatui_ruby/scrollbar_state"
|
|
26
26
|
|
|
27
|
+
# Behavioral mixins
|
|
28
|
+
require_relative "ratatui_ruby/output_guard"
|
|
29
|
+
require_relative "ratatui_ruby/terminal_lifecycle"
|
|
30
|
+
|
|
27
31
|
# TUI facade (for external instantiation and caching)
|
|
28
32
|
require_relative "ratatui_ruby/tui"
|
|
29
33
|
|
|
@@ -49,11 +53,19 @@ module RatatuiRuby
|
|
|
49
53
|
#
|
|
50
54
|
# === Example
|
|
51
55
|
#
|
|
56
|
+
#--
|
|
57
|
+
# SPDX-SnippetBegin
|
|
58
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
59
|
+
# SPDX-License-Identifier: MIT-0
|
|
60
|
+
#++
|
|
52
61
|
# begin
|
|
53
62
|
# RatatuiRuby.run { |tui| ... }
|
|
54
63
|
# rescue RatatuiRuby::Error => e
|
|
55
64
|
# puts "RatatuiRuby error: #{e.message}"
|
|
56
65
|
# end
|
|
66
|
+
#--
|
|
67
|
+
# SPDX-SnippetEnd
|
|
68
|
+
#++
|
|
57
69
|
class Error < StandardError
|
|
58
70
|
# Operational failure during terminal I/O.
|
|
59
71
|
#
|
|
@@ -67,11 +79,19 @@ module RatatuiRuby
|
|
|
67
79
|
#
|
|
68
80
|
# === Example
|
|
69
81
|
#
|
|
82
|
+
#--
|
|
83
|
+
# SPDX-SnippetBegin
|
|
84
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
85
|
+
# SPDX-License-Identifier: MIT-0
|
|
86
|
+
#++
|
|
70
87
|
# begin
|
|
71
88
|
# RatatuiRuby.init_terminal
|
|
72
89
|
# rescue RatatuiRuby::Error::Terminal => e
|
|
73
90
|
# puts "Terminal failed: #{e.message}"
|
|
74
91
|
# end
|
|
92
|
+
#--
|
|
93
|
+
# SPDX-SnippetEnd
|
|
94
|
+
#++
|
|
75
95
|
class Terminal < Error; end
|
|
76
96
|
|
|
77
97
|
# Object lifetime violation.
|
|
@@ -87,9 +107,17 @@ module RatatuiRuby
|
|
|
87
107
|
#
|
|
88
108
|
# === Example
|
|
89
109
|
#
|
|
110
|
+
#--
|
|
111
|
+
# SPDX-SnippetBegin
|
|
112
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
113
|
+
# SPDX-License-Identifier: MIT-0
|
|
114
|
+
#++
|
|
90
115
|
# stored_frame = nil
|
|
91
116
|
# RatatuiRuby.draw { |frame| stored_frame = frame }
|
|
92
117
|
# stored_frame.area # => raises Error::Safety
|
|
118
|
+
#--
|
|
119
|
+
# SPDX-SnippetEnd
|
|
120
|
+
#++
|
|
93
121
|
class Safety < Error; end
|
|
94
122
|
|
|
95
123
|
# State invariant violation.
|
|
@@ -105,49 +133,31 @@ module RatatuiRuby
|
|
|
105
133
|
#
|
|
106
134
|
# === Example
|
|
107
135
|
#
|
|
136
|
+
#--
|
|
137
|
+
# SPDX-SnippetBegin
|
|
138
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
139
|
+
# SPDX-License-Identifier: MIT-0
|
|
140
|
+
#++
|
|
108
141
|
# RatatuiRuby.init_terminal
|
|
109
142
|
# RatatuiRuby.init_terminal # => raises Error::Invariant
|
|
143
|
+
#--
|
|
144
|
+
# SPDX-SnippetEnd
|
|
145
|
+
#++
|
|
110
146
|
class Invariant < Error; end
|
|
111
147
|
end
|
|
112
148
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
-
def self.init_terminal(focus_events: true, bracketed_paste: true)
|
|
120
|
-
if @tui_session_active
|
|
121
|
-
raise Error::Invariant, "Cannot initialize terminal: TUI session already active"
|
|
122
|
-
end
|
|
123
|
-
@tui_session_active = true
|
|
124
|
-
_init_terminal(focus_events, bracketed_paste)
|
|
125
|
-
end
|
|
149
|
+
# Mix in terminal lifecycle and output protection methods
|
|
150
|
+
extend OutputGuard
|
|
151
|
+
extend TerminalLifecycle
|
|
152
|
+
|
|
153
|
+
# Re-export NullIO at module root for backward compatibility
|
|
154
|
+
NullIO = OutputGuard::NullIO
|
|
126
155
|
|
|
127
156
|
@experimental_warnings = true
|
|
128
157
|
@tui_session_active = false
|
|
158
|
+
@headless_mode = false
|
|
129
159
|
@deferred_warnings = []
|
|
130
160
|
|
|
131
|
-
##
|
|
132
|
-
# Whether a TUI session is currently active.
|
|
133
|
-
#
|
|
134
|
-
# Writing to stdout/stderr during a TUI session corrupts the display.
|
|
135
|
-
# Use this to defer logging, warnings, or debug output until
|
|
136
|
-
# after the session ends.
|
|
137
|
-
#
|
|
138
|
-
# === Example
|
|
139
|
-
#
|
|
140
|
-
# def log(message)
|
|
141
|
-
# if RatatuiRuby.terminal_active?
|
|
142
|
-
# @deferred_logs << message
|
|
143
|
-
# else
|
|
144
|
-
# puts message
|
|
145
|
-
# end
|
|
146
|
-
# end
|
|
147
|
-
def self.terminal_active?
|
|
148
|
-
@tui_session_active
|
|
149
|
-
end
|
|
150
|
-
|
|
151
161
|
class << self
|
|
152
162
|
##
|
|
153
163
|
# :attr_accessor: experimental_warnings
|
|
@@ -165,25 +175,22 @@ module RatatuiRuby
|
|
|
165
175
|
end
|
|
166
176
|
end
|
|
167
177
|
|
|
168
|
-
##
|
|
169
|
-
# Restores the terminal to its original state.
|
|
170
|
-
# Leaves alternate screen and disables raw mode.
|
|
171
|
-
# Also flushes any deferred warnings that were queued during the session.
|
|
172
|
-
def self.restore_terminal
|
|
173
|
-
_restore_terminal
|
|
174
|
-
ensure
|
|
175
|
-
@tui_session_active = false
|
|
176
|
-
flush_warnings
|
|
177
|
-
end
|
|
178
|
-
|
|
179
178
|
##
|
|
180
179
|
# :singleton-method: inject_test_event
|
|
181
180
|
# Injects a mock event into the event queue for testing purposes.
|
|
182
181
|
# [event_type] "key" or "mouse"
|
|
183
182
|
# [data] a Hash containing event data
|
|
184
183
|
#
|
|
184
|
+
#--
|
|
185
|
+
# SPDX-SnippetBegin
|
|
186
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
187
|
+
# SPDX-License-Identifier: MIT-0
|
|
188
|
+
#++
|
|
185
189
|
# inject_test_event("key", { code: "a" })
|
|
186
190
|
#
|
|
191
|
+
#--
|
|
192
|
+
# SPDX-SnippetEnd
|
|
193
|
+
#++
|
|
187
194
|
# (Native method implemented in Rust)
|
|
188
195
|
|
|
189
196
|
##
|
|
@@ -207,20 +214,6 @@ module RatatuiRuby
|
|
|
207
214
|
@warned_features[feature_name] = true
|
|
208
215
|
end
|
|
209
216
|
|
|
210
|
-
##
|
|
211
|
-
# Initializes a test terminal for unit testing.
|
|
212
|
-
# Sets session active state like init_terminal.
|
|
213
|
-
#
|
|
214
|
-
# [width] Integer width of the test terminal.
|
|
215
|
-
# [height] Integer height of the test terminal.
|
|
216
|
-
def self.init_test_terminal(width, height)
|
|
217
|
-
if @tui_session_active
|
|
218
|
-
raise Error::Invariant, "Cannot initialize terminal: TUI session already active"
|
|
219
|
-
end
|
|
220
|
-
@tui_session_active = true
|
|
221
|
-
_init_test_terminal(width, height)
|
|
222
|
-
end
|
|
223
|
-
|
|
224
217
|
# (Native methods implemented in Rust)
|
|
225
218
|
private_class_method :_init_terminal, :_restore_terminal, :_init_test_terminal
|
|
226
219
|
|
|
@@ -236,20 +229,44 @@ module RatatuiRuby
|
|
|
236
229
|
# {Frame} object for imperative drawing.
|
|
237
230
|
#
|
|
238
231
|
# [tree] A widget tree (Widgets::Paragraph, Layout::Layout, etc.) to render. Optional if
|
|
232
|
+
#--
|
|
233
|
+
# SPDX-SnippetBegin
|
|
234
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
235
|
+
# SPDX-License-Identifier: MIT-0
|
|
236
|
+
#++
|
|
239
237
|
# a block is given.
|
|
240
238
|
#
|
|
239
|
+
#--
|
|
240
|
+
# SPDX-SnippetEnd
|
|
241
|
+
#++
|
|
241
242
|
# === Examples
|
|
242
243
|
#
|
|
243
244
|
# Legacy declarative style (tree-based):
|
|
244
245
|
#
|
|
246
|
+
#--
|
|
247
|
+
# SPDX-SnippetBegin
|
|
248
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
249
|
+
# SPDX-License-Identifier: MIT-0
|
|
250
|
+
#++
|
|
245
251
|
# RatatuiRuby.draw(Widgets::Paragraph.new(text: "Hello"))
|
|
246
252
|
#
|
|
253
|
+
#--
|
|
254
|
+
# SPDX-SnippetEnd
|
|
255
|
+
#++
|
|
247
256
|
# New imperative style (block-based):
|
|
248
257
|
#
|
|
258
|
+
#--
|
|
259
|
+
# SPDX-SnippetBegin
|
|
260
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
261
|
+
# SPDX-License-Identifier: MIT-0
|
|
262
|
+
#++
|
|
249
263
|
# RatatuiRuby.draw do |frame|
|
|
250
264
|
# frame.render_widget(Widgets::Paragraph.new(text: "Hello"), frame.area)
|
|
251
265
|
# end
|
|
252
266
|
#
|
|
267
|
+
#--
|
|
268
|
+
# SPDX-SnippetEnd
|
|
269
|
+
#++
|
|
253
270
|
def self.draw(tree = nil, &block)
|
|
254
271
|
if tree && block
|
|
255
272
|
raise ArgumentError, "Cannot provide both a tree and a block to draw"
|
|
@@ -276,11 +293,24 @@ module RatatuiRuby
|
|
|
276
293
|
# This method checks for an event. It returns the event if one is found. It returns {RatatuiRuby::Event::None} if the timeout expires.
|
|
277
294
|
#
|
|
278
295
|
# [timeout] Float seconds to wait (default: 0.016).
|
|
296
|
+
#--
|
|
297
|
+
# SPDX-SnippetBegin
|
|
298
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
299
|
+
# SPDX-License-Identifier: MIT-0
|
|
300
|
+
#++
|
|
279
301
|
# Pass <tt>nil</tt> to block indefinitely (wait forever).
|
|
280
302
|
# Pass <tt>0.0</tt> for a non-blocking check.
|
|
281
303
|
#
|
|
304
|
+
#--
|
|
305
|
+
# SPDX-SnippetEnd
|
|
306
|
+
#++
|
|
282
307
|
# === Examples
|
|
283
308
|
#
|
|
309
|
+
#--
|
|
310
|
+
# SPDX-SnippetBegin
|
|
311
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
312
|
+
# SPDX-License-Identifier: MIT-0
|
|
313
|
+
#++
|
|
284
314
|
# # Standard loop (approx 60 FPS)
|
|
285
315
|
# event = RatatuiRuby.poll_event
|
|
286
316
|
#
|
|
@@ -290,6 +320,9 @@ module RatatuiRuby
|
|
|
290
320
|
# # Non-blocking check (returns immediately)
|
|
291
321
|
# event = RatatuiRuby.poll_event(timeout: 0.0)
|
|
292
322
|
#
|
|
323
|
+
#--
|
|
324
|
+
# SPDX-SnippetEnd
|
|
325
|
+
#++
|
|
293
326
|
def self.poll_event(timeout: 0.016)
|
|
294
327
|
raise ArgumentError, "timeout must be non-negative" if timeout && timeout < 0
|
|
295
328
|
|
|
@@ -328,26 +361,6 @@ module RatatuiRuby
|
|
|
328
361
|
# (Native method _poll_event implemented in Rust)
|
|
329
362
|
private_class_method :_poll_event
|
|
330
363
|
|
|
331
|
-
##
|
|
332
|
-
# Starts the TUI application lifecycle.
|
|
333
|
-
#
|
|
334
|
-
# Managing generic setup/teardown (raw mode, alternate screen) manualy is error-prone. If your app crashes, the terminal might be left in a broken state.
|
|
335
|
-
#
|
|
336
|
-
# This method handles the safety net. It initializes the terminal, yields a {TUI}, and ensures the terminal state is restored even if exceptions occur.
|
|
337
|
-
#
|
|
338
|
-
# === Example
|
|
339
|
-
#
|
|
340
|
-
# RatatuiRuby.run(focus_events: false) do |tui|
|
|
341
|
-
# tui.draw(tui.paragraph(text: "Hi"))
|
|
342
|
-
# sleep 1
|
|
343
|
-
# end
|
|
344
|
-
def self.run(focus_events: true, bracketed_paste: true)
|
|
345
|
-
init_terminal(focus_events:, bracketed_paste:)
|
|
346
|
-
yield TUI.new
|
|
347
|
-
ensure
|
|
348
|
-
restore_terminal
|
|
349
|
-
end
|
|
350
|
-
|
|
351
364
|
##
|
|
352
365
|
# Inspects the terminal buffer at specific coordinates.
|
|
353
366
|
#
|
|
@@ -360,11 +373,19 @@ module RatatuiRuby
|
|
|
360
373
|
#
|
|
361
374
|
# === Example
|
|
362
375
|
#
|
|
376
|
+
#--
|
|
377
|
+
# SPDX-SnippetBegin
|
|
378
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long
|
|
379
|
+
# SPDX-License-Identifier: MIT-0
|
|
380
|
+
#++
|
|
363
381
|
# cell = RatatuiRuby.get_cell_at(10, 5)
|
|
364
382
|
# expect(cell.symbol).to eq("X")
|
|
365
383
|
# expect(cell.fg).to eq(:red)
|
|
366
384
|
# expect(cell).to be_bold
|
|
367
385
|
#
|
|
386
|
+
#--
|
|
387
|
+
# SPDX-SnippetEnd
|
|
388
|
+
#++
|
|
368
389
|
def self.get_cell_at(x, y)
|
|
369
390
|
raw = _get_cell_at(x, y)
|
|
370
391
|
Buffer::Cell.new(
|
|
@@ -380,4 +401,18 @@ module RatatuiRuby
|
|
|
380
401
|
|
|
381
402
|
# Hide native Layout._split helper
|
|
382
403
|
Layout::Layout.singleton_class.__send__(:private, :_split)
|
|
404
|
+
|
|
405
|
+
# --- Terminal Safety Hooks ---
|
|
406
|
+
# These ensure the terminal is restored even on unexpected exits.
|
|
407
|
+
|
|
408
|
+
at_exit do
|
|
409
|
+
restore_terminal if terminal_active?
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
%i[INT TERM].each do |signal|
|
|
413
|
+
trap(signal) do
|
|
414
|
+
restore_terminal if terminal_active?
|
|
415
|
+
exit(128 + Signal.list[signal.to_s])
|
|
416
|
+
end
|
|
417
|
+
end
|
|
383
418
|
end
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
2
8
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
9
|
|
|
4
10
|
module View
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
2
8
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
9
|
|
|
4
10
|
class ViewState < Data
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
3
8
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
9
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
10
|
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
2
8
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
9
|
|
|
4
10
|
class AppStatefulInteraction
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
|
+
#++
|
|
7
|
+
|
|
2
8
|
#
|
|
3
9
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
10
|
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: MIT-0
|
|
6
|
+
#++
|
|
7
|
+
|
|
2
8
|
#
|
|
3
9
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
10
|
|