Skip to content

Commit

Permalink
Kitty protocol
Browse files Browse the repository at this point in the history
changes retired by alacritty/alacritty#7125
  • Loading branch information
raphamorim committed Aug 28, 2023
1 parent 9f3c7be commit cd463ca
Show file tree
Hide file tree
Showing 13 changed files with 678 additions and 260 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,7 +2,9 @@

## In progress

- *breaking change*: Action `TabSwitchNext` and `TabSwitchPrev` has been renamed to `SelectNextTab` and `SelectPrevTab`.
- Support to `NativeTab` (MacOS only).
- Support for kitty's keyboard protocol (`CSI u`). Ref: https://sw.kovidgoyal.net/kitty/keyboard-protocol/
- Added new actions for tab selection: `SelectTab1`, `SelectTab2`, `SelectTab3`, `SelectTab4`, `SelectTab5`, `SelectTab6`, `SelectTab7`, `SelectTab8`, `SelectTab9`, `SelectLastTab`.
- Support lowercased action and fix overwrite for actions in custom key bindings.
- Added action `Minimize` for minimize Rio terminal window.
Expand Down
35 changes: 6 additions & 29 deletions config/src/bindings.rs
@@ -1,6 +1,7 @@
use serde::Deserialize;

// { key = "W", mods: "super", action = "Quit" }
// Examples:
// { key = "w", mods: "super", action = "quit" }
// Bytes[27, 91, 53, 126] is equivalent to "\x1b[5~"
// { key = "Home", mods: "super | shift", bytes = [27, 91, 53, 126] }

Expand All @@ -26,30 +27,6 @@ pub struct Bindings {
pub keys: KeyBindings,
}

// pub(crate) fn bytes_deserialize<'de, D>(de: D) -> Result<Vec<u8>, D::Error>
// where
// D: Deserializer<'de>,
// {
// de.deserialize_byte_buf(ByteBufVisitor)
// }

// struct ByteBufVisitor;

// impl<'de> Visitor<'de> for ByteBufVisitor {
// type Value = String;

// fn expecting(&self, out: &mut fmt::Formatter) -> fmt::Result {
// out.write_str("string")
// }

// fn visit_str<E>(self, v: &str) -> Result<String, E>
// where
// E: Error,
// {
// Ok(v.to_string())
// }
// }

#[cfg(test)]
mod tests {

Expand Down Expand Up @@ -137,8 +114,8 @@ mod tests {
{ key = '-', with = 'super', action = 'decreasefontsize' },
{ key = '0', with = 'super', action = 'resetfontsize' },
{ key = '[', with = 'super | shift', action = 'tabswitchnext' },
{ key = ']', with = 'super | shift', action = 'tabswitchprev' },
{ key = '[', with = 'super | shift', action = 'selectnexttab' },
{ key = ']', with = 'super | shift', action = 'selectprevtab' },
]
"#;

Expand Down Expand Up @@ -172,12 +149,12 @@ mod tests {

assert_eq!(decoded.bindings.keys[4].key, "[");
assert_eq!(decoded.bindings.keys[4].with, "super | shift");
assert_eq!(decoded.bindings.keys[4].action.to_owned(), "tabswitchnext");
assert_eq!(decoded.bindings.keys[4].action.to_owned(), "selectnexttab");
assert!(decoded.bindings.keys[4].text.to_owned().is_empty());

assert_eq!(decoded.bindings.keys[5].key, "]");
assert_eq!(decoded.bindings.keys[5].with, "super | shift");
assert_eq!(decoded.bindings.keys[5].action.to_owned(), "tabswitchprev");
assert_eq!(decoded.bindings.keys[5].action.to_owned(), "selectprevtab");
assert!(decoded.bindings.keys[5].text.to_owned().is_empty());
}
}
4 changes: 2 additions & 2 deletions docs/docs/custom-key-bindings.md
Expand Up @@ -43,12 +43,12 @@ Quit
ResetFontSize
IncreaseFontSize
DecreaseFontSize
TabSwitchNext
TabSwitchPrev
CreateWindow
CreateTab
CloseTab
OpenConfigEditor
SelectPrevTab
SelectNextTab
SelectTab1
SelectTab2
SelectTab3
Expand Down
19 changes: 19 additions & 0 deletions docs/features/index.md
Expand Up @@ -17,6 +17,7 @@ Short introduction of Rio terminal features. Many other features are in developm
- [• Spawn or Fork processes](#spawn-or-fork)
- [• Collapsed tabs, breadcrumb, expanded tabs on top or bottom](#navigation)
- [• Colorize tabs based on programs](#color-automation-for-navigation)
- [• Kitty's keyboard protocol](#kitty-keyboard-protocol)

### Cross-platform

Expand Down Expand Up @@ -96,3 +97,21 @@ color-automation = [
{ program = "nvim", color = "#FFFF00" }
]
{% endhighlight %}

### Kitty keyboard protocol

Rio terminal implements Kitty keyboard protocol.

There are various problems with the current state of keyboard handling in terminals. They include:

- • No way to use modifiers other than ctrl and alt

- • No way to reliably use multiple modifier keys, other than, shift+alt and ctrl+alt.

- • Many of the existing escape codes used to encode these events are ambiguous with different key presses mapping to the same escape code.

- • No way to handle different types of keyboard events, such as press, release or repeat

- • No reliable way to distinguish single Esc key presses from the start of a escape sequence. Currently, client programs use fragile timing related hacks for this, leading to bugs, for example: [neovim #2035](https://github.com/neovim/neovim/issues/2035).

To solve these issues and others, kitty has created a new keyboard protocol, that is backward compatible but allows applications to opt-in to support more advanced usages.
39 changes: 39 additions & 0 deletions rio/src/ansi/mod.rs
@@ -1,3 +1,5 @@
use bitflags::bitflags;

pub mod charset;
pub mod control;
pub mod mode;
Expand Down Expand Up @@ -53,3 +55,40 @@ pub enum LineClearMode {
/// Clear entire line.
All,
}

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,
}

0 comments on commit cd463ca

Please sign in to comment.