Fix ESC key encoding in kitty mode with disambiguate flag (#7787)

This commit is contained in:
Mikhail f. Shiryaev 2026-06-20 00:38:14 +02:00 committed by GitHub
parent cd4b4fd27c
commit aea9b9f2e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1723,6 +1723,12 @@ impl KeyEvent {
match &self.key {
Char('\x08') => return '\x7f'.to_string(),
Char('\x7f') => return '\x08'.to_string(),
// With DISAMBIGUATE_ESCAPE_CODES, ESC must not be sent as a
// raw \x1b byte — the entire point of the flag is to eliminate
// that ambiguity. Let it fall through to the CSI-u path below
// which will produce \x1b[27;1u as required by the spec.
// https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate
Char('\x1b') if flags.contains(KittyKeyboardFlags::DISAMBIGUATE_ESCAPE_CODES) => {}
Char(c) => return c.to_string(),
_ => {}
}
@ -3208,4 +3214,62 @@ mod test {
"\u{1b}[102;14u".to_string()
);
}
/// ESC with DISAMBIGUATE_ESCAPE_CODES must produce \x1b[27;1u, not a raw \x1b.
/// https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate
#[test]
fn encode_escape_disambiguate() {
// Flag 1 only: ESC on key-down → \x1b[27;1u
let flags = KittyKeyboardFlags::DISAMBIGUATE_ESCAPE_CODES;
assert_eq!(
KeyEvent {
key: KeyCode::Char('\x1b'),
modifiers: Modifiers::NONE,
leds: KeyboardLedStatus::empty(),
repeat_count: 1,
key_is_down: true,
raw: None,
#[cfg(windows)]
win32_uni_char: None,
}
.encode_kitty(flags),
"\x1b[27;1u".to_string()
);
// No flags at all: ESC on key-down must still be sent as a raw \x1b
// (legacy behaviour is unchanged).
let flags = KittyKeyboardFlags::NONE;
assert_eq!(
KeyEvent {
key: KeyCode::Char('\x1b'),
modifiers: Modifiers::NONE,
leds: KeyboardLedStatus::empty(),
repeat_count: 1,
key_is_down: true,
raw: None,
#[cfg(windows)]
win32_uni_char: None,
}
.encode_kitty(flags),
"\x1b".to_string()
);
// DISAMBIGUATE + REPORT_EVENT_TYPES: key-up must produce \x1b[27;1:3u
let flags =
KittyKeyboardFlags::DISAMBIGUATE_ESCAPE_CODES | KittyKeyboardFlags::REPORT_EVENT_TYPES;
assert_eq!(
KeyEvent {
key: KeyCode::Char('\x1b'),
modifiers: Modifiers::NONE,
leds: KeyboardLedStatus::empty(),
repeat_count: 1,
key_is_down: false,
raw: None,
#[cfg(windows)]
win32_uni_char: None,
}
.encode_kitty(flags),
"\x1b[27;1:3u".to_string()
);
}
}