docs(parity): tighten the rawMode Ctrl+C wording (lead with echo; note exitOnCtrlC default) (#121)

The rawMode 'always' divergence entry overstated the Ctrl+C benefit — it framed
"reaching the app's interrupt handler" as the headline, which only applies under
the non-default `exitOnCtrlC: false`. Both Ink and vue-tui default exitOnCtrlC to
true, so by default Ctrl+C exits either way; the lazy-vs-always difference there is
only the exit path/code (graceful 0 vs re-raised SIGINT 130). Reword to lead with
the real default consequence (echo into the frame on no-input screens) and state
the Ctrl+C difference accurately, noting it only bites an app that sets
exitOnCtrlC:false. No behavior change.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-06-01 17:11:53 +08:00
committed by GitHub
parent 2372b6b03b
commit 27307910a2
+14 -10
View File
@@ -92,16 +92,20 @@ deliberate. Divergences fall into a few kinds:
'auto'` opts back into Ink's exact lazy behavior. 'auto'` opts back into Ink's exact lazy behavior.
- **Why:** for a long-running interactive app (a full-screen TUI, a coding agent), - **Why:** for a long-running interactive app (a full-screen TUI, a coding agent),
Ink's lazy model makes raw mode **oscillate** as the user moves between input and Ink's lazy model makes raw mode **oscillate** as the user moves between input and
no-input screens, with two real consequences: (1) keystrokes echo into a no-input screens. The main consequence is **echo**: on a no-input / streaming
half-drawn frame on a no-input / streaming screen; (2) Ctrl+C flips meaning — on a screen the terminal is back in cooked mode, so typed keys echo into the
no-input screen raw is off, so Ctrl+C becomes a kernel SIGINT and (e.g.) kills an half-drawn frame (and line-buffer). Ctrl+C also changes path — on a no-input
agent mid-generation instead of reaching the app's "interrupt this generation" screen it is a kernel SIGINT rather than the app's own `\x03` intercept. Note
handler. Holding raw for the lifetime makes Ctrl+C and keystroke handling `exitOnCtrlC` defaults to `true` in both Ink and vue-tui, so by default Ctrl+C
identical on every screen and removes the echo. This matches the cross-framework exits either way; the divergence is only the exit path/code (a graceful exit `0`
norm — Bubble Tea, Textual, Ratatui, and prompt_toolkit all own the terminal for vs a re-raised SIGINT `130`). It matters for an app that sets `exitOnCtrlC:
the program lifetime; Ink's hook-driven model is the outlier (its "cooked on a false` to handle Ctrl+C itself: under the lazy model its opt-out is silently
no-input screen" is an emergent side-effect of refcounting input hooks, not a bypassed on a no-input screen (the SIGINT still exits). Holding raw for the
relied-upon feature). lifetime keeps echo and Ctrl+C handling identical on every screen. This matches
the cross-framework norm — Bubble Tea, Textual, Ratatui, and prompt_toolkit all
own the terminal for the program lifetime; Ink's hook-driven model is the outlier
(its "cooked on a no-input screen" is an emergent side-effect of refcounting
input hooks, not a relied-upon feature).
- **Consequence:** owning raw mode `ref()`s stdin, so an `'always'` app stays alive - **Consequence:** owning raw mode `ref()`s stdin, so an `'always'` app stays alive
until you explicitly `unmount()` / `exit()` — it does **not** auto-exit when idle until you explicitly `unmount()` / `exit()` — it does **not** auto-exit when idle
(the same way an Ink app holding a `useInput` already doesn't). The "render and (the same way an Ink app holding a `useInput` already doesn't). The "render and