Skip to content

feat(input): negotiate keyboard enhancement protocol when supported#124

Open
laurigates wants to merge 1 commit into
ynqa:mainfrom
laurigates:feat/keyboard-enhancement-protocol
Open

feat(input): negotiate keyboard enhancement protocol when supported#124
laurigates wants to merge 1 commit into
ynqa:mainfrom
laurigates:feat/keyboard-enhancement-protocol

Conversation

@laurigates

Copy link
Copy Markdown

What

Negotiate the keyboard enhancement ("kitty") protocol at startup when the
terminal advertises support, and pop it on teardown.

jnv enables raw mode but never requests the protocol, so supporting terminals
fall back to legacy encoding. In legacy mode Ctrl+J is indistinguishable from
Enter (both 0x0A) and Ctrl+I from Tab, so the JSON viewer's default
down = ["Down", "Ctrl+J", "ScrollDown"] binding can never fire via Ctrl+J
(it lands on Enter/toggle instead), and modified/bracket keys are reported
inconsistently across terminals.

How

  • main.rs: when supports_keyboard_enhancement() reports support, push
    KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES; TerminalCleanupGuard
    pops it on drop. Terminals without support keep the exact prior behavior.
  • event_dispatcher.rs: keybinds are matched by exact Event equality, so
    enabling the protocol requires canonicalizing incoming events. Added a pure
    normalize_event helper at the single event-dispatch chokepoint (covers every
    downstream matcher) that drops non-Press events (releases/repeats become
    possible under the protocol) and strips KeyEventState lock bits (Caps/Num
    Lock) so a binding matches regardless of lock state. The existing scroll
    position-zeroing moved into the same helper. Unit-tested.

Deliberately requests only DISAMBIGUATE_ESCAPE_CODES — not
REPORT_EVENT_TYPES/REPORT_ALL_KEYS — to keep the event stream close to legacy
(no release-event noise) while fixing the ambiguous-control-key class.

Verification

cargo fmt --all -- --check, cargo clippy, and cargo test all pass.
Manually verified on kitty (macOS): Ctrl+J/Ctrl+K now scroll the JSON viewer
as bound; bracket entry on a Finnish layout is unaffected.

Notes / open questions

This is offered as "here's what made jnv work better for me on kitty" — happy to
adjust or drop it if it doesn't fit the roadmap.

  • I have not tested behavior under a terminal multiplexer (tmux/screen),
    where supports_keyboard_enhancement() and protocol passthrough are
    historically finicky. If you have tmux users, that path may warrant a look.
  • Enabling the protocol is a behavior change on all enhancement-capable
    terminals (Ctrl+JEnter, Ctrl+ITab). That's the intended fix, but
    flagging it explicitly.
  • The normalize_event approach keeps the existing exact-Event matching; if
    you'd prefer a different matching strategy, glad to rework.

jnv enabled raw mode but never requested the keyboard enhancement
(kitty) protocol, so terminals fell back to legacy encoding. There,
Ctrl+J is indistinguishable from Enter (both 0x0A) and Ctrl+I from Tab,
so bindings like the JSON viewer's `down = Ctrl+J` could never fire, and
modified/bracket keys were reported inconsistently.

Push `DISAMBIGUATE_ESCAPE_CODES` at startup when
`supports_keyboard_enhancement()` reports support, and pop it on
teardown. Terminals without support keep the prior legacy behavior.

Because keybinds are matched by exact `Event` equality, enabling the
protocol requires canonicalizing incoming events: drop non-`Press`
kinds (releases/repeats become possible under the protocol) and strip
`KeyEventState` lock bits (Caps/Num Lock) so a binding matches
regardless of lock state. This is done once at the event-dispatch
chokepoint via a pure `normalize_event` helper, covering every
downstream matcher, with unit tests.
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