fix(cli): Super+<printable> under modifyOtherKeys types the character
Ghostty encodes Super+o as ESC[27;9;111~ (Super+Shift as modifier 10) once modifyOtherKeys=2 is pushed; the CLI has no Super bindings, so the sequence leaked as literal escape text (#114242). Map the tilde form for modifiers 9 and 10 over the printable range to chr(cp), the same produced-codepoint rule the Shift rows use and what the Ink TUI already does.
This commit is contained in:
@@ -252,8 +252,12 @@ def _modify_other_keys_aliases(ANSI_SEQUENCES: dict, Keys) -> dict[str, object]:
|
||||
# Existing entries (Shift+Enter \x1b[27;2;13~, Shift+Tab, Shift+Space) win via setdefault.
|
||||
# xterm/Ghostty only use this encoding for produced codepoints 0x40-0x7E (`IsControlInput`);
|
||||
# '!' '#' '$' still arrive as plain text, so the 33-63 rows are inert there but harmless.
|
||||
# Super+<printable> (modifier 9, Super+Shift 10) follows the same produced-codepoint rule:
|
||||
# Ghostty sends Super+o as ESC[27;9;111~ (#114242). The CLI has no Super bindings, so type
|
||||
# the character — what the terminal sends without modifyOtherKeys and what the Ink TUI does.
|
||||
for cp in range(33, 127):
|
||||
_put(f"\x1b[27;2;{cp}~", chr(cp))
|
||||
for modifier in (2, 9, 10):
|
||||
_put(f"\x1b[27;{modifier};{cp}~", chr(cp))
|
||||
|
||||
# The Esc KEY under Kitty disambiguate mode: ESC[27u (+ modifiers 1-16 incl. super 9+, and
|
||||
# lock twins of the modifier-less form, which is how a lone Esc arrives with a lock on).
|
||||
|
||||
@@ -287,6 +287,17 @@ def test_modify_other_keys_shift_symbol_produces_char(cp):
|
||||
assert ANSI_SEQUENCES.get(f"\x1b[{cp};2u") is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("seq, ch", [
|
||||
("\x1b[27;9;111~", "o"), # Super+o (the #114242 report)
|
||||
("\x1b[27;10;79~", "O"), # Super+Shift+o
|
||||
])
|
||||
def test_modify_other_keys_super_printable_produces_char(seq, ch):
|
||||
"""Ghostty encodes Super+<printable> as ESC[27;9;<cp>~ under modifyOtherKeys=2;
|
||||
the CLI has no Super bindings, so it must type the character (Ink TUI parity),
|
||||
not leak the escape text (#114242)."""
|
||||
assert _parse(seq) == [ch]
|
||||
|
||||
|
||||
def test_shift_symbol_data_normalized_in_buffer():
|
||||
"""End-to-end: Vt100Parser with install_keypress_data_normalization
|
||||
must deliver the character in KeyPress.data, not the raw escape."""
|
||||
|
||||
Reference in New Issue
Block a user