141 lines
5.8 KiB
Rust
141 lines
5.8 KiB
Rust
use bitflags::bitflags;
|
|
|
|
bitflags! {
|
|
#[derive(Copy, Clone)]
|
|
pub struct TermMode: u32 {
|
|
const NONE = 0;
|
|
const SHOW_CURSOR = 0b0000_0000_0000_0000_0001;
|
|
const APP_CURSOR = 0b0000_0000_0000_0000_0010;
|
|
const APP_KEYPAD = 0b0000_0000_0000_0000_0100;
|
|
const MOUSE_REPORT_CLICK = 0b0000_0000_0000_0000_1000;
|
|
const BRACKETED_PASTE = 0b0000_0000_0000_0001_0000;
|
|
const SGR_MOUSE = 0b0000_0000_0000_0010_0000;
|
|
const MOUSE_MOTION = 0b0000_0000_0000_0100_0000;
|
|
const LINE_WRAP = 0b0000_0000_0000_1000_0000;
|
|
const LINE_FEED_NEW_LINE = 0b0000_0000_0001_0000_0000;
|
|
const ORIGIN = 0b0000_0000_0010_0000_0000;
|
|
const INSERT = 0b0000_0000_0100_0000_0000;
|
|
const FOCUS_IN_OUT = 0b0000_0000_1000_0000_0000;
|
|
const MOUSE_DRAG = 0b0000_0010_0000_0000_0000;
|
|
const MOUSE_MODE = 0b0000_0010_0000_0100_1000;
|
|
const UTF8_MOUSE = 0b0000_0100_0000_0000_0000;
|
|
const ALTERNATE_SCROLL = 0b0000_1000_0000_0000_0000;
|
|
const VI = 0b0001_0000_0000_0000_0000;
|
|
const URGENCY_HINTS = 0b0010_0000_0000_0000_0000;
|
|
|
|
// Kitty keyboard protocol enhancement flags
|
|
// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
|
|
|
|
/// Flag 1: Disambiguate escape codes.
|
|
/// Encodes ambiguous keys using CSI u sequences instead of legacy encodings:
|
|
/// - Esc key → CSI 27 u (distinguishes standalone Esc from escape sequence starts)
|
|
/// - Modified keys (Alt+key, Ctrl+key, Ctrl+Alt+key, Shift+Alt+key) → CSI u format
|
|
const KEYBOARD_DISAMBIGUATE_ESCAPE = 0b0100_0000_0000_0000_0000;
|
|
|
|
/// Flag 2: Report event types.
|
|
/// Enables reporting of key press, repeat, and release events, not just key presses.
|
|
/// Format includes event type in the CSI u sequence.
|
|
const KEYBOARD_REPORT_EVENT_TYPES = 0b1000_0000_0000_0000_0000;
|
|
|
|
/// Flag 4: Report alternate keys.
|
|
/// Reports the unshifted key alongside the shifted key. For example, when Shift+2 is
|
|
/// pressed, reports both "@" (shifted) and "2" (unshifted) for layout-independent
|
|
/// keybinding support.
|
|
const KEYBOARD_REPORT_ALTERNATE_KEYS = 0b0001_0000_0000_0000_0000_0000;
|
|
|
|
/// Flag 8: Report all keys as escape codes.
|
|
/// Forces all keys, including printable characters, to be encoded as CSI u sequences.
|
|
/// Provides a uniform encoding format. For example, plain 'a' becomes ESC[97;1u instead
|
|
/// of just 0x61. Often combined with flag 1 for "full CSI u" mode (flags = 9).
|
|
const KEYBOARD_REPORT_ALL_AS_ESCAPE = 0b0010_0000_0000_0000_0000_0000;
|
|
|
|
/// Flag 16: Report associated text.
|
|
/// Includes the text that would be generated by the key event, useful for applications
|
|
/// that want both the semantic key information and the resulting text.
|
|
const KEYBOARD_REPORT_ASSOCIATED_TEXT = 0b0100_0000_0000_0000_0000_0000;
|
|
|
|
const KEYBOARD_PROTOCOL = Self::KEYBOARD_DISAMBIGUATE_ESCAPE.bits()
|
|
| Self::KEYBOARD_REPORT_EVENT_TYPES.bits()
|
|
| Self::KEYBOARD_REPORT_ALTERNATE_KEYS.bits()
|
|
| Self::KEYBOARD_REPORT_ALL_AS_ESCAPE.bits()
|
|
| Self::KEYBOARD_REPORT_ASSOCIATED_TEXT.bits();
|
|
|
|
const ANY = u32::MAX;
|
|
}
|
|
}
|
|
|
|
impl Default for TermMode {
|
|
fn default() -> TermMode {
|
|
TermMode::SHOW_CURSOR
|
|
| TermMode::LINE_WRAP
|
|
| TermMode::ALTERNATE_SCROLL
|
|
| TermMode::URGENCY_HINTS
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
/// Kitty keyboard protocol modes.
|
|
/// These map to the flags sent via CSI > flags u, CSI = flags u, etc.
|
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
|
pub struct KeyboardModes: u32 {
|
|
const NO_MODE = 0;
|
|
const DISAMBIGUATE_ESC_CODES = 0b0000_0001;
|
|
const REPORT_EVENT_TYPES = 0b0000_0010;
|
|
const REPORT_ALTERNATE_KEYS = 0b0000_0100;
|
|
const REPORT_ALL_KEYS_AS_ESC = 0b0000_1000;
|
|
const REPORT_ASSOCIATED_TEXT = 0b0001_0000;
|
|
}
|
|
}
|
|
|
|
/// Convert KeyboardModes to TermMode flags
|
|
impl From<KeyboardModes> for TermMode {
|
|
fn from(modes: KeyboardModes) -> Self {
|
|
let mut term_mode = TermMode::NONE;
|
|
|
|
if modes.contains(KeyboardModes::DISAMBIGUATE_ESC_CODES) {
|
|
term_mode |= TermMode::KEYBOARD_DISAMBIGUATE_ESCAPE;
|
|
}
|
|
if modes.contains(KeyboardModes::REPORT_EVENT_TYPES) {
|
|
term_mode |= TermMode::KEYBOARD_REPORT_EVENT_TYPES;
|
|
}
|
|
if modes.contains(KeyboardModes::REPORT_ALTERNATE_KEYS) {
|
|
term_mode |= TermMode::KEYBOARD_REPORT_ALTERNATE_KEYS;
|
|
}
|
|
if modes.contains(KeyboardModes::REPORT_ALL_KEYS_AS_ESC) {
|
|
term_mode |= TermMode::KEYBOARD_REPORT_ALL_AS_ESCAPE;
|
|
}
|
|
if modes.contains(KeyboardModes::REPORT_ASSOCIATED_TEXT) {
|
|
term_mode |= TermMode::KEYBOARD_REPORT_ASSOCIATED_TEXT;
|
|
}
|
|
|
|
term_mode
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum KeyboardModesApplyBehavior {
|
|
/// Replace all current modes with new ones
|
|
Replace,
|
|
/// Union (add) new modes to existing ones
|
|
Union,
|
|
/// Difference (remove) modes from existing ones
|
|
Difference,
|
|
}
|
|
|
|
impl KeyboardModesApplyBehavior {
|
|
/// Maps kitty keyboard protocol apply-mode values to behavior.
|
|
///
|
|
/// From kitty's `CSI = flags ; mode u` command:
|
|
/// - `1` (or omitted) = replace current flags
|
|
/// - `2` = union/add flags
|
|
/// - `3` = difference/remove flags
|
|
pub fn from_kitty_apply_mode(mode: u16) -> Option<Self> {
|
|
match mode {
|
|
1 => Some(Self::Replace),
|
|
2 => Some(Self::Union),
|
|
3 => Some(Self::Difference),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|