fix(tui): distinguish ctrl+backspace from backspace on Windows Terminal

0x08 (BS) was treated as plain backspace alongside 0x7f (DEL). On
Windows Terminal, Backspace sends 0x7f and Ctrl+Backspace sends 0x08,
making ctrl+backspace bindings unreachable.

Now 0x08 matches ctrl+backspace (and ctrl+h, same byte) but not plain
backspace. 0x7f remains plain backspace.

fixes #2139
This commit is contained in:
Mario Zechner
2026-03-14 03:58:28 +01:00
parent 5c9ce47c53
commit 9c0ba357ad
3 changed files with 27 additions and 2 deletions

View File

@@ -846,8 +846,14 @@ export function matchesKey(data: string, keyId: KeyId): boolean {
}
return matchesKittySequence(data, CODEPOINTS.backspace, MODIFIERS.alt);
}
if (ctrl && !alt && !shift) {
// Legacy: 0x08 (BS) is sent by Windows Terminal for Ctrl+Backspace.
// Also matches Ctrl+H (same byte, ambiguous in legacy terminals).
if (data === "\x08") return true;
return matchesKittySequence(data, CODEPOINTS.backspace, MODIFIERS.ctrl);
}
if (modifier === 0) {
return data === "\x7f" || data === "\x08" || matchesKittySequence(data, CODEPOINTS.backspace, 0);
return data === "\x7f" || matchesKittySequence(data, CODEPOINTS.backspace, 0);
}
return matchesKittySequence(data, CODEPOINTS.backspace, modifier);
@@ -1165,7 +1171,8 @@ export function parseKey(data: string): string | undefined {
if (data === "\r" || (!_kittyProtocolActive && data === "\n") || data === "\x1bOM") return "enter";
if (data === "\x00") return "ctrl+space";
if (data === " ") return "space";
if (data === "\x7f" || data === "\x08") return "backspace";
if (data === "\x7f") return "backspace";
if (data === "\x08") return "ctrl+backspace";
if (data === "\x1b[Z") return "shift+tab";
if (!_kittyProtocolActive && data === "\x1b\r") return "alt+enter";
if (!_kittyProtocolActive && data === "\x1b ") return "alt+space";