ratatui_ruby 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +2 -2
  3. data/.builds/ruby-3.3.yml +2 -2
  4. data/.builds/ruby-3.4.yml +2 -2
  5. data/.builds/ruby-4.0.0.yml +2 -2
  6. data/.pre-commit-config.yaml +1 -1
  7. data/AGENTS.md +3 -3
  8. data/CHANGELOG.md +77 -1
  9. data/LICENSES/LGPL-3.0-or-later.txt +304 -0
  10. data/LICENSES/MIT-0.txt +16 -0
  11. data/README.md +33 -5
  12. data/Rakefile +1 -1
  13. data/doc/concepts/application_architecture.md +44 -3
  14. data/doc/concepts/application_testing.md +43 -1
  15. data/doc/concepts/async.md +32 -2
  16. data/doc/concepts/custom_widgets.md +247 -0
  17. data/doc/concepts/event_handling.md +32 -3
  18. data/doc/concepts/interactive_design.md +32 -2
  19. data/doc/contributors/auditing/parity.md +7 -1
  20. data/doc/contributors/design/ruby_frontend.md +85 -1
  21. data/doc/contributors/design/rust_backend.md +67 -1
  22. data/doc/contributors/developing_examples.md +56 -2
  23. data/doc/contributors/documentation_style.md +20 -3
  24. data/doc/contributors/future_work.md +169 -0
  25. data/doc/contributors/index.md +1 -1
  26. data/doc/contributors/v1.0.0_blockers.md +19 -185
  27. data/doc/getting_started/quickstart.md +22 -4
  28. data/doc/getting_started/why.md +1 -1
  29. data/doc/index.md +2 -1
  30. data/doc/troubleshooting/debugging.md +32 -2
  31. data/doc/troubleshooting/terminal_limitations.md +8 -2
  32. data/doc/troubleshooting/tui_output.md +42 -0
  33. data/examples/app_all_events/README.md +14 -2
  34. data/examples/app_all_events/app.rb +1 -1
  35. data/examples/app_all_events/model/app_model.rb +1 -1
  36. data/examples/app_all_events/model/event_color_cycle.rb +1 -1
  37. data/examples/app_all_events/model/event_entry.rb +1 -1
  38. data/examples/app_all_events/model/msg.rb +1 -1
  39. data/examples/app_all_events/model/timestamp.rb +1 -1
  40. data/examples/app_all_events/update.rb +1 -1
  41. data/examples/app_all_events/view/app_view.rb +1 -1
  42. data/examples/app_all_events/view/controls_view.rb +1 -1
  43. data/examples/app_all_events/view/counts_view.rb +1 -1
  44. data/examples/app_all_events/view/live_view.rb +1 -1
  45. data/examples/app_all_events/view/log_view.rb +1 -1
  46. data/examples/app_all_events/view.rb +1 -1
  47. data/examples/app_color_picker/README.md +20 -2
  48. data/examples/app_color_picker/app.rb +1 -1
  49. data/examples/app_color_picker/clipboard.rb +1 -1
  50. data/examples/app_color_picker/color.rb +1 -1
  51. data/examples/app_color_picker/controls.rb +1 -1
  52. data/examples/app_color_picker/copy_dialog.rb +1 -1
  53. data/examples/app_color_picker/export_pane.rb +1 -1
  54. data/examples/app_color_picker/harmony.rb +1 -1
  55. data/examples/app_color_picker/input.rb +1 -1
  56. data/examples/app_color_picker/main_container.rb +1 -1
  57. data/examples/app_color_picker/palette.rb +1 -1
  58. data/examples/app_login_form/README.md +8 -2
  59. data/examples/app_login_form/app.rb +1 -1
  60. data/examples/app_stateful_interaction/README.md +2 -2
  61. data/examples/app_stateful_interaction/app.rb +71 -17
  62. data/examples/timeout_demo.rb +1 -1
  63. data/examples/verify_quickstart_dsl/README.md +6 -0
  64. data/examples/verify_quickstart_dsl/app.rb +3 -3
  65. data/examples/verify_quickstart_layout/README.md +6 -0
  66. data/examples/verify_quickstart_layout/app.rb +3 -3
  67. data/examples/verify_quickstart_lifecycle/README.md +6 -0
  68. data/examples/verify_quickstart_lifecycle/app.rb +3 -3
  69. data/examples/verify_readme_usage/README.md +6 -0
  70. data/examples/verify_readme_usage/app.rb +3 -3
  71. data/examples/widget_barchart/README.md +6 -0
  72. data/examples/widget_barchart/app.rb +2 -2
  73. data/examples/widget_block/README.md +7 -1
  74. data/examples/widget_block/app.rb +2 -2
  75. data/examples/widget_box/README.md +6 -0
  76. data/examples/widget_box/app.rb +9 -6
  77. data/examples/widget_calendar/README.md +6 -0
  78. data/examples/widget_calendar/app.rb +2 -2
  79. data/examples/widget_canvas/README.md +4 -0
  80. data/examples/widget_canvas/app.rb +2 -2
  81. data/examples/widget_cell/README.md +6 -0
  82. data/examples/widget_cell/app.rb +2 -3
  83. data/examples/widget_center/README.md +4 -0
  84. data/examples/widget_center/app.rb +2 -2
  85. data/examples/widget_chart/README.md +6 -0
  86. data/examples/widget_chart/app.rb +2 -2
  87. data/examples/widget_gauge/README.md +6 -0
  88. data/examples/widget_gauge/app.rb +2 -2
  89. data/examples/widget_layout_split/README.md +6 -0
  90. data/examples/widget_layout_split/app.rb +9 -3
  91. data/examples/widget_line_gauge/README.md +6 -0
  92. data/examples/widget_line_gauge/app.rb +2 -2
  93. data/examples/widget_list/README.md +6 -0
  94. data/examples/widget_list/app.rb +2 -2
  95. data/examples/widget_map/README.md +8 -2
  96. data/examples/widget_map/app.rb +2 -2
  97. data/examples/widget_overlay/README.md +7 -1
  98. data/examples/widget_overlay/app.rb +2 -2
  99. data/examples/widget_popup/README.md +6 -0
  100. data/examples/widget_popup/app.rb +2 -2
  101. data/examples/widget_ratatui_logo/README.md +6 -0
  102. data/examples/widget_ratatui_logo/app.rb +2 -3
  103. data/examples/widget_ratatui_mascot/README.md +6 -0
  104. data/examples/widget_ratatui_mascot/app.rb +2 -2
  105. data/examples/widget_rect/README.md +12 -0
  106. data/examples/widget_rect/app.rb +40 -26
  107. data/examples/widget_render/README.md +6 -0
  108. data/examples/widget_render/app.rb +2 -2
  109. data/examples/widget_render/app.rbs +41 -0
  110. data/examples/widget_rich_text/README.md +6 -0
  111. data/examples/widget_rich_text/app.rb +2 -2
  112. data/examples/widget_scroll_text/README.md +6 -0
  113. data/examples/widget_scroll_text/app.rb +2 -2
  114. data/examples/widget_scrollbar/README.md +6 -0
  115. data/examples/widget_scrollbar/app.rb +2 -2
  116. data/examples/widget_sparkline/README.md +6 -0
  117. data/examples/widget_sparkline/app.rb +2 -2
  118. data/examples/widget_style_colors/README.md +6 -0
  119. data/examples/widget_style_colors/app.rb +2 -2
  120. data/examples/widget_table/README.md +8 -2
  121. data/examples/widget_table/app.rb +2 -2
  122. data/examples/widget_tabs/README.md +6 -0
  123. data/examples/widget_tabs/app.rb +2 -2
  124. data/examples/widget_text_width/README.md +6 -0
  125. data/examples/widget_text_width/app.rb +4 -4
  126. data/ext/ratatui_ruby/Cargo.lock +1 -1
  127. data/ext/ratatui_ruby/Cargo.toml +1 -1
  128. data/ext/ratatui_ruby/extconf.rb +2 -2
  129. data/ext/ratatui_ruby/src/events.rs +1 -0
  130. data/ext/ratatui_ruby/src/rendering.rs +1 -1
  131. data/ext/ratatui_ruby/src/style.rs +0 -8
  132. data/ext/ratatui_ruby/src/widgets/chart.rs +0 -118
  133. data/ext/ratatui_ruby/src/widgets/list_state.rs +36 -0
  134. data/lib/ratatui_ruby/buffer/cell.rb +34 -2
  135. data/lib/ratatui_ruby/buffer.rb +2 -2
  136. data/lib/ratatui_ruby/cell.rb +34 -2
  137. data/lib/ratatui_ruby/event/focus_gained.rb +26 -2
  138. data/lib/ratatui_ruby/event/focus_lost.rb +26 -2
  139. data/lib/ratatui_ruby/event/key/character.rb +18 -2
  140. data/lib/ratatui_ruby/event/key/media.rb +2 -2
  141. data/lib/ratatui_ruby/event/key/modifier.rb +10 -2
  142. data/lib/ratatui_ruby/event/key/navigation.rb +2 -2
  143. data/lib/ratatui_ruby/event/key/system.rb +2 -2
  144. data/lib/ratatui_ruby/event/key.rb +114 -2
  145. data/lib/ratatui_ruby/event/mouse.rb +42 -2
  146. data/lib/ratatui_ruby/event/none.rb +10 -2
  147. data/lib/ratatui_ruby/event/paste.rb +34 -2
  148. data/lib/ratatui_ruby/event/resize.rb +34 -2
  149. data/lib/ratatui_ruby/event/sync.rb +52 -0
  150. data/lib/ratatui_ruby/event.rb +32 -2
  151. data/lib/ratatui_ruby/frame.rb +74 -2
  152. data/lib/ratatui_ruby/layout/constraint.rb +193 -2
  153. data/lib/ratatui_ruby/layout/layout.rb +47 -2
  154. data/lib/ratatui_ruby/layout/rect.rb +403 -2
  155. data/lib/ratatui_ruby/layout.rb +2 -2
  156. data/lib/ratatui_ruby/list_state.rb +113 -2
  157. data/lib/ratatui_ruby/output_guard.rb +26 -3
  158. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
  159. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +2 -2
  160. data/lib/ratatui_ruby/schema/bar_chart.rb +50 -2
  161. data/lib/ratatui_ruby/schema/block.rb +21 -15
  162. data/lib/ratatui_ruby/schema/calendar.rb +2 -2
  163. data/lib/ratatui_ruby/schema/canvas.rb +10 -2
  164. data/lib/ratatui_ruby/schema/center.rb +10 -2
  165. data/lib/ratatui_ruby/schema/chart.rb +2 -28
  166. data/lib/ratatui_ruby/schema/clear.rb +10 -2
  167. data/lib/ratatui_ruby/schema/constraint.rb +58 -2
  168. data/lib/ratatui_ruby/schema/cursor.rb +10 -2
  169. data/lib/ratatui_ruby/schema/draw.rb +10 -2
  170. data/lib/ratatui_ruby/schema/gauge.rb +2 -2
  171. data/lib/ratatui_ruby/schema/layout.rb +18 -2
  172. data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
  173. data/lib/ratatui_ruby/schema/list.rb +10 -2
  174. data/lib/ratatui_ruby/schema/list_item.rb +10 -2
  175. data/lib/ratatui_ruby/schema/overlay.rb +10 -2
  176. data/lib/ratatui_ruby/schema/paragraph.rb +10 -2
  177. data/lib/ratatui_ruby/schema/ratatui_logo.rb +2 -2
  178. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +2 -2
  179. data/lib/ratatui_ruby/schema/rect.rb +58 -2
  180. data/lib/ratatui_ruby/schema/row.rb +10 -2
  181. data/lib/ratatui_ruby/schema/scrollbar.rb +2 -2
  182. data/lib/ratatui_ruby/schema/shape/label.rb +10 -2
  183. data/lib/ratatui_ruby/schema/sparkline.rb +10 -2
  184. data/lib/ratatui_ruby/schema/style.rb +18 -2
  185. data/lib/ratatui_ruby/schema/table.rb +2 -2
  186. data/lib/ratatui_ruby/schema/tabs.rb +2 -2
  187. data/lib/ratatui_ruby/schema/text.rb +34 -2
  188. data/lib/ratatui_ruby/scrollbar_state.rb +10 -2
  189. data/lib/ratatui_ruby/style/style.rb +18 -2
  190. data/lib/ratatui_ruby/style.rb +2 -2
  191. data/lib/ratatui_ruby/synthetic_events.rb +86 -0
  192. data/lib/ratatui_ruby/table_state.rb +10 -2
  193. data/lib/ratatui_ruby/terminal_lifecycle.rb +18 -3
  194. data/lib/ratatui_ruby/test_helper/event_injection.rb +62 -2
  195. data/lib/ratatui_ruby/test_helper/snapshot.rb +74 -9
  196. data/lib/ratatui_ruby/test_helper/style_assertions.rb +98 -2
  197. data/lib/ratatui_ruby/test_helper/terminal.rb +50 -2
  198. data/lib/ratatui_ruby/test_helper/test_doubles.rb +18 -2
  199. data/lib/ratatui_ruby/test_helper.rb +10 -2
  200. data/lib/ratatui_ruby/tui/buffer_factories.rb +2 -2
  201. data/lib/ratatui_ruby/tui/canvas_factories.rb +2 -2
  202. data/lib/ratatui_ruby/tui/core.rb +2 -2
  203. data/lib/ratatui_ruby/tui/layout_factories.rb +32 -2
  204. data/lib/ratatui_ruby/tui/state_factories.rb +2 -2
  205. data/lib/ratatui_ruby/tui/style_factories.rb +2 -2
  206. data/lib/ratatui_ruby/tui/text_factories.rb +2 -2
  207. data/lib/ratatui_ruby/tui/widget_factories.rb +2 -2
  208. data/lib/ratatui_ruby/tui.rb +11 -3
  209. data/lib/ratatui_ruby/version.rb +3 -3
  210. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -2
  211. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -2
  212. data/lib/ratatui_ruby/widgets/bar_chart.rb +58 -2
  213. data/lib/ratatui_ruby/widgets/block.rb +37 -15
  214. data/lib/ratatui_ruby/widgets/calendar.rb +2 -2
  215. data/lib/ratatui_ruby/widgets/canvas.rb +10 -2
  216. data/lib/ratatui_ruby/widgets/cell.rb +10 -2
  217. data/lib/ratatui_ruby/widgets/center.rb +10 -2
  218. data/lib/ratatui_ruby/widgets/chart.rb +2 -28
  219. data/lib/ratatui_ruby/widgets/clear.rb +10 -2
  220. data/lib/ratatui_ruby/widgets/cursor.rb +10 -2
  221. data/lib/ratatui_ruby/widgets/gauge.rb +16 -2
  222. data/lib/ratatui_ruby/widgets/line_gauge.rb +16 -2
  223. data/lib/ratatui_ruby/widgets/list.rb +41 -2
  224. data/lib/ratatui_ruby/widgets/list_item.rb +10 -2
  225. data/lib/ratatui_ruby/widgets/overlay.rb +10 -2
  226. data/lib/ratatui_ruby/widgets/paragraph.rb +10 -2
  227. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -2
  228. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -2
  229. data/lib/ratatui_ruby/widgets/row.rb +10 -2
  230. data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -2
  231. data/lib/ratatui_ruby/widgets/shape/label.rb +10 -2
  232. data/lib/ratatui_ruby/widgets/sparkline.rb +10 -2
  233. data/lib/ratatui_ruby/widgets/table.rb +62 -2
  234. data/lib/ratatui_ruby/widgets/tabs.rb +2 -2
  235. data/lib/ratatui_ruby/widgets.rb +2 -2
  236. data/lib/ratatui_ruby.rb +101 -9
  237. data/sig/examples/app_all_events/view.rbs +7 -1
  238. data/sig/examples/app_all_events/view_state.rbs +7 -1
  239. data/sig/examples/app_color_picker/app.rbs +5 -0
  240. data/sig/examples/app_stateful_interaction/app.rbs +7 -1
  241. data/sig/examples/verify_quickstart_dsl/app.rbs +7 -1
  242. data/sig/examples/verify_quickstart_lifecycle/app.rbs +7 -1
  243. data/sig/examples/verify_readme_usage/app.rbs +7 -1
  244. data/sig/examples/widget_block_demo/app.rbs +6 -0
  245. data/sig/examples/widget_box_demo/app.rbs +7 -1
  246. data/sig/examples/widget_calendar_demo/app.rbs +7 -1
  247. data/sig/examples/widget_cell_demo/app.rbs +7 -1
  248. data/sig/examples/widget_chart_demo/app.rbs +7 -1
  249. data/sig/examples/widget_gauge_demo/app.rbs +7 -1
  250. data/sig/examples/widget_layout_split/app.rbs +7 -1
  251. data/sig/examples/widget_line_gauge_demo/app.rbs +7 -1
  252. data/sig/examples/widget_list_demo/app.rbs +5 -0
  253. data/sig/examples/widget_map_demo/app.rbs +7 -1
  254. data/sig/examples/widget_popup_demo/app.rbs +7 -1
  255. data/sig/examples/widget_ratatui_logo_demo/app.rbs +7 -1
  256. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +7 -1
  257. data/sig/examples/widget_rect/app.rbs +7 -1
  258. data/sig/examples/widget_render/app.rbs +7 -1
  259. data/sig/examples/widget_rich_text/app.rbs +7 -1
  260. data/sig/examples/widget_scroll_text/app.rbs +7 -1
  261. data/sig/examples/widget_scrollbar_demo/app.rbs +7 -1
  262. data/sig/examples/widget_sparkline_demo/app.rbs +7 -1
  263. data/sig/examples/widget_style_colors/app.rbs +7 -1
  264. data/sig/examples/widget_table_demo/app.rbs +7 -1
  265. data/sig/examples/widget_text_width/app.rbs +7 -1
  266. data/sig/ratatui_ruby/event.rbs +7 -1
  267. data/sig/ratatui_ruby/frame.rbs +15 -3
  268. data/sig/ratatui_ruby/list_state.rbs +11 -1
  269. data/sig/ratatui_ruby/ratatui_ruby.rbs +8 -2
  270. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +7 -1
  271. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +6 -0
  272. data/sig/ratatui_ruby/schema/bar_chart.rbs +6 -0
  273. data/sig/ratatui_ruby/schema/block.rbs +7 -1
  274. data/sig/ratatui_ruby/schema/calendar.rbs +6 -0
  275. data/sig/ratatui_ruby/schema/canvas.rbs +6 -0
  276. data/sig/ratatui_ruby/schema/center.rbs +6 -0
  277. data/sig/ratatui_ruby/schema/chart.rbs +6 -9
  278. data/sig/ratatui_ruby/schema/constraint.rbs +14 -0
  279. data/sig/ratatui_ruby/schema/cursor.rbs +6 -0
  280. data/sig/ratatui_ruby/schema/draw.rbs +6 -0
  281. data/sig/ratatui_ruby/schema/gauge.rbs +9 -1
  282. data/sig/ratatui_ruby/schema/layout.rbs +6 -0
  283. data/sig/ratatui_ruby/schema/line_gauge.rbs +9 -1
  284. data/sig/ratatui_ruby/schema/list.rbs +9 -1
  285. data/sig/ratatui_ruby/schema/list_item.rbs +7 -1
  286. data/sig/ratatui_ruby/schema/overlay.rbs +6 -0
  287. data/sig/ratatui_ruby/schema/paragraph.rbs +6 -0
  288. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +6 -0
  289. data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +5 -0
  290. data/sig/ratatui_ruby/schema/rect.rbs +30 -0
  291. data/sig/ratatui_ruby/schema/row.rbs +7 -1
  292. data/sig/ratatui_ruby/schema/scrollbar.rbs +6 -0
  293. data/sig/ratatui_ruby/schema/sparkline.rbs +6 -0
  294. data/sig/ratatui_ruby/schema/style.rbs +7 -1
  295. data/sig/ratatui_ruby/schema/table.rbs +11 -1
  296. data/sig/ratatui_ruby/schema/tabs.rbs +6 -0
  297. data/sig/ratatui_ruby/schema/text.rbs +7 -1
  298. data/sig/ratatui_ruby/scrollbar_state.rbs +7 -1
  299. data/sig/ratatui_ruby/session.rbs +7 -1
  300. data/sig/ratatui_ruby/table_state.rbs +7 -1
  301. data/sig/ratatui_ruby/test_helper/event_injection.rbs +7 -1
  302. data/sig/ratatui_ruby/test_helper/snapshot.rbs +7 -1
  303. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +7 -1
  304. data/sig/ratatui_ruby/test_helper/terminal.rbs +7 -1
  305. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -1
  306. data/sig/ratatui_ruby/test_helper.rbs +7 -1
  307. data/sig/ratatui_ruby/tui/buffer_factories.rbs +7 -1
  308. data/sig/ratatui_ruby/tui/canvas_factories.rbs +7 -1
  309. data/sig/ratatui_ruby/tui/core.rbs +7 -1
  310. data/sig/ratatui_ruby/tui/layout_factories.rbs +7 -1
  311. data/sig/ratatui_ruby/tui/state_factories.rbs +7 -1
  312. data/sig/ratatui_ruby/tui/style_factories.rbs +7 -1
  313. data/sig/ratatui_ruby/tui/text_factories.rbs +7 -1
  314. data/sig/ratatui_ruby/tui/widget_factories.rbs +7 -1
  315. data/sig/ratatui_ruby/tui.rbs +7 -1
  316. data/sig/ratatui_ruby/version.rbs +6 -0
  317. data/tasks/autodoc/examples.rb +1 -1
  318. data/tasks/autodoc/member.rb +1 -1
  319. data/tasks/autodoc/name.rb +1 -1
  320. data/tasks/bump/cargo_lockfile.rb +1 -1
  321. data/tasks/bump/changelog.rb +1 -1
  322. data/tasks/bump/header.rb +1 -1
  323. data/tasks/bump/history.rb +1 -1
  324. data/tasks/bump/links.rb +1 -1
  325. data/tasks/bump/manifest.rb +1 -1
  326. data/tasks/bump/ruby_gem.rb +1 -1
  327. data/tasks/bump/sem_ver.rb +1 -1
  328. data/tasks/bump/unreleased_section.rb +1 -1
  329. data/tasks/license/headers_md.rb +223 -0
  330. data/tasks/license/headers_rb.rb +210 -0
  331. data/tasks/license/license_utils.rb +130 -0
  332. data/tasks/license/snippets_md.rb +315 -0
  333. data/tasks/license/snippets_rdoc.rb +150 -0
  334. data/tasks/license.rake +91 -0
  335. data/tasks/rdoc_config.rb +1 -1
  336. data/tasks/resources/build.yml.erb +13 -7
  337. data/tasks/sourcehut.rake +3 -1
  338. data/tasks/terminal_preview/app_screenshot.rb +1 -1
  339. data/tasks/terminal_preview/crash_report.rb +1 -1
  340. data/tasks/terminal_preview/example_app.rb +1 -1
  341. data/tasks/terminal_preview/launcher_script.rb +1 -1
  342. data/tasks/terminal_preview/preview_collection.rb +1 -1
  343. data/tasks/terminal_preview/preview_timing.rb +1 -1
  344. data/tasks/terminal_preview/safety_confirmation.rb +1 -1
  345. data/tasks/terminal_preview/saved_screenshot.rb +1 -1
  346. data/tasks/terminal_preview/system_appearance.rb +1 -1
  347. data/tasks/terminal_preview/terminal_window.rb +1 -1
  348. data/tasks/terminal_preview/window_id.rb +1 -1
  349. data/tasks/website/index_page.rb +1 -1
  350. data/tasks/website/version.rb +1 -1
  351. data/tasks/website/version_menu.rb +1 -1
  352. data/tasks/website/versioned_documentation.rb +1 -1
  353. data/tasks/website/website.rb +1 -1
  354. metadata +15 -3
  355. data/doc/migration/v0_7_0.md +0 -236
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <!--
2
- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
3
  SPDX-License-Identifier: CC-BY-SA-4.0
4
4
  -->
5
5
  # ratatui_ruby
@@ -21,7 +21,7 @@ Mailing List: Announcements](https://img.shields.io/badge/mailing_list-announcem
21
21
  **ratatui_ruby** is a community wrapper that is not affiliated with [the Ratatui team](https://github.com/orgs/ratatui/people).
22
22
 
23
23
  > [!WARNING]
24
- > **ratatui_ruby** is currently in **BETA**. The API may change between minor versions.
24
+ > **ratatui_ruby** is currently in **ALPHA**. The API may change between minor versions.
25
25
 
26
26
  **[Why RatatuiRuby?](./doc/getting_started/why.md)** — Native Rust performance, zero runtime overhead, and Ruby's expressiveness. [See how we compare](./doc/getting_started/why.md) to CharmRuby, raw Rust, and Go.
27
27
 
@@ -44,27 +44,50 @@ including Ruby 4.
44
44
 
45
45
  Add this line to your application's Gemfile:
46
46
 
47
+ <!-- SPDX-SnippetBegin -->
48
+ <!--
49
+ SPDX-FileCopyrightText: 2025 Kerrick Long
50
+ SPDX-License-Identifier: MIT-0
51
+ -->
47
52
  ```ruby
48
53
  gem "ratatui_ruby"
49
54
  ```
55
+ <!-- SPDX-SnippetEnd -->
50
56
 
51
57
  And then execute:
52
58
 
59
+ <!-- SPDX-SnippetBegin -->
60
+ <!--
61
+ SPDX-FileCopyrightText: 2025 Kerrick Long
62
+ SPDX-License-Identifier: MIT-0
63
+ -->
53
64
  ```bash
54
65
  bundle install
55
66
  ```
67
+ <!-- SPDX-SnippetEnd -->
56
68
 
57
69
  Or install it yourself with:
58
70
 
71
+ <!-- SPDX-SnippetBegin -->
72
+ <!--
73
+ SPDX-FileCopyrightText: 2025 Kerrick Long
74
+ SPDX-License-Identifier: MIT-0
75
+ -->
59
76
  ```bash
60
77
  gem install ratatui_ruby
61
78
  ```
79
+ <!-- SPDX-SnippetEnd -->
62
80
 
63
81
 
64
82
  ## Usage
65
83
 
66
84
  **ratatui_ruby** uses an immediate-mode API. You describe your UI using Ruby objects and call `draw` in a loop.
67
85
 
86
+ <!-- SPDX-SnippetBegin -->
87
+ <!--
88
+ SPDX-FileCopyrightText: 2026 Kerrick Long
89
+ SPDX-License-Identifier: MIT-0
90
+ -->
68
91
  <!-- SYNC:START:examples/verify_readme_usage/app.rb:main -->
69
92
  ```ruby
70
93
  RatatuiRuby.run do |tui|
@@ -77,7 +100,7 @@ RatatuiRuby.run do |tui|
77
100
  block: tui.block(
78
101
  title: "My Ruby TUI App",
79
102
  borders: [:all],
80
- border_color: "cyan"
103
+ border_style: { fg: "cyan" }
81
104
  )
82
105
  ),
83
106
  frame.area
@@ -93,6 +116,7 @@ RatatuiRuby.run do |tui|
93
116
  end
94
117
  ```
95
118
  <!-- SYNC:END -->
119
+ <!-- SPDX-SnippetEnd -->
96
120
 
97
121
  ![Hello Ratatui](./doc/images/verify_readme_usage.png)
98
122
 
@@ -138,8 +162,12 @@ Want to help develop **ratatui_ruby**? Check out the [contribution guide on the
138
162
 
139
163
  ## Copyright & License
140
164
 
141
- **ratatui_ruby** is copyright 2025, Kerrick Long. **ratatui_ruby** is licensed under the GNU Affero General Public License v3.0 or later; see [LICENSES/AGPL-3.0-or-later.txt](./LICENSES/AGPL-3.0-or-later) for the full text.
165
+ **ratatui_ruby** is copyright 2025, Kerrick Long.
166
+
167
+ The library is [LGPL-3.0-or-later](./LICENSES/LGPL-3.0-or-later.txt): you can use it in proprietary applications, but you must share changes you make to **ratatui_ruby** itself. Documentation snippets and widget examples are [MIT-0](./LICENSES/MIT-0.txt): copy and use them without attribution.
168
+
169
+ Documentation is [CC-BY-SA-4.0](./LICENSES/CC-BY-SA-4.0.txt). Build tooling and full app examples are [AGPL-3.0-or-later](./LICENSES/AGPL-3.0-or-later.txt). See each file's SPDX comment for specifics.
142
170
 
143
- Some parts of this program are copied from other sources under appropriate reuse licenses, and the copyright belongs to their respective owners. See the [REUSE Specification – Version 3.3](https://reuse.software/spec-3.3/) for information about how we comply with attribution and licensing requirements.
171
+ Some parts of this program are copied from other sources under appropriate reuse licenses, and the copyright belongs to their respective owners. See the [REUSE Specification – Version 3.3](https://reuse.software/spec-3.3/) for details.
144
172
 
145
173
  This program was created with significant assistance from multiple LLMs. The process was human-controlled through creative prompts, with human contributions to each commit. See commit footers for model attribution. [declare-ai.org](https://declare-ai.org/1.0.0/creative.html)
data/Rakefile CHANGED
@@ -8,4 +8,4 @@ require "bundler/gem_tasks"
8
8
  # Import all tasks from the tasks/ directory
9
9
  Dir.glob("tasks/*.rake").each { |r| import r }
10
10
 
11
- task default: %w[lint:fix sourcehut test lint]
11
+ task default: %w[lint:fix sourcehut test lint license:new]
@@ -1,7 +1,6 @@
1
1
  <!--
2
- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
3
-
4
- SPDX-License-Identifier: AGPL-3.0-or-later
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
5
4
  -->
6
5
 
7
6
  # Application Architecture
@@ -24,6 +23,11 @@ Terminals have state. They remember cursor positions, input modes, and screen bu
24
23
 
25
24
  This method acts as a safety net. It initializes the terminal, yields control to your block, and restores the terminal afterwards—even if your code raises an exception.
26
25
 
26
+ <!-- SPDX-SnippetBegin -->
27
+ <!--
28
+ SPDX-FileCopyrightText: 2026 Kerrick Long
29
+ SPDX-License-Identifier: MIT-0
30
+ -->
27
31
  ```ruby
28
32
  RatatuiRuby.run do |tui|
29
33
  loop do
@@ -35,11 +39,17 @@ RatatuiRuby.run do |tui|
35
39
  end
36
40
  # Terminal is restored here
37
41
  ```
42
+ <!-- SPDX-SnippetEnd -->
38
43
 
39
44
  #### Manual Management
40
45
 
41
46
  Need granular control? You can initialize and restore the terminal yourself. Use `ensure` blocks to guarantee cleanup.
42
47
 
48
+ <!-- SPDX-SnippetBegin -->
49
+ <!--
50
+ SPDX-FileCopyrightText: 2026 Kerrick Long
51
+ SPDX-License-Identifier: MIT-0
52
+ -->
43
53
  ```ruby
44
54
  RatatuiRuby.init_terminal
45
55
  begin
@@ -51,6 +61,7 @@ ensure
51
61
  # Terminal is restored here
52
62
  end
53
63
  ```
64
+ <!-- SPDX-SnippetEnd -->
54
65
 
55
66
  #### Signal Handling
56
67
 
@@ -69,6 +80,11 @@ External processes send signals. Your TUI must handle them gracefully.
69
80
  > [!IMPORTANT]
70
81
  > **Ctrl+C in Raw Mode:** When your app is in raw mode, pressing Ctrl+C does *not* send SIGINT. It's captured as a `:ctrl_c` key event. Handle this in your event loop—don't use `trap("INT")`.
71
82
 
83
+ <!-- SPDX-SnippetBegin -->
84
+ <!--
85
+ SPDX-FileCopyrightText: 2026 Kerrick Long
86
+ SPDX-License-Identifier: MIT-0
87
+ -->
72
88
  ```ruby
73
89
  RatatuiRuby.run do |tui|
74
90
  loop do
@@ -78,6 +94,7 @@ RatatuiRuby.run do |tui|
78
94
  end
79
95
  end
80
96
  ```
97
+ <!-- SPDX-SnippetEnd -->
81
98
 
82
99
  **Recovery:** If a TUI app leaves your terminal broken, run `reset` in the shell to restore normal behavior.
83
100
 
@@ -97,6 +114,11 @@ Most widgets are stateless configuration. You create them, render them, and they
97
114
 
98
115
  **Use Case:** When you need to read back the scroll offset (e.g., for mouse hit testing) or persist selection without managing indexes manually.
99
116
 
117
+ <!-- SPDX-SnippetBegin -->
118
+ <!--
119
+ SPDX-FileCopyrightText: 2026 Kerrick Long
120
+ SPDX-License-Identifier: MIT-0
121
+ -->
100
122
  ```ruby
101
123
  # Initialize state once
102
124
  @list_state = RatatuiRuby::ListState.new
@@ -116,6 +138,7 @@ RatatuiRuby.run do |tui|
116
138
  end
117
139
  end
118
140
  ```
141
+ <!-- SPDX-SnippetEnd -->
119
142
 
120
143
  ### API Convenience
121
144
 
@@ -125,6 +148,11 @@ Writing UI trees involves nesting many widgets.
125
148
 
126
149
  **The Solution:** The TUI API (`tui`) provides shorthand factories for every widget. It yields a TUI object to your block.
127
150
 
151
+ <!-- SPDX-SnippetBegin -->
152
+ <!--
153
+ SPDX-FileCopyrightText: 2026 Kerrick Long
154
+ SPDX-License-Identifier: MIT-0
155
+ -->
128
156
  ```ruby
129
157
  RatatuiRuby.run do |tui|
130
158
  loop do
@@ -167,11 +195,17 @@ RatatuiRuby.run do |tui|
167
195
  end
168
196
  end
169
197
  ```
198
+ <!-- SPDX-SnippetEnd -->
170
199
 
171
200
  #### Raw API
172
201
 
173
202
  Building your own abstractions? You might prefer explicit class instantiation. The raw constants are always available.
174
203
 
204
+ <!-- SPDX-SnippetBegin -->
205
+ <!--
206
+ SPDX-FileCopyrightText: 2026 Kerrick Long
207
+ SPDX-License-Identifier: MIT-0
208
+ -->
175
209
  ```ruby
176
210
  RatatuiRuby.run do
177
211
  loop do
@@ -212,6 +246,7 @@ RatatuiRuby.run do
212
246
  end
213
247
  end
214
248
  ```
249
+ <!-- SPDX-SnippetEnd -->
215
250
 
216
251
  ## Thread and Ractor Safety
217
252
 
@@ -236,6 +271,11 @@ These have side effects and are intentionally not shareable:
236
271
  | `TUI` | Cache in `@tui` during run loop. Don't include in Models. |
237
272
  | `Frame` | Pass to helpers during draw block. Invalid after block returns. |
238
273
 
274
+ <!-- SPDX-SnippetBegin -->
275
+ <!--
276
+ SPDX-FileCopyrightText: 2026 Kerrick Long
277
+ SPDX-License-Identifier: MIT-0
278
+ -->
239
279
  ```ruby
240
280
  # Good: Cache session in instance variable
241
281
  RatatuiRuby.run do |tui|
@@ -246,6 +286,7 @@ end
246
286
  # Bad: Include in immutable Model (won't work with Ractors)
247
287
  Model = Data.define(:tui, :count) # Don't do this
248
288
  ```
289
+ <!-- SPDX-SnippetEnd -->
249
290
 
250
291
 
251
292
  ## Reference Architectures
@@ -1,5 +1,5 @@
1
1
  <!--
2
- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
3
  SPDX-License-Identifier: CC-BY-SA-4.0
4
4
  -->
5
5
  # Application Testing Guide
@@ -18,19 +18,31 @@ Use it to write fast, deterministic tests for your TUI applications.
18
18
 
19
19
  First, require the test helper in your test file or `test_helper.rb`:
20
20
 
21
+ <!-- SPDX-SnippetBegin -->
22
+ <!--
23
+ SPDX-FileCopyrightText: 2025 Kerrick Long
24
+ SPDX-License-Identifier: MIT-0
25
+ -->
21
26
  ```ruby
22
27
  require "ratatui_ruby/test_helper"
23
28
  require "minitest/autorun" # or your preferred test framework
24
29
  ```
30
+ <!-- SPDX-SnippetEnd -->
25
31
 
26
32
  Then, include the module in your test class:
27
33
 
34
+ <!-- SPDX-SnippetBegin -->
35
+ <!--
36
+ SPDX-FileCopyrightText: 2025 Kerrick Long
37
+ SPDX-License-Identifier: MIT-0
38
+ -->
28
39
  ```ruby
29
40
  class MyApplicationTest < Minitest::Test
30
41
  include RatatuiRuby::TestHelper
31
42
  # ...
32
43
  end
33
44
  ```
45
+ <!-- SPDX-SnippetEnd -->
34
46
 
35
47
  ## Writing a View Test
36
48
 
@@ -40,6 +52,11 @@ To test a view or widget, wrap your assertions in `with_test_terminal`. This set
40
52
  2. **Render your code:** Instantiate your widget and draw it to a frame.
41
53
  3. **Assert output:** Check the `buffer_content` against your expectations.
42
54
 
55
+ <!-- SPDX-SnippetBegin -->
56
+ <!--
57
+ SPDX-FileCopyrightText: 2026 Kerrick Long
58
+ SPDX-License-Identifier: MIT-0
59
+ -->
43
60
  ```ruby
44
61
  def test_rendering
45
62
  # Uses default 80x24 terminal
@@ -57,6 +74,7 @@ def test_rendering
57
74
  end
58
75
  end
59
76
  ```
77
+ <!-- SPDX-SnippetEnd -->
60
78
 
61
79
  For the full API list, including `buffer_content` and `cursor_position`, see [RatatuiRuby::TestHelper::Terminal](../lib/ratatui_ruby/test_helper/terminal.rb).
62
80
 
@@ -66,6 +84,11 @@ You often need to check colors and modifiers (bold, italic) to ensure your highl
66
84
 
67
85
  Use `assert_fg_color`, `assert_bg_color`, and modifier helpers like `assert_bold`.
68
86
 
87
+ <!-- SPDX-SnippetBegin -->
88
+ <!--
89
+ SPDX-FileCopyrightText: 2026 Kerrick Long
90
+ SPDX-License-Identifier: MIT-0
91
+ -->
69
92
  ```ruby
70
93
  # Assert specific cell style
71
94
  assert_fg_color(:red, 0, 0)
@@ -74,6 +97,7 @@ assert_bold(0, 0)
74
97
  # Or check a whole area
75
98
  assert_area_style({ x: 0, y: 0, w: 10, h: 1 }, bg: :blue)
76
99
  ```
100
+ <!-- SPDX-SnippetEnd -->
77
101
 
78
102
  See [RatatuiRuby::TestHelper::StyleAssertions](../lib/ratatui_ruby/test_helper/style_assertions.rb) for the comprehensive list of style helpers.
79
103
 
@@ -86,6 +110,11 @@ Use `inject_event` to push mock events into the queue. This ensures safe, determ
86
110
  > [!IMPORTANT]
87
111
  > Call `inject_event` inside a `with_test_terminal` block to avoid race conditions.
88
112
 
113
+ <!-- SPDX-SnippetBegin -->
114
+ <!--
115
+ SPDX-FileCopyrightText: 2026 Kerrick Long
116
+ SPDX-License-Identifier: MIT-0
117
+ -->
89
118
  ```ruby
90
119
  with_test_terminal do
91
120
  # Simulate 'q' key press
@@ -96,6 +125,7 @@ with_test_terminal do
96
125
  assert_equal "q", event.code
97
126
  end
98
127
  ```
128
+ <!-- SPDX-SnippetEnd -->
99
129
 
100
130
  See [RatatuiRuby::TestHelper::EventInjection](../lib/ratatui_ruby/test_helper/event_injection.rb) for helper methods like `inject_keys` and `inject_click`.
101
131
 
@@ -105,12 +135,18 @@ Snapshots let you verify complex layouts without manually asserting every line.
105
135
 
106
136
  Use `assert_snapshots` to compare the current screen against stored reference files.
107
137
 
138
+ <!-- SPDX-SnippetBegin -->
139
+ <!--
140
+ SPDX-FileCopyrightText: 2026 Kerrick Long
141
+ SPDX-License-Identifier: MIT-0
142
+ -->
108
143
  ```ruby
109
144
  with_test_terminal do
110
145
  MyApp.new.run
111
146
  assert_snapshots("dashboard_view")
112
147
  end
113
148
  ```
149
+ <!-- SPDX-SnippetEnd -->
114
150
 
115
151
  This generates both `.txt` (plain text) and `.ansi` (styled) snapshot files. The `.ansi` files contain ANSI escape codes—`cat` them in a terminal to see exactly what the screen looked like. For a visual tour of your test suite, try `cat **/*.ansi` in any shell that supports globbing.
116
152
 
@@ -130,6 +166,11 @@ Sometimes you want to test a single view component without spinning up the full
130
166
 
131
167
  Use `MockFrame` and `StubRect` to test render logic in isolation.
132
168
 
169
+ <!-- SPDX-SnippetBegin -->
170
+ <!--
171
+ SPDX-FileCopyrightText: 2026 Kerrick Long
172
+ SPDX-License-Identifier: MIT-0
173
+ -->
133
174
  ```ruby
134
175
  def test_logs_view
135
176
  frame = RatatuiRuby::TestHelper::TestDoubles::MockFrame.new
@@ -143,6 +184,7 @@ def test_logs_view
143
184
  assert_equal "Logs", rendered[:widget].block.title
144
185
  end
145
186
  ```
187
+ <!-- SPDX-SnippetEnd -->
146
188
 
147
189
  See [RatatuiRuby::TestHelper::TestDoubles](../lib/ratatui_ruby/test_helper/test_doubles.rb).
148
190
 
@@ -1,6 +1,6 @@
1
1
  <!--
2
- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: AGPL-3.0-or-later
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
4
4
  -->
5
5
 
6
6
  # Async Operations in TUI Applications
@@ -21,12 +21,18 @@ This guide explains async patterns that work with raw terminal mode.
21
21
 
22
22
  ### What Breaks
23
23
 
24
+ <!-- SPDX-SnippetBegin -->
25
+ <!--
26
+ SPDX-FileCopyrightText: 2026 Kerrick Long
27
+ SPDX-License-Identifier: MIT-0
28
+ -->
24
29
  ```ruby
25
30
  # These fail inside a Thread during raw mode:
26
31
  `git ls-remote --tags origin` # Returns empty or hangs
27
32
  IO.popen(["git", "ls-remote", ...]) # Same
28
33
  Open3.capture2("git", "ls-remote", ...) # Same
29
34
  ```
35
+ <!-- SPDX-SnippetEnd -->
30
36
 
31
37
  The commands succeed synchronously. They fail asynchronously. The difference: thread context inherits the parent's raw terminal state.
32
38
 
@@ -46,11 +52,17 @@ Ruby's GIL releases during I/O. But:
46
52
 
47
53
  Run slow operations before entering the TUI:
48
54
 
55
+ <!-- SPDX-SnippetBegin -->
56
+ <!--
57
+ SPDX-FileCopyrightText: 2026 Kerrick Long
58
+ SPDX-License-Identifier: MIT-0
59
+ -->
49
60
  ```ruby
50
61
  def initialize
51
62
  @data = fetch_data # Runs before RatatuiRuby.run
52
63
  end
53
64
  ```
65
+ <!-- SPDX-SnippetEnd -->
54
66
 
55
67
  **Trade-off**: Delays startup.
56
68
 
@@ -58,6 +70,11 @@ end
58
70
 
59
71
  Spawn a separate process before entering raw mode. Write results to a temp file. Poll for completion:
60
72
 
73
+ <!-- SPDX-SnippetBegin -->
74
+ <!--
75
+ SPDX-FileCopyrightText: 2026 Kerrick Long
76
+ SPDX-License-Identifier: MIT-0
77
+ -->
61
78
  ```ruby
62
79
  class AsyncChecker
63
80
  CACHE_FILE = File.join(Dir.tmpdir, "my_check_result.txt")
@@ -81,6 +98,7 @@ class AsyncChecker
81
98
  end
82
99
  end
83
100
  ```
101
+ <!-- SPDX-SnippetEnd -->
84
102
 
85
103
  **Key points**:
86
104
 
@@ -93,9 +111,15 @@ end
93
111
 
94
112
  Ruby threads work for pure computation:
95
113
 
114
+ <!-- SPDX-SnippetBegin -->
115
+ <!--
116
+ SPDX-FileCopyrightText: 2026 Kerrick Long
117
+ SPDX-License-Identifier: MIT-0
118
+ -->
96
119
  ```ruby
97
120
  Thread.new { @result = expensive_calculation }
98
121
  ```
122
+ <!-- SPDX-SnippetEnd -->
99
123
 
100
124
  Avoid threads for shell commands.
101
125
 
@@ -122,6 +146,11 @@ For TUI async, `Process.spawn` solves the problem cleanly.
122
146
 
123
147
  Check if a tag exists on the remote:
124
148
 
149
+ <!-- SPDX-SnippetBegin -->
150
+ <!--
151
+ SPDX-FileCopyrightText: 2026 Kerrick Long
152
+ SPDX-License-Identifier: MIT-0
153
+ -->
125
154
  ```ruby
126
155
  class GitRepo
127
156
  CACHE_FILE = File.join(Dir.tmpdir, "git_tag_pushed.txt")
@@ -156,5 +185,6 @@ class GitRepo
156
185
  end
157
186
  end
158
187
  ```
188
+ <!-- SPDX-SnippetEnd -->
159
189
 
160
190
  The TUI starts instantly. The tag check runs in the background. The checklist updates when the result arrives.