ratatui_ruby 1.2.0 → 1.2.2

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 (260) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ratatui_ruby/Cargo.lock +2 -1
  3. data/ext/ratatui_ruby/Cargo.toml +2 -1
  4. data/ext/ratatui_ruby/src/events.rs +157 -18
  5. data/lib/ratatui_ruby/version.rb +1 -1
  6. metadata +1 -255
  7. data/.builds/ruby-3.2.yml +0 -54
  8. data/.builds/ruby-3.3.yml +0 -54
  9. data/.builds/ruby-3.4.yml +0 -54
  10. data/.builds/ruby-4.0.0.yml +0 -54
  11. data/.pre-commit-config.yaml +0 -16
  12. data/.rubocop.yml +0 -10
  13. data/AGENTS.md +0 -147
  14. data/CHANGELOG.md +0 -751
  15. data/README.md +0 -187
  16. data/README.rdoc +0 -302
  17. data/Rakefile +0 -11
  18. data/Steepfile +0 -50
  19. data/doc/concepts/application_architecture.md +0 -321
  20. data/doc/concepts/application_testing.md +0 -193
  21. data/doc/concepts/async.md +0 -190
  22. data/doc/concepts/custom_widgets.md +0 -247
  23. data/doc/concepts/debugging.md +0 -401
  24. data/doc/concepts/event_handling.md +0 -162
  25. data/doc/concepts/interactive_design.md +0 -146
  26. data/doc/contributors/auditing/parity.md +0 -239
  27. data/doc/contributors/design/ruby_frontend.md +0 -448
  28. data/doc/contributors/design/rust_backend.md +0 -434
  29. data/doc/contributors/design.md +0 -11
  30. data/doc/contributors/developing_examples.md +0 -400
  31. data/doc/contributors/documentation_style.md +0 -121
  32. data/doc/contributors/index.md +0 -21
  33. data/doc/contributors/releasing.md +0 -215
  34. data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -381
  35. data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -200
  36. data/doc/contributors/todo/align/term.md +0 -351
  37. data/doc/contributors/todo/align/terminal.md +0 -647
  38. data/doc/contributors/todo/future_work.md +0 -169
  39. data/doc/contributors/upstream_requests/paragraph_span_rects.md +0 -259
  40. data/doc/contributors/upstream_requests/tab_rects.md +0 -173
  41. data/doc/contributors/upstream_requests/title_rects.md +0 -132
  42. data/doc/custom.css +0 -22
  43. data/doc/getting_started/quickstart.md +0 -291
  44. data/doc/getting_started/why.md +0 -93
  45. data/doc/images/app_all_events.png +0 -0
  46. data/doc/images/app_cli_rich_moments.gif +0 -0
  47. data/doc/images/app_color_picker.png +0 -0
  48. data/doc/images/app_debugging_showcase.gif +0 -0
  49. data/doc/images/app_debugging_showcase.png +0 -0
  50. data/doc/images/app_external_editor.gif +0 -0
  51. data/doc/images/app_login_form.png +0 -0
  52. data/doc/images/app_stateful_interaction.png +0 -0
  53. data/doc/images/verify_quickstart_dsl.png +0 -0
  54. data/doc/images/verify_quickstart_layout.png +0 -0
  55. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  56. data/doc/images/verify_readme_usage.png +0 -0
  57. data/doc/images/widget_barchart.png +0 -0
  58. data/doc/images/widget_block.png +0 -0
  59. data/doc/images/widget_box.png +0 -0
  60. data/doc/images/widget_calendar.png +0 -0
  61. data/doc/images/widget_canvas.png +0 -0
  62. data/doc/images/widget_cell.png +0 -0
  63. data/doc/images/widget_center.png +0 -0
  64. data/doc/images/widget_chart.png +0 -0
  65. data/doc/images/widget_gauge.png +0 -0
  66. data/doc/images/widget_layout_split.png +0 -0
  67. data/doc/images/widget_line_gauge.png +0 -0
  68. data/doc/images/widget_list.png +0 -0
  69. data/doc/images/widget_map.png +0 -0
  70. data/doc/images/widget_overlay.png +0 -0
  71. data/doc/images/widget_popup.png +0 -0
  72. data/doc/images/widget_ratatui_logo.png +0 -0
  73. data/doc/images/widget_ratatui_mascot.png +0 -0
  74. data/doc/images/widget_rect.png +0 -0
  75. data/doc/images/widget_render.png +0 -0
  76. data/doc/images/widget_rich_text.png +0 -0
  77. data/doc/images/widget_scroll_text.png +0 -0
  78. data/doc/images/widget_scrollbar.png +0 -0
  79. data/doc/images/widget_sparkline.png +0 -0
  80. data/doc/images/widget_style_colors.png +0 -0
  81. data/doc/images/widget_table.png +0 -0
  82. data/doc/images/widget_tabs.png +0 -0
  83. data/doc/images/widget_text_width.png +0 -0
  84. data/doc/index.md +0 -34
  85. data/doc/troubleshooting/async.md +0 -4
  86. data/doc/troubleshooting/terminal_limitations.md +0 -131
  87. data/doc/troubleshooting/tui_output.md +0 -197
  88. data/examples/app_all_events/README.md +0 -114
  89. data/examples/app_all_events/app.rb +0 -98
  90. data/examples/app_all_events/model/app_model.rb +0 -159
  91. data/examples/app_all_events/model/event_color_cycle.rb +0 -43
  92. data/examples/app_all_events/model/event_entry.rb +0 -94
  93. data/examples/app_all_events/model/msg.rb +0 -39
  94. data/examples/app_all_events/model/timestamp.rb +0 -56
  95. data/examples/app_all_events/update.rb +0 -75
  96. data/examples/app_all_events/view/app_view.rb +0 -80
  97. data/examples/app_all_events/view/controls_view.rb +0 -54
  98. data/examples/app_all_events/view/counts_view.rb +0 -61
  99. data/examples/app_all_events/view/live_view.rb +0 -72
  100. data/examples/app_all_events/view/log_view.rb +0 -57
  101. data/examples/app_all_events/view.rb +0 -9
  102. data/examples/app_cli_rich_moments/README.md +0 -81
  103. data/examples/app_cli_rich_moments/app.rb +0 -189
  104. data/examples/app_color_picker/README.md +0 -156
  105. data/examples/app_color_picker/app.rb +0 -76
  106. data/examples/app_color_picker/clipboard.rb +0 -86
  107. data/examples/app_color_picker/color.rb +0 -193
  108. data/examples/app_color_picker/controls.rb +0 -92
  109. data/examples/app_color_picker/copy_dialog.rb +0 -168
  110. data/examples/app_color_picker/export_pane.rb +0 -128
  111. data/examples/app_color_picker/harmony.rb +0 -58
  112. data/examples/app_color_picker/input.rb +0 -176
  113. data/examples/app_color_picker/main_container.rb +0 -180
  114. data/examples/app_color_picker/palette.rb +0 -111
  115. data/examples/app_debugging_showcase/README.md +0 -119
  116. data/examples/app_debugging_showcase/app.rb +0 -318
  117. data/examples/app_external_editor/README.md +0 -62
  118. data/examples/app_external_editor/app.rb +0 -344
  119. data/examples/app_login_form/README.md +0 -58
  120. data/examples/app_login_form/app.rb +0 -109
  121. data/examples/app_stateful_interaction/README.md +0 -35
  122. data/examples/app_stateful_interaction/app.rb +0 -328
  123. data/examples/timeout_demo.rb +0 -45
  124. data/examples/verify_quickstart_dsl/README.md +0 -55
  125. data/examples/verify_quickstart_dsl/app.rb +0 -49
  126. data/examples/verify_quickstart_layout/README.md +0 -77
  127. data/examples/verify_quickstart_layout/app.rb +0 -73
  128. data/examples/verify_quickstart_lifecycle/README.md +0 -68
  129. data/examples/verify_quickstart_lifecycle/app.rb +0 -62
  130. data/examples/verify_readme_usage/README.md +0 -49
  131. data/examples/verify_readme_usage/app.rb +0 -42
  132. data/examples/verify_website_managed/README.md +0 -48
  133. data/examples/verify_website_managed/app.rb +0 -36
  134. data/examples/verify_website_menu/README.md +0 -60
  135. data/examples/verify_website_menu/app.rb +0 -84
  136. data/examples/verify_website_spinner/README.md +0 -44
  137. data/examples/verify_website_spinner/app.rb +0 -34
  138. data/examples/widget_barchart/README.md +0 -58
  139. data/examples/widget_barchart/app.rb +0 -240
  140. data/examples/widget_block/README.md +0 -44
  141. data/examples/widget_block/app.rb +0 -258
  142. data/examples/widget_box/README.md +0 -54
  143. data/examples/widget_box/app.rb +0 -255
  144. data/examples/widget_calendar/README.md +0 -48
  145. data/examples/widget_calendar/app.rb +0 -115
  146. data/examples/widget_canvas/README.md +0 -31
  147. data/examples/widget_canvas/app.rb +0 -130
  148. data/examples/widget_cell/README.md +0 -45
  149. data/examples/widget_cell/app.rb +0 -112
  150. data/examples/widget_center/README.md +0 -33
  151. data/examples/widget_center/app.rb +0 -118
  152. data/examples/widget_chart/README.md +0 -50
  153. data/examples/widget_chart/app.rb +0 -220
  154. data/examples/widget_gauge/README.md +0 -50
  155. data/examples/widget_gauge/app.rb +0 -229
  156. data/examples/widget_layout_split/README.md +0 -53
  157. data/examples/widget_layout_split/app.rb +0 -260
  158. data/examples/widget_line_gauge/README.md +0 -50
  159. data/examples/widget_line_gauge/app.rb +0 -219
  160. data/examples/widget_list/README.md +0 -58
  161. data/examples/widget_list/app.rb +0 -382
  162. data/examples/widget_map/README.md +0 -48
  163. data/examples/widget_map/app.rb +0 -95
  164. data/examples/widget_overlay/README.md +0 -45
  165. data/examples/widget_overlay/app.rb +0 -250
  166. data/examples/widget_popup/README.md +0 -45
  167. data/examples/widget_popup/app.rb +0 -106
  168. data/examples/widget_ratatui_logo/README.md +0 -43
  169. data/examples/widget_ratatui_logo/app.rb +0 -104
  170. data/examples/widget_ratatui_mascot/README.md +0 -43
  171. data/examples/widget_ratatui_mascot/app.rb +0 -95
  172. data/examples/widget_rect/README.md +0 -53
  173. data/examples/widget_rect/app.rb +0 -222
  174. data/examples/widget_render/README.md +0 -46
  175. data/examples/widget_render/app.rb +0 -186
  176. data/examples/widget_render/app.rbs +0 -41
  177. data/examples/widget_rich_text/README.md +0 -44
  178. data/examples/widget_rich_text/app.rb +0 -193
  179. data/examples/widget_scroll_text/README.md +0 -46
  180. data/examples/widget_scroll_text/app.rb +0 -109
  181. data/examples/widget_scrollbar/README.md +0 -46
  182. data/examples/widget_scrollbar/app.rb +0 -155
  183. data/examples/widget_sparkline/README.md +0 -51
  184. data/examples/widget_sparkline/app.rb +0 -277
  185. data/examples/widget_style_colors/README.md +0 -43
  186. data/examples/widget_style_colors/app.rb +0 -83
  187. data/examples/widget_table/README.md +0 -57
  188. data/examples/widget_table/app.rb +0 -285
  189. data/examples/widget_tabs/README.md +0 -50
  190. data/examples/widget_tabs/app.rb +0 -183
  191. data/examples/widget_text_width/README.md +0 -44
  192. data/examples/widget_text_width/app.rb +0 -117
  193. data/migrate_to_buffer.rb +0 -145
  194. data/mise.toml +0 -8
  195. data/tasks/autodoc/examples.rb +0 -87
  196. data/tasks/autodoc/member.rb +0 -58
  197. data/tasks/autodoc/name.rb +0 -21
  198. data/tasks/autodoc.rake +0 -21
  199. data/tasks/bump/bump_workflow.rb +0 -49
  200. data/tasks/bump/cargo_lockfile.rb +0 -21
  201. data/tasks/bump/changelog.rb +0 -104
  202. data/tasks/bump/header.rb +0 -32
  203. data/tasks/bump/history.rb +0 -32
  204. data/tasks/bump/links.rb +0 -69
  205. data/tasks/bump/manifest.rb +0 -33
  206. data/tasks/bump/patch_release.rb +0 -19
  207. data/tasks/bump/release_branch.rb +0 -17
  208. data/tasks/bump/release_from_trunk.rb +0 -49
  209. data/tasks/bump/repository.rb +0 -54
  210. data/tasks/bump/ruby_gem.rb +0 -29
  211. data/tasks/bump/sem_ver.rb +0 -44
  212. data/tasks/bump/unreleased_section.rb +0 -73
  213. data/tasks/bump.rake +0 -61
  214. data/tasks/doc/documentation.rb +0 -59
  215. data/tasks/doc/link/file_url.rb +0 -30
  216. data/tasks/doc/link/relative_path.rb +0 -61
  217. data/tasks/doc/link/web_url.rb +0 -55
  218. data/tasks/doc/link.rb +0 -52
  219. data/tasks/doc/link_audit.rb +0 -116
  220. data/tasks/doc/problem.rb +0 -40
  221. data/tasks/doc/source_file.rb +0 -93
  222. data/tasks/doc.rake +0 -905
  223. data/tasks/example_viewer.html.erb +0 -172
  224. data/tasks/extension.rake +0 -14
  225. data/tasks/license/headers_md.rb +0 -223
  226. data/tasks/license/headers_rb.rb +0 -210
  227. data/tasks/license/license_utils.rb +0 -130
  228. data/tasks/license/snippets_md.rb +0 -315
  229. data/tasks/license/snippets_rdoc.rb +0 -150
  230. data/tasks/license.rake +0 -91
  231. data/tasks/lint.rake +0 -170
  232. data/tasks/rbs_predicates/predicate_catalog.rb +0 -52
  233. data/tasks/rbs_predicates/predicate_tests.rb +0 -124
  234. data/tasks/rbs_predicates/rbs_signature.rb +0 -63
  235. data/tasks/rbs_predicates.rake +0 -31
  236. data/tasks/rdoc_config.rb +0 -29
  237. data/tasks/resources/build.yml.erb +0 -60
  238. data/tasks/resources/index.html.erb +0 -141
  239. data/tasks/resources/rubies.yml +0 -7
  240. data/tasks/sourcehut.rake +0 -122
  241. data/tasks/steep.rake +0 -11
  242. data/tasks/terminal_preview/app_screenshot.rb +0 -45
  243. data/tasks/terminal_preview/crash_report.rb +0 -54
  244. data/tasks/terminal_preview/example_app.rb +0 -27
  245. data/tasks/terminal_preview/launcher_script.rb +0 -48
  246. data/tasks/terminal_preview/preview_collection.rb +0 -60
  247. data/tasks/terminal_preview/preview_timing.rb +0 -24
  248. data/tasks/terminal_preview/safety_confirmation.rb +0 -58
  249. data/tasks/terminal_preview/saved_screenshot.rb +0 -56
  250. data/tasks/terminal_preview/system_appearance.rb +0 -13
  251. data/tasks/terminal_preview/terminal_window.rb +0 -138
  252. data/tasks/terminal_preview/window_id.rb +0 -16
  253. data/tasks/terminal_preview.rake +0 -30
  254. data/tasks/test.rake +0 -36
  255. data/tasks/website/index_page.rb +0 -30
  256. data/tasks/website/version.rb +0 -122
  257. data/tasks/website/version_menu.rb +0 -68
  258. data/tasks/website/versioned_documentation.rb +0 -83
  259. data/tasks/website/website.rb +0 -53
  260. data/tasks/website.rake +0 -28
@@ -1,200 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
-
4
- SPDX-License-Identifier: CC-BY-SA-4.0
5
- -->
6
-
7
- # Ratatui Features Audit - Complete Comprehensive Catalog
8
-
9
- These documents catalog EVERY public feature, method, function, enum variant, and constructor in the Ratatui Rust library with precise file/line references. This has the unfinished items; [the other has the finished items](./api_completeness_audit-finished.md).
10
-
11
- ## Terminal & Initialization Features
12
-
13
- | Feature Name | File/Line | Status |
14
- |--------------|-----------|--------|
15
- | try_init | ratatui/src/init.rs:330 | ❌ |
16
- | try_init_with_options | ratatui/src/init.rs:425 | ❌ |
17
- | try_restore | ratatui/src/init.rs:487 | ❌ |
18
- | Viewport::Fixed(Rect) | ratatui-core/src/terminal/viewport.rs:30 | ❌ |
19
- | Terminal struct | ratatui-core/src/terminal/terminal.rs:76 | ⚠️ |
20
- | Terminal::hide_cursor | ratatui-core/src/terminal/terminal.rs:495 | ❌ |
21
- | Terminal::show_cursor | ratatui-core/src/terminal/terminal.rs:502 | ❌ |
22
- | Terminal::get_cursor | ratatui-core/src/terminal/terminal.rs:513 | ❌ |
23
- | Terminal::set_cursor | ratatui-core/src/terminal/terminal.rs:520 | ❌ |
24
- | Terminal::get_cursor_position | ratatui-core/src/terminal/terminal.rs:527 | ⚠️ |
25
- | Terminal::set_cursor_position | ratatui-core/src/terminal/terminal.rs:532 | ⚠️ |
26
- | Terminal::clear | ratatui-core/src/terminal/terminal.rs:540 | ❌ |
27
- | Terminal::swap_buffers | ratatui-core/src/terminal/terminal.rs:562 | ❌ |
28
- | CompletedFrame struct | ratatui-core/src/terminal/frame.rs:40 | ❌ |
29
-
30
- **Notes:**
31
- - **Terminal struct**: No direct Terminal object; abstracted behind `RatatuiRuby` module methods
32
- - **Terminal::get_cursor_position/set_cursor_position**: Only available via [Frame](../../../../lib/ratatui_ruby/frame.rb#72-257) during draw, not on Terminal
33
-
34
- ## Layout Features
35
-
36
- | Feature Name | File/Line | Status |
37
- |--------------|-----------|--------|
38
- | Spacing enum | ratatui-core/src/layout/layout.rs:80 | ❌ |
39
- | Offset struct | ratatui-core/src/layout/offset.rs:10 | ❌ |
40
- | Margin struct | ratatui-core/src/layout/margin.rs:38 | ❌ |
41
-
42
- ## Style Features
43
-
44
- | Feature Name | File/Line | Status |
45
- |--------------|-----------|--------|
46
- | Styled trait | ratatui-core/src/style/stylize.rs:15 | ❌ |
47
- | Stylize trait | ratatui-core/src/style/stylize.rs:* | ❌ |
48
-
49
- ## Text Features
50
-
51
- | Feature Name | File/Line | Status |
52
- |--------------|-----------| -------|
53
- | Masked struct | ratatui-core/src/text/masked.rs:26 | ❌ |
54
- | ToText trait | ratatui-core/src/text/text.rs:721 | ❌ |
55
- | ToSpan trait | ratatui-core/src/text/span.rs:481 | ❌ |
56
- | StyledGrapheme struct | ratatui-core/src/text/grapheme.rs:12 | ❌ |
57
- | ToLine trait | ratatui-core/src/text/line.rs:810 | ❌ |
58
-
59
- ## Widgets
60
-
61
- ### Block Widget
62
-
63
- | Feature Name | File/Line | Status |
64
- |--------------|-----------|--------|
65
- | BorderType::LightDoubleDashed | ratatui-widgets/src/borders.rs:89 | ❌ |
66
- | BorderType::HeavyDoubleDashed | ratatui-widgets/src/borders.rs:97 | ❌ |
67
- | BorderType::LightTripleDashed | ratatui-widgets/src/borders.rs:105 | ❌ |
68
- | BorderType::HeavyTripleDashed | ratatui-widgets/src/borders.rs:113 | ❌ |
69
- | BorderType::LightQuadrupleDashed | ratatui-widgets/src/borders.rs:121 | ❌ |
70
- | BorderType::HeavyQuadrupleDashed | ratatui-widgets/src/borders.rs:129 | ❌ |
71
-
72
- ### Table Widget
73
-
74
- | Feature Name | File/Line | Status |
75
- |--------------|-----------|--------|
76
- | TableState struct | ratatui-widgets/src/table/state.rs:55 | ⚠️ |
77
- | TableState::new | ratatui-widgets/src/table/state.rs:62 | ⚠️ |
78
- | TableState::with_offset | ratatui-widgets/src/table/state.rs:79 | ❌ |
79
- | TableState::with_selected | ratatui-widgets/src/table/state.rs:96 | ❌ |
80
- | TableState::with_selected_column | ratatui-widgets/src/table/state.rs:116 | ❌ |
81
- | TableState::with_selected_cell | ratatui-widgets/src/table/state.rs:135 | ❌ |
82
- | TableState::offset | ratatui-widgets/src/table/state.rs:161 | ⚠️ |
83
- | TableState::offset_mut | ratatui-widgets/src/table/state.rs:175 | ❌ |
84
- | TableState::selected | ratatui-widgets/src/table/state.rs:189 | ⚠️ |
85
- | TableState::selected_column | ratatui-widgets/src/table/state.rs:205 | ⚠️ |
86
- | TableState::selected_cell | ratatui-widgets/src/table/state.rs:220 | ❌ |
87
- | TableState::selected_mut | ratatui-widgets/src/table/state.rs:238 | ❌ |
88
- | TableState::select | ratatui-widgets/src/table/state.rs:269 | ⚠️ |
89
- | TableState::select_next | ratatui-widgets/src/table/state.rs:336 | ❌ |
90
- | TableState::select_previous | ratatui-widgets/src/table/state.rs:371 | ❌ |
91
- | TableState::select_next_column | ratatui-widgets/src/table/state.rs:353 | ❌ |
92
- | TableState::select_previous_column | ratatui-widgets/src/table/state.rs:388 | ❌ |
93
- | TableState::scroll_down_by | ratatui-widgets/src/table/state.rs:475 | ❌ |
94
- | TableState::scroll_up_by | ratatui-widgets/src/table/state.rs:494 | ❌ |
95
-
96
- **Notes:**
97
- - **TableState**: Implemented as Data.define attributes on Table widget itself (selected_row, selected_column, offset) instead of separate state object
98
-
99
- ### List Widget
100
-
101
- | Feature Name | File/Line | Status |
102
- |--------------|-----------|--------|
103
- | ListState struct | ratatui-widgets/src/list/state.rs:45 | ⚠️ |
104
- | ListState::with_offset | ratatui-widgets/src/list/state.rs:51 | ❌ |
105
- | ListState::with_selected | ratatui-widgets/src/list/state.rs:68 | ❌ |
106
- | ListState::offset | ratatui-widgets/src/list/state.rs:85 | ⚠️ |
107
- | ListState::offset_mut | ratatui-widgets/src/list/state.rs:99 | ❌ |
108
- | ListState::selected | ratatui-widgets/src/list/state.rs:113 | ⚠️ |
109
- | ListState::selected_mut | ratatui-widgets/src/list/state.rs:129 | ❌ |
110
- | ListState::select | ratatui-widgets/src/list/state.rs:145 | ⚠️ |
111
- | ListState::select_next | ratatui-widgets/src/list/state.rs:177 | ❌ |
112
- | ListState::select_previous | ratatui-widgets/src/list/state.rs:195 | ❌ |
113
- | ListState::select_first | ratatui-widgets/src/list/state.rs:200 | ❌ |
114
- | ListState::select_last | ratatui-widgets/src/list/state.rs:217 | ❌ |
115
-
116
- **Notes:**
117
- - **ListState**: Implemented as Data.define attributes on List widget itself (selected_index, offset) instead of separate state object
118
- | ListState::scroll_down_by | ratatui-widgets/src/list/state.rs:248 | ❌ |
119
- | ListState::scroll_up_by | ratatui-widgets/src/list/state.rs:267 | ❌ |
120
-
121
- ### Sparkline Widget
122
-
123
- | Feature Name | File/Line | Status |
124
- |--------------|-----------|--------|
125
- | SparklineBar struct | ratatui-widgets/src/sparkline.rs:253 | ❌ |
126
-
127
- ### Scrollbar Widget
128
-
129
- | Feature Name | File/Line | Status |
130
- |--------------|-----------|--------|
131
- | ScrollbarState struct | ratatui-widgets/src/scrollbar.rs:149 | ⚠️ |
132
- | ScrollDirection::Forward | ratatui-widgets/src/scrollbar.rs:169 | ❌ |
133
- | ScrollDirection::Backward | ratatui-widgets/src/scrollbar.rs:172 | ❌ |
134
-
135
- **Notes:**
136
- - **ScrollbarState**: Implemented as Data.define attributes on Scrollbar widget itself (content_length, position) instead of separate state object
137
-
138
- ### Calendar Widget
139
-
140
- | Feature Name | File/Line | Status |
141
- |--------------|-----------|--------|
142
- | CalendarEventStore struct | ratatui-widgets/src/calendar.rs:258 | ❌ |
143
-
144
- ### Canvas Widget
145
-
146
- | Feature Name | File/Line | Status |
147
- |--------------|-----------|--------|
148
- | Context struct | ratatui-widgets/src/canvas.rs:515 | ❌ |
149
- | Painter struct | ratatui-widgets/src/canvas.rs:403 | ❌ |
150
- | Label struct | ratatui-widgets/src/canvas.rs:61 | ❌ |
151
- | Points shape | ratatui-widgets/src/canvas/points.rs:7 | ❌ |
152
-
153
- ## Buffer Features
154
-
155
- | Feature Name | File/Line | Status |
156
- |--------------|-----------|--------|
157
- | Buffer::empty | ratatui-core/src/buffer/buffer.rs:77 | ❌ |
158
- | Buffer::filled | ratatui-core/src/buffer/buffer.rs:83 | ❌ |
159
- | Buffer::with_lines | ratatui-core/src/buffer/buffer.rs:91 | ❌ |
160
- | Buffer::get_mut | ratatui-core/src/buffer/buffer.rs:150 | ❌ |
161
- | Buffer::index_of | ratatui-core/src/buffer/buffer.rs:248 | ❌ |
162
- | Buffer::set_string | ratatui-core/src/buffer/buffer.rs:323 | ❌ |
163
- | Buffer::set_stringn | ratatui-core/src/buffer/buffer.rs:335 | ❌ |
164
- | Buffer::set_line | ratatui-core/src/buffer/buffer.rs:372 | ❌ |
165
- | Buffer::set_span | ratatui-core/src/buffer/buffer.rs:394 | ❌ |
166
- | Buffer::set_style | ratatui-core/src/buffer/buffer.rs:404 | ❌ |
167
- | Buffer::reset | ratatui-core/src/buffer/buffer.rs:427 | ❌ |
168
- | Cell::set_style | ratatui-core/src/buffer/cell.rs:153 | ❌ |
169
- | Cell::reset | ratatui-core/src/buffer/cell.rs:193 | ❌ |
170
-
171
- **Notes:**
172
- - **Buffer**: Read-only access implemented via `RatatuiRuby.get_cell_at`. Direct mutation methods not exposed in Ruby API
173
-
174
- ## Widget Traits
175
-
176
- | Feature Name | File/Line | Status |
177
- |--------------|-----------|--------|
178
- | Widget trait | ratatui-core/src/widgets/widget.rs:70 | ⚠️ |
179
- | StatefulWidget trait | ratatui-core/src/widgets/stateful_widget.rs:124 | ⚠️ |
180
-
181
- **Notes:**
182
- - **Widget/StatefulWidget traits**: Not exposed as Ruby traits. Widgets implement `CoerceableWidget` mixin and rendering handled via FFI
183
-
184
- ## Backend Features
185
-
186
- | Feature Name | File/Line | Status |
187
- |--------------|-----------|--------|
188
- | Backend trait | ratatui-core/src/backend.rs:148 | ⚠️ |
189
- | ClearType::All | ratatui-core/src/backend.rs:117 | ❌ |
190
- | ClearType::AfterCursor | ratatui-core/src/backend.rs:119 | ❌ |
191
- | ClearType::BeforeCursor | ratatui-core/src/backend.rs:121 | ❌ |
192
- | ClearType::CurrentLine | ratatui-core/src/backend.rs:123 | ❌ |
193
- | ClearType::UntilNewLine | ratatui-core/src/backend.rs:125 | ❌ |
194
- | WindowSize struct | ratatui-core/src/backend.rs:130 | ❌ |
195
- | TermionBackend | ratatui-termion/src/lib.rs:* | ❌ |
196
- | TermwizBackend | ratatui-termwiz/src/lib.rs:* | ❌ |
197
-
198
- **Notes:**
199
- - **Backend trait**: Abstracted away. Terminal uses Crossterm backend internally, not exposed to Ruby API
200
- - **ClearType**: Not exposed. Clearing handled via `Clear` widget
@@ -1,351 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # TERM Environment Variable Respect
7
-
8
- Expose terminal capability detection so applications can degrade gracefully.
9
-
10
- ---
11
-
12
- ## Crossterm Audit (2026-01-17)
13
-
14
- What crossterm actually exposes that we can wrap:
15
-
16
- ### Available Public APIs
17
-
18
- | Function | Location | Notes |
19
- |----------|----------|-------|
20
- | `available_color_count()` | `src/style.rs:163` | Returns `u16`: 8, 256, or `u16::MAX` (truecolor). Checks `COLORTERM`, `TERM` env vars. |
21
- | `force_color_output(bool)` | `src/style.rs:191` | Override `NO_COLOR` check globally. |
22
- | `supports_keyboard_enhancement()` | `src/terminal/sys/unix.rs:188` | Requires `events` feature. Queries terminal via escape sequence. |
23
- | `window_size()` | `src/terminal.rs:148` | Returns `WindowSize { columns, rows, width, height }` including **pixel dimensions**. |
24
- | `supports_ansi()` | `src/ansi_support.rs:33` | **Windows only**. Checks VT processing + `TERM != "dumb"`. |
25
-
26
- ### Internal Logic (Not Exposed, But Informs Design)
27
-
28
- From `src/style.rs:174-180`:
29
- <!-- SPDX-SnippetBegin -->
30
- <!--
31
- SPDX-FileCopyrightText: 2026 Kerrick Long
32
- SPDX-License-Identifier: MIT-0
33
- -->
34
- ```rust
35
- env::var("COLORTERM")
36
- .or_else(|_| env::var("TERM"))
37
- .map_or(DEFAULT, |x| match x {
38
- _ if x.contains("24bit") || x.contains("truecolor") => u16::MAX,
39
- _ if x.contains("256") => 256,
40
- _ => DEFAULT, // 8 colors
41
- })
42
- ```
43
- <!-- SPDX-SnippetEnd -->
44
-
45
- From `src/ansi_support.rs:39-40` (Windows):
46
- <!-- SPDX-SnippetBegin -->
47
- <!--
48
- SPDX-FileCopyrightText: 2026 Kerrick Long
49
- SPDX-License-Identifier: MIT-0
50
- -->
51
- ```rust
52
- let supported = enable_vt_processing().is_ok()
53
- || std::env::var("TERM").map_or(false, |term| term != "dumb");
54
- ```
55
- <!-- SPDX-SnippetEnd -->
56
-
57
- ### What Ratatui Exposes
58
-
59
- The `Backend` trait in `ratatui-core/src/backend.rs` exposes:
60
- - `size()` → `Result<Size>` (columns/rows)
61
- - `window_size()` → `Result<WindowSize>` (columns/rows + pixels)
62
-
63
- **No capability detection is exposed through ratatui itself.** We must call crossterm directly.
64
-
65
- ### Audit Summary
66
-
67
- | Proposed API | Implementation | Source |
68
- |--------------|----------------|--------|
69
- | `tty?` | Pure Ruby | `$stdout.tty?` |
70
- | `dumb?` | Pure Ruby | `ENV["TERM"]` |
71
- | `no_color?` | Pure Ruby | `ENV.key?("NO_COLOR")` |
72
- | `force_color?` | Pure Ruby | `ENV.key?("FORCE_COLOR")` |
73
- | `color_support` | **Wrap crossterm** | `crossterm::style::available_color_count()` |
74
- | `supports_keyboard_enhancement?` | **Wrap crossterm** | `crossterm::terminal::supports_keyboard_enhancement()` |
75
- | `size_pixels` | **Wrap crossterm** | `crossterm::terminal::window_size().{width,height}` |
76
- | `interactive?` | Pure Ruby | Combines `tty?` + `dumb?` |
77
- | `suggested_style` | Pure Ruby | Derives from `color_support` |
78
-
79
- ---
80
-
81
- ## Problem Statement
82
-
83
- Rust-based CLI libraries often ignore the `TERM` environment variable and assume modern terminal features. This causes issues in:
84
-
85
- - **CI environments** — `TERM=dumb` or missing entirely
86
- - **Piped output** — stdout isn't a TTY
87
- - **Legacy terminals** — SSH to old systems, embedded devices
88
- - **Accessibility** — Screen readers need simpler output
89
- - **`NO_COLOR` movement** — Users explicitly disable color
90
-
91
- RatatuiRuby currently provides no capability detection APIs. Applications cannot query terminal support before rendering.
92
-
93
- ---
94
-
95
- ## Proposed API
96
-
97
- > [!NOTE]
98
- > These capability detection methods integrate with the `Terminal` class design from [terminal.md](terminal.md).
99
- > They are **class methods** on `RatatuiRuby::Terminal`, not a separate module.
100
-
101
- ### Phase 1: Environment Detection (Ruby-side)
102
-
103
- Pure Ruby class methods using environment variables and standard library.
104
-
105
- <!-- SPDX-SnippetBegin -->
106
- <!--
107
- SPDX-FileCopyrightText: 2026 Kerrick Long
108
- SPDX-License-Identifier: MIT-0
109
- -->
110
- ```ruby
111
- # lib/ratatui_ruby/terminal.rb (additions to existing Terminal class)
112
- module RatatuiRuby
113
- class Terminal
114
- class << self
115
- # Is stdout connected to a terminal?
116
- def tty? = $stdout.tty?
117
-
118
- # Is this a dumb terminal with no capabilities?
119
- def dumb? = ENV["TERM"] == "dumb" || ENV["TERM"].to_s.empty?
120
-
121
- # Should color be disabled? (NO_COLOR standard)
122
- def no_color? = ENV.key?("NO_COLOR")
123
-
124
- # Should color be forced? (overrides tty? check)
125
- def force_color? = ENV.key?("FORCE_COLOR")
126
-
127
- # Detected color support level
128
- # :none - No color (dumb terminal, NO_COLOR set, not a tty)
129
- # :basic - 16 colors (standard ANSI)
130
- # :ansi256 - 256 colors
131
- # :truecolor - 24-bit RGB
132
- def color_support
133
- return :none if no_color? || dumb?
134
- return detect_color_level if tty? || force_color?
135
- :none
136
- end
137
-
138
- private
139
-
140
- def detect_color_level
141
- colorterm = ENV["COLORTERM"]
142
- return :truecolor if colorterm == "truecolor" || colorterm == "24bit"
143
-
144
- term = ENV["TERM"].to_s
145
- return :truecolor if term.include?("truecolor") || term.include?("24bit")
146
- return :ansi256 if term.include?("256color")
147
- return :basic if term.start_with?("xterm", "screen", "vt100", "linux")
148
-
149
- :basic # Conservative default for unknown terminals
150
- end
151
- end
152
- end
153
- end
154
- ```
155
- <!-- SPDX-SnippetEnd -->
156
-
157
- ### Phase 2: Crossterm Capability Queries (Rust-side)
158
-
159
- Expose crossterm's runtime detection through Magnus bindings.
160
-
161
- <!-- SPDX-SnippetBegin -->
162
- <!--
163
- SPDX-FileCopyrightText: 2026 Kerrick Long
164
- SPDX-License-Identifier: MIT-0
165
- -->
166
- ```rust
167
- // ext/ratatui_ruby/src/terminal_capabilities.rs
168
-
169
- use crossterm::terminal;
170
- use magnus::{function, Error, Module, Object};
171
-
172
- /// Query if the terminal supports the Kitty keyboard protocol
173
- pub fn supports_keyboard_enhancement() -> Result<bool, Error> {
174
- Ok(terminal::supports_keyboard_enhancement()
175
- .map_err(|e| Error::new(magnus::exception::runtime_error(), e.to_string()))?)
176
- }
177
-
178
- /// Query terminal size in pixels (if supported)
179
- pub fn terminal_size_pixels() -> Result<Option<(u16, u16)>, Error> {
180
- match crossterm::terminal::window_size() {
181
- Ok(size) => Ok(Some((size.width, size.height))),
182
- Err(_) => Ok(None),
183
- }
184
- }
185
-
186
- pub fn register(ruby: &magnus::Ruby, module: &magnus::RModule) -> Result<(), Error> {
187
- module.define_module_function("_supports_keyboard_enhancement",
188
- function!(supports_keyboard_enhancement, 0))?;
189
- module.define_module_function("_terminal_size_pixels",
190
- function!(terminal_size_pixels, 0))?;
191
- Ok(())
192
- }
193
- ```
194
- <!-- SPDX-SnippetEnd -->
195
-
196
- Ruby wrapper (class methods on Terminal):
197
-
198
- <!-- SPDX-SnippetBegin -->
199
- <!--
200
- SPDX-FileCopyrightText: 2026 Kerrick Long
201
- SPDX-License-Identifier: MIT-0
202
- -->
203
- ```ruby
204
- # lib/ratatui_ruby/terminal.rb (continued)
205
- module RatatuiRuby
206
- class Terminal
207
- class << self
208
- # Does the terminal support the Kitty keyboard protocol?
209
- def supports_keyboard_enhancement?
210
- RatatuiRuby._supports_keyboard_enhancement
211
- rescue
212
- false
213
- end
214
-
215
- # Terminal size in pixels (for graphics protocols)
216
- # Returns { width:, height: } or nil if unsupported
217
- def size_pixels
218
- result = RatatuiRuby._terminal_size_pixels
219
- result ? { width: result[0], height: result[1] } : nil
220
- rescue
221
- nil
222
- end
223
- end
224
- end
225
- end
226
- ```
227
- <!-- SPDX-SnippetEnd -->
228
-
229
- ### Phase 3: Graceful Degradation Helpers
230
-
231
- Convenience class methods for common patterns.
232
-
233
- <!-- SPDX-SnippetBegin -->
234
- <!--
235
- SPDX-FileCopyrightText: 2026 Kerrick Long
236
- SPDX-License-Identifier: MIT-0
237
- -->
238
- ```ruby
239
- # lib/ratatui_ruby/terminal.rb (continued)
240
- module RatatuiRuby
241
- class Terminal
242
- class << self
243
- # Should the application use TUI mode?
244
- # Returns false for dumb terminals, piped output, etc.
245
- def interactive?
246
- tty? && !dumb?
247
- end
248
-
249
- # Suggested style based on terminal capabilities
250
- def suggested_style
251
- case color_support
252
- when :none then :plain
253
- when :basic then :ansi16
254
- when :ansi256 then :ansi256
255
- when :truecolor then :truecolor
256
- end
257
- end
258
- end
259
- end
260
- end
261
- ```
262
- <!-- SPDX-SnippetEnd -->
263
-
264
- ---
265
-
266
- ## Implementation Plan
267
-
268
- ### Phase 1: Environment Detection
269
-
270
- | File | Change |
271
- |------|--------|
272
- | [NEW] `lib/ratatui_ruby/terminal.rb` | `Terminal` module with `tty?`, `dumb?`, `no_color?`, `force_color?`, `color_support` |
273
- | [NEW] `sig/ratatui_ruby/terminal.rbs` | RBS type declarations |
274
- | [NEW] `test/test_terminal_capabilities.rb` | Unit tests with mocked ENV |
275
- | [MODIFY] `lib/ratatui_ruby.rb` | Require the new module |
276
-
277
- ### Phase 2: Crossterm Queries
278
-
279
- | File | Change |
280
- |------|--------|
281
- | [NEW] `ext/ratatui_ruby/src/terminal_capabilities.rs` | `supports_keyboard_enhancement`, `terminal_size_pixels` |
282
- | [MODIFY] `ext/ratatui_ruby/src/lib.rs` | Register new module |
283
- | [MODIFY] `lib/ratatui_ruby/terminal.rb` | Add `supports_keyboard_enhancement?`, `size_pixels` |
284
- | [MODIFY] `sig/ratatui_ruby/terminal.rbs` | Add new method types |
285
- | [MODIFY] `test/test_terminal_capabilities.rb` | Add integration tests |
286
-
287
- ### Phase 3: Convenience Methods
288
-
289
- | File | Change |
290
- |------|--------|
291
- | [MODIFY] `lib/ratatui_ruby/terminal.rb` | Add `interactive?`, `suggested_style` |
292
- | [MODIFY] `sig/ratatui_ruby/terminal.rbs` | Add new method types |
293
- | [MODIFY] `test/test_terminal_capabilities.rb` | Add convenience method tests |
294
-
295
- ---
296
-
297
- ## Documentation Updates
298
-
299
- | File | Change |
300
- |------|--------|
301
- | [NEW] `doc/concepts/terminal_capabilities.md` | Guide for capability detection |
302
- | [MODIFY] `doc/troubleshooting/terminal_limitations.md` | Reference new detection APIs |
303
- | [MODIFY] `CHANGELOG.md` | Document new feature |
304
-
305
- ---
306
-
307
- ## Verification Plan
308
-
309
- ### Automated Tests
310
-
311
- <!-- SPDX-SnippetBegin -->
312
- <!--
313
- SPDX-FileCopyrightText: 2026 Kerrick Long
314
- SPDX-License-Identifier: MIT-0
315
- -->
316
- ```bash
317
- bundle exec rake test TEST=test/test_terminal_capabilities.rb
318
- bundle exec steep check
319
- ```
320
- <!-- SPDX-SnippetEnd -->
321
-
322
- ### Manual Verification
323
-
324
- <!-- SPDX-SnippetBegin -->
325
- <!--
326
- SPDX-FileCopyrightText: 2026 Kerrick Long
327
- SPDX-License-Identifier: MIT-0
328
- -->
329
- ```bash
330
- # Test NO_COLOR respect
331
- NO_COLOR=1 bundle exec ruby -e "require 'ratatui_ruby'; p RatatuiRuby::Terminal.color_support"
332
- # Expected: :none
333
-
334
- # Test dumb terminal
335
- TERM=dumb bundle exec ruby -e "require 'ratatui_ruby'; p RatatuiRuby::Terminal.dumb?"
336
- # Expected: true
337
-
338
- # Test truecolor detection
339
- COLORTERM=truecolor bundle exec ruby -e "require 'ratatui_ruby'; p RatatuiRuby::Terminal.color_support"
340
- # Expected: :truecolor
341
- ```
342
- <!-- SPDX-SnippetEnd -->
343
-
344
- ---
345
-
346
- ## References
347
-
348
- - [NO_COLOR Standard](https://no-color.org/)
349
- - [Crossterm Terminal Queries](https://docs.rs/crossterm/latest/crossterm/terminal/index.html)
350
- - [Kitty Keyboard Protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/)
351
- - [terminfo(5)](https://man7.org/linux/man-pages/man5/terminfo.5.html)