diff options
author | Kirill Chibisov <contact@kchibisov.com> | 2023-08-10 13:34:42 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-10 13:34:42 +0400 |
commit | 90deacff851b27244c93795ddbc7d91fe7ea3cb4 (patch) | |
tree | 953cbb4fac64db164ea1ca1ba93d5a38308878da | |
parent | 8cf8505956aaab7565902c900b514a018a579d35 (diff) | |
download | r-alacritty-vte-90deacff851b27244c93795ddbc7d91fe7ea3cb4.tar.gz r-alacritty-vte-90deacff851b27244c93795ddbc7d91fe7ea3cb4.tar.bz2 r-alacritty-vte-90deacff851b27244c93795ddbc7d91fe7ea3cb4.zip |
Add support for kitty keyboard protocol
This just adds handling of the CSI u escapes mentioned in the spec
and don't provide key to escape sequence transformation for the terminals.
Links: https://sw.kovidgoyal.net/kitty/keyboard-protocol
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | Cargo.toml | 13 | ||||
-rw-r--r-- | src/ansi.rs | 73 | ||||
-rw-r--r-- | src/lib.rs | 2 |
4 files changed, 82 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7abdcae..d7bcec7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG ## Unreleased - Add support for OSC 22 +- Add support for kitty keyboard protocol ## 0.11.1 @@ -14,19 +14,20 @@ edition = "2021" rust-version = "1.62.1" [dependencies] -cursor-icon = { version = "1.0.0", default-features = false, optional = true } -vte_generate_state_changes = { version = "0.1.0", path = "vte_generate_state_changes" } arrayvec = { version = "0.7.2", default-features = false, optional = true } +bitflags = { version = "2.3.3", default-features = false, optional = true } +cursor-icon = { version = "1.0.0", default-features = false, optional = true } log = { version = "0.4.17", optional = true } -utf8parse = { version = "0.2.0", path = "utf8parse" } serde = { version = "1.0.160", features = ["derive"], optional = true } +utf8parse = { version = "0.2.0", path = "utf8parse" } +vte_generate_state_changes = { version = "0.1.0", path = "vte_generate_state_changes" } [features] -ansi = ["log", "cursor-icon"] -serde = ["dep:serde"] +ansi = ["log", "cursor-icon", "bitflags"] default = ["no_std"] -no_std = ["arrayvec"] nightly = ["utf8parse/nightly"] +no_std = ["arrayvec"] +serde = ["dep:serde"] [workspace] members = ["utf8parse", "vte_generate_state_changes"] 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)), @@ -374,7 +374,7 @@ impl<const OSC_RAW_BUF_SIZE: usize> Parser<OSC_RAW_BUF_SIZE> { /// movement, or simply printing characters to the screen. /// /// The methods on this type correspond to actions described in -/// http://vt100.net/emu/dec_ansi_parser. I've done my best to describe them in +/// <http://vt100.net/emu/dec_ansi_parser>. I've done my best to describe them in /// a useful way in my own words for completeness, but the site should be /// referenced if something isn't clear. If the site disappears at some point in /// the future, consider checking archive.org. |