fix(input): properly query bracketed paste mode in terminals (#858)
This commit is contained in:
parent
ba5ec8e493
commit
3f408b5251
3 changed files with 46 additions and 10 deletions
|
|
@ -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 {
|
if self.mode == InputMode::Normal || self.mode == InputMode::Locked {
|
||||||
let action = Action::Write(raw_bytes);
|
if send_bracketed_paste_start {
|
||||||
self.dispatch_action(action);
|
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)) => {
|
Ok((InputInstruction::SwitchToMode(input_mode), _error_context)) => {
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ pub enum ClientInfo {
|
||||||
pub(crate) enum InputInstruction {
|
pub(crate) enum InputInstruction {
|
||||||
KeyEvent(termion::event::Event, Vec<u8>),
|
KeyEvent(termion::event::Event, Vec<u8>),
|
||||||
SwitchToMode(InputMode),
|
SwitchToMode(InputMode),
|
||||||
PastedText(Vec<u8>),
|
PastedText((bool, Vec<u8>, bool)), // (send_brackted_paste_start, pasted_text, send_bracketed_paste_end)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_client(
|
pub fn start_client(
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,14 @@ fn keys_to_adjust() -> HashMap<Vec<u8>, Vec<u8>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bracketed_paste_end_position(stdin_buffer: &[u8]) -> Option<usize> {
|
fn bracketed_paste_end_position(stdin_buffer: &[u8]) -> Option<usize> {
|
||||||
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 bp_position = 0;
|
||||||
let mut position = None;
|
let mut position = None;
|
||||||
for (i, byte) in stdin_buffer.iter().enumerate() {
|
for (i, byte) in stdin_buffer.iter().enumerate() {
|
||||||
if Some(byte) == bracketed_paste_end.get(bp_position) {
|
if Some(byte) == bracketed_paste_end.get(bp_position) {
|
||||||
position = Some(i);
|
position = Some(i);
|
||||||
bp_position += 1;
|
bp_position += 1;
|
||||||
if bp_position == bracketed_paste_end.len() - 1 {
|
if bp_position == bracketed_paste_end.len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -45,7 +45,7 @@ fn bracketed_paste_end_position(stdin_buffer: &[u8]) -> Option<usize> {
|
||||||
position = None;
|
position = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bp_position == bracketed_paste_end.len() - 1 {
|
if bp_position == bracketed_paste_end.len() {
|
||||||
position
|
position
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -70,15 +70,32 @@ pub(crate) fn stdin_loop(
|
||||||
{
|
{
|
||||||
match bracketed_paste_end_position(&stdin_buffer) {
|
match bracketed_paste_end_position(&stdin_buffer) {
|
||||||
Some(paste_end_position) => {
|
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<u8> =
|
||||||
|
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_input_instructions
|
||||||
.send(InputInstruction::PastedText(pasted_input))
|
.send(InputInstruction::PastedText((
|
||||||
|
starts_with_bracketed_paste_start,
|
||||||
|
pasted_input,
|
||||||
|
ends_with_bracketed_paste_end,
|
||||||
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
pasting = false;
|
pasting = false;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
send_input_instructions
|
send_input_instructions
|
||||||
.send(InputInstruction::PastedText(stdin_buffer))
|
.send(InputInstruction::PastedText((true, stdin_buffer, false)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
pasting = true;
|
pasting = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue