ratatui_ruby 0.9.1 → 0.10.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 +1 -1
- data/.builds/ruby-3.3.yml +1 -1
- data/.builds/ruby-3.4.yml +1 -1
- data/.builds/ruby-4.0.0.yml +1 -1
- data/AGENTS.md +2 -1
- data/CHANGELOG.md +113 -0
- data/README.md +17 -0
- data/REUSE.toml +5 -0
- data/Rakefile +1 -1
- data/Steepfile +49 -0
- data/doc/concepts/debugging.md +401 -0
- data/doc/getting_started/quickstart.md +8 -3
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_debugging_showcase.gif +0 -0
- data/doc/images/app_debugging_showcase.png +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_stateful_interaction.png +0 -0
- data/doc/images/verify_quickstart_dsl.png +0 -0
- data/doc/images/verify_quickstart_layout.png +0 -0
- data/doc/images/verify_quickstart_lifecycle.png +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_barchart.png +0 -0
- data/doc/images/widget_block.png +0 -0
- data/doc/images/widget_box.png +0 -0
- data/doc/images/widget_calendar.png +0 -0
- data/doc/images/widget_canvas.png +0 -0
- data/doc/images/widget_cell.png +0 -0
- data/doc/images/widget_center.png +0 -0
- data/doc/images/widget_chart.png +0 -0
- data/doc/images/widget_gauge.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge.png +0 -0
- data/doc/images/widget_list.png +0 -0
- data/doc/images/widget_map.png +0 -0
- data/doc/images/widget_overlay.png +0 -0
- data/doc/images/widget_popup.png +0 -0
- data/doc/images/widget_ratatui_logo.png +0 -0
- data/doc/images/widget_ratatui_mascot.png +0 -0
- data/doc/images/widget_rect.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_rich_text.png +0 -0
- data/doc/images/widget_scroll_text.png +0 -0
- data/doc/images/widget_scrollbar.png +0 -0
- data/doc/images/widget_sparkline.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table.png +0 -0
- data/doc/images/widget_tabs.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/troubleshooting/async.md +4 -0
- data/examples/app_debugging_showcase/README.md +119 -0
- data/examples/app_debugging_showcase/app.rb +318 -0
- data/examples/widget_canvas/app.rb +19 -14
- data/examples/widget_gauge/app.rb +18 -3
- data/examples/widget_layout_split/app.rb +10 -4
- data/examples/widget_list/app.rb +22 -6
- data/examples/widget_rect/app.rb +7 -6
- data/examples/widget_rich_text/app.rb +62 -37
- data/examples/widget_style_colors/app.rb +26 -47
- data/examples/widget_table/app.rb +28 -5
- data/examples/widget_text_width/app.rb +6 -4
- data/ext/ratatui_ruby/Cargo.lock +48 -1
- data/ext/ratatui_ruby/Cargo.toml +6 -2
- data/ext/ratatui_ruby/src/color.rs +82 -0
- data/ext/ratatui_ruby/src/errors.rs +28 -0
- data/ext/ratatui_ruby/src/events.rs +15 -14
- data/ext/ratatui_ruby/src/lib.rs +56 -0
- data/ext/ratatui_ruby/src/rendering.rs +3 -1
- data/ext/ratatui_ruby/src/style.rs +48 -21
- data/ext/ratatui_ruby/src/terminal.rs +40 -9
- data/ext/ratatui_ruby/src/text.rs +21 -9
- data/ext/ratatui_ruby/src/widgets/chart.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/layout.rs +90 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +6 -5
- data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/table.rs +7 -6
- data/ext/ratatui_ruby/src/widgets/table_state.rs +55 -0
- data/ext/ratatui_ruby/src/widgets/tabs.rs +3 -2
- data/lib/ratatui_ruby/buffer/cell.rb +25 -15
- data/lib/ratatui_ruby/buffer.rb +134 -2
- data/lib/ratatui_ruby/cell.rb +13 -5
- data/lib/ratatui_ruby/debug.rb +215 -0
- data/lib/ratatui_ruby/event/key.rb +3 -2
- data/lib/ratatui_ruby/event.rb +1 -1
- data/lib/ratatui_ruby/layout/constraint.rb +49 -0
- data/lib/ratatui_ruby/layout/layout.rb +119 -13
- data/lib/ratatui_ruby/layout/position.rb +55 -0
- data/lib/ratatui_ruby/layout/rect.rb +188 -0
- data/lib/ratatui_ruby/layout/size.rb +55 -0
- data/lib/ratatui_ruby/layout.rb +4 -0
- data/lib/ratatui_ruby/style/color.rb +149 -0
- data/lib/ratatui_ruby/style/style.rb +51 -4
- data/lib/ratatui_ruby/style.rb +2 -0
- data/lib/ratatui_ruby/symbols.rb +435 -0
- data/lib/ratatui_ruby/synthetic_events.rb +1 -1
- data/lib/ratatui_ruby/table_state.rb +51 -0
- data/lib/ratatui_ruby/terminal_lifecycle.rb +2 -1
- data/lib/ratatui_ruby/test_helper/event_injection.rb +6 -1
- data/lib/ratatui_ruby/test_helper.rb +9 -0
- data/lib/ratatui_ruby/text/line.rb +245 -0
- data/lib/ratatui_ruby/text/span.rb +158 -0
- data/lib/ratatui_ruby/text.rb +99 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +103 -0
- data/lib/ratatui_ruby/tui/core.rb +13 -2
- data/lib/ratatui_ruby/tui/layout_factories.rb +50 -3
- data/lib/ratatui_ruby/tui/state_factories.rb +42 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +40 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +135 -60
- data/lib/ratatui_ruby/tui.rb +22 -1
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +30 -20
- data/lib/ratatui_ruby/widgets/block.rb +14 -6
- data/lib/ratatui_ruby/widgets/calendar.rb +2 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +56 -0
- data/lib/ratatui_ruby/widgets/cell.rb +2 -0
- data/lib/ratatui_ruby/widgets/center.rb +2 -0
- data/lib/ratatui_ruby/widgets/chart.rb +6 -0
- data/lib/ratatui_ruby/widgets/clear.rb +2 -0
- data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +2 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +61 -3
- data/lib/ratatui_ruby/widgets/line_gauge.rb +66 -4
- data/lib/ratatui_ruby/widgets/list.rb +87 -3
- data/lib/ratatui_ruby/widgets/list_item.rb +2 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +2 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +4 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -0
- data/lib/ratatui_ruby/widgets/row.rb +45 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +2 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +21 -13
- data/lib/ratatui_ruby/widgets/table.rb +13 -3
- data/lib/ratatui_ruby/widgets/tabs.rb +6 -4
- data/lib/ratatui_ruby/widgets.rb +1 -0
- data/lib/ratatui_ruby.rb +42 -11
- data/sig/examples/app_all_events/model/app_model.rbs +23 -0
- data/sig/examples/app_all_events/model/event_entry.rbs +15 -8
- data/sig/examples/app_all_events/model/timestamp.rbs +1 -1
- data/sig/examples/app_all_events/view.rbs +1 -1
- data/sig/examples/app_stateful_interaction/app.rbs +5 -5
- data/sig/examples/widget_block_demo/app.rbs +6 -6
- data/sig/manifest.yaml +5 -0
- data/sig/patches/data.rbs +26 -0
- data/sig/patches/debugger__.rbs +8 -0
- data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
- data/sig/ratatui_ruby/buffer.rbs +18 -0
- data/sig/ratatui_ruby/cell.rbs +44 -0
- data/sig/ratatui_ruby/clear.rbs +18 -0
- data/sig/ratatui_ruby/constraint.rbs +26 -0
- data/sig/ratatui_ruby/debug.rbs +45 -0
- data/sig/ratatui_ruby/draw.rbs +30 -0
- data/sig/ratatui_ruby/event.rbs +68 -8
- data/sig/ratatui_ruby/frame.rbs +4 -4
- data/sig/ratatui_ruby/interfaces.rbs +25 -0
- data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
- data/sig/ratatui_ruby/layout/layout.rbs +45 -0
- data/sig/ratatui_ruby/layout/position.rbs +18 -0
- data/sig/ratatui_ruby/layout/rect.rbs +64 -0
- data/sig/ratatui_ruby/layout/size.rbs +18 -0
- data/sig/ratatui_ruby/output_guard.rbs +23 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +84 -5
- data/sig/ratatui_ruby/rect.rbs +17 -0
- data/sig/ratatui_ruby/style/color.rbs +22 -0
- data/sig/ratatui_ruby/style/style.rbs +29 -0
- data/sig/ratatui_ruby/symbols.rbs +141 -0
- data/sig/ratatui_ruby/synthetic_events.rbs +21 -0
- data/sig/ratatui_ruby/table_state.rbs +6 -0
- data/sig/ratatui_ruby/terminal_lifecycle.rbs +31 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +2 -2
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +22 -3
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +8 -1
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -3
- data/sig/ratatui_ruby/text/line.rbs +27 -0
- data/sig/ratatui_ruby/text/span.rbs +23 -0
- data/sig/ratatui_ruby/text.rbs +12 -0
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +1 -1
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +23 -5
- data/sig/ratatui_ruby/tui/core.rbs +2 -2
- data/sig/ratatui_ruby/tui/layout_factories.rbs +16 -2
- data/sig/ratatui_ruby/tui/state_factories.rbs +8 -3
- data/sig/ratatui_ruby/tui/style_factories.rbs +3 -1
- data/sig/ratatui_ruby/tui/text_factories.rbs +7 -4
- data/sig/ratatui_ruby/tui/widget_factories.rbs +123 -30
- data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
- data/sig/ratatui_ruby/widgets/block.rbs +51 -0
- data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
- data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
- data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
- data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
- data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
- data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
- data/sig/ratatui_ruby/widgets/list.rbs +63 -0
- data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
- data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
- data/sig/ratatui_ruby/widgets/row.rbs +43 -0
- data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
- data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
- data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
- data/sig/ratatui_ruby/widgets/table.rbs +78 -0
- data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
- data/sig/ratatui_ruby/{schema/list_item.rbs → widgets.rbs} +4 -4
- data/tasks/steep.rake +11 -0
- metadata +80 -63
- data/doc/contributors/v1.0.0_blockers.md +0 -870
- data/doc/troubleshooting/debugging.md +0 -101
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +0 -47
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +0 -25
- data/lib/ratatui_ruby/schema/bar_chart.rb +0 -287
- data/lib/ratatui_ruby/schema/block.rb +0 -198
- data/lib/ratatui_ruby/schema/calendar.rb +0 -84
- data/lib/ratatui_ruby/schema/canvas.rb +0 -239
- data/lib/ratatui_ruby/schema/center.rb +0 -67
- data/lib/ratatui_ruby/schema/chart.rb +0 -159
- data/lib/ratatui_ruby/schema/clear.rb +0 -62
- data/lib/ratatui_ruby/schema/constraint.rb +0 -151
- data/lib/ratatui_ruby/schema/cursor.rb +0 -50
- data/lib/ratatui_ruby/schema/gauge.rb +0 -72
- data/lib/ratatui_ruby/schema/layout.rb +0 -122
- data/lib/ratatui_ruby/schema/line_gauge.rb +0 -80
- data/lib/ratatui_ruby/schema/list.rb +0 -135
- data/lib/ratatui_ruby/schema/list_item.rb +0 -51
- data/lib/ratatui_ruby/schema/overlay.rb +0 -51
- data/lib/ratatui_ruby/schema/paragraph.rb +0 -107
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +0 -31
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +0 -36
- data/lib/ratatui_ruby/schema/rect.rb +0 -174
- data/lib/ratatui_ruby/schema/row.rb +0 -76
- data/lib/ratatui_ruby/schema/scrollbar.rb +0 -143
- data/lib/ratatui_ruby/schema/shape/label.rb +0 -76
- data/lib/ratatui_ruby/schema/sparkline.rb +0 -142
- data/lib/ratatui_ruby/schema/style.rb +0 -97
- data/lib/ratatui_ruby/schema/table.rb +0 -141
- data/lib/ratatui_ruby/schema/tabs.rb +0 -85
- data/lib/ratatui_ruby/schema/text.rb +0 -217
- data/sig/examples/app_all_events/model/events.rbs +0 -15
- data/sig/examples/app_all_events/view_state.rbs +0 -21
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +0 -22
- data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +0 -19
- data/sig/ratatui_ruby/schema/bar_chart.rbs +0 -38
- data/sig/ratatui_ruby/schema/block.rbs +0 -18
- data/sig/ratatui_ruby/schema/calendar.rbs +0 -23
- data/sig/ratatui_ruby/schema/canvas.rbs +0 -81
- data/sig/ratatui_ruby/schema/center.rbs +0 -17
- data/sig/ratatui_ruby/schema/chart.rbs +0 -39
- data/sig/ratatui_ruby/schema/constraint.rbs +0 -30
- data/sig/ratatui_ruby/schema/cursor.rbs +0 -16
- data/sig/ratatui_ruby/schema/draw.rbs +0 -33
- data/sig/ratatui_ruby/schema/gauge.rbs +0 -23
- data/sig/ratatui_ruby/schema/layout.rbs +0 -27
- data/sig/ratatui_ruby/schema/line_gauge.rbs +0 -24
- data/sig/ratatui_ruby/schema/list.rbs +0 -28
- data/sig/ratatui_ruby/schema/overlay.rbs +0 -15
- data/sig/ratatui_ruby/schema/paragraph.rbs +0 -20
- data/sig/ratatui_ruby/schema/ratatui_logo.rbs +0 -14
- data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +0 -17
- data/sig/ratatui_ruby/schema/rect.rbs +0 -48
- data/sig/ratatui_ruby/schema/row.rbs +0 -28
- data/sig/ratatui_ruby/schema/scrollbar.rbs +0 -42
- data/sig/ratatui_ruby/schema/sparkline.rbs +0 -22
- data/sig/ratatui_ruby/schema/style.rbs +0 -19
- data/sig/ratatui_ruby/schema/table.rbs +0 -32
- data/sig/ratatui_ruby/schema/tabs.rbs +0 -21
- data/sig/ratatui_ruby/schema/text.rbs +0 -31
- /data/lib/ratatui_ruby/{schema/draw.rb → draw.rb} +0 -0
|
@@ -15,6 +15,8 @@ module RatatuiRuby
|
|
|
15
15
|
#
|
|
16
16
|
# Use it for everything from simple labels to complex, multi-paragraph documents.
|
|
17
17
|
#
|
|
18
|
+
# See also: <tt>examples/widget_scroll_text/app.rb</tt> for scrollable paragraphs.
|
|
19
|
+
#
|
|
18
20
|
# === Examples
|
|
19
21
|
#
|
|
20
22
|
#--
|
|
@@ -39,6 +41,8 @@ module RatatuiRuby
|
|
|
39
41
|
# SPDX-SnippetEnd
|
|
40
42
|
#++
|
|
41
43
|
class Paragraph < Data.define(:text, :style, :block, :wrap, :alignment, :scroll)
|
|
44
|
+
include CoerceableWidget
|
|
45
|
+
|
|
42
46
|
##
|
|
43
47
|
# :attr_reader: text
|
|
44
48
|
# The content to display.
|
|
@@ -37,6 +37,8 @@ module RatatuiRuby
|
|
|
37
37
|
# SPDX-SnippetEnd
|
|
38
38
|
#++
|
|
39
39
|
class Row < Data.define(:cells, :style, :height, :top_margin, :bottom_margin)
|
|
40
|
+
include CoerceableWidget
|
|
41
|
+
|
|
40
42
|
##
|
|
41
43
|
# :attr_reader: cells
|
|
42
44
|
# The cells to display (Array of Strings, Text::Spans, Text::Lines, Paragraphs, or Cells).
|
|
@@ -73,6 +75,49 @@ module RatatuiRuby
|
|
|
73
75
|
bottom_margin: bottom_margin.nil? ? nil : Integer(bottom_margin)
|
|
74
76
|
)
|
|
75
77
|
end
|
|
78
|
+
|
|
79
|
+
# Returns a new Row with strikethrough styling enabled.
|
|
80
|
+
#
|
|
81
|
+
# Table rows sometimes need strikethrough styling to indicate
|
|
82
|
+
# deleted, deprecated, or cancelled items. Manually managing
|
|
83
|
+
# style modifiers is tedious.
|
|
84
|
+
#
|
|
85
|
+
# This method adds the <tt>:crossed_out</tt> modifier to the row's
|
|
86
|
+
# style. If the row has no existing style, a new style is created.
|
|
87
|
+
#
|
|
88
|
+
# Use it to visually mark rows as cancelled, completed, or invalid.
|
|
89
|
+
#
|
|
90
|
+
# *Terminal Compatibility:* Strikethrough (SGR 9) is not universally
|
|
91
|
+
# supported. macOS Terminal.app notably lacks support. Modern terminals
|
|
92
|
+
# like Kitty, iTerm2, Alacritty, and WezTerm render it correctly.
|
|
93
|
+
# Consider pairing with <tt>:dim</tt> as a fallback for visibility.
|
|
94
|
+
#
|
|
95
|
+
# Returns a new Row instance with strikethrough enabled.
|
|
96
|
+
#
|
|
97
|
+
# === Example
|
|
98
|
+
#
|
|
99
|
+
#--
|
|
100
|
+
# SPDX-SnippetBegin
|
|
101
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
102
|
+
# SPDX-License-Identifier: MIT-0
|
|
103
|
+
#++
|
|
104
|
+
# row = Row.new(cells: ["Cancelled Task", "2024-01-15"])
|
|
105
|
+
# strikethrough_row = row.enable_strikethrough
|
|
106
|
+
# # Row style now includes :crossed_out modifier
|
|
107
|
+
#--
|
|
108
|
+
# SPDX-SnippetEnd
|
|
109
|
+
#++
|
|
110
|
+
def enable_strikethrough
|
|
111
|
+
current_style = style || Style::Style.new
|
|
112
|
+
current_modifiers = current_style.modifiers || []
|
|
113
|
+
new_modifiers = current_modifiers.include?(:crossed_out) ? current_modifiers : current_modifiers + [:crossed_out]
|
|
114
|
+
|
|
115
|
+
new_style = current_style.with(modifiers: new_modifiers)
|
|
116
|
+
with(style: new_style)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Ruby-idiomatic alias
|
|
120
|
+
alias strikethrough enable_strikethrough
|
|
76
121
|
end
|
|
77
122
|
end
|
|
78
123
|
end
|
|
@@ -24,6 +24,8 @@ module RatatuiRuby
|
|
|
24
24
|
#
|
|
25
25
|
# ruby examples/widget_sparkline/app.rb
|
|
26
26
|
class Sparkline < Data.define(:data, :max, :style, :block, :direction, :absent_value_symbol, :absent_value_style, :bar_set)
|
|
27
|
+
include CoerceableWidget
|
|
28
|
+
|
|
27
29
|
##
|
|
28
30
|
# :attr_reader: data
|
|
29
31
|
# Array of integer values to plot.
|
|
@@ -114,19 +116,25 @@ module RatatuiRuby
|
|
|
114
116
|
# [bar_set] Symbol, Hash, or Array of custom characters (optional).
|
|
115
117
|
# Symbols: <tt>:nine_levels</tt> (default gradient), <tt>:three_levels</tt> (simplified).
|
|
116
118
|
def initialize(data:, max: nil, style: nil, block: nil, direction: :left_to_right, absent_value_symbol: nil, absent_value_style: nil, bar_set: nil)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
119
|
+
# Normalize bar_set to Hash[Symbol, String] if provided as Array or Hash
|
|
120
|
+
bar_set = case bar_set
|
|
121
|
+
when Symbol, nil
|
|
122
|
+
bar_set
|
|
123
|
+
when Array
|
|
124
|
+
# Convert Array to Hash using BAR_KEYS order
|
|
125
|
+
BAR_KEYS.zip(bar_set).to_h
|
|
126
|
+
when Hash
|
|
127
|
+
# @type var raw_hash: Hash[untyped, untyped]
|
|
128
|
+
raw_hash = bar_set.dup
|
|
129
|
+
normalized = {} #: Hash[Symbol, String]
|
|
130
|
+
# Normalize numeric keys (0-8) to symbolic keys
|
|
131
|
+
BAR_KEYS.each_with_index do |key, i|
|
|
132
|
+
val = raw_hash.delete(i) || raw_hash.delete(i.to_s) || raw_hash.delete(key)
|
|
133
|
+
normalized[key] = val.to_s if val
|
|
134
|
+
end
|
|
135
|
+
normalized
|
|
136
|
+
else
|
|
137
|
+
bar_set
|
|
130
138
|
end
|
|
131
139
|
coerced_data = data.map { |v| v.nil? ? nil : Integer(v) }
|
|
132
140
|
super(
|
|
@@ -24,6 +24,8 @@ 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
|
+
include CoerceableWidget
|
|
28
|
+
|
|
27
29
|
##
|
|
28
30
|
# Highlight spacing: always show the spacing column.
|
|
29
31
|
HIGHLIGHT_ALWAYS = :always
|
|
@@ -66,7 +68,8 @@ module RatatuiRuby
|
|
|
66
68
|
|
|
67
69
|
##
|
|
68
70
|
# :attr_reader: widths
|
|
69
|
-
# Column width constraints (Array of Constraint).
|
|
71
|
+
# Column width constraints (Array of Constraint or Integer).
|
|
72
|
+
# Integers are automatically coerced to Constraint.length.
|
|
70
73
|
|
|
71
74
|
##
|
|
72
75
|
# :attr_reader: row_highlight_style
|
|
@@ -136,7 +139,7 @@ module RatatuiRuby
|
|
|
136
139
|
#
|
|
137
140
|
# [header] Array of strings, Text::Spans, Text::Lines, or paragraphs.
|
|
138
141
|
# [rows] 2D Array where each cell is String, Text::Span, Text::Line, Paragraph, or Cell.
|
|
139
|
-
# [widths] Array of Constraints.
|
|
142
|
+
# [widths] Array of Constraints or Integers (integers coerce to Constraint.length).
|
|
140
143
|
# [row_highlight_style] Style object.
|
|
141
144
|
# [highlight_symbol] String.
|
|
142
145
|
# [highlight_spacing] Symbol (optional, default: <tt>:when_selected</tt>).
|
|
@@ -151,10 +154,14 @@ module RatatuiRuby
|
|
|
151
154
|
# [style] Style object or Hash (optional).
|
|
152
155
|
# [column_spacing] Integer (optional, default: 1).
|
|
153
156
|
def initialize(header: nil, rows: [], widths: [], row_highlight_style: nil, highlight_symbol: "> ", highlight_spacing: :when_selected, column_highlight_style: nil, cell_highlight_style: nil, selected_row: nil, selected_column: nil, offset: nil, block: nil, footer: nil, flex: :legacy, style: nil, column_spacing: 1)
|
|
157
|
+
coerced_widths = widths.map do |w|
|
|
158
|
+
w.is_a?(Integer) ? Layout::Constraint.length(w) : w
|
|
159
|
+
end
|
|
160
|
+
|
|
154
161
|
super(
|
|
155
162
|
header:,
|
|
156
163
|
rows:,
|
|
157
|
-
widths
|
|
164
|
+
widths: coerced_widths,
|
|
158
165
|
row_highlight_style:,
|
|
159
166
|
highlight_symbol:,
|
|
160
167
|
highlight_spacing:,
|
|
@@ -198,6 +205,9 @@ module RatatuiRuby
|
|
|
198
205
|
def empty?
|
|
199
206
|
rows.empty?
|
|
200
207
|
end
|
|
208
|
+
|
|
209
|
+
# NOTE: No 'selection' alias - it's ambiguous whether it returns a row or index.
|
|
210
|
+
# Use selected_row for the row index, selected_column for the column index.
|
|
201
211
|
end
|
|
202
212
|
end
|
|
203
213
|
end
|
|
@@ -23,6 +23,8 @@ module RatatuiRuby
|
|
|
23
23
|
#
|
|
24
24
|
# ruby examples/widget_tabs/app.rb
|
|
25
25
|
class Tabs < Data.define(:titles, :selected_index, :block, :divider, :highlight_style, :style, :padding_left, :padding_right)
|
|
26
|
+
include CoerceableWidget
|
|
27
|
+
|
|
26
28
|
##
|
|
27
29
|
# :attr_reader: titles
|
|
28
30
|
# Tab titles (Array of Strings).
|
|
@@ -65,8 +67,8 @@ module RatatuiRuby
|
|
|
65
67
|
# [divider] String (optional).
|
|
66
68
|
# [highlight_style] Style (optional).
|
|
67
69
|
# [style] Style (optional).
|
|
68
|
-
# [padding_left]
|
|
69
|
-
# [padding_right]
|
|
70
|
+
# [padding_left] String, Line, or anything that responds to <tt>to_i</tt> (default: 0).
|
|
71
|
+
# [padding_right] String, Line, or anything that responds to <tt>to_i</tt> (default: 0).
|
|
70
72
|
def initialize(titles: [], selected_index: 0, block: nil, divider: nil, highlight_style: nil, style: nil, padding_left: 0, padding_right: 0)
|
|
71
73
|
super(
|
|
72
74
|
titles:,
|
|
@@ -75,8 +77,8 @@ module RatatuiRuby
|
|
|
75
77
|
divider:,
|
|
76
78
|
highlight_style:,
|
|
77
79
|
style:,
|
|
78
|
-
padding_left
|
|
79
|
-
padding_right:
|
|
80
|
+
padding_left: (padding_left.is_a?(Text::Line) || padding_left.is_a?(String)) ? padding_left : Integer(padding_left),
|
|
81
|
+
padding_right: (padding_right.is_a?(Text::Line) || padding_right.is_a?(String)) ? padding_right : Integer(padding_right)
|
|
80
82
|
)
|
|
81
83
|
end
|
|
82
84
|
|
data/lib/ratatui_ruby/widgets.rb
CHANGED
data/lib/ratatui_ruby.rb
CHANGED
|
@@ -12,8 +12,9 @@ require_relative "ratatui_ruby/layout" # Layout::Rect, Layout::Constraint, Lay
|
|
|
12
12
|
require_relative "ratatui_ruby/style" # Style::Style
|
|
13
13
|
require_relative "ratatui_ruby/widgets" # Widgets::Block, Widgets::Paragraph, etc.
|
|
14
14
|
require_relative "ratatui_ruby/buffer" # Buffer::Cell (for inspection)
|
|
15
|
-
require_relative "ratatui_ruby/
|
|
16
|
-
require_relative "ratatui_ruby/
|
|
15
|
+
require_relative "ratatui_ruby/text" # Text::Span, Text::Line, Text.width
|
|
16
|
+
require_relative "ratatui_ruby/draw" # Draw commands
|
|
17
|
+
require_relative "ratatui_ruby/symbols" # Symbols::Shade, etc.
|
|
17
18
|
|
|
18
19
|
# Event types
|
|
19
20
|
require_relative "ratatui_ruby/event"
|
|
@@ -41,6 +42,10 @@ rescue LoadError
|
|
|
41
42
|
require_relative "ratatui_ruby/ratatui_ruby"
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
# Debug mode (for Rust backtraces and diagnostic features)
|
|
46
|
+
# Loaded after native extension so _enable_rust_backtrace is defined
|
|
47
|
+
require_relative "ratatui_ruby/debug"
|
|
48
|
+
|
|
44
49
|
# Main entry point for the library.
|
|
45
50
|
#
|
|
46
51
|
# Terminal UIs require low-level control using C/Rust and high-level abstraction in Ruby.
|
|
@@ -154,13 +159,10 @@ module RatatuiRuby
|
|
|
154
159
|
extend OutputGuard
|
|
155
160
|
extend TerminalLifecycle
|
|
156
161
|
|
|
157
|
-
# Re-export NullIO at module root for backward compatibility
|
|
158
|
-
NullIO = OutputGuard::NullIO
|
|
159
|
-
|
|
160
162
|
@experimental_warnings = true
|
|
161
163
|
@tui_session_active = false
|
|
162
164
|
@headless_mode = false
|
|
163
|
-
@deferred_warnings = []
|
|
165
|
+
@deferred_warnings = [] #: Array[String]
|
|
164
166
|
|
|
165
167
|
class << self
|
|
166
168
|
##
|
|
@@ -177,6 +179,13 @@ module RatatuiRuby
|
|
|
177
179
|
@deferred_warnings.each { |msg| warn msg }
|
|
178
180
|
@deferred_warnings.clear
|
|
179
181
|
end
|
|
182
|
+
|
|
183
|
+
private def flush_panic_info
|
|
184
|
+
return unless Debug.rust_backtrace_enabled?
|
|
185
|
+
panic_info = _get_last_panic
|
|
186
|
+
return unless panic_info
|
|
187
|
+
warn panic_info
|
|
188
|
+
end
|
|
180
189
|
end
|
|
181
190
|
|
|
182
191
|
##
|
|
@@ -206,7 +215,7 @@ module RatatuiRuby
|
|
|
206
215
|
def self.warn_experimental_feature(feature_name)
|
|
207
216
|
return unless experimental_warnings
|
|
208
217
|
|
|
209
|
-
@warned_features ||= {}
|
|
218
|
+
@warned_features ||= {} #: Hash[String, bool]
|
|
210
219
|
return if @warned_features[feature_name]
|
|
211
220
|
|
|
212
221
|
message = "WARNING: #{feature_name} is an experimental feature and may change in future versions. Disable this warning with RatatuiRuby.experimental_warnings = false."
|
|
@@ -219,7 +228,28 @@ module RatatuiRuby
|
|
|
219
228
|
end
|
|
220
229
|
|
|
221
230
|
# (Native methods implemented in Rust)
|
|
222
|
-
private_class_method :_init_terminal, :_restore_terminal, :_init_test_terminal
|
|
231
|
+
private_class_method :_init_terminal, :_restore_terminal, :_init_test_terminal, :_enable_rust_backtrace, :_get_last_panic
|
|
232
|
+
|
|
233
|
+
##
|
|
234
|
+
# Enables full debug mode.
|
|
235
|
+
#
|
|
236
|
+
# Convenience alias for Debug.enable!.
|
|
237
|
+
#
|
|
238
|
+
# === Example
|
|
239
|
+
#
|
|
240
|
+
#--
|
|
241
|
+
# SPDX-SnippetBegin
|
|
242
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
243
|
+
# SPDX-License-Identifier: MIT-0
|
|
244
|
+
#++
|
|
245
|
+
# RatatuiRuby.debug_mode!
|
|
246
|
+
#
|
|
247
|
+
#--
|
|
248
|
+
# SPDX-SnippetEnd
|
|
249
|
+
#++
|
|
250
|
+
def self.debug_mode!
|
|
251
|
+
Debug.enable!
|
|
252
|
+
end
|
|
223
253
|
|
|
224
254
|
##
|
|
225
255
|
# Draws the given UI node tree to the terminal.
|
|
@@ -281,7 +311,7 @@ module RatatuiRuby
|
|
|
281
311
|
|
|
282
312
|
if tree
|
|
283
313
|
_draw(tree)
|
|
284
|
-
|
|
314
|
+
elsif block
|
|
285
315
|
_draw(&block)
|
|
286
316
|
end
|
|
287
317
|
end
|
|
@@ -357,8 +387,8 @@ module RatatuiRuby
|
|
|
357
387
|
when :focus_lost
|
|
358
388
|
Event::FocusLost.new.freeze
|
|
359
389
|
else
|
|
360
|
-
#
|
|
361
|
-
|
|
390
|
+
# Return None for unknown event types
|
|
391
|
+
Event::None.new.freeze
|
|
362
392
|
end
|
|
363
393
|
end
|
|
364
394
|
|
|
@@ -396,6 +426,7 @@ module RatatuiRuby
|
|
|
396
426
|
char: raw["char"],
|
|
397
427
|
fg: raw["fg"],
|
|
398
428
|
bg: raw["bg"],
|
|
429
|
+
underline_color: raw["underline_color"],
|
|
399
430
|
modifiers: raw["modifiers"] || []
|
|
400
431
|
)
|
|
401
432
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
# MVU application model for the All Events example.
|
|
5
|
+
class AppModel < Data
|
|
6
|
+
HIGHLIGHT_DURATION_MS: Integer
|
|
7
|
+
|
|
8
|
+
attr_reader entries: Array[EventEntry]
|
|
9
|
+
attr_reader focused: bool
|
|
10
|
+
attr_reader window_size: [Integer, Integer]
|
|
11
|
+
attr_reader lit_types: Hash[Symbol, Timestamp]
|
|
12
|
+
attr_reader none_count: Integer
|
|
13
|
+
attr_reader color_cycle_index: Integer
|
|
14
|
+
|
|
15
|
+
def self.initial: () -> instance
|
|
16
|
+
def count: (Symbol type) -> Integer
|
|
17
|
+
def sub_counts: (Symbol type) -> Hash[String, Integer]
|
|
18
|
+
def lit?: (Symbol type) -> bool
|
|
19
|
+
def visible: (Integer max_entries) -> Array[EventEntry]
|
|
20
|
+
def empty?: () -> bool
|
|
21
|
+
def live_event: (Symbol type) -> { time: Time, description: String }?
|
|
22
|
+
def next_color: () -> Symbol
|
|
23
|
+
end
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
2
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
3
|
|
|
4
|
+
# Type alias for any Event subtype.
|
|
5
|
+
type event_type = RatatuiRuby::Event::Key
|
|
6
|
+
| RatatuiRuby::Event::Mouse
|
|
7
|
+
| RatatuiRuby::Event::Resize
|
|
8
|
+
| RatatuiRuby::Event::Paste
|
|
9
|
+
| RatatuiRuby::Event::FocusGained
|
|
10
|
+
| RatatuiRuby::Event::FocusLost
|
|
11
|
+
| RatatuiRuby::Event::None
|
|
12
|
+
|
|
4
13
|
class EventEntry < Data
|
|
5
|
-
attr_reader
|
|
6
|
-
attr_reader sub_key: Symbol | String | nil
|
|
14
|
+
attr_reader event: event_type
|
|
7
15
|
attr_reader color: Symbol
|
|
8
16
|
attr_reader timestamp: Timestamp
|
|
9
|
-
attr_reader data: Hash[Symbol, untyped]
|
|
10
17
|
|
|
11
|
-
def self.
|
|
18
|
+
def self.create: (event_type event, Symbol color, Timestamp timestamp) -> instance
|
|
19
|
+
def type: () -> Symbol
|
|
20
|
+
def description: () -> String
|
|
12
21
|
def matches_type?: (Symbol check_type) -> bool
|
|
13
|
-
def
|
|
14
|
-
def matches_kind?: (String kind) -> bool
|
|
15
|
-
def self.new: (?type: Symbol, ?sub_key: Symbol | String | nil, ?color: Symbol, ?timestamp: Timestamp, ?data: Hash[Symbol, untyped]) -> instance
|
|
22
|
+
def live_type: () -> Symbol
|
|
16
23
|
end
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
module View
|
|
11
11
|
interface _View
|
|
12
|
-
def call
|
|
12
|
+
def call: (AppModel model, RatatuiRuby::TUI tui, RatatuiRuby::Frame frame, RatatuiRuby::Layout::Rect area) -> void
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -13,12 +13,12 @@ class AppStatefulInteraction
|
|
|
13
13
|
@list_state: RatatuiRuby::ListState
|
|
14
14
|
@table_state: RatatuiRuby::TableState
|
|
15
15
|
@active_pane: :list | :table
|
|
16
|
-
@tui:
|
|
16
|
+
@tui: RatatuiRuby::TUI
|
|
17
17
|
@style_active: RatatuiRuby::Style
|
|
18
18
|
@style_inactive: RatatuiRuby::Style
|
|
19
19
|
@style_highlight: RatatuiRuby::Style
|
|
20
|
-
@list_area: RatatuiRuby::Rect
|
|
21
|
-
@table_area: RatatuiRuby::Rect
|
|
20
|
+
@list_area: RatatuiRuby::Layout::Rect
|
|
21
|
+
@table_area: RatatuiRuby::Layout::Rect
|
|
22
22
|
|
|
23
23
|
# @public
|
|
24
24
|
def self.new: () -> AppStatefulInteraction
|
|
@@ -29,8 +29,8 @@ class AppStatefulInteraction
|
|
|
29
29
|
private
|
|
30
30
|
|
|
31
31
|
def render: () -> void
|
|
32
|
-
def render_list: (
|
|
33
|
-
def render_table: (
|
|
32
|
+
def render_list: (RatatuiRuby::Frame frame, RatatuiRuby::Layout::Rect area) -> void
|
|
33
|
+
def render_table: (RatatuiRuby::Frame frame, RatatuiRuby::Layout::Rect area) -> void
|
|
34
34
|
def handle_input: () -> (:quit | nil)
|
|
35
35
|
def scroll_active: (Integer delta) -> void
|
|
36
36
|
def handle_click: (Integer x, Integer y) -> void
|
|
@@ -10,25 +10,25 @@
|
|
|
10
10
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
11
11
|
|
|
12
12
|
class WidgetBlockDemo
|
|
13
|
-
@tui: RatatuiRuby::
|
|
13
|
+
@tui: RatatuiRuby::TUI
|
|
14
14
|
@hotkey_style: RatatuiRuby::Style
|
|
15
15
|
@title_configs: Array[{name: String, title: String?}]
|
|
16
16
|
@title_index: Integer
|
|
17
|
-
@titles_configs: Array[{name: String, titles: Array[
|
|
17
|
+
@titles_configs: Array[{name: String, titles: Array[untyped]}]
|
|
18
18
|
@titles_index: Integer
|
|
19
|
-
@alignment_configs: Array[{name: String, alignment:
|
|
19
|
+
@alignment_configs: Array[{name: String, alignment: Symbol}]
|
|
20
20
|
@alignment_index: Integer
|
|
21
21
|
@title_styles: Array[{name: String, style: RatatuiRuby::Style?}]
|
|
22
22
|
@title_style_index: Integer
|
|
23
|
-
@border_configs: Array[{name: String, borders: Array[
|
|
23
|
+
@border_configs: Array[{name: String, borders: Array[Symbol]}]
|
|
24
24
|
@border_index: Integer
|
|
25
|
-
@border_type_configs: Array[{name: String, type:
|
|
25
|
+
@border_type_configs: Array[{name: String, type: Symbol?, set: Hash[Symbol, String]?}]
|
|
26
26
|
@border_type_index: Integer
|
|
27
27
|
@border_styles: Array[{name: String, style: RatatuiRuby::Style?}]
|
|
28
28
|
@border_style_index: Integer
|
|
29
29
|
@base_styles: Array[{name: String, style: RatatuiRuby::Style?}]
|
|
30
30
|
@base_style_index: Integer
|
|
31
|
-
@padding_configs: Array[{name: String, padding:
|
|
31
|
+
@padding_configs: Array[{name: String, padding: (Integer | Array[Integer])}]
|
|
32
32
|
@padding_index: Integer
|
|
33
33
|
|
|
34
34
|
def self.new: () -> WidgetBlockDemo
|
data/sig/manifest.yaml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
9
|
+
|
|
10
|
+
# Patch for Data class to support super() calls in Data.define subclasses.
|
|
11
|
+
#
|
|
12
|
+
# The core RBS Data class defines `self.new: (**untyped) -> Data` but not `initialize`.
|
|
13
|
+
# When Steep type-checks `super(items:, ...)` in a Data.define subclass, it looks for
|
|
14
|
+
# the parent's `initialize` method. Since Data has no `initialize` signature in core RBS,
|
|
15
|
+
# Steep can't match arguments and raises errors.
|
|
16
|
+
#
|
|
17
|
+
# This patch adds the missing `initialize` signatures that Data.define generates dynamically.
|
|
18
|
+
class Data
|
|
19
|
+
# Accept both positional and keyword arguments for the dynamically-generated initialize.
|
|
20
|
+
# This allows subclasses to call super(foo, bar, ...) or super(foo:, bar:, ...) without type errors.
|
|
21
|
+
def initialize: (*untyped) -> void
|
|
22
|
+
| (**untyped) -> void
|
|
23
|
+
# Allow super() calls from overridden self.new methods to work with any keyword args
|
|
24
|
+
def self.new: (**untyped) -> instance
|
|
25
|
+
end
|
|
26
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
# Minimal stub for debug gem's DEBUGGER__ constant
|
|
5
|
+
# Full library causes Steep deadlock on Ruby 4.0 (Steep 1.10.0 threading issue)
|
|
6
|
+
module DEBUGGER__
|
|
7
|
+
def self.create_unix_domain_socket_name: () -> String?
|
|
8
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
module Buffer
|
|
10
|
+
class Cell
|
|
11
|
+
type color = Symbol | String | nil
|
|
12
|
+
|
|
13
|
+
attr_reader symbol: String
|
|
14
|
+
attr_reader fg: color
|
|
15
|
+
attr_reader bg: color
|
|
16
|
+
attr_reader underline_color: color
|
|
17
|
+
attr_reader modifiers: Array[Symbol]
|
|
18
|
+
|
|
19
|
+
alias char symbol
|
|
20
|
+
|
|
21
|
+
def self.new: (?symbol: String?, ?char: String?, ?fg: color, ?bg: color, ?underline_color: color, ?modifiers: Array[String | Symbol]) -> Cell
|
|
22
|
+
def self.empty: () -> Cell
|
|
23
|
+
def self.default: () -> Cell
|
|
24
|
+
def self.symbol: (String symbol) -> Cell
|
|
25
|
+
def self.char: (String char) -> Cell
|
|
26
|
+
|
|
27
|
+
def initialize: (?symbol: String?, ?char: String?, ?fg: color, ?bg: color, ?underline_color: color, ?modifiers: Array[String | Symbol]) -> void
|
|
28
|
+
|
|
29
|
+
# Modifier predicates
|
|
30
|
+
def bold?: () -> bool
|
|
31
|
+
def dim?: () -> bool
|
|
32
|
+
def italic?: () -> bool
|
|
33
|
+
def underlined?: () -> bool
|
|
34
|
+
def slow_blink?: () -> bool
|
|
35
|
+
def rapid_blink?: () -> bool
|
|
36
|
+
def reversed?: () -> bool
|
|
37
|
+
def hidden?: () -> bool
|
|
38
|
+
def crossed_out?: () -> bool
|
|
39
|
+
|
|
40
|
+
def ==: (untyped other) -> bool
|
|
41
|
+
def inspect: () -> String
|
|
42
|
+
def to_s: () -> String
|
|
43
|
+
def deconstruct_keys: (Array[Symbol]? keys) -> { symbol: String, char: String, fg: color, bg: color, underline_color: color, modifiers: Array[Symbol] }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
module Buffer
|
|
10
|
+
def self.index_of: (Integer x, Integer y) -> Integer
|
|
11
|
+
def self.pos_of: (Integer index) -> [Integer, Integer]
|
|
12
|
+
def self.get: (Integer x, Integer y) -> Cell
|
|
13
|
+
def self.content: () -> Array[Cell]
|
|
14
|
+
|
|
15
|
+
# Ruby-idiomatic alias
|
|
16
|
+
alias self.[] self.get
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
class Cell
|
|
10
|
+
type color = Symbol | String | nil
|
|
11
|
+
|
|
12
|
+
attr_reader symbol: String
|
|
13
|
+
attr_reader fg: color
|
|
14
|
+
attr_reader bg: color
|
|
15
|
+
attr_reader underline_color: color
|
|
16
|
+
attr_reader modifiers: Array[String]
|
|
17
|
+
|
|
18
|
+
alias char symbol
|
|
19
|
+
|
|
20
|
+
def self.new: (?symbol: String?, ?char: String?, ?fg: color, ?bg: color, ?underline_color: color, ?modifiers: Array[String]) -> Cell
|
|
21
|
+
def self.empty: () -> Cell
|
|
22
|
+
def self.default: () -> Cell
|
|
23
|
+
def self.symbol: (String symbol) -> Cell
|
|
24
|
+
def self.char: (String char) -> Cell
|
|
25
|
+
|
|
26
|
+
def initialize: (?symbol: String?, ?char: String?, ?fg: color, ?bg: color, ?underline_color: color, ?modifiers: Array[String]) -> void
|
|
27
|
+
|
|
28
|
+
# Modifier predicates
|
|
29
|
+
def bold?: () -> bool
|
|
30
|
+
def dim?: () -> bool
|
|
31
|
+
def italic?: () -> bool
|
|
32
|
+
def underlined?: () -> bool
|
|
33
|
+
def slow_blink?: () -> bool
|
|
34
|
+
def rapid_blink?: () -> bool
|
|
35
|
+
def reversed?: () -> bool
|
|
36
|
+
def hidden?: () -> bool
|
|
37
|
+
def crossed_out?: () -> bool
|
|
38
|
+
|
|
39
|
+
def ==: (untyped other) -> bool
|
|
40
|
+
def inspect: () -> String
|
|
41
|
+
def to_s: () -> String
|
|
42
|
+
def deconstruct_keys: (Array[Symbol]? keys) -> { symbol: String, char: String, fg: color, bg: color, underline_color: color, modifiers: Array[String] }
|
|
43
|
+
end
|
|
44
|
+
end
|