ratatui_ruby 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) 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 +53 -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 +15 -175
  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 +3 -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/rendering.rs +1 -1
  130. data/ext/ratatui_ruby/src/style.rs +0 -8
  131. data/ext/ratatui_ruby/src/widgets/chart.rs +0 -118
  132. data/ext/ratatui_ruby/src/widgets/list_state.rs +36 -0
  133. data/lib/ratatui_ruby/buffer/cell.rb +34 -2
  134. data/lib/ratatui_ruby/buffer.rb +2 -2
  135. data/lib/ratatui_ruby/cell.rb +34 -2
  136. data/lib/ratatui_ruby/event/focus_gained.rb +26 -2
  137. data/lib/ratatui_ruby/event/focus_lost.rb +26 -2
  138. data/lib/ratatui_ruby/event/key/character.rb +18 -2
  139. data/lib/ratatui_ruby/event/key/media.rb +2 -2
  140. data/lib/ratatui_ruby/event/key/modifier.rb +10 -2
  141. data/lib/ratatui_ruby/event/key/navigation.rb +2 -2
  142. data/lib/ratatui_ruby/event/key/system.rb +2 -2
  143. data/lib/ratatui_ruby/event/key.rb +114 -2
  144. data/lib/ratatui_ruby/event/mouse.rb +42 -2
  145. data/lib/ratatui_ruby/event/none.rb +10 -2
  146. data/lib/ratatui_ruby/event/paste.rb +34 -2
  147. data/lib/ratatui_ruby/event/resize.rb +34 -2
  148. data/lib/ratatui_ruby/event.rb +26 -2
  149. data/lib/ratatui_ruby/frame.rb +74 -2
  150. data/lib/ratatui_ruby/layout/constraint.rb +58 -2
  151. data/lib/ratatui_ruby/layout/layout.rb +47 -2
  152. data/lib/ratatui_ruby/layout/rect.rb +403 -2
  153. data/lib/ratatui_ruby/layout.rb +2 -2
  154. data/lib/ratatui_ruby/list_state.rb +113 -2
  155. data/lib/ratatui_ruby/output_guard.rb +26 -3
  156. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
  157. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +2 -2
  158. data/lib/ratatui_ruby/schema/bar_chart.rb +50 -2
  159. data/lib/ratatui_ruby/schema/block.rb +21 -15
  160. data/lib/ratatui_ruby/schema/calendar.rb +2 -2
  161. data/lib/ratatui_ruby/schema/canvas.rb +10 -2
  162. data/lib/ratatui_ruby/schema/center.rb +10 -2
  163. data/lib/ratatui_ruby/schema/chart.rb +2 -28
  164. data/lib/ratatui_ruby/schema/clear.rb +10 -2
  165. data/lib/ratatui_ruby/schema/constraint.rb +58 -2
  166. data/lib/ratatui_ruby/schema/cursor.rb +10 -2
  167. data/lib/ratatui_ruby/schema/draw.rb +10 -2
  168. data/lib/ratatui_ruby/schema/gauge.rb +2 -2
  169. data/lib/ratatui_ruby/schema/layout.rb +18 -2
  170. data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
  171. data/lib/ratatui_ruby/schema/list.rb +10 -2
  172. data/lib/ratatui_ruby/schema/list_item.rb +10 -2
  173. data/lib/ratatui_ruby/schema/overlay.rb +10 -2
  174. data/lib/ratatui_ruby/schema/paragraph.rb +10 -2
  175. data/lib/ratatui_ruby/schema/ratatui_logo.rb +2 -2
  176. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +2 -2
  177. data/lib/ratatui_ruby/schema/rect.rb +58 -2
  178. data/lib/ratatui_ruby/schema/row.rb +10 -2
  179. data/lib/ratatui_ruby/schema/scrollbar.rb +2 -2
  180. data/lib/ratatui_ruby/schema/shape/label.rb +10 -2
  181. data/lib/ratatui_ruby/schema/sparkline.rb +10 -2
  182. data/lib/ratatui_ruby/schema/style.rb +18 -2
  183. data/lib/ratatui_ruby/schema/table.rb +2 -2
  184. data/lib/ratatui_ruby/schema/tabs.rb +2 -2
  185. data/lib/ratatui_ruby/schema/text.rb +34 -2
  186. data/lib/ratatui_ruby/scrollbar_state.rb +10 -2
  187. data/lib/ratatui_ruby/style/style.rb +18 -2
  188. data/lib/ratatui_ruby/style.rb +2 -2
  189. data/lib/ratatui_ruby/table_state.rb +10 -2
  190. data/lib/ratatui_ruby/terminal_lifecycle.rb +18 -3
  191. data/lib/ratatui_ruby/test_helper/event_injection.rb +34 -2
  192. data/lib/ratatui_ruby/test_helper/snapshot.rb +74 -9
  193. data/lib/ratatui_ruby/test_helper/style_assertions.rb +98 -2
  194. data/lib/ratatui_ruby/test_helper/terminal.rb +50 -2
  195. data/lib/ratatui_ruby/test_helper/test_doubles.rb +18 -2
  196. data/lib/ratatui_ruby/test_helper.rb +10 -2
  197. data/lib/ratatui_ruby/tui/buffer_factories.rb +2 -2
  198. data/lib/ratatui_ruby/tui/canvas_factories.rb +2 -2
  199. data/lib/ratatui_ruby/tui/core.rb +2 -2
  200. data/lib/ratatui_ruby/tui/layout_factories.rb +32 -2
  201. data/lib/ratatui_ruby/tui/state_factories.rb +2 -2
  202. data/lib/ratatui_ruby/tui/style_factories.rb +2 -2
  203. data/lib/ratatui_ruby/tui/text_factories.rb +2 -2
  204. data/lib/ratatui_ruby/tui/widget_factories.rb +2 -2
  205. data/lib/ratatui_ruby/tui.rb +11 -3
  206. data/lib/ratatui_ruby/version.rb +3 -3
  207. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -2
  208. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -2
  209. data/lib/ratatui_ruby/widgets/bar_chart.rb +58 -2
  210. data/lib/ratatui_ruby/widgets/block.rb +37 -15
  211. data/lib/ratatui_ruby/widgets/calendar.rb +2 -2
  212. data/lib/ratatui_ruby/widgets/canvas.rb +10 -2
  213. data/lib/ratatui_ruby/widgets/cell.rb +10 -2
  214. data/lib/ratatui_ruby/widgets/center.rb +10 -2
  215. data/lib/ratatui_ruby/widgets/chart.rb +2 -28
  216. data/lib/ratatui_ruby/widgets/clear.rb +10 -2
  217. data/lib/ratatui_ruby/widgets/cursor.rb +10 -2
  218. data/lib/ratatui_ruby/widgets/gauge.rb +16 -2
  219. data/lib/ratatui_ruby/widgets/line_gauge.rb +16 -2
  220. data/lib/ratatui_ruby/widgets/list.rb +41 -2
  221. data/lib/ratatui_ruby/widgets/list_item.rb +10 -2
  222. data/lib/ratatui_ruby/widgets/overlay.rb +10 -2
  223. data/lib/ratatui_ruby/widgets/paragraph.rb +10 -2
  224. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -2
  225. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -2
  226. data/lib/ratatui_ruby/widgets/row.rb +10 -2
  227. data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -2
  228. data/lib/ratatui_ruby/widgets/shape/label.rb +10 -2
  229. data/lib/ratatui_ruby/widgets/sparkline.rb +10 -2
  230. data/lib/ratatui_ruby/widgets/table.rb +62 -2
  231. data/lib/ratatui_ruby/widgets/tabs.rb +2 -2
  232. data/lib/ratatui_ruby/widgets.rb +2 -2
  233. data/lib/ratatui_ruby.rb +90 -2
  234. data/sig/examples/app_all_events/view.rbs +7 -1
  235. data/sig/examples/app_all_events/view_state.rbs +7 -1
  236. data/sig/examples/app_color_picker/app.rbs +5 -0
  237. data/sig/examples/app_stateful_interaction/app.rbs +7 -1
  238. data/sig/examples/verify_quickstart_dsl/app.rbs +7 -1
  239. data/sig/examples/verify_quickstart_lifecycle/app.rbs +7 -1
  240. data/sig/examples/verify_readme_usage/app.rbs +7 -1
  241. data/sig/examples/widget_block_demo/app.rbs +6 -0
  242. data/sig/examples/widget_box_demo/app.rbs +7 -1
  243. data/sig/examples/widget_calendar_demo/app.rbs +7 -1
  244. data/sig/examples/widget_cell_demo/app.rbs +7 -1
  245. data/sig/examples/widget_chart_demo/app.rbs +7 -1
  246. data/sig/examples/widget_gauge_demo/app.rbs +7 -1
  247. data/sig/examples/widget_layout_split/app.rbs +7 -1
  248. data/sig/examples/widget_line_gauge_demo/app.rbs +7 -1
  249. data/sig/examples/widget_list_demo/app.rbs +5 -0
  250. data/sig/examples/widget_map_demo/app.rbs +7 -1
  251. data/sig/examples/widget_popup_demo/app.rbs +7 -1
  252. data/sig/examples/widget_ratatui_logo_demo/app.rbs +7 -1
  253. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +7 -1
  254. data/sig/examples/widget_rect/app.rbs +7 -1
  255. data/sig/examples/widget_render/app.rbs +7 -1
  256. data/sig/examples/widget_rich_text/app.rbs +7 -1
  257. data/sig/examples/widget_scroll_text/app.rbs +7 -1
  258. data/sig/examples/widget_scrollbar_demo/app.rbs +7 -1
  259. data/sig/examples/widget_sparkline_demo/app.rbs +7 -1
  260. data/sig/examples/widget_style_colors/app.rbs +7 -1
  261. data/sig/examples/widget_table_demo/app.rbs +7 -1
  262. data/sig/examples/widget_text_width/app.rbs +7 -1
  263. data/sig/ratatui_ruby/event.rbs +7 -1
  264. data/sig/ratatui_ruby/frame.rbs +15 -3
  265. data/sig/ratatui_ruby/list_state.rbs +11 -1
  266. data/sig/ratatui_ruby/ratatui_ruby.rbs +8 -2
  267. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +7 -1
  268. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +6 -0
  269. data/sig/ratatui_ruby/schema/bar_chart.rbs +6 -0
  270. data/sig/ratatui_ruby/schema/block.rbs +7 -1
  271. data/sig/ratatui_ruby/schema/calendar.rbs +6 -0
  272. data/sig/ratatui_ruby/schema/canvas.rbs +6 -0
  273. data/sig/ratatui_ruby/schema/center.rbs +6 -0
  274. data/sig/ratatui_ruby/schema/chart.rbs +6 -9
  275. data/sig/ratatui_ruby/schema/constraint.rbs +6 -0
  276. data/sig/ratatui_ruby/schema/cursor.rbs +6 -0
  277. data/sig/ratatui_ruby/schema/draw.rbs +6 -0
  278. data/sig/ratatui_ruby/schema/gauge.rbs +9 -1
  279. data/sig/ratatui_ruby/schema/layout.rbs +6 -0
  280. data/sig/ratatui_ruby/schema/line_gauge.rbs +9 -1
  281. data/sig/ratatui_ruby/schema/list.rbs +9 -1
  282. data/sig/ratatui_ruby/schema/list_item.rbs +7 -1
  283. data/sig/ratatui_ruby/schema/overlay.rbs +6 -0
  284. data/sig/ratatui_ruby/schema/paragraph.rbs +6 -0
  285. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +6 -0
  286. data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +5 -0
  287. data/sig/ratatui_ruby/schema/rect.rbs +30 -0
  288. data/sig/ratatui_ruby/schema/row.rbs +7 -1
  289. data/sig/ratatui_ruby/schema/scrollbar.rbs +6 -0
  290. data/sig/ratatui_ruby/schema/sparkline.rbs +6 -0
  291. data/sig/ratatui_ruby/schema/style.rbs +7 -1
  292. data/sig/ratatui_ruby/schema/table.rbs +11 -1
  293. data/sig/ratatui_ruby/schema/tabs.rbs +6 -0
  294. data/sig/ratatui_ruby/schema/text.rbs +7 -1
  295. data/sig/ratatui_ruby/scrollbar_state.rbs +7 -1
  296. data/sig/ratatui_ruby/session.rbs +7 -1
  297. data/sig/ratatui_ruby/table_state.rbs +7 -1
  298. data/sig/ratatui_ruby/test_helper/event_injection.rbs +7 -1
  299. data/sig/ratatui_ruby/test_helper/snapshot.rbs +7 -1
  300. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +7 -1
  301. data/sig/ratatui_ruby/test_helper/terminal.rbs +7 -1
  302. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -1
  303. data/sig/ratatui_ruby/test_helper.rbs +7 -1
  304. data/sig/ratatui_ruby/tui/buffer_factories.rbs +7 -1
  305. data/sig/ratatui_ruby/tui/canvas_factories.rbs +7 -1
  306. data/sig/ratatui_ruby/tui/core.rbs +7 -1
  307. data/sig/ratatui_ruby/tui/layout_factories.rbs +7 -1
  308. data/sig/ratatui_ruby/tui/state_factories.rbs +7 -1
  309. data/sig/ratatui_ruby/tui/style_factories.rbs +7 -1
  310. data/sig/ratatui_ruby/tui/text_factories.rbs +7 -1
  311. data/sig/ratatui_ruby/tui/widget_factories.rbs +7 -1
  312. data/sig/ratatui_ruby/tui.rbs +7 -1
  313. data/sig/ratatui_ruby/version.rbs +6 -0
  314. data/tasks/autodoc/examples.rb +1 -1
  315. data/tasks/autodoc/member.rb +1 -1
  316. data/tasks/autodoc/name.rb +1 -1
  317. data/tasks/bump/cargo_lockfile.rb +1 -1
  318. data/tasks/bump/changelog.rb +1 -1
  319. data/tasks/bump/header.rb +1 -1
  320. data/tasks/bump/history.rb +1 -1
  321. data/tasks/bump/links.rb +1 -1
  322. data/tasks/bump/manifest.rb +1 -1
  323. data/tasks/bump/ruby_gem.rb +1 -1
  324. data/tasks/bump/sem_ver.rb +1 -1
  325. data/tasks/bump/unreleased_section.rb +1 -1
  326. data/tasks/license/headers_md.rb +223 -0
  327. data/tasks/license/headers_rb.rb +210 -0
  328. data/tasks/license/license_utils.rb +130 -0
  329. data/tasks/license/snippets_md.rb +315 -0
  330. data/tasks/license/snippets_rdoc.rb +150 -0
  331. data/tasks/license.rake +91 -0
  332. data/tasks/rdoc_config.rb +1 -1
  333. data/tasks/resources/build.yml.erb +13 -7
  334. data/tasks/sourcehut.rake +3 -1
  335. data/tasks/terminal_preview/app_screenshot.rb +1 -1
  336. data/tasks/terminal_preview/crash_report.rb +1 -1
  337. data/tasks/terminal_preview/example_app.rb +1 -1
  338. data/tasks/terminal_preview/launcher_script.rb +1 -1
  339. data/tasks/terminal_preview/preview_collection.rb +1 -1
  340. data/tasks/terminal_preview/preview_timing.rb +1 -1
  341. data/tasks/terminal_preview/safety_confirmation.rb +1 -1
  342. data/tasks/terminal_preview/saved_screenshot.rb +1 -1
  343. data/tasks/terminal_preview/system_appearance.rb +1 -1
  344. data/tasks/terminal_preview/terminal_window.rb +1 -1
  345. data/tasks/terminal_preview/window_id.rb +1 -1
  346. data/tasks/website/index_page.rb +1 -1
  347. data/tasks/website/version.rb +1 -1
  348. data/tasks/website/version_menu.rb +1 -1
  349. data/tasks/website/versioned_documentation.rb +1 -1
  350. data/tasks/website/website.rb +1 -1
  351. metadata +13 -3
  352. data/doc/migration/v0_7_0.md +0 -236
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: MIT-0
6
6
  #++
7
7
 
8
8
  $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
@@ -73,7 +73,7 @@ class WidgetTextWidth
73
73
  block: @tui.block(
74
74
  title: "Text Width Calculator",
75
75
  borders: [:all],
76
- border_color: "cyan"
76
+ border_style: { fg: "cyan" }
77
77
  ),
78
78
  alignment: :left
79
79
  )
@@ -88,7 +88,7 @@ class WidgetTextWidth
88
88
 
89
89
  widget = @tui.paragraph(
90
90
  text:,
91
- block: @tui.block(borders: [:top], border_color: "gray"),
91
+ block: @tui.block(borders: [:top], border_style: { fg: "gray" }),
92
92
  alignment: :center
93
93
  )
94
94
 
@@ -1012,7 +1012,7 @@ dependencies = [
1012
1012
 
1013
1013
  [[package]]
1014
1014
  name = "ratatui_ruby"
1015
- version = "0.8.0"
1015
+ version = "0.9.0"
1016
1016
  dependencies = [
1017
1017
  "bumpalo",
1018
1018
  "lazy_static",
@@ -3,7 +3,7 @@
3
3
 
4
4
  [package]
5
5
  name = "ratatui_ruby"
6
- version = "0.8.0"
6
+ version = "0.9.0"
7
7
  edition = "2021"
8
8
 
9
9
  [lib]
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  require "mkmf"
@@ -53,7 +53,7 @@ pub fn render_node(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Err
53
53
  "RatatuiRuby::Widgets::Canvas" => widgets::canvas::render(frame, area, node)?,
54
54
  "RatatuiRuby::Widgets::Calendar" => widgets::calendar::render(frame, area, node)?,
55
55
  "RatatuiRuby::Widgets::Sparkline" => widgets::sparkline::render(frame, area, node)?,
56
- "RatatuiRuby::Widgets::Chart" | "RatatuiRuby::LineChart" => {
56
+ "RatatuiRuby::Widgets::Chart" => {
57
57
  widgets::chart::render(frame, area, node)?;
58
58
  }
59
59
  "RatatuiRuby::Widgets::RatatuiLogo" => widgets::ratatui_logo::render(frame, area, node),
@@ -398,14 +398,6 @@ fn parse_borders<'a>(
398
398
  if let Ok(v) = block_val.funcall::<&str, _, Value>("border_style", ()) {
399
399
  if !v.is_nil() {
400
400
  block = block.border_style(parse_style(v)?);
401
- } else if let Ok(color_val) = block_val.funcall::<&str, _, Value>("border_color", ()) {
402
- if !color_val.is_nil() {
403
- if let Ok(s) = color_val.funcall::<&str, _, String>("to_s", ()) {
404
- if let Some(c) = parse_color(&s) {
405
- block = block.border_style(Style::default().fg(c));
406
- }
407
- }
408
- }
409
401
  }
410
402
  }
411
403
 
@@ -8,7 +8,6 @@ use magnus::{prelude::*, Error, Symbol, Value};
8
8
  use ratatui::{
9
9
  layout::Rect,
10
10
  symbols,
11
- text::Span,
12
11
  widgets::{Axis, Chart, Dataset, GraphType, LegendPosition},
13
12
  Frame,
14
13
  };
@@ -17,12 +16,6 @@ use ratatui::{
17
16
  pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
18
17
  let bump = Bump::new();
19
18
  let ruby = magnus::Ruby::get().unwrap();
20
- // SAFETY: Immediate conversion to owned string avoids GC-unsafe borrowed reference.
21
- let class_name = unsafe { node.class().name() }.into_owned();
22
-
23
- if class_name == "RatatuiRuby::LineChart" {
24
- return render_line_chart(frame, area, node);
25
- }
26
19
 
27
20
  let datasets_val: magnus::RArray = node.funcall("datasets", ())?;
28
21
  let x_axis_val: Value = node.funcall("x_axis", ())?;
@@ -194,117 +187,6 @@ fn parse_axis(axis_val: Value) -> Result<Axis<'static>, Error> {
194
187
  Ok(axis)
195
188
  }
196
189
 
197
- fn render_line_chart(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
198
- let bump = Bump::new();
199
- let ruby = magnus::Ruby::get().unwrap();
200
- let datasets_val: magnus::RArray = node.funcall("datasets", ())?;
201
- let x_labels_val: magnus::RArray = node.funcall("x_labels", ())?;
202
- let y_labels_val: magnus::RArray = node.funcall("y_labels", ())?;
203
- let y_bounds_val: magnus::RArray = node.funcall("y_bounds", ())?;
204
- let block_val: Value = node.funcall("block", ())?;
205
-
206
- let mut datasets = Vec::new();
207
- let mut data_storage: Vec<Vec<(f64, f64)>> = Vec::new();
208
-
209
- for i in 0..datasets_val.len() {
210
- let index = isize::try_from(i)
211
- .map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
212
- let ds_val: Value = datasets_val.entry(index)?;
213
- let data_array: magnus::RArray = ds_val.funcall("data", ())?;
214
-
215
- let mut points = Vec::new();
216
- for j in 0..data_array.len() {
217
- let index = isize::try_from(j)
218
- .map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
219
- let point_array_val: Value = data_array.entry(index)?;
220
- let point_array = magnus::RArray::from_value(point_array_val).ok_or_else(|| {
221
- Error::new(ruby.exception_type_error(), "expected array for point")
222
- })?;
223
- let x: f64 = point_array.entry(0)?;
224
- let y: f64 = point_array.entry(1)?;
225
- points.push((x, y));
226
- }
227
- data_storage.push(points);
228
- }
229
-
230
- for (i, points) in data_storage.iter().enumerate() {
231
- let index = isize::try_from(i)
232
- .map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
233
- let ds_val: Value = datasets_val.entry(index)?;
234
- let name: String = ds_val.funcall("name", ())?;
235
-
236
- let mut ds_style = ratatui::style::Style::default();
237
- let style_val: Value = ds_val.funcall("style", ())?;
238
- if !style_val.is_nil() {
239
- ds_style = parse_style(style_val)?;
240
- }
241
-
242
- let ds = Dataset::default()
243
- .name(name)
244
- .marker(symbols::Marker::Braille)
245
- .style(ds_style)
246
- .data(points);
247
- datasets.push(ds);
248
- }
249
-
250
- let mut x_labels = Vec::new();
251
- for i in 0..x_labels_val.len() {
252
- let index = isize::try_from(i)
253
- .map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
254
- let label: String = x_labels_val.entry(index)?;
255
- x_labels.push(Span::from(label));
256
- }
257
-
258
- let mut y_labels = Vec::new();
259
- for i in 0..y_labels_val.len() {
260
- let index = isize::try_from(i)
261
- .map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
262
- let label: String = y_labels_val.entry(index)?;
263
- y_labels.push(Span::from(label));
264
- }
265
- // Ratatui 0.29+ requires labels to be present for the axis line to render
266
- if y_labels.is_empty() {
267
- y_labels.push(Span::from(""));
268
- y_labels.push(Span::from(""));
269
- }
270
-
271
- let y_bounds: [f64; 2] = [y_bounds_val.entry(0)?, y_bounds_val.entry(1)?];
272
-
273
- let mut min_x = 0.0;
274
- let mut max_x = 0.0;
275
- let mut first = true;
276
- for ds_data in &data_storage {
277
- for (x, _) in ds_data {
278
- if first {
279
- min_x = *x;
280
- max_x = *x;
281
- first = false;
282
- } else {
283
- if *x < min_x {
284
- min_x = *x;
285
- }
286
- if *x > max_x {
287
- max_x = *x;
288
- }
289
- }
290
- }
291
- }
292
- if (min_x - max_x).abs() < f64::EPSILON {
293
- max_x = min_x + 1.0;
294
- }
295
-
296
- let x_axis = Axis::default().labels(x_labels).bounds([min_x, max_x]);
297
- let y_axis = Axis::default().labels(y_labels).bounds(y_bounds);
298
-
299
- let mut chart = Chart::new(datasets).x_axis(x_axis).y_axis(y_axis);
300
- if !block_val.is_nil() {
301
- chart = chart.block(parse_block(block_val, &bump)?);
302
- }
303
-
304
- frame.render_widget(chart, area);
305
- Ok(())
306
- }
307
-
308
190
  #[cfg(test)]
309
191
  mod tests {
310
192
  use super::*;
@@ -78,6 +78,35 @@ impl RubyListState {
78
78
  self.inner.borrow_mut().scroll_up_by(amount);
79
79
  }
80
80
 
81
+ /// Selects the next item or the first one if no item is selected.
82
+ ///
83
+ /// Note: until the list is rendered, the number of items is not known, so the index
84
+ /// is set to 0 and will be corrected when the list is rendered.
85
+ pub fn select_next(&self) {
86
+ self.inner.borrow_mut().select_next();
87
+ }
88
+
89
+ /// Selects the previous item or the last one if no item is selected.
90
+ ///
91
+ /// Note: until the list is rendered, the number of items is not known, so the index
92
+ /// is set to `usize::MAX` and will be corrected when the list is rendered.
93
+ pub fn select_previous(&self) {
94
+ self.inner.borrow_mut().select_previous();
95
+ }
96
+
97
+ /// Selects the first item.
98
+ pub fn select_first(&self) {
99
+ self.inner.borrow_mut().select_first();
100
+ }
101
+
102
+ /// Selects the last item.
103
+ ///
104
+ /// Note: until the list is rendered, the number of items is not known, so the index
105
+ /// is set to `usize::MAX` and will be corrected when the list is rendered.
106
+ pub fn select_last(&self) {
107
+ self.inner.borrow_mut().select_last();
108
+ }
109
+
81
110
  /// Borrows the inner `ListState` mutably for rendering.
82
111
  ///
83
112
  /// # Safety
@@ -98,6 +127,13 @@ pub fn register(ruby: &Ruby, module: magnus::RModule) -> Result<(), Error> {
98
127
  class.define_method("offset", method!(RubyListState::offset, 0))?;
99
128
  class.define_method("scroll_down_by", method!(RubyListState::scroll_down_by, 1))?;
100
129
  class.define_method("scroll_up_by", method!(RubyListState::scroll_up_by, 1))?;
130
+ class.define_method("select_next", method!(RubyListState::select_next, 0))?;
131
+ class.define_method(
132
+ "select_previous",
133
+ method!(RubyListState::select_previous, 0),
134
+ )?;
135
+ class.define_method("select_first", method!(RubyListState::select_first, 0))?;
136
+ class.define_method("select_last", method!(RubyListState::select_last, 0))?;
101
137
  Ok(())
102
138
  }
103
139
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -18,11 +18,19 @@ module RatatuiRuby
18
18
  #
19
19
  # === Examples
20
20
  #
21
+ #--
22
+ # SPDX-SnippetBegin
23
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
24
+ # SPDX-License-Identifier: MIT-0
25
+ #++
21
26
  # cell = RatatuiRuby.get_cell_at(0, 0)
22
27
  # cell.char # => "H"
23
28
  # cell.fg # => :red
24
29
  # cell.bold? # => true
25
30
  #
31
+ #--
32
+ # SPDX-SnippetEnd
33
+ #++
26
34
  class Cell
27
35
  # The character displayed in the cell.
28
36
  #
@@ -45,8 +53,16 @@ module RatatuiRuby
45
53
  #
46
54
  # === Example
47
55
  #
56
+ #--
57
+ # SPDX-SnippetBegin
58
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
59
+ # SPDX-License-Identifier: MIT-0
60
+ #++
48
61
  # Buffer::Cell.empty # => #<RatatuiRuby::Buffer::Cell char=" ">
49
62
  #
63
+ #--
64
+ # SPDX-SnippetEnd
65
+ #++
50
66
  def self.empty
51
67
  new(symbol: " ", fg: nil, bg: nil, modifiers: [])
52
68
  end
@@ -55,8 +71,16 @@ module RatatuiRuby
55
71
  #
56
72
  # === Example
57
73
  #
74
+ #--
75
+ # SPDX-SnippetBegin
76
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
77
+ # SPDX-License-Identifier: MIT-0
78
+ #++
58
79
  # Buffer::Cell.default # => #<RatatuiRuby::Buffer::Cell char=" ">
59
80
  #
81
+ #--
82
+ # SPDX-SnippetEnd
83
+ #++
60
84
  def self.default
61
85
  empty
62
86
  end
@@ -67,8 +91,16 @@ module RatatuiRuby
67
91
  #
68
92
  # === Example
69
93
  #
94
+ #--
95
+ # SPDX-SnippetBegin
96
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
97
+ # SPDX-License-Identifier: MIT-0
98
+ #++
70
99
  # Buffer::Cell.symbol("X") # => #<RatatuiRuby::Buffer::Cell symbol="X">
71
100
  #
101
+ #--
102
+ # SPDX-SnippetEnd
103
+ #++
72
104
  def self.symbol(symbol)
73
105
  new(symbol:, fg: nil, bg: nil, modifiers: [])
74
106
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -17,11 +17,19 @@ module RatatuiRuby
17
17
  #
18
18
  # === Examples
19
19
  #
20
+ #--
21
+ # SPDX-SnippetBegin
22
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
23
+ # SPDX-License-Identifier: MIT-0
24
+ #++
20
25
  # cell = RatatuiRuby.get_cell_at(0, 0)
21
26
  # cell.char # => "H"
22
27
  # cell.fg # => :red
23
28
  # cell.bold? # => true
24
29
  #
30
+ #--
31
+ # SPDX-SnippetEnd
32
+ #++
25
33
  class Cell
26
34
  # The character displayed in the cell.
27
35
  #
@@ -44,8 +52,16 @@ module RatatuiRuby
44
52
  #
45
53
  # === Example
46
54
  #
55
+ #--
56
+ # SPDX-SnippetBegin
57
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
58
+ # SPDX-License-Identifier: MIT-0
59
+ #++
47
60
  # Cell.empty # => #<RatatuiRuby::Cell char=" ">
48
61
  #
62
+ #--
63
+ # SPDX-SnippetEnd
64
+ #++
49
65
  def self.empty
50
66
  new(symbol: " ", fg: nil, bg: nil, modifiers: [])
51
67
  end
@@ -54,8 +70,16 @@ module RatatuiRuby
54
70
  #
55
71
  # === Example
56
72
  #
73
+ #--
74
+ # SPDX-SnippetBegin
75
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
76
+ # SPDX-License-Identifier: MIT-0
77
+ #++
57
78
  # Cell.default # => #<RatatuiRuby::Cell char=" ">
58
79
  #
80
+ #--
81
+ # SPDX-SnippetEnd
82
+ #++
59
83
  def self.default
60
84
  empty
61
85
  end
@@ -66,8 +90,16 @@ module RatatuiRuby
66
90
  #
67
91
  # === Example
68
92
  #
93
+ #--
94
+ # SPDX-SnippetBegin
95
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
96
+ # SPDX-License-Identifier: MIT-0
97
+ #++
69
98
  # Cell.symbol("X") # => #<RatatuiRuby::Cell symbol="X">
70
99
  #
100
+ #--
101
+ # SPDX-SnippetEnd
102
+ #++
71
103
  def self.symbol(symbol)
72
104
  new(symbol:, fg: nil, bg: nil, modifiers: [])
73
105
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -19,24 +19,48 @@ module RatatuiRuby
19
19
  #
20
20
  # === Example
21
21
  #
22
+ #--
23
+ # SPDX-SnippetBegin
24
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
25
+ # SPDX-License-Identifier: MIT-0
26
+ #++
22
27
  # if event.focus_gained?
23
28
  # puts "Focus gained"
24
29
  # end
30
+ #--
31
+ # SPDX-SnippetEnd
32
+ #++
25
33
  class FocusGained < Event
26
34
  # Returns true for FocusGained events.
27
35
  #
36
+ #--
37
+ # SPDX-SnippetBegin
38
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
39
+ # SPDX-License-Identifier: MIT-0
40
+ #++
28
41
  # event.focus_gained? # => true
29
42
  # event.key? # => false
43
+ #--
44
+ # SPDX-SnippetEnd
45
+ #++
30
46
  def focus_gained?
31
47
  true
32
48
  end
33
49
 
34
50
  # Deconstructs the event for pattern matching.
35
51
  #
52
+ #--
53
+ # SPDX-SnippetBegin
54
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
55
+ # SPDX-License-Identifier: MIT-0
56
+ #++
36
57
  # case event
37
58
  # in type: :focus_gained
38
59
  # puts "Application gained focus"
39
60
  # end
61
+ #--
62
+ # SPDX-SnippetEnd
63
+ #++
40
64
  def deconstruct_keys(keys)
41
65
  { type: :focus_gained }
42
66
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -20,24 +20,48 @@ module RatatuiRuby
20
20
  #
21
21
  # === Example
22
22
  #
23
+ #--
24
+ # SPDX-SnippetBegin
25
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
26
+ # SPDX-License-Identifier: MIT-0
27
+ #++
23
28
  # if event.focus_lost?
24
29
  # puts "Focus lost"
25
30
  # end
31
+ #--
32
+ # SPDX-SnippetEnd
33
+ #++
26
34
  class FocusLost < Event
27
35
  # Returns true for FocusLost events.
28
36
  #
37
+ #--
38
+ # SPDX-SnippetBegin
39
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
40
+ # SPDX-License-Identifier: MIT-0
41
+ #++
29
42
  # event.focus_lost? # => true
30
43
  # event.key? # => false
44
+ #--
45
+ # SPDX-SnippetEnd
46
+ #++
31
47
  def focus_lost?
32
48
  true
33
49
  end
34
50
 
35
51
  # Deconstructs the event for pattern matching.
36
52
  #
53
+ #--
54
+ # SPDX-SnippetBegin
55
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
56
+ # SPDX-License-Identifier: MIT-0
57
+ #++
37
58
  # case event
38
59
  # in type: :focus_lost
39
60
  # puts "Application lost focus"
40
61
  # end
62
+ #--
63
+ # SPDX-SnippetEnd
64
+ #++
41
65
  def deconstruct_keys(keys)
42
66
  { type: :focus_lost }
43
67
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -12,9 +12,17 @@ module RatatuiRuby
12
12
  module Character
13
13
  # Returns true if the key represents a single printable character.
14
14
  #
15
+ #--
16
+ # SPDX-SnippetBegin
17
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
18
+ # SPDX-License-Identifier: MIT-0
19
+ #++
15
20
  # RatatuiRuby::Event::Key.new(code: "a").text? # => true
16
21
  # RatatuiRuby::Event::Key.new(code: "enter").text? # => false
17
22
  # RatatuiRuby::Event::Key.new(code: "space").text? # => false ("space" is not 1 char, " " is)
23
+ #--
24
+ # SPDX-SnippetEnd
25
+ #++
18
26
  def text?
19
27
  @code.length == 1
20
28
  end
@@ -24,10 +32,18 @@ module RatatuiRuby
24
32
  # [Printable Characters]
25
33
  # Returns the character itself (e.g., <tt>"a"</tt>, <tt>"1"</tt>, <tt>" "</tt>).
26
34
  # [Special Keys]
35
+ #--
36
+ # SPDX-SnippetBegin
37
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
38
+ # SPDX-License-Identifier: MIT-0
39
+ #++
27
40
  # Returns <tt>nil</tt> (e.g., <tt>"enter"</tt>, <tt>"up"</tt>, <tt>"f1"</tt>).
28
41
  #
29
42
  # RatatuiRuby::Event::Key.new(code: "a").char # => "a"
30
43
  # RatatuiRuby::Event::Key.new(code: "enter").char # => nil
44
+ #--
45
+ # SPDX-SnippetEnd
46
+ #++
31
47
  def char
32
48
  text? ? @code : nil
33
49
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -66,9 +66,17 @@ module RatatuiRuby
66
66
  #
67
67
  # === Example
68
68
  #
69
+ #--
70
+ # SPDX-SnippetBegin
71
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
72
+ # SPDX-License-Identifier: MIT-0
73
+ #++
69
74
  # if event.modifier?
70
75
  # # Handle solo modifier key press
71
76
  # end
77
+ #--
78
+ # SPDX-SnippetEnd
79
+ #++
72
80
  def modifier?
73
81
  @kind == :modifier
74
82
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby