mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-22 00:01:06 +00:00
fix: recognize kitty CSI-u codepoints for F1 through F12 (#2378)
Codepoints 57364-57375 (F1-F12) were missing from the kitty-protocol codepoint table, so terminals that send function keys as full CSI-u sequences (e.g. Ghostty, which enables the kitty keyboard protocol by default) had those keys silently dropped. Confirmed live against a running herdr session: injecting the raw F3/F4 codepoint sequences did nothing before this fix and correctly triggered previous_tab/next_tab after. refs #1809 Co-authored-by: JJ Liebig <jonathan.liebig@gmail.com>
This commit is contained in:
co-authored by
JJ Liebig
parent
1e3c625d86
commit
0305fdb6f7
+22
-7
@@ -311,6 +311,7 @@ fn kitty_codepoint_to_keycode(codepoint: u32) -> Option<KeyCode> {
|
||||
57361 => Some(KeyCode::PrintScreen),
|
||||
57362 => Some(KeyCode::Pause),
|
||||
57363 => Some(KeyCode::Menu),
|
||||
57364..=57375 => Some(KeyCode::F((codepoint - 57364 + 1) as u8)),
|
||||
57376..=57398 => Some(KeyCode::F((codepoint - 57376 + 13) as u8)),
|
||||
57399 => Some(KeyCode::Char('0')),
|
||||
57400 => Some(KeyCode::Char('1')),
|
||||
@@ -367,15 +368,10 @@ fn kitty_codepoint_to_keycode(codepoint: u32) -> Option<KeyCode> {
|
||||
57452 => Some(KeyCode::Modifier(ModifierKeyCode::RightMeta)),
|
||||
57453 => Some(KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift)),
|
||||
57454 => Some(KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift)),
|
||||
value if is_kitty_functional_codepoint(value) => None,
|
||||
value => char::from_u32(value).map(KeyCode::Char),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_kitty_functional_codepoint(codepoint: u32) -> bool {
|
||||
(57358..=57454).contains(&codepoint)
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // Reserved for the upcoming raw stdin parser.
|
||||
fn key_modifiers_from_u8(modifier: u8) -> KeyModifiers {
|
||||
let mut mods = KeyModifiers::empty();
|
||||
@@ -1016,8 +1012,27 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unknown_kitty_functional_key_remains_unsupported() {
|
||||
assert!(parse_terminal_key_sequence("\x1b[57364;1u").is_none());
|
||||
fn kitty_f1_through_f12_codepoints_are_recognized() {
|
||||
let cases = [
|
||||
("\x1b[57364;1u", KeyCode::F(1)),
|
||||
("\x1b[57365;1u", KeyCode::F(2)),
|
||||
("\x1b[57366;1u", KeyCode::F(3)),
|
||||
("\x1b[57367;1u", KeyCode::F(4)),
|
||||
("\x1b[57368;1u", KeyCode::F(5)),
|
||||
("\x1b[57375;1u", KeyCode::F(12)),
|
||||
("\x1b[57376;1u", KeyCode::F(13)),
|
||||
];
|
||||
|
||||
for (sequence, code) in cases {
|
||||
let parsed = parse_terminal_key_sequence(sequence).unwrap();
|
||||
assert_terminal_key_eq(
|
||||
parsed,
|
||||
code,
|
||||
KeyModifiers::empty(),
|
||||
crossterm::event::KeyEventKind::Press,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_fixture_corpus_parses(corpus: &str) {
|
||||
|
||||
@@ -1535,6 +1535,11 @@ mod tests {
|
||||
(b"\x1b[57423;1u", KeyCode::Home, KeyModifiers::empty()),
|
||||
(b"\x1bOq", KeyCode::Char('1'), KeyModifiers::empty()),
|
||||
(b"\x1b[14~", KeyCode::F(4), KeyModifiers::empty()),
|
||||
(b"\x1b[57364;1u", KeyCode::F(1), KeyModifiers::empty()),
|
||||
(b"\x1b[57366;1u", KeyCode::F(3), KeyModifiers::empty()),
|
||||
(b"\x1b[57366;2u", KeyCode::F(3), KeyModifiers::SHIFT),
|
||||
(b"\x1b[57375;1u", KeyCode::F(12), KeyModifiers::empty()),
|
||||
(b"\x1b[57376;1u", KeyCode::F(13), KeyModifiers::empty()),
|
||||
(b"\x1b[49:33;2:1u", KeyCode::Char('1'), KeyModifiers::SHIFT),
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user