From ca93e6e2511d13b7041504e0665fff2d7a402c28 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Mon, 30 Mar 2026 13:50:24 +0300 Subject: fix: send shifted printable keys as text input --- src/input/encode.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/input/encode.rs') diff --git a/src/input/encode.rs b/src/input/encode.rs index 657fab80..b114935a 100644 --- a/src/input/encode.rs +++ b/src/input/encode.rs @@ -11,6 +11,10 @@ pub fn encode_key(key: KeyEvent, protocol: KeyboardProtocol) -> Vec { } pub fn encode_terminal_key(key: TerminalKey, protocol: KeyboardProtocol) -> Vec { + if let Some(bytes) = encode_text_input(&key) { + return bytes; + } + if let KeyboardProtocol::Kitty { flags } = protocol { if let Some(bytes) = try_encode_csi_u(&key, flags) { return bytes; @@ -187,6 +191,41 @@ fn kitty_modifier(mods: KeyModifiers) -> u32 { m } +fn encode_text_input(key: &TerminalKey) -> Option> { + if key.modifiers != KeyModifiers::SHIFT { + return None; + } + + let ch = match key.code { + KeyCode::Char(ch) => shifted_text_char(key, ch)?, + _ => return None, + }; + + match key.kind { + crossterm::event::KeyEventKind::Press | crossterm::event::KeyEventKind::Repeat => { + let mut buf = [0u8; 4]; + Some(ch.encode_utf8(&mut buf).as_bytes().to_vec()) + } + crossterm::event::KeyEventKind::Release => Some(Vec::new()), + } +} + +fn shifted_text_char(key: &TerminalKey, ch: char) -> Option { + if let Some(shifted) = key.shifted_codepoint.and_then(char::from_u32) { + return Some(shifted); + } + + if ch.is_ascii_uppercase() { + return Some(ch); + } + + if ch.is_ascii_lowercase() { + return Some(ch.to_ascii_uppercase()); + } + + None +} + fn canonical_kitty_char(ch: char, mods: KeyModifiers) -> char { if mods.contains(KeyModifiers::SHIFT) && ch.is_ascii_uppercase() { ch.to_ascii_lowercase() -- cgit v1.2.3