ratatui_ruby 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +1 -1
  3. data/.builds/ruby-3.3.yml +1 -1
  4. data/.builds/ruby-3.4.yml +1 -1
  5. data/.builds/ruby-4.0.0.yml +1 -1
  6. data/AGENTS.md +98 -176
  7. data/CHANGELOG.md +80 -6
  8. data/README.md +19 -7
  9. data/REUSE.toml +15 -0
  10. data/doc/application_architecture.md +179 -45
  11. data/doc/application_testing.md +80 -32
  12. data/doc/contributors/design/ruby_frontend.md +48 -8
  13. data/doc/contributors/design/rust_backend.md +1 -0
  14. data/doc/contributors/developing_examples.md +191 -48
  15. data/doc/contributors/documentation_style.md +7 -0
  16. data/doc/contributors/examples_audit/p1_high.md +21 -0
  17. data/doc/contributors/examples_audit/p2_moderate.md +81 -0
  18. data/doc/contributors/examples_audit.md +41 -0
  19. data/doc/contributors/index.md +2 -0
  20. data/doc/event_handling.md +21 -7
  21. data/doc/images/app_all_events.png +0 -0
  22. data/doc/images/app_color_picker.png +0 -0
  23. data/doc/images/app_login_form.png +0 -0
  24. data/doc/images/app_stateful_interaction.png +0 -0
  25. data/doc/images/verify_quickstart_dsl.png +0 -0
  26. data/doc/images/verify_quickstart_layout.png +0 -0
  27. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  28. data/doc/images/verify_readme_usage.png +0 -0
  29. data/doc/images/widget_barchart_demo.png +0 -0
  30. data/doc/images/widget_block_demo.png +0 -0
  31. data/doc/images/widget_box_demo.png +0 -0
  32. data/doc/images/widget_calendar_demo.png +0 -0
  33. data/doc/images/widget_canvas_demo.png +0 -0
  34. data/doc/images/widget_cell_demo.png +0 -0
  35. data/doc/images/widget_center_demo.png +0 -0
  36. data/doc/images/widget_chart_demo.png +0 -0
  37. data/doc/images/widget_gauge_demo.png +0 -0
  38. data/doc/images/widget_layout_split.png +0 -0
  39. data/doc/images/widget_line_gauge_demo.png +0 -0
  40. data/doc/images/widget_list_demo.png +0 -0
  41. data/doc/images/widget_overlay_demo.png +0 -0
  42. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  43. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  44. data/doc/images/widget_render.png +0 -0
  45. data/doc/images/widget_rich_text.png +0 -0
  46. data/doc/images/widget_scroll_text.png +0 -0
  47. data/doc/images/widget_scrollbar_demo.png +0 -0
  48. data/doc/images/widget_sparkline_demo.png +0 -0
  49. data/doc/images/widget_style_colors.png +0 -0
  50. data/doc/images/widget_table_demo.png +0 -0
  51. data/doc/images/widget_table_flex.png +0 -0
  52. data/doc/images/widget_tabs_demo.png +0 -0
  53. data/doc/images/widget_text_width.png +0 -0
  54. data/doc/interactive_design.md +25 -30
  55. data/doc/quickstart.md +150 -130
  56. data/doc/terminal_limitations.md +92 -0
  57. data/examples/app_all_events/README.md +99 -0
  58. data/examples/app_all_events/app.rb +96 -0
  59. data/examples/app_all_events/model/app_model.rb +157 -0
  60. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  61. data/examples/app_all_events/model/event_entry.rb +92 -0
  62. data/examples/app_all_events/model/msg.rb +37 -0
  63. data/examples/app_all_events/model/timestamp.rb +54 -0
  64. data/examples/app_all_events/update.rb +73 -0
  65. data/examples/app_all_events/view/app_view.rb +78 -0
  66. data/examples/app_all_events/view/controls_view.rb +52 -0
  67. data/examples/app_all_events/view/counts_view.rb +59 -0
  68. data/examples/app_all_events/view/live_view.rb +70 -0
  69. data/examples/app_all_events/view/log_view.rb +55 -0
  70. data/examples/app_all_events/view.rb +7 -0
  71. data/examples/app_color_picker/README.md +134 -0
  72. data/examples/app_color_picker/app.rb +74 -0
  73. data/examples/app_color_picker/clipboard.rb +84 -0
  74. data/examples/app_color_picker/color.rb +191 -0
  75. data/examples/app_color_picker/controls.rb +90 -0
  76. data/examples/app_color_picker/copy_dialog.rb +166 -0
  77. data/examples/app_color_picker/export_pane.rb +126 -0
  78. data/examples/app_color_picker/harmony.rb +56 -0
  79. data/examples/app_color_picker/input.rb +174 -0
  80. data/examples/app_color_picker/main_container.rb +178 -0
  81. data/examples/app_color_picker/palette.rb +109 -0
  82. data/examples/app_login_form/README.md +47 -0
  83. data/examples/{login_form → app_login_form}/app.rb +38 -42
  84. data/examples/app_stateful_interaction/README.md +31 -0
  85. data/examples/app_stateful_interaction/app.rb +272 -0
  86. data/examples/timeout_demo.rb +43 -0
  87. data/examples/verify_quickstart_dsl/README.md +48 -0
  88. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +17 -6
  89. data/examples/verify_quickstart_layout/README.md +71 -0
  90. data/examples/verify_quickstart_layout/app.rb +71 -0
  91. data/examples/verify_quickstart_lifecycle/README.md +56 -0
  92. data/examples/verify_quickstart_lifecycle/app.rb +54 -0
  93. data/examples/verify_readme_usage/README.md +43 -0
  94. data/examples/verify_readme_usage/app.rb +40 -0
  95. data/examples/widget_barchart_demo/README.md +49 -0
  96. data/examples/widget_barchart_demo/app.rb +238 -0
  97. data/examples/widget_block_demo/README.md +34 -0
  98. data/examples/widget_block_demo/app.rb +256 -0
  99. data/examples/widget_box_demo/README.md +45 -0
  100. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  101. data/examples/widget_calendar_demo/README.md +39 -0
  102. data/examples/widget_calendar_demo/app.rb +109 -0
  103. data/examples/widget_canvas_demo/README.md +27 -0
  104. data/examples/widget_canvas_demo/app.rb +123 -0
  105. data/examples/widget_cell_demo/README.md +36 -0
  106. data/examples/widget_cell_demo/app.rb +111 -0
  107. data/examples/widget_center_demo/README.md +29 -0
  108. data/examples/widget_center_demo/app.rb +116 -0
  109. data/examples/widget_chart_demo/README.md +41 -0
  110. data/examples/widget_chart_demo/app.rb +218 -0
  111. data/examples/widget_gauge_demo/README.md +41 -0
  112. data/examples/widget_gauge_demo/app.rb +212 -0
  113. data/examples/widget_layout_split/README.md +44 -0
  114. data/examples/widget_layout_split/app.rb +246 -0
  115. data/examples/widget_line_gauge_demo/README.md +41 -0
  116. data/examples/widget_line_gauge_demo/app.rb +217 -0
  117. data/examples/widget_list_demo/README.md +49 -0
  118. data/examples/widget_list_demo/app.rb +366 -0
  119. data/examples/widget_map_demo/README.md +39 -0
  120. data/examples/{map_demo → widget_map_demo}/app.rb +24 -21
  121. data/examples/widget_overlay_demo/app.rb +248 -0
  122. data/examples/widget_popup_demo/README.md +36 -0
  123. data/examples/widget_popup_demo/app.rb +104 -0
  124. data/examples/widget_ratatui_logo_demo/README.md +34 -0
  125. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  126. data/examples/widget_ratatui_mascot_demo/README.md +34 -0
  127. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  128. data/examples/widget_rect/README.md +38 -0
  129. data/examples/widget_rect/app.rb +205 -0
  130. data/examples/widget_render/README.md +37 -0
  131. data/examples/widget_render/app.rb +184 -0
  132. data/examples/widget_rich_text/README.md +35 -0
  133. data/examples/widget_rich_text/app.rb +166 -0
  134. data/examples/widget_scroll_text/README.md +37 -0
  135. data/examples/widget_scroll_text/app.rb +107 -0
  136. data/examples/widget_scrollbar_demo/README.md +37 -0
  137. data/examples/widget_scrollbar_demo/app.rb +153 -0
  138. data/examples/widget_sparkline_demo/README.md +42 -0
  139. data/examples/widget_sparkline_demo/app.rb +275 -0
  140. data/examples/widget_style_colors/README.md +34 -0
  141. data/examples/widget_style_colors/app.rb +19 -21
  142. data/examples/widget_table_demo/README.md +48 -0
  143. data/examples/widget_table_demo/app.rb +239 -0
  144. data/examples/widget_tabs_demo/README.md +41 -0
  145. data/examples/widget_tabs_demo/app.rb +181 -0
  146. data/examples/widget_text_width/README.md +35 -0
  147. data/examples/widget_text_width/app.rb +106 -0
  148. data/ext/ratatui_ruby/Cargo.lock +11 -4
  149. data/ext/ratatui_ruby/Cargo.toml +2 -1
  150. data/ext/ratatui_ruby/src/events.rs +359 -62
  151. data/ext/ratatui_ruby/src/frame.rs +227 -0
  152. data/ext/ratatui_ruby/src/lib.rs +110 -27
  153. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  154. data/ext/ratatui_ruby/src/string_width.rs +101 -0
  155. data/ext/ratatui_ruby/src/style.rs +138 -57
  156. data/ext/ratatui_ruby/src/terminal.rs +42 -22
  157. data/ext/ratatui_ruby/src/text.rs +14 -7
  158. data/ext/ratatui_ruby/src/widgets/barchart.rs +74 -54
  159. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  160. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  161. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  162. data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
  163. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  164. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
  165. data/ext/ratatui_ruby/src/widgets/list.rs +211 -12
  166. data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
  167. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  168. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  169. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  170. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  171. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  172. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +97 -3
  173. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
  174. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  175. data/ext/ratatui_ruby/src/widgets/table.rs +121 -5
  176. data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
  177. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  178. data/lib/ratatui_ruby/cell.rb +7 -7
  179. data/lib/ratatui_ruby/event/key/character.rb +35 -0
  180. data/lib/ratatui_ruby/event/key/media.rb +44 -0
  181. data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
  182. data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
  183. data/lib/ratatui_ruby/event/key/system.rb +45 -0
  184. data/lib/ratatui_ruby/event/key.rb +112 -52
  185. data/lib/ratatui_ruby/event/mouse.rb +3 -3
  186. data/lib/ratatui_ruby/event/none.rb +43 -0
  187. data/lib/ratatui_ruby/event/paste.rb +1 -1
  188. data/lib/ratatui_ruby/event.rb +56 -4
  189. data/lib/ratatui_ruby/frame.rb +183 -0
  190. data/lib/ratatui_ruby/list_state.rb +88 -0
  191. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +13 -13
  192. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  193. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  194. data/lib/ratatui_ruby/schema/block.rb +163 -168
  195. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  196. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  197. data/lib/ratatui_ruby/schema/center.rb +46 -46
  198. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  199. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  200. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  201. data/lib/ratatui_ruby/schema/cursor.rb +30 -25
  202. data/lib/ratatui_ruby/schema/gauge.rb +54 -52
  203. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  204. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  205. data/lib/ratatui_ruby/schema/list.rb +103 -80
  206. data/lib/ratatui_ruby/schema/list_item.rb +41 -0
  207. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  208. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  209. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  210. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  211. data/lib/ratatui_ruby/schema/rect.rb +99 -56
  212. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  213. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  214. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  215. data/lib/ratatui_ruby/schema/style.rb +66 -46
  216. data/lib/ratatui_ruby/schema/table.rb +126 -115
  217. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  218. data/lib/ratatui_ruby/schema/text.rb +69 -1
  219. data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
  220. data/lib/ratatui_ruby/session/autodoc.rb +482 -0
  221. data/lib/ratatui_ruby/session.rb +55 -23
  222. data/lib/ratatui_ruby/table_state.rb +90 -0
  223. data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
  224. data/lib/ratatui_ruby/test_helper/snapshot.rb +390 -0
  225. data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
  226. data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
  227. data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
  228. data/lib/ratatui_ruby/test_helper.rb +66 -193
  229. data/lib/ratatui_ruby/version.rb +1 -1
  230. data/lib/ratatui_ruby.rb +100 -51
  231. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  232. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  233. data/sig/examples/app_all_events/model/events.rbs +15 -0
  234. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  235. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  236. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  237. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  238. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  239. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  240. data/sig/examples/app_all_events/view.rbs +8 -0
  241. data/sig/examples/app_all_events/view_state.rbs +15 -0
  242. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  243. data/sig/examples/app_login_form/app.rbs +11 -0
  244. data/sig/examples/app_stateful_interaction/app.rbs +33 -0
  245. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  246. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  247. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  248. data/sig/examples/widget_block_demo/app.rbs +32 -0
  249. data/sig/examples/widget_box_demo/app.rbs +11 -0
  250. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  251. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  252. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  253. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  254. data/sig/examples/widget_layout_split/app.rbs +10 -0
  255. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  256. data/sig/examples/widget_list_demo/app.rbs +12 -0
  257. data/sig/examples/widget_map_demo/app.rbs +11 -0
  258. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  259. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  260. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  261. data/sig/examples/widget_rect/app.rbs +12 -0
  262. data/sig/examples/widget_render/app.rbs +10 -0
  263. data/sig/examples/widget_rich_text/app.rbs +11 -0
  264. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  265. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  266. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  267. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  268. data/sig/examples/widget_table_demo/app.rbs +11 -0
  269. data/sig/examples/widget_text_width/app.rbs +10 -0
  270. data/sig/ratatui_ruby/event.rbs +11 -1
  271. data/sig/ratatui_ruby/frame.rbs +11 -0
  272. data/sig/ratatui_ruby/list_state.rbs +13 -0
  273. data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -4
  274. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
  275. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  276. data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
  277. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  278. data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
  279. data/sig/ratatui_ruby/schema/list.rbs +4 -2
  280. data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
  281. data/sig/ratatui_ruby/schema/rect.rbs +3 -0
  282. data/sig/ratatui_ruby/schema/style.rbs +3 -3
  283. data/sig/ratatui_ruby/schema/table.rbs +3 -1
  284. data/sig/ratatui_ruby/schema/text.rbs +8 -6
  285. data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
  286. data/sig/ratatui_ruby/session.rbs +107 -0
  287. data/sig/ratatui_ruby/table_state.rbs +15 -0
  288. data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
  289. data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
  290. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
  291. data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
  292. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
  293. data/sig/ratatui_ruby/test_helper.rbs +5 -4
  294. data/tasks/autodoc/examples.rb +79 -0
  295. data/tasks/autodoc/inventory.rb +63 -0
  296. data/tasks/autodoc/member.rb +56 -0
  297. data/tasks/autodoc/name.rb +19 -0
  298. data/tasks/autodoc/notice.rb +26 -0
  299. data/tasks/autodoc/rbs.rb +38 -0
  300. data/tasks/autodoc/rdoc.rb +45 -0
  301. data/tasks/autodoc.rake +53 -0
  302. data/tasks/bump/changelog.rb +3 -3
  303. data/tasks/bump/history.rb +2 -2
  304. data/tasks/bump/links.rb +67 -0
  305. data/tasks/doc.rake +600 -6
  306. data/tasks/example_viewer.html.erb +172 -0
  307. data/tasks/lint.rake +8 -4
  308. data/tasks/resources/index.html.erb +6 -0
  309. data/tasks/sourcehut.rake +70 -30
  310. data/tasks/terminal_preview/app_screenshot.rb +14 -6
  311. data/tasks/terminal_preview/crash_report.rb +7 -9
  312. data/tasks/terminal_preview/launcher_script.rb +4 -6
  313. data/tasks/terminal_preview/preview_collection.rb +4 -6
  314. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  315. data/tasks/terminal_preview/saved_screenshot.rb +10 -11
  316. data/tasks/terminal_preview/terminal_window.rb +7 -9
  317. data/tasks/test.rake +1 -1
  318. data/tasks/website/index_page.rb +3 -3
  319. data/tasks/website/version.rb +10 -10
  320. data/tasks/website/version_menu.rb +10 -12
  321. data/tasks/website/versioned_documentation.rb +49 -17
  322. data/tasks/website/website.rb +6 -8
  323. data/tasks/website.rake +4 -4
  324. metadata +232 -127
  325. data/LICENSES/BSD-2-Clause.txt +0 -9
  326. data/doc/contributors/better_dx.md +0 -543
  327. data/doc/contributors/example_analysis.md +0 -82
  328. data/doc/images/all_events.png +0 -0
  329. data/doc/images/block_padding.png +0 -0
  330. data/doc/images/block_titles.png +0 -0
  331. data/doc/images/box_demo.png +0 -0
  332. data/doc/images/calendar_demo.png +0 -0
  333. data/doc/images/cell_demo.png +0 -0
  334. data/doc/images/chart_demo.png +0 -0
  335. data/doc/images/flex_layout.png +0 -0
  336. data/doc/images/gauge_demo.png +0 -0
  337. data/doc/images/line_gauge_demo.png +0 -0
  338. data/doc/images/list_demo.png +0 -0
  339. data/doc/images/list_styles.png +0 -0
  340. data/doc/images/login_form.png +0 -0
  341. data/doc/images/quickstart_dsl.png +0 -0
  342. data/doc/images/quickstart_lifecycle.png +0 -0
  343. data/doc/images/readme_usage.png +0 -0
  344. data/doc/images/rich_text.png +0 -0
  345. data/doc/images/scroll_text.png +0 -0
  346. data/doc/images/scrollbar_demo.png +0 -0
  347. data/doc/images/sparkline_demo.png +0 -0
  348. data/doc/images/table_flex.png +0 -0
  349. data/doc/images/table_select.png +0 -0
  350. data/examples/all_events/app.rb +0 -169
  351. data/examples/all_events/app.rbs +0 -7
  352. data/examples/all_events/test_app.rb +0 -139
  353. data/examples/analytics/app.rb +0 -258
  354. data/examples/analytics/app.rbs +0 -7
  355. data/examples/analytics/test_app.rb +0 -132
  356. data/examples/block_padding/app.rb +0 -63
  357. data/examples/block_padding/app.rbs +0 -7
  358. data/examples/block_padding/test_app.rb +0 -31
  359. data/examples/block_titles/app.rb +0 -61
  360. data/examples/block_titles/app.rbs +0 -7
  361. data/examples/block_titles/test_app.rb +0 -34
  362. data/examples/box_demo/app.rbs +0 -7
  363. data/examples/box_demo/test_app.rb +0 -88
  364. data/examples/calendar_demo/app.rb +0 -101
  365. data/examples/calendar_demo/app.rbs +0 -7
  366. data/examples/calendar_demo/test_app.rb +0 -108
  367. data/examples/cell_demo/app.rb +0 -108
  368. data/examples/cell_demo/app.rbs +0 -7
  369. data/examples/cell_demo/test_app.rb +0 -36
  370. data/examples/chart_demo/app.rb +0 -203
  371. data/examples/chart_demo/app.rbs +0 -7
  372. data/examples/chart_demo/test_app.rb +0 -102
  373. data/examples/custom_widget/app.rb +0 -51
  374. data/examples/custom_widget/app.rbs +0 -7
  375. data/examples/custom_widget/test_app.rb +0 -30
  376. data/examples/flex_layout/app.rb +0 -156
  377. data/examples/flex_layout/app.rbs +0 -7
  378. data/examples/flex_layout/test_app.rb +0 -65
  379. data/examples/gauge_demo/app.rb +0 -182
  380. data/examples/gauge_demo/test_app.rb +0 -120
  381. data/examples/hit_test/app.rb +0 -175
  382. data/examples/hit_test/app.rbs +0 -7
  383. data/examples/hit_test/test_app.rb +0 -102
  384. data/examples/line_gauge_demo/app.rb +0 -190
  385. data/examples/line_gauge_demo/app.rbs +0 -7
  386. data/examples/line_gauge_demo/test_app.rb +0 -129
  387. data/examples/list_demo/app.rb +0 -253
  388. data/examples/list_demo/test_app.rb +0 -237
  389. data/examples/list_styles/app.rb +0 -140
  390. data/examples/list_styles/app.rbs +0 -7
  391. data/examples/list_styles/test_app.rb +0 -157
  392. data/examples/login_form/app.rbs +0 -7
  393. data/examples/login_form/test_app.rb +0 -51
  394. data/examples/map_demo/app.rbs +0 -7
  395. data/examples/map_demo/test_app.rb +0 -149
  396. data/examples/mouse_events/app.rb +0 -97
  397. data/examples/mouse_events/app.rbs +0 -7
  398. data/examples/mouse_events/test_app.rb +0 -53
  399. data/examples/popup_demo/app.rb +0 -103
  400. data/examples/popup_demo/app.rbs +0 -7
  401. data/examples/popup_demo/test_app.rb +0 -54
  402. data/examples/quickstart_dsl/app.rbs +0 -7
  403. data/examples/quickstart_dsl/test_app.rb +0 -29
  404. data/examples/quickstart_lifecycle/app.rb +0 -39
  405. data/examples/quickstart_lifecycle/app.rbs +0 -7
  406. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  407. data/examples/ratatui_logo_demo/app.rb +0 -79
  408. data/examples/ratatui_logo_demo/app.rbs +0 -7
  409. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  410. data/examples/ratatui_mascot_demo/app.rb +0 -84
  411. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  412. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  413. data/examples/readme_usage/app.rb +0 -29
  414. data/examples/readme_usage/app.rbs +0 -7
  415. data/examples/readme_usage/test_app.rb +0 -29
  416. data/examples/rich_text/app.rb +0 -141
  417. data/examples/rich_text/app.rbs +0 -7
  418. data/examples/rich_text/test_app.rb +0 -166
  419. data/examples/scroll_text/app.rb +0 -103
  420. data/examples/scroll_text/app.rbs +0 -7
  421. data/examples/scroll_text/test_app.rb +0 -110
  422. data/examples/scrollbar_demo/app.rb +0 -143
  423. data/examples/scrollbar_demo/app.rbs +0 -7
  424. data/examples/scrollbar_demo/test_app.rb +0 -77
  425. data/examples/sparkline_demo/app.rb +0 -240
  426. data/examples/sparkline_demo/test_app.rb +0 -107
  427. data/examples/table_flex/app.rb +0 -65
  428. data/examples/table_flex/app.rbs +0 -7
  429. data/examples/table_flex/test_app.rb +0 -36
  430. data/examples/table_select/app.rb +0 -198
  431. data/examples/table_select/app.rbs +0 -7
  432. data/examples/table_select/test_app.rb +0 -180
  433. data/examples/widget_style_colors/test_app.rb +0 -48
  434. data/tasks/bump/comparison_links.rb +0 -41
  435. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  436. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  437. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  438. /data/doc/images/{map_demo.png → widget_map_demo.png} +0 -0
  439. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  440. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  441. /data/{doc/images/ratatui_logo_demo.png → exe/.gitkeep} +0 -0
@@ -0,0 +1,107 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ # !!! DO NOT EDIT THIS FILE BY HAND !!!
5
+ # This file is automatically generated by `rake autodoc:rbs:session`.
6
+ # Any changes will be overwritten.
7
+
8
+ module RatatuiRuby
9
+ class Session
10
+ def self.new: () -> Session
11
+ | () { (Session) -> void } -> void
12
+
13
+ def _paragraph_line_count: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
14
+ def _paragraph_line_width: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
15
+ def _tabs_width: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
16
+ def _text_width: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
17
+ def clear_events: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
18
+ def draw: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
19
+ def experimental_warnings: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
20
+ def experimental_warnings=: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
21
+ def get_buffer_content: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
22
+ def get_cell_at: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
23
+ def get_cursor_position: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
24
+ def init_terminal: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
25
+ def init_test_terminal: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
26
+ def inject_test_event: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
27
+ def poll_event: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
28
+ def resize_terminal: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
29
+ def restore_terminal: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
30
+ def run: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
31
+ def warn_experimental_feature: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
32
+ def axis: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
33
+ def bar_chart: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
34
+ def bar_chart_bar: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
35
+ def bar_chart_bar_group: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
36
+ def block: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
37
+ def calendar: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
38
+ def canvas: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
39
+ def cell: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
40
+ def cell_char: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
41
+ def cell_default: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
42
+ def cell_empty: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
43
+ def cell_symbol: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
44
+ def center: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
45
+ def chart: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
46
+ def clear: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
47
+ def constraint: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
48
+ def constraint_fill: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
49
+ def constraint_length: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
50
+ def constraint_max: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
51
+ def constraint_min: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
52
+ def constraint_percentage: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
53
+ def constraint_ratio: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
54
+ def cursor: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
55
+ def dataset: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
56
+ def draw_cell: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
57
+ def draw_string: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
58
+ def draw_cell_cmd: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
59
+ def draw_string_cmd: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
60
+ def error: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
61
+ def error_safety: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
62
+ def error_terminal: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
63
+ def event: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
64
+ def event_focus_gained: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
65
+ def event_focus_lost: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
66
+ def event_key: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
67
+ def event_mouse: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
68
+ def event_none: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
69
+ def event_paste: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
70
+ def event_resize: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
71
+ def frame: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
72
+ def gauge: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
73
+ def layout: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
74
+ def layout_split: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
75
+ def line_chart: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
76
+ def line_gauge: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
77
+ def list: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
78
+ def list_item: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
79
+ def list_state: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
80
+ def list_state_new: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
81
+ def overlay: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
82
+ def paragraph: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
83
+ def paragraph_new: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
84
+ def ratatui_logo: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
85
+ def ratatui_mascot: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
86
+ def rect: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
87
+ def scrollbar: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
88
+ def scrollbar_state: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
89
+ def scrollbar_state_new: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
90
+ def shape_circle: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
91
+ def shape_label: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
92
+ def shape_line: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
93
+ def shape_map: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
94
+ def shape_point: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
95
+ def shape_rectangle: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
96
+ def sparkline: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
97
+ def style: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
98
+ def style_default: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
99
+ def table: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
100
+ def table_state: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
101
+ def table_state_new: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
102
+ def tabs: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
103
+ def text_width: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
104
+ def text_line: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
105
+ def text_span: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped
106
+ end
107
+ end
@@ -0,0 +1,15 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ class TableState
6
+ def self.new: (?Integer? selected) -> TableState
7
+ def select: (Integer? index) -> nil
8
+ def selected: () -> Integer?
9
+ def select_column: (Integer? index) -> nil
10
+ def selected_column: () -> Integer?
11
+ def offset: () -> Integer
12
+ def scroll_down_by: (Integer n) -> nil
13
+ def scroll_up_by: (Integer n) -> nil
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ module TestHelper
6
+ module EventInjection
7
+ def inject_event: (Event::Base event) -> void
8
+ def inject_mouse: (x: Integer, y: Integer, ?kind: Symbol, ?modifiers: Array[String], ?button: Symbol) -> void
9
+ def inject_click: (x: Integer, y: Integer, ?modifiers: Array[String]) -> void
10
+ def inject_right_click: (x: Integer, y: Integer, ?modifiers: Array[String]) -> void
11
+ def inject_drag: (x: Integer, y: Integer, ?modifiers: Array[String], ?button: Symbol) -> void
12
+ def inject_keys: (*(String | Symbol | (Hash[Symbol, untyped]) | Event::Key) args) -> void
13
+ alias inject_key inject_keys
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ module TestHelper
6
+ module Snapshot
7
+ def assert_snapshot: (String name, ?String? msg) ?{ (Array[String]) -> Array[String] } -> void
8
+ def assert_screen_matches: (String | Array[String] expected, ?String? msg) ?{ (Array[String]) -> Array[String] } -> void
9
+ def assert_rich_snapshot: (String name, ?String? msg) ?{ (Array[String]) -> Array[String] } -> void
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,64 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ module TestHelper
6
+ module StyleAssertions
7
+ def assert_cell_style: (Integer x, Integer y, **untyped expected_attributes) -> void
8
+ def assert_color: (Symbol | Integer | String expected, x: Integer, y: Integer, ?layer: Symbol) -> void
9
+ def assert_area_style: (Rect | Hash[Symbol, Integer] area, **untyped attributes) -> void
10
+ def assert_fg_color: (Symbol | Integer | String expected, Integer x, Integer y) -> void
11
+ alias assert_fg assert_fg_color
12
+ def assert_bg_color: (Symbol | Integer | String expected, Integer x, Integer y) -> void
13
+ alias assert_bg assert_bg_color
14
+ def assert_bold: (Integer x, Integer y) -> void
15
+ def assert_italic: (Integer x, Integer y) -> void
16
+ def assert_underlined: (Integer x, Integer y) -> void
17
+ alias assert_underline assert_underlined
18
+ def assert_dim: (Integer x, Integer y) -> void
19
+ def assert_reversed: (Integer x, Integer y) -> void
20
+ alias assert_inverse assert_reversed
21
+ alias assert_inverse_video assert_reversed
22
+ def assert_crossed_out: (Integer x, Integer y) -> void
23
+ alias assert_strikethrough assert_crossed_out
24
+ alias assert_strike assert_crossed_out
25
+ def assert_hidden: (Integer x, Integer y) -> void
26
+ def assert_slow_blink: (Integer x, Integer y) -> void
27
+ alias assert_blink assert_slow_blink
28
+ def assert_rapid_blink: (Integer x, Integer y) -> void
29
+
30
+ def assert_black: (Integer x, Integer y) -> void
31
+ def assert_bg_black: (Integer x, Integer y) -> void
32
+ def assert_red: (Integer x, Integer y) -> void
33
+ def assert_bg_red: (Integer x, Integer y) -> void
34
+ def assert_green: (Integer x, Integer y) -> void
35
+ def assert_bg_green: (Integer x, Integer y) -> void
36
+ def assert_yellow: (Integer x, Integer y) -> void
37
+ def assert_bg_yellow: (Integer x, Integer y) -> void
38
+ def assert_blue: (Integer x, Integer y) -> void
39
+ def assert_bg_blue: (Integer x, Integer y) -> void
40
+ def assert_magenta: (Integer x, Integer y) -> void
41
+ def assert_bg_magenta: (Integer x, Integer y) -> void
42
+ def assert_cyan: (Integer x, Integer y) -> void
43
+ def assert_bg_cyan: (Integer x, Integer y) -> void
44
+ def assert_gray: (Integer x, Integer y) -> void
45
+ def assert_bg_gray: (Integer x, Integer y) -> void
46
+ def assert_dark_gray: (Integer x, Integer y) -> void
47
+ def assert_bg_dark_gray: (Integer x, Integer y) -> void
48
+ def assert_light_red: (Integer x, Integer y) -> void
49
+ def assert_bg_light_red: (Integer x, Integer y) -> void
50
+ def assert_light_green: (Integer x, Integer y) -> void
51
+ def assert_bg_light_green: (Integer x, Integer y) -> void
52
+ def assert_light_yellow: (Integer x, Integer y) -> void
53
+ def assert_bg_light_yellow: (Integer x, Integer y) -> void
54
+ def assert_light_blue: (Integer x, Integer y) -> void
55
+ def assert_bg_light_blue: (Integer x, Integer y) -> void
56
+ def assert_light_magenta: (Integer x, Integer y) -> void
57
+ def assert_bg_light_magenta: (Integer x, Integer y) -> void
58
+ def assert_light_cyan: (Integer x, Integer y) -> void
59
+ def assert_bg_light_cyan: (Integer x, Integer y) -> void
60
+ def assert_white: (Integer x, Integer y) -> void
61
+ def assert_bg_white: (Integer x, Integer y) -> void
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ module TestHelper
6
+ module Terminal
7
+ def with_test_terminal: (?Integer width, ?Integer height, ?timeout: Integer?) ?{ () -> void } -> void
8
+ def buffer_content: () -> Array[String]
9
+ def cursor_position: () -> { x: Integer, y: Integer }
10
+ def get_cell: (Integer x, Integer y) -> Cell
11
+ def print_buffer: () -> void
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: AGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ module TestHelper
6
+ module TestDoubles
7
+ class MockFrame < Data
8
+ attr_accessor rendered_widgets: Array[{ widget: untyped, area: Rect }]
9
+ def self.new: (?rendered_widgets: Array[{ widget: untyped, area: Rect }]) -> MockFrame
10
+ def render_widget: (untyped widget, Rect area) -> void
11
+ end
12
+
13
+ class StubRect < Data
14
+ attr_accessor x: Integer
15
+ attr_accessor y: Integer
16
+ attr_accessor width: Integer
17
+ attr_accessor height: Integer
18
+ def self.new: (?x: Integer, ?y: Integer, ?width: Integer, ?height: Integer) -> StubRect
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,9 +3,10 @@
3
3
 
4
4
  module RatatuiRuby
5
5
  module TestHelper
6
- def with_test_terminal: (?Integer width, ?Integer height) { () -> void } -> void
7
- def buffer_content: () -> Array[String]
8
- def cursor_position: () -> { x: Integer, y: Integer }
9
- def inject_event: (String event_type, Hash[Symbol, untyped] data) -> void
6
+ include Terminal
7
+ include Snapshot
8
+ include EventInjection
9
+ include StyleAssertions
10
+ include TestDoubles
10
11
  end
11
12
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module Autodoc
7
+ class Examples
8
+ def self.sync
9
+ new.sync
10
+ end
11
+
12
+ def sync
13
+ Dir.glob("{README.md,doc/*.md,examples/*/README.md}").each do |readme_path|
14
+ sync_readme(readme_path)
15
+ end
16
+ end
17
+
18
+ private def sync_readme(readme_path)
19
+ content = File.read(readme_path)
20
+ dir = File.dirname(readme_path)
21
+
22
+ new_content = content.gsub(/<!-- SYNC:START:([^ ]+) -->.*?<!-- SYNC:END -->/m) do
23
+ marker_info = $1
24
+ source_rel_path, segment_id = marker_info.split(":")
25
+ source_path = File.join(dir, source_rel_path)
26
+
27
+ unless File.exist?(source_path)
28
+ warn "Warning: Source file not found: #{source_path}"
29
+ next $&
30
+ end
31
+
32
+ source_content = File.read(source_path)
33
+ extracted_content = if segment_id
34
+ extract_segment(source_content, segment_id, source_path)
35
+ else
36
+ source_content
37
+ end
38
+
39
+ # Detect language from extension
40
+ ext = File.extname(source_path).delete(".")
41
+ lang = (ext == "rb") ? "ruby" : ext
42
+
43
+ # Build replacement
44
+ "<!-- SYNC:START:#{marker_info} -->\n```#{lang}\n#{extracted_content}```\n<!-- SYNC:END -->"
45
+ end
46
+
47
+ if new_content != content
48
+ puts "Syncing #{readme_path}..."
49
+ File.write(readme_path, new_content)
50
+ end
51
+ end
52
+
53
+ def extract_segment(content, segment_id, source_path)
54
+ start_marker = /#\s*\[SYNC:START:#{segment_id}\]/
55
+ end_marker = /#\s*\[SYNC:END:#{segment_id}\]/
56
+
57
+ lines = content.lines
58
+ start_idx = lines.find_index { |l| l =~ start_marker }
59
+ end_idx = lines.find_index { |l| l =~ end_marker }
60
+
61
+ if start_idx && end_idx
62
+ "#{unindent(lines[(start_idx + 1)...end_idx].join).strip}\n"
63
+ else
64
+ warn "Warning: Segment '#{segment_id}' not found in #{source_path}"
65
+ content # Fallback to full content or error? Let's fallback to original for now.
66
+ end
67
+ end
68
+
69
+ def unindent(text)
70
+ lines = text.lines
71
+ # Don't unindent if empty or just one line
72
+ return text if lines.empty?
73
+
74
+ # Find common leading whitespace
75
+ indentation = lines.grep(/\S/).map { |l| l[/^\s*/].length }.min || 0
76
+ lines.map { |l| (l.length > indentation) ? l[indentation..-1] : "#{l.strip}\n" }.join
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ require_relative "name"
7
+ require_relative "member"
8
+
9
+ module Autodoc
10
+ class Inventory
11
+ include Enumerable
12
+
13
+ def each(&)
14
+ delegates.each(&)
15
+ factories.each(&)
16
+ end
17
+
18
+ def delegates
19
+ RatatuiRuby.singleton_methods(false).sort.map do |method_name|
20
+ Member::Delegate.new(name: method_name)
21
+ end
22
+ end
23
+
24
+ def factories
25
+ members = []
26
+ RatatuiRuby.constants.sort.each do |const_name|
27
+ next if const_name == :Buffer
28
+
29
+ const = RatatuiRuby.const_get(const_name)
30
+ next unless const.is_a?(Module)
31
+
32
+ if const.is_a?(Class)
33
+ snake_name = Name.new(const_name).snake
34
+ members << Member::Factory.new(name: snake_name, const_name:)
35
+ end
36
+
37
+ # Singleton methods (for both Classes and Modules)
38
+ parent_prefix = Name.new(const_name).snake
39
+ const.singleton_methods(false).sort.each do |class_method|
40
+ members << Member::Helper.new(
41
+ name: "#{parent_prefix}_#{class_method}",
42
+ class_method:,
43
+ const_name:
44
+ )
45
+ end
46
+
47
+ const.constants.sort.each do |child_name|
48
+ child = const.const_get(child_name)
49
+ next unless child.is_a?(Class)
50
+
51
+ parent_prefix = Name.new(const_name).snake
52
+ child_suffix = Name.new(child_name).snake
53
+
54
+ members << Member::Factory.new(
55
+ name: "#{parent_prefix}_#{child_suffix}",
56
+ const_name: "#{const_name}::#{child_name}"
57
+ )
58
+ end
59
+ end
60
+ members
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module Autodoc
7
+ module Member
8
+ class Delegate < Data.define(:name)
9
+ def rbs
10
+ " def #{name}: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped"
11
+ end
12
+
13
+ def rdoc
14
+ [
15
+ " # :method: #{name}",
16
+ " # :call-seq: #{name}(*args, **kwargs, &block)",
17
+ " #",
18
+ " # Delegates to RatatuiRuby.#{name}.",
19
+ " #",
20
+ ]
21
+ end
22
+ end
23
+
24
+ class Factory < Data.define(:name, :const_name)
25
+ def rbs
26
+ " def #{name}: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped"
27
+ end
28
+
29
+ def rdoc
30
+ [
31
+ " # :method: #{name}",
32
+ " # :call-seq: #{name}(*args, **kwargs, &block)",
33
+ " #",
34
+ " # Factory for RatatuiRuby::#{const_name}.new.",
35
+ " #",
36
+ ]
37
+ end
38
+ end
39
+
40
+ class Helper < Data.define(:name, :class_method, :const_name)
41
+ def rbs
42
+ " def #{name}: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped"
43
+ end
44
+
45
+ def rdoc
46
+ [
47
+ " # :method: #{name}",
48
+ " # :call-seq: #{name}(*args, **kwargs, &block)",
49
+ " #",
50
+ " # Helper for RatatuiRuby::#{const_name}.#{class_method}.",
51
+ " #",
52
+ ]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module Autodoc
7
+ class Name < Data.define(:string)
8
+ def snake
9
+ string.to_s
10
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
11
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
12
+ .downcase
13
+ end
14
+
15
+ def to_s
16
+ string.to_s
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module Autodoc
7
+ class Notice < Data.define(:task_name)
8
+ def rbs
9
+ [
10
+ "# !!! DO NOT EDIT THIS FILE BY HAND !!!",
11
+ "# This file is automatically generated by `rake #{task_name}`.",
12
+ "# Any changes will be overwritten.",
13
+ "",
14
+ ]
15
+ end
16
+
17
+ def rdoc
18
+ [
19
+ "# !!! DO NOT EDIT THIS FILE BY HAND !!!",
20
+ "# This file is automatically generated by `rake #{task_name}`.",
21
+ "# Any changes will be overwritten.",
22
+ "",
23
+ ]
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module Autodoc
7
+ class Rbs < Data.define(:path, :notice)
8
+ def write(inventory)
9
+ FileUtils.mkdir_p(File.dirname(path))
10
+
11
+ # REUSE-IgnoreStart
12
+ lines = [
13
+ "# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>",
14
+ "# SPDX-License-Identifier: AGPL-3.0-or-later",
15
+ "",
16
+ ]
17
+ # REUSE-IgnoreEnd
18
+ lines += notice.rbs
19
+ lines += [
20
+ "module RatatuiRuby",
21
+ " class Session",
22
+ " def self.new: () -> Session",
23
+ " | () { (Session) -> void } -> void",
24
+ "",
25
+ ]
26
+
27
+ inventory.each do |member|
28
+ lines << member.rbs
29
+ end
30
+
31
+ lines << " end"
32
+ lines << "end"
33
+
34
+ File.write(path, "#{lines.join("\n")}\n")
35
+ puts "Generated #{path}"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ module Autodoc
7
+ class Rdoc < Data.define(:path, :notice)
8
+ def write(inventory)
9
+ FileUtils.mkdir_p(File.dirname(path))
10
+
11
+ # REUSE-IgnoreStart
12
+ lines = [
13
+ "# frozen_string_literal: true",
14
+ "",
15
+ "# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>",
16
+ "# SPDX-License-Identifier: AGPL-3.0-or-later",
17
+ "",
18
+ ]
19
+ # REUSE-IgnoreEnd
20
+ lines += notice.rdoc
21
+ lines += [
22
+ "module RatatuiRuby",
23
+ " class Session",
24
+ ]
25
+
26
+ lines << " # == RatatuiRuby Delegates"
27
+ lines << " #"
28
+ inventory.delegates.each do |member|
29
+ lines += member.rdoc
30
+ end
31
+
32
+ lines << " # == Widget Factories"
33
+ lines << " #"
34
+ inventory.factories.each do |member|
35
+ lines += member.rdoc
36
+ end
37
+
38
+ lines << " end"
39
+ lines << "end"
40
+
41
+ File.write(path, "#{lines.join("\n")}\n")
42
+ puts "Generated #{path}"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ require_relative "autodoc/inventory"
7
+ require_relative "autodoc/notice"
8
+ require_relative "autodoc/rbs"
9
+ require_relative "autodoc/rdoc"
10
+ require_relative "autodoc/examples"
11
+
12
+ namespace :autodoc do
13
+ desc "Update all automatically generated documentation"
14
+ task all: [:rbs, :rdoc, :examples]
15
+
16
+ desc "Update all automatically generated RBS signatures"
17
+ task rbs: ["rbs:session"]
18
+
19
+ desc "Update all automatically generated RDoc files"
20
+ task rdoc: ["rdoc:session"]
21
+
22
+ namespace :rbs do
23
+ desc "Generate RBS for RatatuiRuby::Session"
24
+ task :session do
25
+ require_relative "../lib/ratatui_ruby"
26
+
27
+ Autodoc::Rbs.new(
28
+ path: File.expand_path("../sig/ratatui_ruby/session.rbs", __dir__),
29
+ notice: Autodoc::Notice.new("autodoc:rbs:session")
30
+ ).write(Autodoc::Inventory.new)
31
+ end
32
+ end
33
+
34
+ namespace :rdoc do
35
+ desc "Generate RDoc autodoc for RatatuiRuby::Session"
36
+ task :session do
37
+ require_relative "../lib/ratatui_ruby"
38
+
39
+ Autodoc::Rdoc.new(
40
+ path: File.expand_path("../lib/ratatui_ruby/session/autodoc.rb", __dir__),
41
+ notice: Autodoc::Notice.new("autodoc:rdoc:session")
42
+ ).write(Autodoc::Inventory.new)
43
+ end
44
+ end
45
+
46
+ desc "Sync code snippets in example READMEs with source files"
47
+ task :examples do
48
+ Autodoc::Examples.sync
49
+ end
50
+ end
51
+
52
+ desc "Update all automatically generated documentation"
53
+ task autodoc: "autodoc:all"