ratatui_ruby 0.9.1 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.builds/ruby-3.2.yml +1 -1
- data/.builds/ruby-3.3.yml +1 -1
- data/.builds/ruby-3.4.yml +1 -1
- data/.builds/ruby-4.0.0.yml +1 -1
- data/AGENTS.md +2 -1
- data/CHANGELOG.md +113 -0
- data/README.md +17 -0
- data/REUSE.toml +5 -0
- data/Rakefile +1 -1
- data/Steepfile +49 -0
- data/doc/concepts/debugging.md +401 -0
- data/doc/getting_started/quickstart.md +8 -3
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_debugging_showcase.gif +0 -0
- data/doc/images/app_debugging_showcase.png +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_stateful_interaction.png +0 -0
- data/doc/images/verify_quickstart_dsl.png +0 -0
- data/doc/images/verify_quickstart_layout.png +0 -0
- data/doc/images/verify_quickstart_lifecycle.png +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_barchart.png +0 -0
- data/doc/images/widget_block.png +0 -0
- data/doc/images/widget_box.png +0 -0
- data/doc/images/widget_calendar.png +0 -0
- data/doc/images/widget_canvas.png +0 -0
- data/doc/images/widget_cell.png +0 -0
- data/doc/images/widget_center.png +0 -0
- data/doc/images/widget_chart.png +0 -0
- data/doc/images/widget_gauge.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge.png +0 -0
- data/doc/images/widget_list.png +0 -0
- data/doc/images/widget_map.png +0 -0
- data/doc/images/widget_overlay.png +0 -0
- data/doc/images/widget_popup.png +0 -0
- data/doc/images/widget_ratatui_logo.png +0 -0
- data/doc/images/widget_ratatui_mascot.png +0 -0
- data/doc/images/widget_rect.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_rich_text.png +0 -0
- data/doc/images/widget_scroll_text.png +0 -0
- data/doc/images/widget_scrollbar.png +0 -0
- data/doc/images/widget_sparkline.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table.png +0 -0
- data/doc/images/widget_tabs.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/troubleshooting/async.md +4 -0
- data/examples/app_debugging_showcase/README.md +119 -0
- data/examples/app_debugging_showcase/app.rb +318 -0
- data/examples/widget_canvas/app.rb +19 -14
- data/examples/widget_gauge/app.rb +18 -3
- data/examples/widget_layout_split/app.rb +10 -4
- data/examples/widget_list/app.rb +22 -6
- data/examples/widget_rect/app.rb +7 -6
- data/examples/widget_rich_text/app.rb +62 -37
- data/examples/widget_style_colors/app.rb +26 -47
- data/examples/widget_table/app.rb +28 -5
- data/examples/widget_text_width/app.rb +6 -4
- data/ext/ratatui_ruby/Cargo.lock +48 -1
- data/ext/ratatui_ruby/Cargo.toml +6 -2
- data/ext/ratatui_ruby/src/color.rs +82 -0
- data/ext/ratatui_ruby/src/errors.rs +28 -0
- data/ext/ratatui_ruby/src/events.rs +15 -14
- data/ext/ratatui_ruby/src/lib.rs +56 -0
- data/ext/ratatui_ruby/src/rendering.rs +3 -1
- data/ext/ratatui_ruby/src/style.rs +48 -21
- data/ext/ratatui_ruby/src/terminal.rs +40 -9
- data/ext/ratatui_ruby/src/text.rs +21 -9
- data/ext/ratatui_ruby/src/widgets/chart.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/layout.rs +90 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +6 -5
- data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/table.rs +7 -6
- data/ext/ratatui_ruby/src/widgets/table_state.rs +55 -0
- data/ext/ratatui_ruby/src/widgets/tabs.rs +3 -2
- data/lib/ratatui_ruby/buffer/cell.rb +25 -15
- data/lib/ratatui_ruby/buffer.rb +134 -2
- data/lib/ratatui_ruby/cell.rb +13 -5
- data/lib/ratatui_ruby/debug.rb +215 -0
- data/lib/ratatui_ruby/event/key.rb +3 -2
- data/lib/ratatui_ruby/event.rb +1 -1
- data/lib/ratatui_ruby/layout/constraint.rb +49 -0
- data/lib/ratatui_ruby/layout/layout.rb +119 -13
- data/lib/ratatui_ruby/layout/position.rb +55 -0
- data/lib/ratatui_ruby/layout/rect.rb +188 -0
- data/lib/ratatui_ruby/layout/size.rb +55 -0
- data/lib/ratatui_ruby/layout.rb +4 -0
- data/lib/ratatui_ruby/style/color.rb +149 -0
- data/lib/ratatui_ruby/style/style.rb +51 -4
- data/lib/ratatui_ruby/style.rb +2 -0
- data/lib/ratatui_ruby/symbols.rb +435 -0
- data/lib/ratatui_ruby/synthetic_events.rb +1 -1
- data/lib/ratatui_ruby/table_state.rb +51 -0
- data/lib/ratatui_ruby/terminal_lifecycle.rb +2 -1
- data/lib/ratatui_ruby/test_helper/event_injection.rb +6 -1
- data/lib/ratatui_ruby/test_helper.rb +9 -0
- data/lib/ratatui_ruby/text/line.rb +245 -0
- data/lib/ratatui_ruby/text/span.rb +158 -0
- data/lib/ratatui_ruby/text.rb +99 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +103 -0
- data/lib/ratatui_ruby/tui/core.rb +13 -2
- data/lib/ratatui_ruby/tui/layout_factories.rb +50 -3
- data/lib/ratatui_ruby/tui/state_factories.rb +42 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +40 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +135 -60
- data/lib/ratatui_ruby/tui.rb +22 -1
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +30 -20
- data/lib/ratatui_ruby/widgets/block.rb +14 -6
- data/lib/ratatui_ruby/widgets/calendar.rb +2 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +56 -0
- data/lib/ratatui_ruby/widgets/cell.rb +2 -0
- data/lib/ratatui_ruby/widgets/center.rb +2 -0
- data/lib/ratatui_ruby/widgets/chart.rb +6 -0
- data/lib/ratatui_ruby/widgets/clear.rb +2 -0
- data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +2 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +61 -3
- data/lib/ratatui_ruby/widgets/line_gauge.rb +66 -4
- data/lib/ratatui_ruby/widgets/list.rb +87 -3
- data/lib/ratatui_ruby/widgets/list_item.rb +2 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +2 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +4 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -0
- data/lib/ratatui_ruby/widgets/row.rb +45 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +2 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +21 -13
- data/lib/ratatui_ruby/widgets/table.rb +13 -3
- data/lib/ratatui_ruby/widgets/tabs.rb +6 -4
- data/lib/ratatui_ruby/widgets.rb +1 -0
- data/lib/ratatui_ruby.rb +42 -11
- data/sig/examples/app_all_events/model/app_model.rbs +23 -0
- data/sig/examples/app_all_events/model/event_entry.rbs +15 -8
- data/sig/examples/app_all_events/model/timestamp.rbs +1 -1
- data/sig/examples/app_all_events/view.rbs +1 -1
- data/sig/examples/app_stateful_interaction/app.rbs +5 -5
- data/sig/examples/widget_block_demo/app.rbs +6 -6
- data/sig/manifest.yaml +5 -0
- data/sig/patches/data.rbs +26 -0
- data/sig/patches/debugger__.rbs +8 -0
- data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
- data/sig/ratatui_ruby/buffer.rbs +18 -0
- data/sig/ratatui_ruby/cell.rbs +44 -0
- data/sig/ratatui_ruby/clear.rbs +18 -0
- data/sig/ratatui_ruby/constraint.rbs +26 -0
- data/sig/ratatui_ruby/debug.rbs +45 -0
- data/sig/ratatui_ruby/draw.rbs +30 -0
- data/sig/ratatui_ruby/event.rbs +68 -8
- data/sig/ratatui_ruby/frame.rbs +4 -4
- data/sig/ratatui_ruby/interfaces.rbs +25 -0
- data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
- data/sig/ratatui_ruby/layout/layout.rbs +45 -0
- data/sig/ratatui_ruby/layout/position.rbs +18 -0
- data/sig/ratatui_ruby/layout/rect.rbs +64 -0
- data/sig/ratatui_ruby/layout/size.rbs +18 -0
- data/sig/ratatui_ruby/output_guard.rbs +23 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +84 -5
- data/sig/ratatui_ruby/rect.rbs +17 -0
- data/sig/ratatui_ruby/style/color.rbs +22 -0
- data/sig/ratatui_ruby/style/style.rbs +29 -0
- data/sig/ratatui_ruby/symbols.rbs +141 -0
- data/sig/ratatui_ruby/synthetic_events.rbs +21 -0
- data/sig/ratatui_ruby/table_state.rbs +6 -0
- data/sig/ratatui_ruby/terminal_lifecycle.rbs +31 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +2 -2
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +22 -3
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +8 -1
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -3
- data/sig/ratatui_ruby/text/line.rbs +27 -0
- data/sig/ratatui_ruby/text/span.rbs +23 -0
- data/sig/ratatui_ruby/text.rbs +12 -0
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +1 -1
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +23 -5
- data/sig/ratatui_ruby/tui/core.rbs +2 -2
- data/sig/ratatui_ruby/tui/layout_factories.rbs +16 -2
- data/sig/ratatui_ruby/tui/state_factories.rbs +8 -3
- data/sig/ratatui_ruby/tui/style_factories.rbs +3 -1
- data/sig/ratatui_ruby/tui/text_factories.rbs +7 -4
- data/sig/ratatui_ruby/tui/widget_factories.rbs +123 -30
- data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
- data/sig/ratatui_ruby/widgets/block.rbs +51 -0
- data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
- data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
- data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
- data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
- data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
- data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
- data/sig/ratatui_ruby/widgets/list.rbs +63 -0
- data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
- data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
- data/sig/ratatui_ruby/widgets/row.rbs +43 -0
- data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
- data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
- data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
- data/sig/ratatui_ruby/widgets/table.rbs +78 -0
- data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
- data/sig/ratatui_ruby/{schema/list_item.rbs → widgets.rbs} +4 -4
- data/tasks/steep.rake +11 -0
- metadata +80 -63
- data/doc/contributors/v1.0.0_blockers.md +0 -870
- data/doc/troubleshooting/debugging.md +0 -101
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +0 -47
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +0 -25
- data/lib/ratatui_ruby/schema/bar_chart.rb +0 -287
- data/lib/ratatui_ruby/schema/block.rb +0 -198
- data/lib/ratatui_ruby/schema/calendar.rb +0 -84
- data/lib/ratatui_ruby/schema/canvas.rb +0 -239
- data/lib/ratatui_ruby/schema/center.rb +0 -67
- data/lib/ratatui_ruby/schema/chart.rb +0 -159
- data/lib/ratatui_ruby/schema/clear.rb +0 -62
- data/lib/ratatui_ruby/schema/constraint.rb +0 -151
- data/lib/ratatui_ruby/schema/cursor.rb +0 -50
- data/lib/ratatui_ruby/schema/gauge.rb +0 -72
- data/lib/ratatui_ruby/schema/layout.rb +0 -122
- data/lib/ratatui_ruby/schema/line_gauge.rb +0 -80
- data/lib/ratatui_ruby/schema/list.rb +0 -135
- data/lib/ratatui_ruby/schema/list_item.rb +0 -51
- data/lib/ratatui_ruby/schema/overlay.rb +0 -51
- data/lib/ratatui_ruby/schema/paragraph.rb +0 -107
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +0 -31
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +0 -36
- data/lib/ratatui_ruby/schema/rect.rb +0 -174
- data/lib/ratatui_ruby/schema/row.rb +0 -76
- data/lib/ratatui_ruby/schema/scrollbar.rb +0 -143
- data/lib/ratatui_ruby/schema/shape/label.rb +0 -76
- data/lib/ratatui_ruby/schema/sparkline.rb +0 -142
- data/lib/ratatui_ruby/schema/style.rb +0 -97
- data/lib/ratatui_ruby/schema/table.rb +0 -141
- data/lib/ratatui_ruby/schema/tabs.rb +0 -85
- data/lib/ratatui_ruby/schema/text.rb +0 -217
- data/sig/examples/app_all_events/model/events.rbs +0 -15
- data/sig/examples/app_all_events/view_state.rbs +0 -21
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +0 -22
- data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +0 -19
- data/sig/ratatui_ruby/schema/bar_chart.rbs +0 -38
- data/sig/ratatui_ruby/schema/block.rbs +0 -18
- data/sig/ratatui_ruby/schema/calendar.rbs +0 -23
- data/sig/ratatui_ruby/schema/canvas.rbs +0 -81
- data/sig/ratatui_ruby/schema/center.rbs +0 -17
- data/sig/ratatui_ruby/schema/chart.rbs +0 -39
- data/sig/ratatui_ruby/schema/constraint.rbs +0 -30
- data/sig/ratatui_ruby/schema/cursor.rbs +0 -16
- data/sig/ratatui_ruby/schema/draw.rbs +0 -33
- data/sig/ratatui_ruby/schema/gauge.rbs +0 -23
- data/sig/ratatui_ruby/schema/layout.rbs +0 -27
- data/sig/ratatui_ruby/schema/line_gauge.rbs +0 -24
- data/sig/ratatui_ruby/schema/list.rbs +0 -28
- data/sig/ratatui_ruby/schema/overlay.rbs +0 -15
- data/sig/ratatui_ruby/schema/paragraph.rbs +0 -20
- data/sig/ratatui_ruby/schema/ratatui_logo.rbs +0 -14
- data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +0 -17
- data/sig/ratatui_ruby/schema/rect.rbs +0 -48
- data/sig/ratatui_ruby/schema/row.rbs +0 -28
- data/sig/ratatui_ruby/schema/scrollbar.rbs +0 -42
- data/sig/ratatui_ruby/schema/sparkline.rbs +0 -22
- data/sig/ratatui_ruby/schema/style.rbs +0 -19
- data/sig/ratatui_ruby/schema/table.rbs +0 -32
- data/sig/ratatui_ruby/schema/tabs.rbs +0 -21
- data/sig/ratatui_ruby/schema/text.rbs +0 -31
- /data/lib/ratatui_ruby/{schema/draw.rb → draw.rb} +0 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Debugging Guide
|
|
7
|
+
|
|
8
|
+
TUI applications are harder to debug than typical Ruby programs. The terminal is in raw mode. Standard output corrupts the display. Debuggers that rely on REPL input conflict with the event loop. Rust panics produce cryptic stack traces without symbols.
|
|
9
|
+
|
|
10
|
+
This guide covers what RatatuiRuby offers and what works (and what does not) when debugging TUI apps.
|
|
11
|
+
|
|
12
|
+
## Debug Mode
|
|
13
|
+
|
|
14
|
+
RatatuiRuby ships with debug symbols in release builds. Call `RatatuiRuby::Debug.enable!` to get Rust backtraces with meaningful stack frames.
|
|
15
|
+
|
|
16
|
+
### Activation Methods
|
|
17
|
+
|
|
18
|
+
You can turn on debug features in three ways.
|
|
19
|
+
|
|
20
|
+
1. **Environment variable (Rust only):** `RUST_BACKTRACE=1` turns on Rust backtraces without Ruby-side debug features.
|
|
21
|
+
|
|
22
|
+
2. **Environment variable (full):** `RR_DEBUG=1` turns on full debug mode at process startup.
|
|
23
|
+
|
|
24
|
+
3. **Programmatic:** Call `RatatuiRuby.debug_mode!` or `RatatuiRuby::Debug.enable!`.
|
|
25
|
+
|
|
26
|
+
> [!WARNING]
|
|
27
|
+
> Debug mode opens a remote debugging socket. This is a **security vulnerability**. Do not use it in production. See [Remote Debugging](#remote-debugging) for details.
|
|
28
|
+
|
|
29
|
+
Including `RatatuiRuby::TestHelper` auto-enables debug mode. Test authors get backtraces automatically.
|
|
30
|
+
|
|
31
|
+
<!-- SPDX-SnippetBegin -->
|
|
32
|
+
<!--
|
|
33
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
34
|
+
SPDX-License-Identifier: MIT-0
|
|
35
|
+
-->
|
|
36
|
+
```ruby
|
|
37
|
+
# Option 1: Environment variable
|
|
38
|
+
# $ RR_DEBUG=1 ruby my_app.rb
|
|
39
|
+
|
|
40
|
+
# Option 2: Programmatic
|
|
41
|
+
RatatuiRuby.debug_mode!
|
|
42
|
+
|
|
43
|
+
# Now Rust panics show meaningful stack traces
|
|
44
|
+
```
|
|
45
|
+
<!-- SPDX-SnippetEnd -->
|
|
46
|
+
|
|
47
|
+
### Panics vs. Exceptions
|
|
48
|
+
|
|
49
|
+
Rust backtraces only appear for **panics** (unrecoverable crashes). When Rust code raises a Ruby exception (like `TypeError`), Ruby handles the backtrace. Rust provides the error message.
|
|
50
|
+
|
|
51
|
+
| Error Type | Backtrace | When It Happens |
|
|
52
|
+
|------------|-----------|-----------------|
|
|
53
|
+
| **Panic** | Rust stack trace | Internal Rust bug, `Debug.test_panic!` |
|
|
54
|
+
| **Exception** | Ruby stack trace | Type mismatch, invalid arguments |
|
|
55
|
+
|
|
56
|
+
The `RUST_BACKTRACE=1` environment variable and `Debug.enable!` affect panic backtraces. Exceptions always show Ruby backtraces, but RatatuiRuby includes **contextual error messages** showing the actual value that caused the error:
|
|
57
|
+
|
|
58
|
+
<!-- SPDX-SnippetBegin -->
|
|
59
|
+
<!--
|
|
60
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
61
|
+
SPDX-License-Identifier: MIT-0
|
|
62
|
+
-->
|
|
63
|
+
```
|
|
64
|
+
# Without context (generic):
|
|
65
|
+
expected array for rows
|
|
66
|
+
|
|
67
|
+
# With context (RatatuiRuby):
|
|
68
|
+
expected array for rows, got 42
|
|
69
|
+
```
|
|
70
|
+
<!-- SPDX-SnippetEnd -->
|
|
71
|
+
|
|
72
|
+
## Inspecting the Buffer
|
|
73
|
+
|
|
74
|
+
The following methods help you debug rendering issues from tests or scripts.
|
|
75
|
+
|
|
76
|
+
### print_buffer
|
|
77
|
+
|
|
78
|
+
Outputs the current terminal buffer to STDOUT with full ANSI colors. Call it inside `with_test_terminal` to see exactly what would render.
|
|
79
|
+
|
|
80
|
+
<!-- SPDX-SnippetBegin -->
|
|
81
|
+
<!--
|
|
82
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
83
|
+
SPDX-License-Identifier: MIT-0
|
|
84
|
+
-->
|
|
85
|
+
```ruby
|
|
86
|
+
with_test_terminal do
|
|
87
|
+
MyApp.new.render
|
|
88
|
+
print_buffer # Outputs the screen with colors
|
|
89
|
+
end
|
|
90
|
+
```
|
|
91
|
+
<!-- SPDX-SnippetEnd -->
|
|
92
|
+
|
|
93
|
+
### buffer_content
|
|
94
|
+
|
|
95
|
+
Returns the terminal buffer as an array of strings (one per row). Use it for programmatic inspection.
|
|
96
|
+
|
|
97
|
+
<!-- SPDX-SnippetBegin -->
|
|
98
|
+
<!--
|
|
99
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
100
|
+
SPDX-License-Identifier: MIT-0
|
|
101
|
+
-->
|
|
102
|
+
```ruby
|
|
103
|
+
with_test_terminal do
|
|
104
|
+
MyApp.new.render
|
|
105
|
+
pp buffer_content # ["Line 1: ...", "Line 2: ...", ...]
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
<!-- SPDX-SnippetEnd -->
|
|
109
|
+
|
|
110
|
+
### get_cell
|
|
111
|
+
|
|
112
|
+
Returns a `Buffer::Cell` with the character, foreground color, background color, and modifiers at specific coordinates.
|
|
113
|
+
|
|
114
|
+
<!-- SPDX-SnippetBegin -->
|
|
115
|
+
<!--
|
|
116
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
117
|
+
SPDX-License-Identifier: MIT-0
|
|
118
|
+
-->
|
|
119
|
+
```ruby
|
|
120
|
+
with_test_terminal do
|
|
121
|
+
MyApp.new.render
|
|
122
|
+
cell = get_cell(0, 0)
|
|
123
|
+
pp cell.symbol # "H"
|
|
124
|
+
pp cell.fg # :red
|
|
125
|
+
pp cell.bold? # true
|
|
126
|
+
end
|
|
127
|
+
```
|
|
128
|
+
<!-- SPDX-SnippetEnd -->
|
|
129
|
+
|
|
130
|
+
## Protecting Output
|
|
131
|
+
|
|
132
|
+
During a TUI session, writes to `$stdout` or `$stderr` corrupt the display. Third-party gems often print warnings or debug output unexpectedly.
|
|
133
|
+
|
|
134
|
+
Use `guard_io` to temporarily swallow output from chatty code.
|
|
135
|
+
|
|
136
|
+
<!-- SPDX-SnippetBegin -->
|
|
137
|
+
<!--
|
|
138
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
139
|
+
SPDX-License-Identifier: MIT-0
|
|
140
|
+
-->
|
|
141
|
+
```ruby
|
|
142
|
+
RatatuiRuby.run do |tui|
|
|
143
|
+
RatatuiRuby.guard_io do
|
|
144
|
+
SomeChattyGem.process # Any puts/warn calls are swallowed
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
```
|
|
148
|
+
<!-- SPDX-SnippetEnd -->
|
|
149
|
+
|
|
150
|
+
## Interactive Debuggers
|
|
151
|
+
|
|
152
|
+
> [!WARNING]
|
|
153
|
+
> This section has not been verified by a human.
|
|
154
|
+
|
|
155
|
+
> [!CAUTION]
|
|
156
|
+
> Traditional interactive debuggers (Pry, IRB, debug.gem) do not work inside an active TUI session. They require terminal input and output, which conflicts with raw mode.
|
|
157
|
+
|
|
158
|
+
### Workarounds
|
|
159
|
+
|
|
160
|
+
**Temporarily exit TUI mode.** Restore the terminal, run your debugger, then re-initialize.
|
|
161
|
+
|
|
162
|
+
<!-- SPDX-SnippetBegin -->
|
|
163
|
+
<!--
|
|
164
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
165
|
+
SPDX-License-Identifier: MIT-0
|
|
166
|
+
-->
|
|
167
|
+
```ruby
|
|
168
|
+
RatatuiRuby.restore_terminal
|
|
169
|
+
binding.pry # Now Pry works normally
|
|
170
|
+
RatatuiRuby.init_terminal
|
|
171
|
+
```
|
|
172
|
+
<!-- SPDX-SnippetEnd -->
|
|
173
|
+
|
|
174
|
+
**Use test mode.** Debug rendering logic inside `with_test_terminal` where there is no real terminal conflict.
|
|
175
|
+
|
|
176
|
+
<!-- SPDX-SnippetBegin -->
|
|
177
|
+
<!--
|
|
178
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
179
|
+
SPDX-License-Identifier: MIT-0
|
|
180
|
+
-->
|
|
181
|
+
```ruby
|
|
182
|
+
with_test_terminal do
|
|
183
|
+
binding.pry # Works fine in test mode
|
|
184
|
+
MyApp.new.render
|
|
185
|
+
end
|
|
186
|
+
```
|
|
187
|
+
<!-- SPDX-SnippetEnd -->
|
|
188
|
+
|
|
189
|
+
## Remote Debugging
|
|
190
|
+
|
|
191
|
+
Debug mode uses [Ruby's `debug` gem](https://rubygems.org/gems/debug) for [remote debugging](https://github.com/ruby/debug?tab=readme-ov-file#readme). Attach from another terminal (or IDE or Chrome DevTools) while the TUI runs.
|
|
192
|
+
|
|
193
|
+

|
|
194
|
+
|
|
195
|
+
For a hands-on demo, see the [Debugging Showcase](../../examples/app_debugging_showcase/README.md) example.
|
|
196
|
+
|
|
197
|
+
Debug mode loads the `debug` gem and creates a UNIX domain socket. Debuggers attach from another terminal. This works well for TUI apps since the main terminal is in raw mode.
|
|
198
|
+
|
|
199
|
+
### How It Works
|
|
200
|
+
|
|
201
|
+
- **`RR_DEBUG=1`**: Loads `debug/open`. The app stops at startup and waits for a debugger to attach.
|
|
202
|
+
- **`RatatuiRuby.debug_mode!`**: Loads `debug/open_nonstop`. The app continues running. Attach whenever you want.
|
|
203
|
+
|
|
204
|
+
Attach from another terminal with `rdbg --attach`.
|
|
205
|
+
|
|
206
|
+
<!-- SPDX-SnippetBegin -->
|
|
207
|
+
<!--
|
|
208
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
209
|
+
SPDX-License-Identifier: MIT-0
|
|
210
|
+
-->
|
|
211
|
+
```sh
|
|
212
|
+
$ rdbg --attach
|
|
213
|
+
```
|
|
214
|
+
<!-- SPDX-SnippetEnd -->
|
|
215
|
+
|
|
216
|
+
> [!CAUTION]
|
|
217
|
+
> Remote debugging opens a backdoor to your application. This is a **security vulnerability**. The `debug/open_nonstop` mode is particularly dangerous because it allows attachment at any time. Do not run debug mode in production. Anyone who can access the socket can execute arbitrary code.
|
|
218
|
+
|
|
219
|
+
### Example: Debugging a Running TUI
|
|
220
|
+
|
|
221
|
+
Terminal 1 (your app):
|
|
222
|
+
<!-- SPDX-SnippetBegin -->
|
|
223
|
+
<!--
|
|
224
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
225
|
+
SPDX-License-Identifier: MIT-0
|
|
226
|
+
-->
|
|
227
|
+
```sh
|
|
228
|
+
$ ruby my_tui_app.rb
|
|
229
|
+
# App starts, TUI is running
|
|
230
|
+
# In your code: RatatuiRuby.debug_mode!
|
|
231
|
+
# Console shows: DEBUGGER: Debugger can attach via UNIX domain socket (...)
|
|
232
|
+
```
|
|
233
|
+
<!-- SPDX-SnippetEnd -->
|
|
234
|
+
|
|
235
|
+
Terminal 2 (debugger):
|
|
236
|
+
<!-- SPDX-SnippetBegin -->
|
|
237
|
+
<!--
|
|
238
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
239
|
+
SPDX-License-Identifier: MIT-0
|
|
240
|
+
-->
|
|
241
|
+
```sh
|
|
242
|
+
$ rdbg --attach
|
|
243
|
+
# Now you have a full debugger REPL
|
|
244
|
+
(rdbg) info locals
|
|
245
|
+
(rdbg) break MyApp#handle_key
|
|
246
|
+
(rdbg) continue
|
|
247
|
+
```
|
|
248
|
+
<!-- SPDX-SnippetEnd -->
|
|
249
|
+
|
|
250
|
+
### Requirements
|
|
251
|
+
|
|
252
|
+
Add the `debug` gem to your Gemfile:
|
|
253
|
+
|
|
254
|
+
<!-- SPDX-SnippetBegin -->
|
|
255
|
+
<!--
|
|
256
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
257
|
+
SPDX-License-Identifier: MIT-0
|
|
258
|
+
-->
|
|
259
|
+
```ruby
|
|
260
|
+
gem "debug", ">= 1.0"
|
|
261
|
+
```
|
|
262
|
+
<!-- SPDX-SnippetEnd -->
|
|
263
|
+
|
|
264
|
+
If `RR_DEBUG=1` is set but the debug gem is missing, RatatuiRuby raises a `LoadError` with installation instructions.
|
|
265
|
+
|
|
266
|
+
## File Logging
|
|
267
|
+
|
|
268
|
+
You can write debug output to a log file instead of stdout.
|
|
269
|
+
|
|
270
|
+
### Basic Logging
|
|
271
|
+
|
|
272
|
+
<!-- SPDX-SnippetBegin -->
|
|
273
|
+
<!--
|
|
274
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
275
|
+
SPDX-License-Identifier: MIT-0
|
|
276
|
+
-->
|
|
277
|
+
```ruby
|
|
278
|
+
DEBUG_LOG = File.open("debug.log", "a")
|
|
279
|
+
|
|
280
|
+
def debug(msg)
|
|
281
|
+
DEBUG_LOG.puts("[#{Time.now}] #{msg}")
|
|
282
|
+
DEBUG_LOG.flush
|
|
283
|
+
end
|
|
284
|
+
```
|
|
285
|
+
<!-- SPDX-SnippetEnd -->
|
|
286
|
+
|
|
287
|
+
Then tail the log in a separate terminal.
|
|
288
|
+
|
|
289
|
+
<!-- SPDX-SnippetBegin -->
|
|
290
|
+
<!--
|
|
291
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
292
|
+
SPDX-License-Identifier: MIT-0
|
|
293
|
+
-->
|
|
294
|
+
```bash
|
|
295
|
+
tail -f debug.log
|
|
296
|
+
```
|
|
297
|
+
<!-- SPDX-SnippetEnd -->
|
|
298
|
+
|
|
299
|
+
### Timestamped Logging
|
|
300
|
+
|
|
301
|
+
For high-frequency logging (like inside a render loop), use timestamped files to avoid overwrites:
|
|
302
|
+
|
|
303
|
+
<!-- SPDX-SnippetBegin -->
|
|
304
|
+
<!--
|
|
305
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
306
|
+
SPDX-License-Identifier: MIT-0
|
|
307
|
+
-->
|
|
308
|
+
```ruby
|
|
309
|
+
FileUtils.mkdir_p(File.join(Dir.tmpdir, "my_debug"))
|
|
310
|
+
timestamp = Time.now.strftime('%Y%m%d_%H%M%S_%N')
|
|
311
|
+
File.write(
|
|
312
|
+
File.join(Dir.tmpdir, "my_debug", "#{timestamp}.log"),
|
|
313
|
+
"variable=#{value.inspect}\n"
|
|
314
|
+
)
|
|
315
|
+
```
|
|
316
|
+
<!-- SPDX-SnippetEnd -->
|
|
317
|
+
|
|
318
|
+
Then tail the directory.
|
|
319
|
+
|
|
320
|
+
<!-- SPDX-SnippetBegin -->
|
|
321
|
+
<!--
|
|
322
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
323
|
+
SPDX-License-Identifier: MIT-0
|
|
324
|
+
-->
|
|
325
|
+
```bash
|
|
326
|
+
watch -n 0.5 'ls -la /tmp/my_debug/ && cat /tmp/my_debug/*.log'
|
|
327
|
+
```
|
|
328
|
+
<!-- SPDX-SnippetEnd -->
|
|
329
|
+
|
|
330
|
+
## REPL Without the TUI
|
|
331
|
+
|
|
332
|
+
Unit tests verify correctness, but sometimes you want to poke at objects interactively. Wrap your main execution in a guard:
|
|
333
|
+
|
|
334
|
+
<!-- SPDX-SnippetBegin -->
|
|
335
|
+
<!--
|
|
336
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
337
|
+
SPDX-License-Identifier: MIT-0
|
|
338
|
+
-->
|
|
339
|
+
```ruby
|
|
340
|
+
if __FILE__ == $PROGRAM_NAME
|
|
341
|
+
MyApp.new.run
|
|
342
|
+
end
|
|
343
|
+
```
|
|
344
|
+
<!-- SPDX-SnippetEnd -->
|
|
345
|
+
|
|
346
|
+
Then load the file without entering raw mode.
|
|
347
|
+
|
|
348
|
+
<!-- SPDX-SnippetBegin -->
|
|
349
|
+
<!--
|
|
350
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
351
|
+
SPDX-License-Identifier: MIT-0
|
|
352
|
+
-->
|
|
353
|
+
```bash
|
|
354
|
+
ruby -e 'load "./bin/my_tui"; obj = MyClass.new; puts obj.result'
|
|
355
|
+
```
|
|
356
|
+
<!-- SPDX-SnippetEnd -->
|
|
357
|
+
|
|
358
|
+
This exercises domain logic without the terminal conflict. Use it for exploration. Write tests with [TestHelper](application_testing.md) for regression coverage.
|
|
359
|
+
|
|
360
|
+
## Isolating Terminal Issues
|
|
361
|
+
|
|
362
|
+
Sometimes code works in a `ruby -e` script but fails in the TUI. Here are common causes.
|
|
363
|
+
|
|
364
|
+
1. **Thread context.** Ruby threads share the process's terminal state.
|
|
365
|
+
2. **Raw mode.** External commands fail when stdin/stdout are reconfigured.
|
|
366
|
+
3. **SSH/Git auth.** Commands that prompt for credentials hang or return empty.
|
|
367
|
+
|
|
368
|
+
See [Async Operations](./async.md) for solutions.
|
|
369
|
+
|
|
370
|
+
## Error Classes
|
|
371
|
+
|
|
372
|
+
RatatuiRuby has semantic exception classes for different failure modes:
|
|
373
|
+
|
|
374
|
+
| Class | Meaning |
|
|
375
|
+
|-------|---------|
|
|
376
|
+
| `RatatuiRuby::Error::Terminal` | I/O failure (backend crashed, terminal unavailable) |
|
|
377
|
+
| `RatatuiRuby::Error::Safety` | Lifetime violation (using Frame after draw block exits) |
|
|
378
|
+
| `RatatuiRuby::Error::Invariant` | Contract violation (double init, headless mode conflict) |
|
|
379
|
+
|
|
380
|
+
Catch these specifically instead of rescuing `StandardError` broadly.
|
|
381
|
+
|
|
382
|
+
<!-- SPDX-SnippetBegin -->
|
|
383
|
+
<!--
|
|
384
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
385
|
+
SPDX-License-Identifier: MIT-0
|
|
386
|
+
-->
|
|
387
|
+
```ruby
|
|
388
|
+
begin
|
|
389
|
+
RatatuiRuby.run { |tui| ... }
|
|
390
|
+
rescue RatatuiRuby::Error::Terminal => e
|
|
391
|
+
puts "Terminal I/O failed: #{e.message}"
|
|
392
|
+
rescue RatatuiRuby::Error::Safety => e
|
|
393
|
+
puts "API misuse: #{e.message}"
|
|
394
|
+
end
|
|
395
|
+
```
|
|
396
|
+
<!-- SPDX-SnippetEnd -->
|
|
397
|
+
|
|
398
|
+
## Further Reading
|
|
399
|
+
|
|
400
|
+
- [Application Testing Guide](application_testing.md) — Test helpers, snapshots, event injection
|
|
401
|
+
- [RatatuiRuby::Debug](../../lib/ratatui_ruby/debug.rb) — Debug module source
|
|
@@ -258,20 +258,25 @@ These larger examples combine widgets into complete applications, demonstrating
|
|
|
258
258
|
|-------------|--------------|-------------------|
|
|
259
259
|
| [All Events](../examples/app_all_events/app.rb) | Model-View-Update | Event handling, unidirectional data flow, scalable structure |
|
|
260
260
|
| [Color Picker](../examples/app_color_picker/app.rb) | Component-Based | Hit testing, modal dialogs, encapsulated state |
|
|
261
|
+
| [Debugging Showcase](../examples/app_debugging_showcase/app.rb) | Simple Loop | Remote debugging, Rust backtraces, improved error messages |
|
|
261
262
|
| [Login Form](../examples/app_login_form/app.rb) | Overlay + Center | Modal forms, cursor positioning, text input |
|
|
262
263
|
| [Stateful Interaction](../examples/app_stateful_interaction/app.rb) | State Objects | ListState/TableState, offset read-back, mouse click-to-row |
|
|
263
264
|
|
|
264
265
|
#### All Events
|
|
265
266
|
|
|
266
|
-
[](../examples/app_all_events/README.md)
|
|
267
268
|
|
|
268
269
|
#### Color Picker
|
|
269
270
|
|
|
270
|
-
[](../examples/app_color_picker/README.md)
|
|
272
|
+
|
|
273
|
+
#### Debugging Showcase
|
|
274
|
+
|
|
275
|
+
[](../examples/app_debugging_showcase/README.md)
|
|
271
276
|
|
|
272
277
|
#### Login Form
|
|
273
278
|
|
|
274
|
-
[](../examples/app_login_form/README.md)
|
|
275
280
|
|
|
276
281
|
|
|
277
282
|
## Next Steps
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/doc/images/widget_block.png
CHANGED
|
Binary file
|
data/doc/images/widget_box.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/doc/images/widget_cell.png
CHANGED
|
Binary file
|
|
Binary file
|
data/doc/images/widget_chart.png
CHANGED
|
Binary file
|
data/doc/images/widget_gauge.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/doc/images/widget_list.png
CHANGED
|
Binary file
|
data/doc/images/widget_map.png
CHANGED
|
Binary file
|
|
Binary file
|
data/doc/images/widget_popup.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/doc/images/widget_rect.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/doc/images/widget_table.png
CHANGED
|
Binary file
|
data/doc/images/widget_tabs.png
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Debugging Showcase
|
|
7
|
+
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
10
|
+
Interactive demonstration of RatatuiRuby's debugging features.
|
|
11
|
+
|
|
12
|
+
For comprehensive documentation, see the [Debugging Guide](../../doc/concepts/debugging.md).
|
|
13
|
+
|
|
14
|
+
## What This Example Does
|
|
15
|
+
|
|
16
|
+
This app lets you trigger each debugging feature with a hotkey. Test your setup before encountering a real bug.
|
|
17
|
+
|
|
18
|
+
| Key | Action |
|
|
19
|
+
|-----|--------|
|
|
20
|
+
| `d` | Enable `debug_mode!` programmatically |
|
|
21
|
+
| `p` | Trigger a Rust panic |
|
|
22
|
+
| `t` | Trigger a Rust `TypeError` |
|
|
23
|
+
| `b` | Refresh debug status |
|
|
24
|
+
| `q` | Quit |
|
|
25
|
+
|
|
26
|
+
## Library Features Showcased
|
|
27
|
+
|
|
28
|
+
Reading this code will teach you how to:
|
|
29
|
+
|
|
30
|
+
* **Enable Remote Debugging**: Call `RatatuiRuby.debug_mode!` and receive the socket path
|
|
31
|
+
* **Detect Debug State**: Query `Debug.enabled?`, `Debug.rust_backtrace_enabled?`, and `Debug.remote_debugging_mode`
|
|
32
|
+
* **Trigger Test Panics**: Use `Debug.test_panic!` to verify Rust backtrace visibility
|
|
33
|
+
* **See Improved Error Messages**: Bypass DWIM coercion to see `TypeError` messages with value context
|
|
34
|
+
|
|
35
|
+
**Note:** Rust backtraces only appear for panics (`[p]`). Exceptions (`[t]`) show Ruby backtraces with improved error messages from Rust.
|
|
36
|
+
|
|
37
|
+
## Environment Variables
|
|
38
|
+
|
|
39
|
+
The example behaves differently depending on which environment variables you set.
|
|
40
|
+
|
|
41
|
+
### No Environment Variables
|
|
42
|
+
|
|
43
|
+
<!-- SPDX-SnippetBegin -->
|
|
44
|
+
<!--
|
|
45
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
46
|
+
SPDX-License-Identifier: MIT-0
|
|
47
|
+
-->
|
|
48
|
+
```bash
|
|
49
|
+
ruby examples/app_debugging_showcase/app.rb
|
|
50
|
+
```
|
|
51
|
+
<!-- SPDX-SnippetEnd -->
|
|
52
|
+
|
|
53
|
+
The TUI starts normally. Rust backtraces are disabled. Press `[d]` to enable remote debugging mid-session.
|
|
54
|
+
|
|
55
|
+
### `RUST_BACKTRACE=1`
|
|
56
|
+
|
|
57
|
+
<!-- SPDX-SnippetBegin -->
|
|
58
|
+
<!--
|
|
59
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
60
|
+
SPDX-License-Identifier: MIT-0
|
|
61
|
+
-->
|
|
62
|
+
```bash
|
|
63
|
+
RUST_BACKTRACE=1 ruby examples/app_debugging_showcase/app.rb
|
|
64
|
+
```
|
|
65
|
+
<!-- SPDX-SnippetEnd -->
|
|
66
|
+
|
|
67
|
+
Enables Rust backtraces. Press `[p]` to see the full Rust stack trace with file names and line numbers.
|
|
68
|
+
|
|
69
|
+
### `RR_DEBUG=1`
|
|
70
|
+
|
|
71
|
+
<!-- SPDX-SnippetBegin -->
|
|
72
|
+
<!--
|
|
73
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
74
|
+
SPDX-License-Identifier: MIT-0
|
|
75
|
+
-->
|
|
76
|
+
```bash
|
|
77
|
+
RR_DEBUG=1 ruby examples/app_debugging_showcase/app.rb
|
|
78
|
+
```
|
|
79
|
+
<!-- SPDX-SnippetEnd -->
|
|
80
|
+
|
|
81
|
+
Full debug mode at startup. The debugger opens a socket and **waits for a connection** before the TUI starts. You'll see the socket path printed before the app runs.
|
|
82
|
+
|
|
83
|
+
In another terminal:
|
|
84
|
+
|
|
85
|
+
<!-- SPDX-SnippetBegin -->
|
|
86
|
+
<!--
|
|
87
|
+
SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
88
|
+
SPDX-License-Identifier: MIT-0
|
|
89
|
+
-->
|
|
90
|
+
```bash
|
|
91
|
+
rdbg --attach
|
|
92
|
+
```
|
|
93
|
+
<!-- SPDX-SnippetEnd -->
|
|
94
|
+
|
|
95
|
+
When you attach, you'll see "Stop by SIGURG" — that's normal! SIGURG is how the debug gem signals the app to pause. Type `continue` to resume.
|
|
96
|
+
|
|
97
|
+
This uses the [ruby/debug](https://github.com/ruby/debug?tab=readme-ov-file#readme) gem for remote debugging.
|
|
98
|
+
|
|
99
|
+
### When to Use Which
|
|
100
|
+
|
|
101
|
+
`RR_DEBUG=1` includes Rust backtraces automatically (it calls `enable_rust_backtrace!` internally).
|
|
102
|
+
|
|
103
|
+
Use `RUST_BACKTRACE=1` alone when you want backtraces but **don't** want the debugger to stop and wait for a connection at startup.
|
|
104
|
+
|
|
105
|
+
## What Problems Does This Solve?
|
|
106
|
+
|
|
107
|
+
### "Is my Rust backtrace setup working?"
|
|
108
|
+
|
|
109
|
+
Press `[p]`. If you see a stack trace with file names and line numbers, you're good. If not, you need `RUST_BACKTRACE=1`.
|
|
110
|
+
|
|
111
|
+
### "How do I attach a debugger to a TUI?"
|
|
112
|
+
|
|
113
|
+
TUIs run in raw mode — you can't type into a REPL. Press `[d]` to enable remote debugging. The socket path appears in the UI. Run `rdbg --attach` from another terminal.
|
|
114
|
+
|
|
115
|
+
### "What does a Rust TypeError look like?"
|
|
116
|
+
|
|
117
|
+
Press `[t]`. The error message shows the expected type and the actual value you passed (e.g., `expected array for rows, got 42`). Note: This shows Ruby's backtrace — only panics (`[p]`) show Rust backtraces.
|
|
118
|
+
|
|
119
|
+
[Read the source code →](app.rb)
|