The largest defect was not the one the plan named. Every control character was
being dropped before it reached the PTY — ctrl-c, ctrl-d, ctrl-a, ctrl-r, not
just ctrl-k — because terminal_key_from_parts required a key_char and GPUI
reports none for a control chord, since ctrl-k produces no printable character.
Verified with `cat -v`, which now prints ^K^A^R; ctrl-c interrupts a sleep and
ctrl-d ends a heredoc. The engine had always encoded these correctly; nothing
ever handed them to it.
The binding shadowing was real too. OpenPalette was on secondary-k, which is
ctrl-k on Linux, and GPUI stops dispatching once a binding claims an event, so
readline's kill-line was unreachable in every pane. Pane selection sat on
alt-1..6, which readline reads as a digit argument, and focus movement on
alt-arrows, which is word motion in most terminals.
Bindings now live in keymap.rs with the rule written down and tested: no binding
may be a bare control character or a bare Meta sequence, because those are what
a terminal application actually receives. A leader chord was considered and
rejected — GPUI parks a chord prefix for a second and drops it if focus moves.
Also in this pass:
- Paste on secondary-shift-v, through the engine's bracketed-paste path so a
shell that asked for bracketed paste is told this is a paste. secondary-v
would have been ctrl-v, which readline reads as quoted-insert. There is no
matching copy: the engine has no selection yet, and a key that copied the
whole screen would not be the same feature under the same name.
- A scroll wheel on the terminal surface. Shift+PageUp was the only route to
scrollback, which is not something anyone guesses.
- Restart and Terminate. RuntimeRegistry::shutdown existed and was called only
from its own crate's tests, so nothing in the application could ever stop a
PTY. Terminate is the literal words with a confirmation naming the pid, per
decision 0010, never a close icon; restart keeps the pane and replaces the
process, per decision 0011.
- A dead or faulted pane now says so over its stale screen instead of looking
idle, and typing into a pane with no terminal explains where the keystroke
went instead of silently discarding it.
- The twelve reachable .expect panics on live-terminal state are gone. A pane
can outlive its runtime — failed spawn, terminate, restored snapshot — and
every one of those paths used to be a panic in the middle of a paint.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>