From 3f408b5251efa8d92229555b26bb9db1de4866d0 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Wed, 10 Nov 2021 17:41:19 +0100 Subject: fix(input): properly query bracketed paste mode in terminals (#858) --- zellij-client/src/input_handler.rs | 25 ++++++++++++++++++++++--- zellij-client/src/lib.rs | 2 +- zellij-client/src/stdin_handler.rs | 29 +++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 10 deletions(-) (limited to 'zellij-client') diff --git a/zellij-client/src/input_handler.rs b/zellij-client/src/input_handler.rs index c2d93a0cf..0f8a60ff2 100644 --- a/zellij-client/src/input_handler.rs +++ b/zellij-client/src/input_handler.rs @@ -95,10 +95,29 @@ impl InputHandler { } } } - Ok((InputInstruction::PastedText(raw_bytes), _error_context)) => { + Ok(( + InputInstruction::PastedText(( + send_bracketed_paste_start, + raw_bytes, + send_bracketed_paste_end, + )), + _error_context, + )) => { if self.mode == InputMode::Normal || self.mode == InputMode::Locked { - let action = Action::Write(raw_bytes); - self.dispatch_action(action); + if send_bracketed_paste_start { + let bracketed_paste_start = vec![27, 91, 50, 48, 48, 126]; // \u{1b}[200~ + let paste_start_action = Action::Write(bracketed_paste_start); + self.dispatch_action(paste_start_action); + } + + let pasted_text_action = Action::Write(raw_bytes); + self.dispatch_action(pasted_text_action); + + if send_bracketed_paste_end { + let bracketed_paste_end = vec![27, 91, 50, 48, 49, 126]; // \u{1b}[201~ + let paste_end_action = Action::Write(bracketed_paste_end); + self.dispatch_action(paste_end_action); + } } } Ok((InputInstruction::SwitchToMode(input_mode), _error_context)) => { diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index cbad733cb..7633fcdb0 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -95,7 +95,7 @@ pub enum ClientInfo { pub(crate) enum InputInstruction { KeyEvent(termion::event::Event, Vec), SwitchToMode(InputMode), - PastedText(Vec), + PastedText((bool, Vec, bool)), // (send_brackted_paste_start, pasted_text, send_bracketed_paste_end) } pub fn start_client( diff --git a/zellij-client/src/stdin_handler.rs b/zellij-client/src/stdin_handler.rs index 9398ff4d5..2cd307ea7 100644 --- a/zellij-client/src/stdin_handler.rs +++ b/zellij-client/src/stdin_handler.rs @@ -30,14 +30,14 @@ fn keys_to_adjust() -> HashMap, Vec> { } fn bracketed_paste_end_position(stdin_buffer: &[u8]) -> Option { - let bracketed_paste_end = vec![27, 91, 50, 48, 49, 126]; // \u{1b}[201 + let bracketed_paste_end = vec![27, 91, 50, 48, 49, 126]; // \u{1b}[201~ let mut bp_position = 0; let mut position = None; for (i, byte) in stdin_buffer.iter().enumerate() { if Some(byte) == bracketed_paste_end.get(bp_position) { position = Some(i); bp_position += 1; - if bp_position == bracketed_paste_end.len() - 1 { + if bp_position == bracketed_paste_end.len() { break; } } else { @@ -45,7 +45,7 @@ fn bracketed_paste_end_position(stdin_buffer: &[u8]) -> Option { position = None; } } - if bp_position == bracketed_paste_end.len() - 1 { + if bp_position == bracketed_paste_end.len() { position } else { None @@ -70,15 +70,32 @@ pub(crate) fn stdin_loop( { match bracketed_paste_end_position(&stdin_buffer) { Some(paste_end_position) => { - let pasted_input = stdin_buffer.drain(..=paste_end_position).collect(); + let starts_with_bracketed_paste_start = stdin_buffer + .iter() + .take(bracketed_paste_start.len()) + .eq(bracketed_paste_start.iter()); + + let ends_with_bracketed_paste_end = true; + + let mut pasted_input: Vec = + stdin_buffer.drain(..=paste_end_position).collect(); + if starts_with_bracketed_paste_start { + drop(pasted_input.drain(..6)); // bracketed paste start + } + drop(pasted_input.drain(pasted_input.len() - 6..)); // bracketed paste end + send_input_instructions - .send(InputInstruction::PastedText(pasted_input)) + .send(InputInstruction::PastedText(( + starts_with_bracketed_paste_start, + pasted_input, + ends_with_bracketed_paste_end, + ))) .unwrap(); pasting = false; } None => { send_input_instructions - .send(InputInstruction::PastedText(stdin_buffer)) + .send(InputInstruction::PastedText((true, stdin_buffer, false))) .unwrap(); pasting = true; continue; -- cgit v1.2.3