Skip to content

fix(ui): recognize encoded arrows so C-a Up/Down/Left/Right works again#56

Merged
kylecarbs merged 1 commit into
mainfrom
fix/ui-prefixed-arrows-encoded
Jun 13, 2026
Merged

fix(ui): recognize encoded arrows so C-a Up/Down/Left/Right works again#56
kylecarbs merged 1 commit into
mainfrom
fix/ui-prefixed-arrows-encoded

Conversation

@kylecarbs

Copy link
Copy Markdown
Member

Problem

After v0.5.16, pressing C-a then an arrow key no longer browses the sidebar (C-a Up/Down) or resizes it (C-a Left/Right) when a kitty-protocol app is focused.

Root cause

v0.5.16 mirrors the focused app's keyboard protocols onto the real terminal. When the app enables report event types (kitty flag 2, which Claude Code and most modern TUIs set), the terminal then encodes even an unmodified arrow press in the functional form ESC [ 1;1:1 A instead of the legacy ESC [ A (confirmed against ghostty's own encodeSpecial: any sequence with an event type emits \x1b[1;{mods}:{event}{ABCD}).

The UI input parser only recognized the bare ESC [ A form, so after the C-a prefix the encoded arrow diverged from the hold grammar and was flushed to the session — no browse/resize. Before v0.5.16 the terminal stayed in legacy mode, so arrows were ESC [ A and it worked.

Fix

  • The parser now accepts the functional cursor-key grammar ESC [ 1 ; mods [: event] A/B/C/D (its hold grammar accepts AD after a digit body).
  • An unmodified press or repeat becomes an arrow event (drives browse/resize). A modified arrow (e.g. Ctrl+Left word motion) or a release event is the application's input and is forwarded verbatim, never intercepted.
  • Arrow events now carry their original bytes; arrows forwarded to the focused app keep the exact encoding the terminal produced rather than a downgraded legacy arrow.

Testing

  • 3 new parser unit tests: functional press/repeat navigate (prefixed and bare), original-byte forwarding, modified/release passthrough.
  • 1 new PTY integration test: a kitty app focused, C-a + report-events Down arms sidebar browse without leaking into the session.
  • zig build test-all (116 unit + 67 integration) passes, integration re-run 3x for flakes; zig fmt --check clean.
Notes
  • SS3 cursor keys (ESC O A, application-cursor-keys mode) are intentionally not handled: boo ui never puts the real terminal into DECCKM, so that encoding cannot occur there. boo at forwards arrows to the app verbatim and is unaffected.
  • Modified arrows and releases reaching the app verbatim preserves Ctrl+arrow word motion and report-events press/release pairing.

This PR was generated by Coder Agents on behalf of @kylecarbs.

v0.5.16 began mirroring the focused app's keyboard protocols onto the
real terminal. When the app reports event types (kitty flag 2, set by
Claude Code and most modern TUIs), the terminal then encodes even an
unmodified arrow press as the functional form ESC [ 1;1:1 A rather
than the legacy ESC [ A. The UI input parser only recognized the bare
form, so after the C-a prefix the encoded arrow was flushed to the
session instead of driving sidebar browse (C-a Up/Down) or resize
(C-a Left/Right).

The parser now accepts the functional cursor-key grammar
(ESC [ 1 ; mods [: event] A/B/C/D). An unmodified press or repeat
becomes an arrow event (browse/resize); a modified arrow (Ctrl+Left
word motion) or a release event is the application's input and is
forwarded verbatim. Arrow events now carry their original bytes, so
arrows forwarded to the focused app keep the exact encoding the
terminal produced instead of a downgraded legacy arrow.

Tests: 3 parser unit tests (functional press/repeat navigate,
original-byte forwarding, modified/release passthrough) and a PTY
integration test driving C-a + report-events Down to browse without
leaking into the session.
@kylecarbs kylecarbs merged commit 788ca95 into main Jun 13, 2026
5 checks passed
@kylecarbs kylecarbs mentioned this pull request Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant