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: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  require_relative "key/character"
@@ -27,21 +27,45 @@ module RatatuiRuby
27
27
  # === Examples
28
28
  #
29
29
  # Using predicates:
30
+ #--
31
+ # SPDX-SnippetBegin
32
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
33
+ # SPDX-License-Identifier: MIT-0
34
+ #++
30
35
  # if event.key? && event.ctrl? && event.code == "c"
31
36
  # exit
32
37
  # end
33
38
  #
39
+ #--
40
+ # SPDX-SnippetEnd
41
+ #++
34
42
  # Using symbol comparison:
43
+ #--
44
+ # SPDX-SnippetBegin
45
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
46
+ # SPDX-License-Identifier: MIT-0
47
+ #++
35
48
  # if event == :ctrl_c
36
49
  # exit
37
50
  # end
38
51
  #
52
+ #--
53
+ # SPDX-SnippetEnd
54
+ #++
39
55
  # Using pattern matching:
56
+ #--
57
+ # SPDX-SnippetBegin
58
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
59
+ # SPDX-License-Identifier: MIT-0
60
+ #++
40
61
  # case event
41
62
  # in type: :key, code: "c", modifiers: ["ctrl"]
42
63
  # exit
43
64
  # end
44
65
  #
66
+ #--
67
+ # SPDX-SnippetEnd
68
+ #++
45
69
  # === Terminal Compatibility
46
70
  #
47
71
  # Some key combinations never reach your application. Terminal emulators intercept them for
@@ -90,9 +114,17 @@ module RatatuiRuby
90
114
 
91
115
  # Returns true for Key events.
92
116
  #
117
+ #--
118
+ # SPDX-SnippetBegin
119
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
120
+ # SPDX-License-Identifier: MIT-0
121
+ #++
93
122
  # event.key? # => true
94
123
  # event.mouse? # => false
95
124
  # event.resize? # => false
125
+ #--
126
+ # SPDX-SnippetEnd
127
+ #++
96
128
  def key?
97
129
  true
98
130
  end
@@ -104,8 +136,16 @@ module RatatuiRuby
104
136
  # [modifiers]
105
137
  # List of modifiers (Array<String>).
106
138
  # [kind]
139
+ #--
140
+ # SPDX-SnippetBegin
141
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
142
+ # SPDX-License-Identifier: MIT-0
143
+ #++
107
144
  # The key category (Symbol). One of: <tt>:standard</tt>, <tt>:function</tt>,
108
145
  # <tt>:media</tt>, <tt>:modifier</tt>, <tt>:system</tt>. Defaults to <tt>:standard</tt>.
146
+ #--
147
+ # SPDX-SnippetEnd
148
+ #++
109
149
  def initialize(code:, modifiers: [], kind: :standard)
110
150
  @code = code.freeze
111
151
  @modifiers = modifiers.map(&:freeze).sort.freeze
@@ -141,8 +181,16 @@ module RatatuiRuby
141
181
  # [Standard]
142
182
  # <tt>:enter</tt>, <tt>:backspace</tt>, <tt>:tab</tt>, <tt>:back_tab</tt>, <tt>:esc</tt>, <tt>:null</tt>
143
183
  # [Navigation]
184
+ #--
185
+ # SPDX-SnippetBegin
186
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
187
+ # SPDX-License-Identifier: MIT-0
188
+ #++
144
189
  # <tt>:up</tt>, <tt>:down</tt>, <tt>:left</tt>, <tt>:right</tt>, <tt>:home</tt>, <tt>:end</tt>,
145
190
  # <tt>:page_up</tt>, <tt>:page_down</tt>, <tt>:insert</tt>, <tt>:delete</tt>
191
+ #--
192
+ # SPDX-SnippetEnd
193
+ #++
146
194
  # [Function Keys]
147
195
  # <tt>:f1</tt> through <tt>:f12</tt> (and beyond, e.g. <tt>:f24</tt>)
148
196
  # [Lock Keys]
@@ -150,17 +198,41 @@ module RatatuiRuby
150
198
  # [System Keys]
151
199
  # <tt>:print_screen</tt>, <tt>:pause</tt>, <tt>:menu</tt>, <tt>:keypad_begin</tt>
152
200
  # [Media Keys]
201
+ #--
202
+ # SPDX-SnippetBegin
203
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
204
+ # SPDX-License-Identifier: MIT-0
205
+ #++
153
206
  # <tt>:play</tt>, <tt>:media_pause</tt>, <tt>:play_pause</tt>, <tt>:reverse</tt>, <tt>:stop</tt>,
154
207
  # <tt>:fast_forward</tt>, <tt>:rewind</tt>, <tt>:track_next</tt>, <tt>:track_previous</tt>,
155
208
  # <tt>:record</tt>, <tt>:lower_volume</tt>, <tt>:raise_volume</tt>, <tt>:mute_volume</tt>
209
+ #--
210
+ # SPDX-SnippetEnd
211
+ #++
156
212
  # [Modifier Keys]
213
+ #--
214
+ # SPDX-SnippetBegin
215
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
216
+ # SPDX-License-Identifier: MIT-0
217
+ #++
157
218
  # <tt>:left_shift</tt>, <tt>:left_control</tt>, <tt>:left_alt</tt>, <tt>:left_super</tt>,
158
219
  # <tt>:left_hyper</tt>, <tt>:left_meta</tt>, <tt>:right_shift</tt>, <tt>:right_control</tt>,
159
220
  # <tt>:right_alt</tt>, <tt>:right_super</tt>, <tt>:right_hyper</tt>, <tt>:right_meta</tt>,
160
221
  # <tt>:iso_level3_shift</tt>, <tt>:iso_level5_shift</tt>
222
+ #--
223
+ # SPDX-SnippetEnd
224
+ #++
161
225
  # [Characters]
226
+ #--
227
+ # SPDX-SnippetBegin
228
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
229
+ # SPDX-License-Identifier: MIT-0
230
+ #++
162
231
  # <tt>:a</tt>, <tt>:b</tt>, <tt>:1</tt>, <tt>:space</tt>, etc.
163
232
  #
233
+ #--
234
+ # SPDX-SnippetEnd
235
+ #++
164
236
  # === Modifier Examples
165
237
  #
166
238
  # * <tt>:ctrl_c</tt>
@@ -183,8 +255,16 @@ module RatatuiRuby
183
255
  # [Special Keys]
184
256
  # Returns an empty string (e.g., <tt>"enter"</tt>, <tt>"up"</tt>, <tt>"f1"</tt> all return <tt>""</tt>).
185
257
  # [Modifiers]
258
+ #--
259
+ # SPDX-SnippetBegin
260
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
261
+ # SPDX-License-Identifier: MIT-0
262
+ #++
186
263
  # Returns the character if printable, ignoring modifiers unless they alter the character code itself.
187
264
  # Note that <tt>ctrl+c</tt> typically returns <tt>"c"</tt> as the code, so +to_s+ will return <tt>"c"</tt>.
265
+ #--
266
+ # SPDX-SnippetEnd
267
+ #++
188
268
  def to_s
189
269
  if text?
190
270
  @code
@@ -202,11 +282,19 @@ module RatatuiRuby
202
282
  #
203
283
  # Allows convenient checking for specific keys or key combinations:
204
284
  #
285
+ #--
286
+ # SPDX-SnippetBegin
287
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
288
+ # SPDX-License-Identifier: MIT-0
289
+ #++
205
290
  # event.ctrl_c? # => true if Ctrl+C
206
291
  # event.enter? # => true if Enter
207
292
  # event.shift_up? # => true if Shift+Up
208
293
  # event.q? # => true if "q"
209
294
  #
295
+ #--
296
+ # SPDX-SnippetEnd
297
+ #++
210
298
  # The method name is converted to a symbol and compared against the event.
211
299
  # This works for any key code or modifier+key combination.
212
300
  #
@@ -214,18 +302,34 @@ module RatatuiRuby
214
302
  #
215
303
  # For convenience, generic predicates match both system and media variants:
216
304
  #
305
+ #--
306
+ # SPDX-SnippetBegin
307
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
308
+ # SPDX-License-Identifier: MIT-0
309
+ #++
217
310
  # event.pause? # => true for BOTH system "pause" AND "media_pause"
218
311
  # event.play? # => true for "media_play"
219
312
  # event.stop? # => true for "media_stop"
220
313
  #
314
+ #--
315
+ # SPDX-SnippetEnd
316
+ #++
221
317
  # This "Do What I Mean" behavior reduces boilerplate when you just want to
222
318
  # respond to a conceptual action (e.g., "pause the playback") regardless of
223
319
  # whether the user pressed a keyboard key or a media button.
224
320
  #
225
321
  # For strict matching, use the full predicate or compare the code directly:
226
322
  #
323
+ #--
324
+ # SPDX-SnippetBegin
325
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
326
+ # SPDX-License-Identifier: MIT-0
327
+ #++
227
328
  # event.media_pause? # => true ONLY for media pause
228
329
  # event.code == "pause" # => true ONLY for system pause
330
+ #--
331
+ # SPDX-SnippetEnd
332
+ #++
229
333
  def method_missing(name, *args, &block)
230
334
  if name.to_s.end_with?("?")
231
335
  key_name = name.to_s[0...-1]
@@ -259,12 +363,20 @@ module RatatuiRuby
259
363
 
260
364
  # Deconstructs the event for pattern matching.
261
365
  #
366
+ #--
367
+ # SPDX-SnippetBegin
368
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
369
+ # SPDX-License-Identifier: MIT-0
370
+ #++
262
371
  # case event
263
372
  # in type: :key, code: "c", modifiers: ["ctrl"]
264
373
  # puts "Ctrl+C pressed"
265
374
  # in type: :key, kind: :media
266
375
  # puts "Media key pressed"
267
376
  # end
377
+ #--
378
+ # SPDX-SnippetEnd
379
+ #++
268
380
  def deconstruct_keys(keys)
269
381
  { type: :key, code: @code, modifiers: @modifiers, kind: @kind }
270
382
  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,9 +20,17 @@ 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.mouse? && event.down? && event.button == "left"
24
29
  # puts "Left click at #{event.x}, #{event.y}"
25
30
  # end
31
+ #--
32
+ # SPDX-SnippetEnd
33
+ #++
26
34
  class Mouse < Event
27
35
  # The kind of event (<tt>"down"</tt>, <tt>"up"</tt>, <tt>"drag"</tt>, <tt>"moved"</tt>, <tt>"scroll_up"</tt>, <tt>"scroll_down"</tt>).
28
36
  #
@@ -38,8 +46,16 @@ module RatatuiRuby
38
46
  attr_reader :y
39
47
  # The button pressed (<tt>"left"</tt>, <tt>"right"</tt>, <tt>"middle"</tt>, <tt>"none"</tt>).
40
48
  #
49
+ #--
50
+ # SPDX-SnippetBegin
51
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
52
+ # SPDX-License-Identifier: MIT-0
53
+ #++
41
54
  # puts event.button # => "left"
42
55
  #
56
+ #--
57
+ # SPDX-SnippetEnd
58
+ #++
43
59
  # Can be <tt>nil</tt>, which is treated as <tt>"none"</tt>.
44
60
  attr_reader :button
45
61
  # List of active modifiers.
@@ -49,9 +65,17 @@ module RatatuiRuby
49
65
 
50
66
  # Returns true for Mouse events.
51
67
  #
68
+ #--
69
+ # SPDX-SnippetBegin
70
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
71
+ # SPDX-License-Identifier: MIT-0
72
+ #++
52
73
  # event.mouse? # => true
53
74
  # event.key? # => false
54
75
  # event.resize? # => false
76
+ #--
77
+ # SPDX-SnippetEnd
78
+ #++
55
79
  def mouse?
56
80
  true
57
81
  end
@@ -98,19 +122,35 @@ module RatatuiRuby
98
122
 
99
123
  # Returns true if scroll wheel moved down.
100
124
  #
125
+ #--
126
+ # SPDX-SnippetBegin
127
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
128
+ # SPDX-License-Identifier: MIT-0
129
+ #++
101
130
  # if event.scroll_down?
102
131
  # scroll_offset += 1
103
132
  # end
133
+ #--
134
+ # SPDX-SnippetEnd
135
+ #++
104
136
  def scroll_down?
105
137
  @kind == "scroll_down"
106
138
  end
107
139
 
108
140
  # Deconstructs the event for pattern matching.
109
141
  #
142
+ #--
143
+ # SPDX-SnippetBegin
144
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
145
+ # SPDX-License-Identifier: MIT-0
146
+ #++
110
147
  # case event
111
148
  # in type: :mouse, kind: "down", x:, y:
112
149
  # puts "Click at #{x}, #{y}"
113
150
  # end
151
+ #--
152
+ # SPDX-SnippetEnd
153
+ #++
114
154
  def deconstruct_keys(keys)
115
155
  { type: :mouse, kind: @kind, x: @x, y: @y, button: @button, modifiers: @modifiers }
116
156
  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
@@ -23,10 +23,18 @@ module RatatuiRuby
23
23
  #
24
24
  # === Predicate Example
25
25
  #
26
+ #--
27
+ # SPDX-SnippetBegin
28
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
29
+ # SPDX-License-Identifier: MIT-0
30
+ #++
26
31
  # event = RatatuiRuby.poll_event
27
32
  # break if event.ctrl_c?
28
33
  # redraw if event.none?
29
34
  #
35
+ #--
36
+ # SPDX-SnippetEnd
37
+ #++
30
38
  # === Pattern Matching Example
31
39
  #
32
40
  # redraw if RatatuiRuby.poll_event in type: :none
@@ -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,15 +20,31 @@ module RatatuiRuby
20
20
  # === Examples
21
21
  #
22
22
  # Using predicates:
23
+ #--
24
+ # SPDX-SnippetBegin
25
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
26
+ # SPDX-License-Identifier: MIT-0
27
+ #++
23
28
  # if event.paste?
24
29
  # puts "Pasted: #{event.content}"
25
30
  # end
26
31
  #
32
+ #--
33
+ # SPDX-SnippetEnd
34
+ #++
27
35
  # Using pattern matching:
36
+ #--
37
+ # SPDX-SnippetBegin
38
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
39
+ # SPDX-License-Identifier: MIT-0
40
+ #++
28
41
  # case event
29
42
  # in type: :paste, content:
30
43
  # puts "Pasted: #{content}"
31
44
  # end
45
+ #--
46
+ # SPDX-SnippetEnd
47
+ #++
32
48
  class Paste < Event
33
49
  # The pasted content.
34
50
  #
@@ -37,9 +53,17 @@ module RatatuiRuby
37
53
 
38
54
  # Returns true for Paste events.
39
55
  #
56
+ #--
57
+ # SPDX-SnippetBegin
58
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
59
+ # SPDX-License-Identifier: MIT-0
60
+ #++
40
61
  # event.paste? # => true
41
62
  # event.key? # => false
42
63
  # event.resize? # => false
64
+ #--
65
+ # SPDX-SnippetEnd
66
+ #++
43
67
  def paste?
44
68
  true
45
69
  end
@@ -54,10 +78,18 @@ module RatatuiRuby
54
78
 
55
79
  # Deconstructs the event for pattern matching.
56
80
  #
81
+ #--
82
+ # SPDX-SnippetBegin
83
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
84
+ # SPDX-License-Identifier: MIT-0
85
+ #++
57
86
  # case event
58
87
  # in type: :paste, content:
59
88
  # puts "User pasted: #{content}"
60
89
  # end
90
+ #--
91
+ # SPDX-SnippetEnd
92
+ #++
61
93
  def deconstruct_keys(keys)
62
94
  { type: :paste, content: @content }
63
95
  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
@@ -21,15 +21,31 @@ module RatatuiRuby
21
21
  # === Examples
22
22
  #
23
23
  # Using predicates:
24
+ #--
25
+ # SPDX-SnippetBegin
26
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
27
+ # SPDX-License-Identifier: MIT-0
28
+ #++
24
29
  # if event.resize?
25
30
  # puts "Resized to #{event.width}x#{event.height}"
26
31
  # end
27
32
  #
33
+ #--
34
+ # SPDX-SnippetEnd
35
+ #++
28
36
  # Using pattern matching:
37
+ #--
38
+ # SPDX-SnippetBegin
39
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
40
+ # SPDX-License-Identifier: MIT-0
41
+ #++
29
42
  # case event
30
43
  # in type: :resize, width:, height:
31
44
  # puts "Resized to #{width}x#{height}"
32
45
  # end
46
+ #--
47
+ # SPDX-SnippetEnd
48
+ #++
33
49
  class Resize < Event
34
50
  # New terminal width in columns.
35
51
  #
@@ -43,9 +59,17 @@ module RatatuiRuby
43
59
 
44
60
  # Returns true for Resize events.
45
61
  #
62
+ #--
63
+ # SPDX-SnippetBegin
64
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
65
+ # SPDX-License-Identifier: MIT-0
66
+ #++
46
67
  # event.resize? # => true
47
68
  # event.key? # => false
48
69
  # event.mouse? # => false
70
+ #--
71
+ # SPDX-SnippetEnd
72
+ #++
49
73
  def resize?
50
74
  true
51
75
  end
@@ -63,10 +87,18 @@ module RatatuiRuby
63
87
 
64
88
  # Deconstructs the event for pattern matching.
65
89
  #
90
+ #--
91
+ # SPDX-SnippetBegin
92
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
93
+ # SPDX-License-Identifier: MIT-0
94
+ #++
66
95
  # case event
67
96
  # in type: :resize, width:, height:
68
97
  # puts "Resized to #{width}x#{height}"
69
98
  # end
99
+ #--
100
+ # SPDX-SnippetEnd
101
+ #++
70
102
  def deconstruct_keys(keys)
71
103
  { type: :resize, width: @width, height: @height }
72
104
  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
@@ -26,6 +26,11 @@ module RatatuiRuby
26
26
  # Use <tt>case...in</tt> to dispatch on every possible event type. This ensures
27
27
  # you handle every case without needing an +else+ clause:
28
28
  #
29
+ #--
30
+ # SPDX-SnippetBegin
31
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
32
+ # SPDX-License-Identifier: MIT-0
33
+ #++
29
34
  # case RatatuiRuby.poll_event
30
35
  # in { type: :key, code: "q" }
31
36
  # break
@@ -47,10 +52,18 @@ module RatatuiRuby
47
52
  # # Idle
48
53
  # end
49
54
  #
55
+ #--
56
+ # SPDX-SnippetEnd
57
+ #++
50
58
  # == Predicates
51
59
  #
52
60
  # Check event types with predicates without pattern matching:
53
61
  #
62
+ #--
63
+ # SPDX-SnippetBegin
64
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
65
+ # SPDX-License-Identifier: MIT-0
66
+ #++
54
67
  # event = RatatuiRuby.poll_event
55
68
  # if event.key?
56
69
  # puts "Key pressed"
@@ -59,6 +72,9 @@ module RatatuiRuby
59
72
  # elsif event.mouse?
60
73
  # puts "Mouse event"
61
74
  # end
75
+ #--
76
+ # SPDX-SnippetEnd
77
+ #++
62
78
  class Event
63
79
  # Returns true if this is a None event.
64
80
  def none?
@@ -114,10 +130,18 @@ module RatatuiRuby
114
130
  #
115
131
  # Keys argument is unused but required by the protocol.
116
132
  #
133
+ #--
134
+ # SPDX-SnippetBegin
135
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
136
+ # SPDX-License-Identifier: MIT-0
137
+ #++
117
138
  # case event
118
139
  # in type: :key, code:
119
140
  # puts "Key: #{code}"
120
141
  # end
142
+ #--
143
+ # SPDX-SnippetEnd
144
+ #++
121
145
  def deconstruct_keys(keys)
122
146
  {}
123
147
  end