ratatui_ruby 1.0.0 → 1.0.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.
Files changed (236) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ratatui_ruby/Cargo.lock +1 -1
  3. data/ext/ratatui_ruby/Cargo.toml +1 -1
  4. data/lib/ratatui_ruby/version.rb +1 -1
  5. metadata +1 -232
  6. data/.builds/ruby-3.2.yml +0 -54
  7. data/.builds/ruby-3.3.yml +0 -54
  8. data/.builds/ruby-3.4.yml +0 -54
  9. data/.builds/ruby-4.0.0.yml +0 -54
  10. data/.pre-commit-config.yaml +0 -16
  11. data/.rubocop.yml +0 -10
  12. data/AGENTS.md +0 -146
  13. data/CHANGELOG.md +0 -710
  14. data/README.md +0 -187
  15. data/README.rdoc +0 -302
  16. data/Rakefile +0 -11
  17. data/Steepfile +0 -49
  18. data/doc/concepts/application_architecture.md +0 -321
  19. data/doc/concepts/application_testing.md +0 -193
  20. data/doc/concepts/async.md +0 -190
  21. data/doc/concepts/custom_widgets.md +0 -247
  22. data/doc/concepts/debugging.md +0 -401
  23. data/doc/concepts/event_handling.md +0 -162
  24. data/doc/concepts/interactive_design.md +0 -146
  25. data/doc/contributors/auditing/parity.md +0 -239
  26. data/doc/contributors/design/ruby_frontend.md +0 -420
  27. data/doc/contributors/design/rust_backend.md +0 -422
  28. data/doc/contributors/design.md +0 -11
  29. data/doc/contributors/developing_examples.md +0 -400
  30. data/doc/contributors/documentation_style.md +0 -121
  31. data/doc/contributors/index.md +0 -21
  32. data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -375
  33. data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -206
  34. data/doc/contributors/todo/align/terminal.md +0 -647
  35. data/doc/contributors/todo/future_work.md +0 -169
  36. data/doc/contributors/upstream_requests/tab_rects.md +0 -173
  37. data/doc/contributors/upstream_requests/title_rects.md +0 -132
  38. data/doc/custom.css +0 -22
  39. data/doc/getting_started/quickstart.md +0 -291
  40. data/doc/getting_started/why.md +0 -93
  41. data/doc/images/app_all_events.png +0 -0
  42. data/doc/images/app_cli_rich_moments.gif +0 -0
  43. data/doc/images/app_color_picker.png +0 -0
  44. data/doc/images/app_debugging_showcase.gif +0 -0
  45. data/doc/images/app_debugging_showcase.png +0 -0
  46. data/doc/images/app_login_form.png +0 -0
  47. data/doc/images/app_stateful_interaction.png +0 -0
  48. data/doc/images/verify_quickstart_dsl.png +0 -0
  49. data/doc/images/verify_quickstart_layout.png +0 -0
  50. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  51. data/doc/images/verify_readme_usage.png +0 -0
  52. data/doc/images/widget_barchart.png +0 -0
  53. data/doc/images/widget_block.png +0 -0
  54. data/doc/images/widget_box.png +0 -0
  55. data/doc/images/widget_calendar.png +0 -0
  56. data/doc/images/widget_canvas.png +0 -0
  57. data/doc/images/widget_cell.png +0 -0
  58. data/doc/images/widget_center.png +0 -0
  59. data/doc/images/widget_chart.png +0 -0
  60. data/doc/images/widget_gauge.png +0 -0
  61. data/doc/images/widget_layout_split.png +0 -0
  62. data/doc/images/widget_line_gauge.png +0 -0
  63. data/doc/images/widget_list.png +0 -0
  64. data/doc/images/widget_map.png +0 -0
  65. data/doc/images/widget_overlay.png +0 -0
  66. data/doc/images/widget_popup.png +0 -0
  67. data/doc/images/widget_ratatui_logo.png +0 -0
  68. data/doc/images/widget_ratatui_mascot.png +0 -0
  69. data/doc/images/widget_rect.png +0 -0
  70. data/doc/images/widget_render.png +0 -0
  71. data/doc/images/widget_rich_text.png +0 -0
  72. data/doc/images/widget_scroll_text.png +0 -0
  73. data/doc/images/widget_scrollbar.png +0 -0
  74. data/doc/images/widget_sparkline.png +0 -0
  75. data/doc/images/widget_style_colors.png +0 -0
  76. data/doc/images/widget_table.png +0 -0
  77. data/doc/images/widget_tabs.png +0 -0
  78. data/doc/images/widget_text_width.png +0 -0
  79. data/doc/index.md +0 -39
  80. data/doc/troubleshooting/async.md +0 -4
  81. data/doc/troubleshooting/terminal_limitations.md +0 -131
  82. data/doc/troubleshooting/tui_output.md +0 -197
  83. data/examples/app_all_events/README.md +0 -114
  84. data/examples/app_all_events/app.rb +0 -98
  85. data/examples/app_all_events/model/app_model.rb +0 -159
  86. data/examples/app_all_events/model/event_color_cycle.rb +0 -43
  87. data/examples/app_all_events/model/event_entry.rb +0 -94
  88. data/examples/app_all_events/model/msg.rb +0 -39
  89. data/examples/app_all_events/model/timestamp.rb +0 -56
  90. data/examples/app_all_events/update.rb +0 -75
  91. data/examples/app_all_events/view/app_view.rb +0 -80
  92. data/examples/app_all_events/view/controls_view.rb +0 -54
  93. data/examples/app_all_events/view/counts_view.rb +0 -61
  94. data/examples/app_all_events/view/live_view.rb +0 -72
  95. data/examples/app_all_events/view/log_view.rb +0 -57
  96. data/examples/app_all_events/view.rb +0 -9
  97. data/examples/app_cli_rich_moments/README.md +0 -81
  98. data/examples/app_cli_rich_moments/app.rb +0 -189
  99. data/examples/app_color_picker/README.md +0 -156
  100. data/examples/app_color_picker/app.rb +0 -76
  101. data/examples/app_color_picker/clipboard.rb +0 -86
  102. data/examples/app_color_picker/color.rb +0 -193
  103. data/examples/app_color_picker/controls.rb +0 -92
  104. data/examples/app_color_picker/copy_dialog.rb +0 -168
  105. data/examples/app_color_picker/export_pane.rb +0 -128
  106. data/examples/app_color_picker/harmony.rb +0 -58
  107. data/examples/app_color_picker/input.rb +0 -176
  108. data/examples/app_color_picker/main_container.rb +0 -180
  109. data/examples/app_color_picker/palette.rb +0 -111
  110. data/examples/app_debugging_showcase/README.md +0 -119
  111. data/examples/app_debugging_showcase/app.rb +0 -318
  112. data/examples/app_login_form/README.md +0 -58
  113. data/examples/app_login_form/app.rb +0 -109
  114. data/examples/app_stateful_interaction/README.md +0 -35
  115. data/examples/app_stateful_interaction/app.rb +0 -328
  116. data/examples/timeout_demo.rb +0 -45
  117. data/examples/verify_quickstart_dsl/README.md +0 -55
  118. data/examples/verify_quickstart_dsl/app.rb +0 -49
  119. data/examples/verify_quickstart_layout/README.md +0 -77
  120. data/examples/verify_quickstart_layout/app.rb +0 -73
  121. data/examples/verify_quickstart_lifecycle/README.md +0 -68
  122. data/examples/verify_quickstart_lifecycle/app.rb +0 -62
  123. data/examples/verify_readme_usage/README.md +0 -49
  124. data/examples/verify_readme_usage/app.rb +0 -42
  125. data/examples/verify_website_managed/README.md +0 -48
  126. data/examples/verify_website_managed/app.rb +0 -36
  127. data/examples/verify_website_menu/README.md +0 -60
  128. data/examples/verify_website_menu/app.rb +0 -84
  129. data/examples/verify_website_spinner/README.md +0 -44
  130. data/examples/verify_website_spinner/app.rb +0 -34
  131. data/examples/widget_barchart/README.md +0 -58
  132. data/examples/widget_barchart/app.rb +0 -240
  133. data/examples/widget_block/README.md +0 -44
  134. data/examples/widget_block/app.rb +0 -258
  135. data/examples/widget_box/README.md +0 -54
  136. data/examples/widget_box/app.rb +0 -255
  137. data/examples/widget_calendar/README.md +0 -48
  138. data/examples/widget_calendar/app.rb +0 -115
  139. data/examples/widget_canvas/README.md +0 -31
  140. data/examples/widget_canvas/app.rb +0 -130
  141. data/examples/widget_cell/README.md +0 -45
  142. data/examples/widget_cell/app.rb +0 -112
  143. data/examples/widget_center/README.md +0 -33
  144. data/examples/widget_center/app.rb +0 -118
  145. data/examples/widget_chart/README.md +0 -50
  146. data/examples/widget_chart/app.rb +0 -220
  147. data/examples/widget_gauge/README.md +0 -50
  148. data/examples/widget_gauge/app.rb +0 -229
  149. data/examples/widget_layout_split/README.md +0 -53
  150. data/examples/widget_layout_split/app.rb +0 -260
  151. data/examples/widget_line_gauge/README.md +0 -50
  152. data/examples/widget_line_gauge/app.rb +0 -219
  153. data/examples/widget_list/README.md +0 -58
  154. data/examples/widget_list/app.rb +0 -384
  155. data/examples/widget_map/README.md +0 -48
  156. data/examples/widget_map/app.rb +0 -95
  157. data/examples/widget_overlay/README.md +0 -45
  158. data/examples/widget_overlay/app.rb +0 -250
  159. data/examples/widget_popup/README.md +0 -45
  160. data/examples/widget_popup/app.rb +0 -106
  161. data/examples/widget_ratatui_logo/README.md +0 -43
  162. data/examples/widget_ratatui_logo/app.rb +0 -104
  163. data/examples/widget_ratatui_mascot/README.md +0 -43
  164. data/examples/widget_ratatui_mascot/app.rb +0 -95
  165. data/examples/widget_rect/README.md +0 -53
  166. data/examples/widget_rect/app.rb +0 -222
  167. data/examples/widget_render/README.md +0 -46
  168. data/examples/widget_render/app.rb +0 -186
  169. data/examples/widget_render/app.rbs +0 -41
  170. data/examples/widget_rich_text/README.md +0 -44
  171. data/examples/widget_rich_text/app.rb +0 -193
  172. data/examples/widget_scroll_text/README.md +0 -46
  173. data/examples/widget_scroll_text/app.rb +0 -109
  174. data/examples/widget_scrollbar/README.md +0 -46
  175. data/examples/widget_scrollbar/app.rb +0 -155
  176. data/examples/widget_sparkline/README.md +0 -51
  177. data/examples/widget_sparkline/app.rb +0 -277
  178. data/examples/widget_style_colors/README.md +0 -43
  179. data/examples/widget_style_colors/app.rb +0 -83
  180. data/examples/widget_table/README.md +0 -57
  181. data/examples/widget_table/app.rb +0 -279
  182. data/examples/widget_tabs/README.md +0 -50
  183. data/examples/widget_tabs/app.rb +0 -183
  184. data/examples/widget_text_width/README.md +0 -44
  185. data/examples/widget_text_width/app.rb +0 -117
  186. data/migrate_to_buffer.rb +0 -145
  187. data/mise.toml +0 -8
  188. data/tasks/autodoc/examples.rb +0 -87
  189. data/tasks/autodoc/member.rb +0 -58
  190. data/tasks/autodoc/name.rb +0 -21
  191. data/tasks/autodoc.rake +0 -21
  192. data/tasks/bump/cargo_lockfile.rb +0 -21
  193. data/tasks/bump/changelog.rb +0 -47
  194. data/tasks/bump/header.rb +0 -32
  195. data/tasks/bump/history.rb +0 -32
  196. data/tasks/bump/links.rb +0 -69
  197. data/tasks/bump/manifest.rb +0 -33
  198. data/tasks/bump/ruby_gem.rb +0 -49
  199. data/tasks/bump/sem_ver.rb +0 -40
  200. data/tasks/bump/unreleased_section.rb +0 -56
  201. data/tasks/bump.rake +0 -51
  202. data/tasks/doc.rake +0 -887
  203. data/tasks/example_viewer.html.erb +0 -172
  204. data/tasks/extension.rake +0 -14
  205. data/tasks/license/headers_md.rb +0 -223
  206. data/tasks/license/headers_rb.rb +0 -210
  207. data/tasks/license/license_utils.rb +0 -130
  208. data/tasks/license/snippets_md.rb +0 -315
  209. data/tasks/license/snippets_rdoc.rb +0 -150
  210. data/tasks/license.rake +0 -91
  211. data/tasks/lint.rake +0 -170
  212. data/tasks/rdoc_config.rb +0 -29
  213. data/tasks/resources/build.yml.erb +0 -60
  214. data/tasks/resources/index.html.erb +0 -141
  215. data/tasks/resources/rubies.yml +0 -7
  216. data/tasks/sourcehut.rake +0 -110
  217. data/tasks/steep.rake +0 -11
  218. data/tasks/terminal_preview/app_screenshot.rb +0 -45
  219. data/tasks/terminal_preview/crash_report.rb +0 -54
  220. data/tasks/terminal_preview/example_app.rb +0 -27
  221. data/tasks/terminal_preview/launcher_script.rb +0 -48
  222. data/tasks/terminal_preview/preview_collection.rb +0 -60
  223. data/tasks/terminal_preview/preview_timing.rb +0 -24
  224. data/tasks/terminal_preview/safety_confirmation.rb +0 -58
  225. data/tasks/terminal_preview/saved_screenshot.rb +0 -56
  226. data/tasks/terminal_preview/system_appearance.rb +0 -13
  227. data/tasks/terminal_preview/terminal_window.rb +0 -138
  228. data/tasks/terminal_preview/window_id.rb +0 -16
  229. data/tasks/terminal_preview.rake +0 -30
  230. data/tasks/test.rake +0 -33
  231. data/tasks/website/index_page.rb +0 -30
  232. data/tasks/website/version.rb +0 -127
  233. data/tasks/website/version_menu.rb +0 -68
  234. data/tasks/website/versioned_documentation.rb +0 -83
  235. data/tasks/website/website.rb +0 -53
  236. data/tasks/website.rake +0 -28
@@ -1,291 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Quickstart
6
-
7
- Welcome to **ratatui_ruby**! This guide will help you get up and running with your first Terminal User Interface in Ruby.
8
-
9
- ## Installation
10
-
11
- See [Installation in the README](../README.md#installation) for setup instructions.
12
-
13
-
14
- ## Tutorials
15
-
16
- ### Basic Application
17
-
18
- Here is a "Hello World" application that demonstrates the core lifecycle of a **ratatui_ruby** app.
19
-
20
- <!-- SPDX-SnippetBegin -->
21
- <!--
22
- SPDX-FileCopyrightText: 2026 Kerrick Long
23
- SPDX-License-Identifier: MIT-0
24
- -->
25
- <!-- SYNC:START:examples/verify_quickstart_lifecycle/app.rb:main -->
26
- ```ruby
27
- # 1. Initialize the terminal
28
- RatatuiRuby.init_terminal
29
-
30
- begin
31
- # The Main Loop
32
- loop do
33
- # 2. Create your UI (Immediate Mode)
34
- # We define a Paragraph widget inside a Block with a title and borders.
35
- view = RatatuiRuby::Widgets::Paragraph.new(
36
- text: "Hello, Ratatui! Press 'q' to quit.",
37
- alignment: :center,
38
- block: RatatuiRuby::Widgets::Block.new(
39
- title: "My Ruby TUI App",
40
- title_alignment: :center,
41
- borders: [:all],
42
- border_style: { fg: "cyan" },
43
- style: { fg: "white" }
44
- )
45
- )
46
-
47
- # 3. Draw the UI
48
- RatatuiRuby.draw do |frame|
49
- frame.render_widget(view, frame.area)
50
- end
51
-
52
- # 4. Poll for events
53
- case RatatuiRuby.poll_event
54
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
55
- break
56
- else
57
- nil
58
- end
59
-
60
- # 5. Guard against accidental output (optional but recommended)
61
- # Wrap any code that might puts/warn to prevent screen corruption.
62
- RatatuiRuby.guard_io do
63
- # SomeChattyGem.do_something
64
- end
65
- end
66
- ensure
67
- # 6. Restore the terminal to its original state
68
- RatatuiRuby.restore_terminal
69
- end
70
- ```
71
- <!-- SYNC:END -->
72
- <!-- SPDX-SnippetEnd -->
73
-
74
- [![quickstart_lifecycle](../images/verify_quickstart_lifecycle.png)](../../examples/verify_quickstart_lifecycle/README.md)
75
-
76
- #### How it works
77
-
78
- 1. **`RatatuiRuby.init_terminal`**: Enters raw mode and switches to the alternate screen.
79
- 2. **Immediate Mode UI**: On every iteration, describe your UI by creating `Data` objects (e.g., `Paragraph`, `Block`).
80
- 3. **`RatatuiRuby.draw { |frame| ... }`**: The block receives a `Frame` object as a canvas. Render widgets onto specific areas. Nothing is drawn until the block finishes, ensuring flicker-free updates.
81
- 4. **`RatatuiRuby.poll_event`**: Returns a typed `Event` object with predicates like `key?`, `mouse?`, `resize?`, etc. Returns `RatatuiRuby::Event::None` if no events are pending. Use predicates to check event type without pattern matching.
82
- 5. **`RatatuiRuby.guard_io { }`**: Wraps code that might write to stdout/stderr (e.g., chatty gems). Output is swallowed to prevent screen corruption. Optional but recommended for production apps.
83
- 6. **`RatatuiRuby.restore_terminal`**: Essential for leaving raw mode and returning to the shell. Always wrap your loop in `begin...ensure` to guarantee this runs.
84
-
85
- ### Simplified API
86
-
87
- You can simplify your code by using `RatatuiRuby.run`. This method handles the terminal lifecycle for you, yielding a `TUI` object with factory methods for widgets.
88
-
89
- <!-- SPDX-SnippetBegin -->
90
- <!--
91
- SPDX-FileCopyrightText: 2026 Kerrick Long
92
- SPDX-License-Identifier: MIT-0
93
- -->
94
- <!-- SYNC:START:examples/verify_quickstart_dsl/app.rb:main -->
95
- ```ruby
96
- # 1. Initialize the terminal, start the run loop, and ensure the terminal is restored.
97
- RatatuiRuby.run do |tui|
98
- loop do
99
- # 2. Create your UI with methods instead of classes.
100
- view = tui.paragraph(
101
- text: "Hello, Ratatui! Press 'q' to quit.",
102
- alignment: :center,
103
- block: tui.block(
104
- title: "My Ruby TUI App",
105
- title_alignment: :center,
106
- borders: [:all],
107
- border_style: { fg: "cyan" },
108
- style: { fg: "white" }
109
- )
110
- )
111
-
112
- # 3. Use RatatuiRuby methods, too.
113
- tui.draw do |frame|
114
- frame.render_widget(view, frame.area)
115
- end
116
-
117
- # 4. Poll for events with pattern matching
118
- case tui.poll_event
119
- in { type: :key, code: "q" }
120
- break
121
- else
122
- # Ignore other events
123
- end
124
- end
125
- end
126
- ```
127
- <!-- SYNC:END -->
128
- <!-- SPDX-SnippetEnd -->
129
-
130
- #### How it works
131
-
132
- 1. **`RatatuiRuby.run`**: This context manager initializes the terminal before the block starts and ensures `restore_terminal` is called when the block exits (even if an error occurs).
133
- 2. **Widget Shorthand**: The block yields a `TUI` object (here named `tui`). This object provides factory methods for every widget, allowing you to write `tui.paragraph(...)` instead of the more verbose `RatatuiRuby::Widgets::Paragraph.new(...)`.
134
- 3. **Method Shorthand**: The `TUI` object also provides aliases for module functions of `RatatuiRuby`, allowing you to write `tui.draw(...)` instead of the more verbose `RatatuiRuby.draw(...)`.
135
- 4. **Pattern Matching for Events**: Use `case...in` with pattern matching for elegant event dispatch. Always include an `else` clause at the end to catch unmatched event types (mouse, resize, paste, focus, etc.), otherwise Ruby raises `NoMatchingPatternError`.
136
-
137
- For a deeper dive into the available application architectures (Manual vs Managed), see [Application Architecture](../concepts/application_architecture.md).
138
-
139
- ### Adding Layouts
140
-
141
- Real-world applications often need to split the screen into multiple areas. `RatatuiRuby::Layout` lets you do this easily.
142
-
143
- <!-- SPDX-SnippetBegin -->
144
- <!--
145
- SPDX-FileCopyrightText: 2026 Kerrick Long
146
- SPDX-License-Identifier: MIT-0
147
- -->
148
- <!-- SYNC:START:examples/verify_quickstart_layout/app.rb:main -->
149
- ```ruby
150
- loop do
151
- tui.draw do |frame|
152
- # 1. Split the screen
153
- top, bottom = tui.layout_split(
154
- frame.area,
155
- direction: :vertical,
156
- constraints: [
157
- tui.constraint_percentage(75),
158
- tui.constraint_percentage(25),
159
- ]
160
- )
161
-
162
- # 2. Render Top Widget
163
- frame.render_widget(
164
- tui.paragraph(
165
- text: "Hello, Ratatui!",
166
- alignment: :center,
167
- block: tui.block(title: "Content", borders: [:all], border_style: { fg: "cyan" })
168
- ),
169
- top
170
- )
171
-
172
- # 3. Render Bottom Widget with Styled Text
173
- # We use a Line of Spans to style specific characters
174
- text_line = tui.text_line(
175
- spans: [
176
- tui.text_span(content: "Press '"),
177
- tui.text_span(
178
- content: "q",
179
- style: tui.style(modifiers: [:bold, :underlined])
180
- ),
181
- tui.text_span(content: "' to quit."),
182
- ],
183
- alignment: :center
184
- )
185
-
186
- frame.render_widget(
187
- tui.paragraph(
188
- text: text_line,
189
- block: tui.block(title: "Controls", borders: [:all])
190
- ),
191
- bottom
192
- )
193
- end
194
-
195
- case tui.poll_event
196
- in { type: :key, code: "q" }
197
- break
198
- else
199
- # Ignore other events
200
- end
201
- end
202
- ```
203
- <!-- SYNC:END -->
204
- <!-- SPDX-SnippetEnd -->
205
-
206
- #### How it works
207
-
208
- 1. **`tui.layout_split` (`RatatuiRuby::Layout::Layout.split`)**: Takes an area (like `frame.area`) and splits it into multiple sub-areas based on constraints.
209
- 2. **`tui.constraint_*` (`RatatuiRuby::Layout::Constraint`)**: Defines how space is distributed (e.g., `percentage`, `length`, `min`, `max`).
210
- 3. **`Frame#render_widget(widget, rect)`**: You pass the specific area (like `top` or `bottom`) to render the widget into that exact region.
211
- 4. **`tui.text_span` (`RatatuiRuby::Text::Span`)**: Allows for rich styling within a single line of text.
212
-
213
- [![quickstart_layout](../images/verify_quickstart_layout.png)](../../examples/verify_quickstart_layout/README.md)
214
-
215
- ## Examples
216
-
217
- These examples showcase the full power of **ratatui_ruby**. You can find their source code in the [examples directory](../../examples).
218
-
219
- ### Widget Demos
220
-
221
- Focused examples for individual widgets. Each demonstrates a single widget and its configuration options.
222
-
223
- | Widget | What it demonstrates |
224
- | ------------------------------------------------------------- | ---------------------------------------------------------- |
225
- | [Bar Chart](../../examples/widget_barchart/app.rb) | Grouped bars, data visualization, custom bar styling |
226
- | [Block](../../examples/widget_block/app.rb) | Borders, titles, padding, nested widgets |
227
- | [Box](../../examples/widget_box/app.rb) | Block + Paragraph composition, text wrapping |
228
- | [Calendar](../../examples/widget_calendar/app.rb) | Date highlighting, month display, event markers |
229
- | [Chart](../../examples/widget_chart/app.rb) | Line/scatter plots, axes, legends, datasets |
230
- | [Gauge](../../examples/widget_gauge/app.rb) | Progress bars, percentage display, unicode blocks |
231
- | [Layout Split](../../examples/widget_layout_split/app.rb) | Constraint types, flex modes, responsive layouts |
232
- | [Line Gauge](../../examples/widget_line_gauge/app.rb) | Horizontal progress, labels, thin-style gauges |
233
- | [List](../../examples/widget_list/app.rb) | Selection, scrolling, highlight styles, rich text items |
234
- | [Map](../../examples/widget_map/app.rb) | Canvas widget, world map rendering, coordinates |
235
- | [Popup](../../examples/widget_popup/app.rb) | Clear widget, modal dialogs, overlay composition |
236
- | [Ratatui Logo](../../examples/widget_ratatui_logo/app.rb) | Decorative branding widget |
237
- | [Ratatui Mascot](../../examples/widget_ratatui_mascot/app.rb) | ASCII art Ferris mascot |
238
- | [Rect](../../examples/widget_rect/app.rb) | Geometry helpers, area calculations, contains/intersection |
239
- | [Rich Text](../../examples/widget_rich_text/app.rb) | Spans, lines, inline styling, mixed colors |
240
- | [Scrollbar](../../examples/widget_scrollbar/app.rb) | Orientations, thumb/track styling, scroll state |
241
- | [Scroll Text](../../examples/widget_scroll_text/app.rb) | Paragraph scrolling, viewport control, long content |
242
- | [Sparkline](../../examples/widget_sparkline/app.rb) | Mini charts, time series, bar sets |
243
- | [Style Colors](../../examples/widget_style_colors/app.rb) | Named colors, RGB, indexed 256-color palette |
244
- | [Table](../../examples/widget_table/app.rb) | Row selection, column widths, per-cell styling |
245
- | [Tabs](../../examples/widget_tabs/app.rb) | Tab navigation, highlighting, dividers |
246
- | [Text Width](../../examples/widget_text_width/app.rb) | Unicode-aware width measurement, CJK support |
247
- | [Canvas](../../examples/widget_canvas/app.rb) | Drawing shapes, markers, custom graphics |
248
- | [Cell](../../examples/widget_cell/app.rb) | Buffer cell inspection, styling attributes |
249
- | [Center](../../examples/widget_center/app.rb) | Centering content, horizontal/vertical alignment |
250
- | [Overlay](../../examples/widget_overlay/app.rb) | Layering widgets, modal backgrounds |
251
- | [Custom Render](../../examples/widget_render/app.rb) | Low-level Draw API, escape hatch for custom widgets |
252
-
253
- ### Sample Applications
254
-
255
- These larger examples combine widgets into complete applications, demonstrating real-world TUI patterns and architectures.
256
-
257
- | Application | Architecture | What you'll learn |
258
- | ---------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------ |
259
- | [All Events](../../examples/app_all_events/app.rb) | Model-View-Update | Event handling, unidirectional data flow, scalable structure |
260
- | [Color Picker](../../examples/app_color_picker/app.rb) | Component-Based | Hit testing, modal dialogs, encapsulated state |
261
- | [Debugging Showcase](../../examples/app_debugging_showcase/app.rb) | Simple Loop | Remote debugging, Rust backtraces, improved error messages |
262
- | [Login Form](../../examples/app_login_form/app.rb) | Overlay + Center | Modal forms, cursor positioning, text input |
263
- | [Stateful Interaction](../../examples/app_stateful_interaction/app.rb) | State Objects | ListState/TableState, offset read-back, mouse click-to-row |
264
-
265
- #### All Events
266
-
267
- [![all_events](../images/app_all_events.png)](../../examples/app_all_events/README.md)
268
-
269
- #### Color Picker
270
-
271
- [![color_picker](../images/app_color_picker.png)](../../examples/app_color_picker/README.md)
272
-
273
- #### Debugging Showcase
274
-
275
- [![debugging_showcase](../images/app_debugging_showcase.gif)](../../examples/app_debugging_showcase/README.md)
276
-
277
- #### Login Form
278
-
279
- [![login_form](../images/app_login_form.png)](../../examples/app_login_form/README.md)
280
-
281
-
282
- ## Next Steps
283
-
284
- Now that you've seen what **ratatui_ruby** can do:
285
-
286
- - **Deep dive**: Read the [Application Architecture](../concepts/application_architecture.md) guide for scaling patterns
287
- - **Test your TUI**: See the [Testing Guide](../concepts/application_testing.md) for snapshot and style assertions
288
- - **Avoid common mistakes**: See [Terminal Output During TUI Sessions](../troubleshooting/tui_output.md) to prevent screen corruption
289
- - **Explore the API**: Browse the [full RDoc documentation](../index.md)
290
- - **Learn the philosophy**: Read [Why RatatuiRuby?](./why.md) for comparisons and design decisions
291
- - **Get help**: Join the [discussion mailing list](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss)
@@ -1,93 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Why RatatuiRuby?
6
-
7
- The terminal is having a renaissance. Ruby deserves to be at the forefront.
8
-
9
- **RatatuiRuby** is a high-performance, immediate-mode TUI engine that brings the power of Rust's [Ratatui](https://ratatui.rs) library directly into Ruby. No ports. No emulations. A native bridge to the industry-standard Rust crate.
10
-
11
-
12
- ## The Pitch
13
-
14
- You want to build a terminal UI. You love Ruby. Your options were:
15
-
16
- 1. **Learn Go** for Bubble Tea
17
- 2. **Learn Rust** for Ratatui
18
- 3. **Use a pure-Ruby library** with limited performance
19
-
20
- We built a fourth option: **Write Ruby. Run Rust.**
21
-
22
- RatatuiRuby gives you Rust's layout engine, rendering speed, and battle-tested widgets — with Ruby's expressiveness, ecosystem, and joy.
23
-
24
-
25
- ## RatatuiRuby vs. CharmRuby
26
-
27
- [CharmRuby](https://github.com/marcoroth/charm_ruby) is an excellent project by Marco Roth. It provides Ruby bindings to Charm's Go libraries (Bubble Tea, Lipgloss). The Ruby ecosystem is better because both projects exist.
28
-
29
- So which one should you choose?
30
-
31
- | | CharmRuby | RatatuiRuby |
32
- |---|-----------|-------------|
33
- | **Backend** | Go runtime | Rust (no runtime) |
34
- | **Architecture** | Elm Architecture (MVU) | Immediate-mode + your choice |
35
- | **GC Behavior** | Two GCs (Ruby + Go) | One GC (Ruby only) |
36
- | **Rendering** | String manipulation | Constraint-based layout tree |
37
- | **Best for** | Fans of Bubble Tea, MVU | Native performance, heavy-duty apps |
38
-
39
- **What's a runtime?** A runtime is background machinery that a language needs to run. Go has one (for goroutines and garbage collection). Rust doesn't — it compiles to plain machine code. When you use Go bindings, you're running *two* runtimes in the same process (Ruby's and Go's), which adds complexity and memory overhead. With Rust bindings, there's only Ruby.
40
-
41
- **Choose CharmRuby** if you prefer Charm's aesthetics or are migrating existing Bubble Tea code.
42
-
43
- **Choose RatatuiRuby** if you want zero-overhead native performance and architectural freedom. RatatuiRuby doesn't force a framework — you can build MVU, component-based, or any pattern you prefer.
44
-
45
-
46
- ## Why Not Just Write Rust?
47
-
48
- Rust is amazing. It's also strict.
49
-
50
- The borrow checker enforces memory safety. That's great for systems programming. It's painful for UI iteration. Moving a sidebar, changing a color, or swapping a widget often requires refactoring ownership chains.
51
-
52
- With RatatuiRuby, you just change the object. You get Rust's performance where it matters — rendering — and Ruby's flexibility where it counts — designing.
53
-
54
-
55
- ## Why Not Just Write Go?
56
-
57
- Go is pragmatic. But using Go bindings means running *two* runtimes in the same process: Ruby's and Go's. That adds complexity and memory overhead.
58
-
59
- With RatatuiRuby, there's only Ruby. Rust compiles to plain machine code with no runtime — it integrates seamlessly.
60
-
61
-
62
- ## Why Ruby?
63
-
64
- [Ruby isn't just another language](https://www.ruby-lang.org/en/). It's an ecosystem:
65
-
66
- - **[ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html)** — Query your database with elegant, chainable methods
67
- - **[RSpec](https://rspec.info/)** — Write expressive, readable tests with `describe`, `it`, and `expect`
68
- - **[Blocks](https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/blocks.html)** — Pass behavior to methods with `do...end`, the heart of Ruby's expressiveness
69
- - **[Metaprogramming](https://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/objinitialization.html)** — Define methods dynamically, build DSLs, and write code that writes code
70
- - **[Bundler](https://bundler.io/)** — Access 180,000+ gems with a single `bundle add`
71
-
72
- Build a dashboard for your Rails app. Monitor your Sidekiq jobs. Create developer tools in the same language as the code they inspect.
73
-
74
-
75
- ## The Philosophy: A Solid Foundation
76
-
77
- RatatuiRuby is a **low-level engine**. It provides raw primitives — Layouts, Blocks, Text, Tables, Charts — to build anything.
78
-
79
- It doesn't force a framework on you. You can use:
80
- - **Model-View-Update** for dashboards and data displays
81
- - **Component-based** patterns for interactive tools
82
- - **Your own architecture** for everything else
83
-
84
- This is the foundation for Ruby's next generation of TUI tools, dashboards, and interactive scripts.
85
-
86
-
87
- ## Get Started
88
-
89
- Ready to build?
90
-
91
- - [Quickstart Guide](./quickstart.md) — Your first app in 5 minutes
92
- - [Widget Gallery](./quickstart.md#widget-demos) — See what's possible
93
- - [Application Architecture](../concepts/application_architecture.md) — Patterns for scaling
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/doc/index.md DELETED
@@ -1,39 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
- # Start Here
6
-
7
-
8
- ## Documentation for Users
9
-
10
- - [README](../README.md): Project overview and installation
11
-
12
- ### Getting Started
13
-
14
- - [Why RatatuiRuby?](./getting_started/why.md): Philosophy, comparisons, and what makes us different
15
- - [Quickstart](./getting_started/quickstart.md): Build your first TUI app
16
-
17
- ### Concepts
18
-
19
- - [Application Architecture](./concepts/application_architecture.md): Lifecycle patterns and API choices
20
- - [Event Handling](./concepts/event_handling.md): Keyboard, mouse, and terminal events
21
- - [Interactive Design](./concepts/interactive_design.md): Cached layout pattern for hit testing
22
- - [Testing Your Application](./concepts/application_testing.md): Snapshot testing and style assertions
23
- - [Custom Widgets](./concepts/custom_widgets.md): Build anything with the Draw API
24
- - [Async Operations](./concepts/async.md): Background tasks and non-blocking I/O
25
-
26
- ### Troubleshooting
27
-
28
- - [Debugging](./troubleshooting/debugging.md): Debugging techniques and tools
29
- - [Terminal Limitations](./troubleshooting/terminal_limitations.md): Platform quirks and workarounds
30
-
31
- ### Migration
32
-
33
- - [Migrating to v0.7.0](./migration/v0_7_0.md): Namespace changes and upgrade guide
34
-
35
-
36
- ## Documentation for Contributors
37
-
38
- - [Contributing Guidelines](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md): How to contribute patches and features
39
- - [More Documentation for Contributors](./contributors/index.md): Internal design docs and style guides
@@ -1,4 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
@@ -1,131 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Terminal Limitations
7
-
8
- Some behaviors are outside the control of `ratatui_ruby`. This document explains common pitfalls that affect your application or your users, but cannot be fixed in the library.
9
-
10
- ## Keyboard Event Interception
11
-
12
- ### The Problem
13
-
14
- Your application receives a key event, but the modifier flags are missing. You pressed Ctrl+PageUp, but the event shows `code="page_up"` with `modifiers=[]`.
15
-
16
- ### The Cause
17
-
18
- Terminal emulators intercept certain key combinations for their own features. The key press never reaches your application—the terminal consumes it first.
19
-
20
- Common culprits on macOS:
21
-
22
- | Key Combination | Terminal Behavior |
23
- |---------------------|--------------------------------------|
24
- | Ctrl+PageUp/Down | Switch tabs (Terminal.app, iTerm2) |
25
- | Ctrl+Tab | Switch tabs |
26
- | Cmd+T / Cmd+N | New tab / New window |
27
- | Cmd+C / Cmd+V | Copy / Paste (not Ctrl) |
28
-
29
- Linux terminals vary widely. Windows Terminal and ConEmu have their own defaults.
30
-
31
- ### The Solution
32
-
33
- 1. **Test with different terminals.** Kitty, WezTerm, and Alacritty pass more key combinations through to applications by default. If a key works in Kitty but not Terminal.app, the terminal is the issue.
34
-
35
- 2. **Reconfigure your terminal.** Most terminal emulators let you unbind or remap default shortcuts in their settings.
36
-
37
- 3. **Use alternative key bindings.** If your users will run your application in various terminals, design your keybindings to avoid commonly intercepted combinations:
38
- - Use Alt+PageUp instead of Ctrl+PageUp
39
- - Use Ctrl+J/K instead of Ctrl+Up/Down
40
- - Avoid Ctrl+Tab entirely
41
-
42
- 4. **Document requirements.** If your application depends on specific key combinations, document the terminal requirements for your users.
43
-
44
- ### Enhanced Keyboard Protocol
45
-
46
- Some terminals support the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/), which provides unambiguous key event reporting including:
47
-
48
- - Individual modifier key events (LeftShift vs RightShift)
49
- - Media keys (Play, Pause, Volume controls)
50
- - Repeat and release events
51
-
52
- Terminals with full protocol support:
53
- - Kitty
54
- - WezTerm
55
- - Foot
56
- - Alacritty (partial)
57
-
58
- Standard terminals (Terminal.app, iTerm2, GNOME Terminal) do not support the enhanced protocol.
59
-
60
- **RatatuiRuby Status:** The underlying library (crossterm) supports this protocol, but RatatuiRuby does not yet expose a way to enable it. The key code mappings for media keys and individual modifier keys exist, but they will only be received from terminals that enable the protocol by default. This is planned for a future release.
61
-
62
- ## Mouse Event Limitations
63
-
64
- ### The Problem
65
-
66
- Mouse events work in some terminals but not others. Or they work, but only up to certain coordinates.
67
-
68
- ### The Cause
69
-
70
- Mouse reporting requires terminal escape sequence support. Older terminals may not support:
71
-
72
- - SGR mouse mode (coordinates > 223)
73
- - Mouse motion tracking
74
- - Button-event tracking
75
-
76
- ### The Solution
77
-
78
- Ensure your terminal supports modern mouse modes. Most actively maintained terminals do. If running in a legacy environment, test mouse functionality and provide keyboard alternatives.
79
-
80
- ## Focus Events
81
-
82
- ### The Problem
83
-
84
- `Event::FocusGained` and `Event::FocusLost` are never received.
85
-
86
- ### The Cause
87
-
88
- Focus event reporting requires explicit terminal support and configuration. Some terminals don't support it at all.
89
-
90
- ### The Solution
91
-
92
- Don't rely on focus events for critical functionality. Treat them as nice-to-have enhancements. If your application shows stale data when the user returns, periodically refresh instead of waiting for focus events.
93
-
94
- ## Process Termination
95
-
96
- ### The Problem
97
-
98
- Your TUI app is terminated by `kill -9` or the [OOM killer](https://en.wikipedia.org/wiki/Out_of_memory#Out_of_memory_management). The terminal stays in raw mode. The user's cursor vanishes. Input echoes weirdly. Their shell is unusable.
99
-
100
- ### The Cause
101
-
102
- SIGKILL (`kill -9`) terminates processes immediately. No cleanup code runs. The terminal never receives the escape sequences to restore normal mode.
103
-
104
- This also happens when:
105
- - The system OOM killer terminates your process
106
- - A parent process force-kills your app
107
- - A debugger disconnects ungracefully
108
-
109
- ### The Solution
110
-
111
- There's no way to catch SIGKILL. You can only mitigate the impact.
112
-
113
- **Tell your users how to recover.** In your README or troubleshooting docs, explain: if the terminal breaks, type `reset` and press Enter. The characters won't echo, but the command runs.
114
-
115
- **Script graceful shutdowns.** If you write deployment or process management scripts, prefer graceful signals with a timeout before SIGKILL:
116
-
117
- <!-- SPDX-SnippetBegin -->
118
- <!--
119
- SPDX-FileCopyrightText: 2026 Kerrick Long
120
- SPDX-License-Identifier: MIT-0
121
- -->
122
- ```bash
123
- # Graceful first, force if needed
124
- kill -15 $PID
125
- sleep 2
126
- kill -0 $PID 2>/dev/null && kill -9 $PID
127
- ```
128
- <!-- SPDX-SnippetEnd -->
129
-
130
- See [Application Architecture: Signal Handling](../concepts/application_architecture.md#signal-handling) for programmatic cleanup strategies.
131
-