diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-08-01 04:27:50 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-01 04:27:50 +0300 |
| commit | b76adc155d979705a353fd6dc87c702f9dfc6c22 (patch) | |
| tree | f613254e0cfbfd2b4450a6a5f3ee7c0ba8136976 /src/raw_input.rs | |
| parent | 8d190eddda2c74afa3dc043f8ec8020ffd7b5a94 (diff) | |
fix(input): preserve native key lifecycle across routing (#2142)
refs #2077
Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/raw_input.rs')
| -rw-r--r-- | src/raw_input.rs | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/src/raw_input.rs b/src/raw_input.rs index 6b59b392..ce7aec19 100644 --- a/src/raw_input.rs +++ b/src/raw_input.rs @@ -53,10 +53,10 @@ pub fn parse_raw_input_bytes_with_ranges(data: &[u8]) -> Vec<RawInputEventWithRa if !buffer.is_empty() { if buffer.as_slice() == [ESC] { events.push(RawInputEventWithRange { - event: RawInputEvent::Key(TerminalKey::new( - crossterm::event::KeyCode::Esc, - KeyModifiers::empty(), - )), + event: RawInputEvent::Key( + TerminalKey::new(crossterm::event::KeyCode::Esc, KeyModifiers::empty()) + .with_vt_bytes(vec![ESC]), + ), start: offset, len: 1, }); @@ -68,7 +68,7 @@ pub fn parse_raw_input_bytes_with_ranges(data: &[u8]) -> Vec<RawInputEventWithRa } else if let Ok(text) = std::str::from_utf8(&buffer) { if let Some(key) = parse_terminal_key_sequence(text) { events.push(RawInputEventWithRange { - event: RawInputEvent::Key(key.as_text_commit()), + event: RawInputEvent::Key(key.with_text_commit().with_vt_bytes(buffer.clone())), start: offset, len: buffer.len(), }); @@ -94,7 +94,7 @@ pub fn parse_raw_input_bytes_sync(data: &[u8]) -> Vec<RawInputEvent> { use std::os::fd::AsRawFd; use tokio::sync::mpsc; -use crate::input::{parse_terminal_key_sequence, TerminalKey}; +use crate::input::{parse_terminal_key_sequence, TerminalKey, TextCommit}; use crate::terminal_theme::{ parse_default_color_response, parse_palette_color_response, DefaultColorKind, HostAppearance, RgbColor, @@ -126,6 +126,7 @@ pub(crate) fn is_complete_text_bracketed_paste(data: &[u8]) -> bool { #[derive(Debug)] pub enum RawInputEvent { Key(TerminalKey), + Text(TextCommit), Paste(String), Mouse(MouseEvent), OuterFocusGained, @@ -187,10 +188,10 @@ impl RawInputFramer { .into_iter() .filter_map(|chunk| { if chunk.as_slice() == [ESC] { - return Some(RawInputEvent::Key(TerminalKey::new( - crossterm::event::KeyCode::Esc, - KeyModifiers::empty(), - ))); + return Some(RawInputEvent::Key( + TerminalKey::new(crossterm::event::KeyCode::Esc, KeyModifiers::empty()) + .with_vt_bytes(chunk), + )); } extract_one_event(&chunk).map(|(event, _consumed)| { tracing::debug!(raw_bytes = ?chunk, event = ?event, "raw input event parsed"); @@ -639,10 +640,10 @@ pub(crate) fn drain_complete_input_bytes(buffer: &mut Vec<u8>) -> Vec<Vec<u8>> { fn flush_incomplete_buffer(buffer: &mut Vec<u8>, tx: &mpsc::Sender<RawInputEvent>) { if let Some(bytes) = flush_incomplete_input_bytes(buffer) { if bytes.as_slice() == [ESC] { - let _ = tx.blocking_send(RawInputEvent::Key(TerminalKey::new( - crossterm::event::KeyCode::Esc, - KeyModifiers::empty(), - ))); + let _ = tx.blocking_send(RawInputEvent::Key( + TerminalKey::new(crossterm::event::KeyCode::Esc, KeyModifiers::empty()) + .with_vt_bytes(bytes), + )); return; } @@ -752,7 +753,10 @@ fn extract_one_event(buffer: &[u8]) -> Option<(RawInputEvent, usize)> { } if let Some(key) = parse_terminal_key_sequence(seq) { - return Some((RawInputEvent::Key(key), seq_len)); + return Some(( + RawInputEvent::Key(key.with_vt_bytes(buffer[..seq_len].to_vec())), + seq_len, + )); } tracing::debug!(sequence = ?seq, "dropping unsupported escape sequence"); @@ -761,7 +765,9 @@ fn extract_one_event(buffer: &[u8]) -> Option<(RawInputEvent, usize)> { let consumed = first_complete_utf8_char_len(buffer)?; let text = std::str::from_utf8(&buffer[..consumed]).ok()?; - let key = parse_terminal_key_sequence(text)?.as_text_commit(); + let key = parse_terminal_key_sequence(text)? + .with_text_commit() + .with_vt_bytes(buffer[..consumed].to_vec()); Some((RawInputEvent::Key(key), consumed)) } |
