diff options
Diffstat (limited to 'src/ansi.rs')
-rw-r--r-- | src/ansi.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/ansi.rs b/src/ansi.rs index cd9499d..f71b773 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -11,6 +11,7 @@ extern crate alloc; use alloc::borrow::ToOwned; use alloc::string::{String, ToString}; use alloc::vec::Vec; +use bitflags::bitflags; use core::convert::TryFrom; use core::fmt::{self, Display, Formatter, Write}; @@ -672,6 +673,59 @@ pub trait Handler { /// Set mouse cursor icon. fn set_mouse_cursor_icon(&mut self, _: CursorIcon) {} + + /// Report current keyboard mode. + fn report_keyboard_mode(&mut self) {} + + /// Push keyboard mode into the keyboard mode stack. + fn push_keyboard_mode(&mut self, _mode: KeyboardModes) {} + + /// Pop the given amount of keyboard modes from the + /// keyboard mode stack. + fn pop_keyboard_modes(&mut self, _to_pop: u16) {} + + /// Set the [`keyboard mode`] using the given [`behavior`]. + /// + /// [`keyboard mode`]: crate::ansi::KeyboardModes + /// [`behavior`]: crate::ansi::KeyboardModesApplyBehavior + fn set_keyboard_mode(&mut self, _mode: KeyboardModes, _behavior: KeyboardModesApplyBehavior) {} +} + +bitflags! { + /// A set of [`kitty keyboard protocol'] modes. + /// + /// [`kitty keyboard protocol']: https://sw.kovidgoyal.net/kitty/keyboard-protocol + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct KeyboardModes : u8 { + /// No keyboard protocol mode is set. + const NO_MODE = 0b0000_0000; + /// Report `Esc`, `alt` + `key`, `ctrl` + `key`, `ctrl` + `alt` + `key`, `shift` + /// + `alt` + `key` keys using `CSI u` sequence instead of raw ones. + const DISAMBIGUATE_ESC_CODES = 0b0000_0001; + /// Report key presses, release, and repetition alongside the escape. Key events + /// that result in text are reported as plain UTF-8, unless the + /// [`Self::REPORT_ALL_KEYS_AS_ESC`] is enabled. + const REPORT_EVENT_TYPES = 0b0000_0010; + /// Additionally report shifted key an dbase layout key. + const REPORT_ALTERNATE_KEYS = 0b0000_0100; + /// Report every key as an escape sequence. + const REPORT_ALL_KEYS_AS_ESC = 0b0000_1000; + /// Report the text generated by the key event. + const REPORT_ASSOCIATED_TEXT = 0b0001_0000; + } +} + +/// Describes how the new [`KeyboardModes`] should be applied. +#[repr(u8)] +#[derive(Default, Clone, Copy, PartialEq, Eq)] +pub enum KeyboardModesApplyBehavior { + /// Replace the active flags with the new ones. + #[default] + Replace, + /// Merge the given flags with currently active ones. + Union, + /// Remove the given flags from the active ones. + Difference, } /// Terminal cursor configuration. @@ -1508,6 +1562,25 @@ where 23 => handler.pop_title(), _ => unhandled!(), }, + ('u', [b'?']) => handler.report_keyboard_mode(), + ('u', [b'=']) => { + let mode = KeyboardModes::from_bits_truncate(next_param_or(0) as u8); + let behavior = match next_param_or(1) { + 3 => KeyboardModesApplyBehavior::Difference, + 2 => KeyboardModesApplyBehavior::Union, + // Default is replace. + _ => KeyboardModesApplyBehavior::Replace, + }; + handler.set_keyboard_mode(mode, behavior); + }, + ('u', [b'>']) => { + let mode = KeyboardModes::from_bits_truncate(next_param_or(0) as u8); + handler.push_keyboard_mode(mode); + }, + ('u', [b'<']) => { + // The default is 1. + handler.pop_keyboard_modes(next_param_or(1)); + }, ('u', []) => handler.restore_cursor_position(), ('X', []) => handler.erase_chars(next_param_or(1) as usize), ('Z', []) => handler.move_backward_tabs(next_param_or(1)), |