Make the terminal usable: control keys, paste, scroll, restart, terminate
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1556b87f37
commit
d76da3babb
@@ -38,8 +38,9 @@ pub(crate) struct ThemeColors {
|
||||
pub(crate) success: Rgba,
|
||||
/// No surface reports failure in colour yet; a dead pane is described in
|
||||
/// words. Defined here so the role exists when one does.
|
||||
#[expect(dead_code, reason = "no failure surface paints yet")]
|
||||
pub(crate) danger: Rgba,
|
||||
/// A danger fill quiet enough to sit behind text.
|
||||
pub(crate) danger_container: Rgba,
|
||||
pub(crate) attention: Rgba,
|
||||
/// The needs-input row tint, which arrives with the sidebar rework.
|
||||
#[expect(dead_code, reason = "the attention row is rebuilt with the sidebar")]
|
||||
@@ -75,6 +76,7 @@ impl From<&Palette> for ThemeColors {
|
||||
accent: rgba(palette.accent),
|
||||
success: rgba(palette.success),
|
||||
danger: rgba(palette.danger),
|
||||
danger_container: rgba(palette.danger_container),
|
||||
attention: rgba(palette.attention),
|
||||
attention_wash: rgba(palette.attention_wash),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user