diff --git a/src/engine.rs b/src/engine.rs index ac69df9a..7ba541a5 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -140,6 +140,9 @@ pub struct Reedline { // Indicate if global terminal have enabled BracketedPaste bracket_paste_enabled: bool, + // Use kitty protocol to handle escape code input or not + use_kitty_protocol: bool, + #[cfg(feature = "external_printer")] external_printer: Option>, } @@ -165,6 +168,9 @@ impl Drop for Reedline { if self.bracket_paste_enabled { let _ = execute!(io::stdout(), DisableBracketedPaste); } + if self.use_kitty_protocol { + let _ = execute!(io::stdout(), event::PopKeyboardEnhancementFlags); + } } } @@ -210,6 +216,7 @@ impl Reedline { buffer_editor: None, cursor_shapes: None, bracket_paste_enabled: false, + use_kitty_protocol: false, #[cfg(feature = "external_printer")] external_printer: None, } @@ -243,6 +250,25 @@ impl Reedline { res } + /// Return terminal support on keyboard enhancement + pub fn can_use_kitty_protocol(&mut self) -> bool { + if let Ok(b) = crossterm::terminal::supports_keyboard_enhancement() { + b + } else { + false + } + } + + /// Enable keyboard enhancement to disambiguate escape code + pub fn enable_kitty_protocol(&mut self) { + self.use_kitty_protocol = true; + } + + /// Disable keyboard enhancement to disambiguate escape code + pub fn disable_kitty_protocol(&mut self) { + self.use_kitty_protocol = false; + } + /// Return the previously generated history session id pub fn get_history_session_id(&self) -> Option { self.history_session_id @@ -575,6 +601,11 @@ impl Reedline { #[cfg(not(target_os = "windows"))] self.disable_bracketed_paste()?; + + if self.use_kitty_protocol { + let _ = execute!(io::stdout(), event::PopKeyboardEnhancementFlags); + } + terminal::disable_raw_mode()?; result } @@ -620,6 +651,31 @@ impl Reedline { let mut crossterm_events: Vec = vec![]; let mut reedline_events: Vec = vec![]; + if self.use_kitty_protocol { + if let Ok(true) = crossterm::terminal::supports_keyboard_enhancement() { + // enable kitty protocol + // + // Note that, currently, only the following support this protocol: + // * [kitty terminal](https://sw.kovidgoyal.net/kitty/) + // * [foot terminal](https://codeberg.org/dnkl/foot/issues/319) + // * [WezTerm terminal](https://wezfurlong.org/wezterm/config/lua/config/enable_kitty_keyboard.html) + // * [notcurses library](https://github.com/dankamongmen/notcurses/issues/2131) + // * [neovim text editor](https://github.com/neovim/neovim/pull/18181) + // * [kakoune text editor](https://github.com/mawww/kakoune/issues/4103) + // * [dte text editor](https://gitlab.com/craigbarnes/dte/-/issues/138) + // + // Refer to https://sw.kovidgoyal.net/kitty/keyboard-protocol/ if you're curious. + let _ = execute!( + io::stdout(), + event::PushKeyboardEnhancementFlags( + event::KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES + ) + ); + } else { + // TODO: Log or warning + } + } + loop { let mut paste_enter_state = false;