aboutsummaryrefslogtreecommitdiff
path: root/src/raw_input.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-08-01 04:27:50 +0300
committerGitHub <noreply@github.com>2026-08-01 04:27:50 +0300
commitb76adc155d979705a353fd6dc87c702f9dfc6c22 (patch)
treef613254e0cfbfd2b4450a6a5f3ee7c0ba8136976 /src/raw_input.rs
parent8d190eddda2c74afa3dc043f8ec8020ffd7b5a94 (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.rs38
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))
}