fix(cli): key combos survive NumLock/CapsLock under kitty CSI-u (salvage #89676 + #90291) - #90561
Merged
kshitijk4poor merged 4 commits intoAug 20, 2026
Merged
Conversation
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 05:56
kshitijk4poor
disabled auto-merge
August 20, 2026 06:00
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 06:19
auto-merge was automatically disabled
August 20, 2026 06:23
Pull Request is not mergeable
…Lock kitty and ghostty OR the CapsLock (64) / NumLock (128) state into the CSI-u modifier parameter. With NumLock on, Ctrl+C arrives as ESC[99;133u (5 + 128) instead of ESC[99;5u; the alias table had no entry for it, so every key combo leaked as literal text like [127;133u (NousResearch#89651). Install every CSI-u alias with the lock-bit variants (+64/+128/+192); the xterm modifyOtherKeys encoding never carries lock bits, so the ESC[27;N;CP~ form is left untouched. The Esc-key registration now covers modifier 1 as well (1+128=129 is a lone Esc with NumLock on).
…ocol With the kitty keyboard protocol push active (CSI >1u disambiguate), kitty encodes lock-key state into the CSI modifier field of function keys: a plain Down with NumLock on arrives as ESC[1;129B (NumLock), ESC[1;65B (CapsLock), or ESC[1;193B (both) instead of the legacy ESC[B. Stock prompt_toolkit maps none of these, so the parser fires Escape and inserts the remainder as literal text in the input line. 03bf85d restored the kitty push and completed the extended-key alias table but left these lock-bit variants unmapped, so kitty + NumLock still leaks [1;129A/B for arrow/nav keys. Map modifier 129/65/193 (plain) and 130/66/194 (+shift) for arrows, Home/End, Insert/Delete/PageUp/PageDown, and CSI-u Enter/Tab/Backspace/ Space to their plain keys.
…s, and PUA functional keys Follow-up to the salvaged NousResearch#89676 + NousResearch#90291 lock-bit fixes: extract a shared _lock_variants() helper and cover the sites both PRs missed - install_shift_enter_alias / install_ctrl_enter_alias / install_cmd_backspace_alias CSI-u spellings, legacy CSI-letter and CSI-tilde navigation twins derived from the existing table for ALL modifiers 1-16 (not just plain/shift), plain F1-F4 SS3 fallback, unmodified CSI-u keys (Tab/Enter/Space/Backspace), and kitty PUA functional keys (keypad, F13-F24, Ignore range) under lock bits. 8 new tests.
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 06:26
auto-merge was automatically disabled
August 20, 2026 06:30
Pull Request is not mergeable
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 06:33
auto-merge was automatically disabled
August 20, 2026 06:37
Pull Request is not mergeable
… forms, _lock_twins idiom Post-review cleanup on the salvage: update the three alias-installer docstrings to mention lock twins (and fix ctrl-enter's stale 'stock maps none of these' claim - stock maps the tilde form to plain ControlM, which the overwrite fixes); skip the never-emitted modifier-1 tilde forms in _install_paired; name the twins-only idiom as _lock_twins() and use it at the legacy-nav + PUA sites; route the Esc loop through _lock_variants; hoist the per-base table lookup out of the lock loop in the legacy-nav section.
kshitijk4poor
force-pushed
the
salvage/kitty-lock-bits
branch
from
August 20, 2026 06:40
6f8f131 to
79ef6ab
Compare
kshitijk4poor
enabled auto-merge (rebase)
August 20, 2026 06:40
This was referenced Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Key combos no longer die (leak as literal text like
[99;133u) when NumLock or CapsLock is on under the kitty keyboard protocol. Closes #88221, closes #89651.kitty/ghostty OR lock-key state into the modifier parameter of every key event while a lock is on (CapsLock=+64, NumLock=+128, both=+192), so
Ctrl+Carrives asESC[99;133uinstead ofESC[99;5uand plainDownasESC[1;129Binstead ofESC[B. None of those variants were inANSI_SEQUENCES, so with a lock enabled every combo — and on keypads every plain nav key — broke.Composite salvage of the two strongest PRs in the 4-PR cluster, with authorship preserved via cherry-pick:
_install_paired+ the Esc-key family, with the correct producer-contract insight that the xterm modifyOtherKeysESC[27;N;CP~form never carries lock bits (so it gets no twins), plus a strong test suite.ESC[1;129Barrows,ESC[3;129~Delete, …) that every CSI-u-focused PR missed.Changes
hermes_cli/pt_input_extras.py:_lock_variants()helper; both cherry-picks and all follow-up sites use itinstall_shift_enter_alias/install_ctrl_enter_alias/install_cmd_backspace_alias: CSI-u spellings get lock twins (Shift+Enter with NumLock =ESC[13;130upreviously fell through)tests/cli/test_modify_other_keys_aliases.py: contributors' tests + 8 follow-up tests for the widened surfacecontributors/emails/: mapping for @grahfmusicValidation
Ctrl+C+ NumLock (ESC[99;133u)Keys.ControlCDown+ NumLock (ESC[1;129B)Keys.DownShift+Enter+ NumLock (ESC[13;130u)Cmd+Backspace+ NumLock (ESC[127;137u)ESC[57399;129u)"0"tests/cli/test_modify_other_keys_aliases.py, 216+2s acrosstests/cli/Vt100Parser: 8-sequence locked stream parses with zero CSI leaksorigin/mainon 14 non-lock sequences: identicalCredit