From 3b60811f57095066f26dcdf75111bf59e41ee0bf Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Tue, 25 Apr 2023 02:07:56 +0800 Subject: [PATCH] support bracketed paste (#571) * support bracketed paste * update demo * fix clippy * no need to enable bracketed paste, leave the behavior to user --- examples/demo.rs | 16 ++++++++++++---- src/edit_mode/emacs.rs | 2 +- src/edit_mode/vi/mod.rs | 2 +- src/engine.rs | 19 +++++++++++++++++++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/examples/demo.rs b/examples/demo.rs index cc5200c..7ad3752 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -1,7 +1,8 @@ use { crossterm::{ - event::{KeyCode, KeyModifiers}, - Result, + cursor::SetCursorStyle, + event::{DisableBracketedPaste, KeyCode, KeyModifiers}, + execute, Result, }, nu_ansi_term::{Color, Style}, reedline::{ @@ -10,9 +11,9 @@ use { EditCommand, EditMode, Emacs, ExampleHighlighter, Keybindings, ListMenu, Reedline, ReedlineEvent, ReedlineMenu, Signal, Vi, }, + std::io::stdout, }; -use crossterm::cursor::SetCursorStyle; use reedline::CursorConfig; #[cfg(not(any(feature = "sqlite", feature = "sqlite-dynlib")))] use reedline::FileBackedHistory; @@ -57,7 +58,6 @@ fn main() -> Result<()> { "こんにちは世界".into(), "こんばんは世界".into(), ]; - let completer = Box::new(DefaultCompleter::new_with_wordlen(commands.clone(), 2)); let cursor_config = CursorConfig { @@ -88,6 +88,11 @@ fn main() -> Result<()> { )) .with_validator(Box::new(DefaultValidator)) .with_ansi_colors(true); + let res = line_editor.enable_bracketed_paste(); + let bracketed_paste_enabled = res.is_ok(); + if !bracketed_paste_enabled { + println!("Warn: failed to enable bracketed paste mode: {res:?}"); + } // Adding default menus for the compiled reedline line_editor = line_editor @@ -211,6 +216,9 @@ fn main() -> Result<()> { } } + if bracketed_paste_enabled { + let _ = execute!(stdout(), DisableBracketedPaste); + } println!(); Ok(()) } diff --git a/src/edit_mode/emacs.rs b/src/edit_mode/emacs.rs index 1172634..ec35384 100644 --- a/src/edit_mode/emacs.rs +++ b/src/edit_mode/emacs.rs @@ -156,7 +156,7 @@ impl EditMode for Emacs { Event::Resize(width, height) => ReedlineEvent::Resize(width, height), Event::FocusGained => ReedlineEvent::None, Event::FocusLost => ReedlineEvent::None, - Event::Paste(_) => ReedlineEvent::None, + Event::Paste(body) => ReedlineEvent::Edit(vec![EditCommand::InsertString(body)]), } } diff --git a/src/edit_mode/vi/mod.rs b/src/edit_mode/vi/mod.rs index f8c8a7d..2a20155 100644 --- a/src/edit_mode/vi/mod.rs +++ b/src/edit_mode/vi/mod.rs @@ -153,7 +153,7 @@ impl EditMode for Vi { Event::Resize(width, height) => ReedlineEvent::Resize(width, height), Event::FocusGained => ReedlineEvent::None, Event::FocusLost => ReedlineEvent::None, - Event::Paste(_) => ReedlineEvent::None, + Event::Paste(body) => ReedlineEvent::Edit(vec![EditCommand::InsertString(body)]), } } diff --git a/src/engine.rs b/src/engine.rs index 5e2b499..8bcfc4c 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,3 +1,6 @@ +use crossterm::event::{DisableBracketedPaste, EnableBracketedPaste}; +use crossterm::execute; + use crate::{enums::ReedlineRawEvent, CursorConfig}; #[cfg(feature = "bashisms")] use crate::{ @@ -130,6 +133,9 @@ pub struct Reedline { // Use different cursors depending on the current edit mode cursor_shapes: Option, + // Indicate if global terminal have enabled BracketedPaste + bracket_paste_enabled: bool, + #[cfg(feature = "external_printer")] external_printer: Option>, } @@ -144,6 +150,9 @@ impl Drop for Reedline { // Ensures that the terminal is in a good state if we panic semigracefully // Calling `disable_raw_mode()` twice is fine with Linux let _ignore = terminal::disable_raw_mode(); + if self.bracket_paste_enabled { + let _ = execute!(io::stdout(), DisableBracketedPaste); + } } } @@ -183,6 +192,7 @@ impl Reedline { menus: Vec::new(), buffer_editor: None, cursor_shapes: None, + bracket_paste_enabled: false, #[cfg(feature = "external_printer")] external_printer: None, } @@ -198,6 +208,15 @@ impl Reedline { Some(HistorySessionId::new(nanos)) } + /// Enable BracketedPaste feature. + pub fn enable_bracketed_paste(&mut self) -> Result<()> { + let res = execute!(io::stdout(), EnableBracketedPaste); + if res.is_ok() { + self.bracket_paste_enabled = true; + } + res + } + /// Return the previously generated history session id pub fn get_history_session_id(&self) -> Option { self.history_session_id