Don't use kitty sequences outside protocol

Originally kitty defined that functional keys, which are not encoded
by default, like `Pause` should be encoded with `CSI u`. However
the specification was clarified and now it says that terminal
may ignore that part. Given that Alacritty tries to follow xterm/urxvt
when it comes to bindings, CSI u bindings are not send for consistency
reasons.

This also brings back F13-F20 bindings used by Alacritty in 0.12.3, as
well as explicitly defines `NumpadEnter` like it was before.

Closes #7623.
This commit is contained in:
Kirill Chibisov 2024-01-31 00:11:16 +04:00 committed by GitHub
parent 7c046f5ae6
commit 38d63abd5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 36 deletions

View File

@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- No unused-key warnings will be emitted for OS-specific config keys
- Use built-in font for sextant symbols from `U+1FB00` to `U+1FB3B`
- Kitty encoding is not used anymore for uncommon keys unless the protocol enabled
## 0.13.1

View File

@ -453,6 +453,7 @@ pub fn default_key_bindings() -> Vec<KeyBinding> {
Backspace, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x7f".into());
Backspace, ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x1b\x7f".into());
Backspace, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC; Action::Esc("\x7f".into());
Enter => KeyLocation::Numpad, ~BindingMode::VI, ~BindingMode::SEARCH, ~BindingMode::REPORT_ALL_KEYS_AS_ESC, ~BindingMode::DISAMBIGUATE_ESC_CODES; Action::Esc("\n".into());
// Vi mode.
Space, ModifiersState::SHIFT | ModifiersState::CONTROL, ~BindingMode::SEARCH; Action::ToggleViMode;
Space, ModifiersState::SHIFT | ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollToBottom;

View File

@ -284,7 +284,8 @@ fn build_sequence(key: KeyEvent, mods: ModifiersState, mode: TermMode) -> Vec<u8
let sequence_base = context
.try_build_numpad(&key)
.or_else(|| context.try_build_named(&key))
.or_else(|| context.try_build_named_kitty(&key))
.or_else(|| context.try_build_named_normal(&key))
.or_else(|| context.try_build_control_char_or_mod(&key, &mut modifiers))
.or_else(|| context.try_build_textual(&key, associated_text));
@ -430,45 +431,17 @@ impl SequenceBuilder {
Some(SequenceBase::new(base.into(), SequenceTerminator::Kitty))
}
/// Try building from [`NamedKey`].
fn try_build_named(&self, key: &KeyEvent) -> Option<SequenceBase> {
/// Try building from [`NamedKey`] using the kitty keyboard protocol encoding
/// for functional keys.
fn try_build_named_kitty(&self, key: &KeyEvent) -> Option<SequenceBase> {
let named = match key.logical_key {
Key::Named(named) => named,
Key::Named(named) if self.kitty_seq => named,
_ => return None,
};
// The default parameter is 1, so we can omit it.
let one_based = if self.modifiers.is_empty() && !self.kitty_event_type { "" } else { "1" };
let (base, terminator) = match named {
NamedKey::PageUp => ("5", SequenceTerminator::Normal('~')),
NamedKey::PageDown => ("6", SequenceTerminator::Normal('~')),
NamedKey::Insert => ("2", SequenceTerminator::Normal('~')),
NamedKey::Delete => ("3", SequenceTerminator::Normal('~')),
NamedKey::Home => (one_based, SequenceTerminator::Normal('H')),
NamedKey::End => (one_based, SequenceTerminator::Normal('F')),
NamedKey::ArrowLeft => (one_based, SequenceTerminator::Normal('D')),
NamedKey::ArrowRight => (one_based, SequenceTerminator::Normal('C')),
NamedKey::ArrowUp => (one_based, SequenceTerminator::Normal('A')),
NamedKey::ArrowDown => (one_based, SequenceTerminator::Normal('B')),
NamedKey::F1 => (one_based, SequenceTerminator::Normal('P')),
NamedKey::F2 => (one_based, SequenceTerminator::Normal('Q')),
NamedKey::F3 => {
// F3 in kitty protocol diverges from alacritty's terminfo.
if self.kitty_seq {
("13", SequenceTerminator::Normal('~'))
} else {
(one_based, SequenceTerminator::Normal('R'))
}
},
NamedKey::F4 => (one_based, SequenceTerminator::Normal('S')),
NamedKey::F5 => ("15", SequenceTerminator::Normal('~')),
NamedKey::F6 => ("17", SequenceTerminator::Normal('~')),
NamedKey::F7 => ("18", SequenceTerminator::Normal('~')),
NamedKey::F8 => ("19", SequenceTerminator::Normal('~')),
NamedKey::F9 => ("20", SequenceTerminator::Normal('~')),
NamedKey::F10 => ("21", SequenceTerminator::Normal('~')),
NamedKey::F11 => ("23", SequenceTerminator::Normal('~')),
NamedKey::F12 => ("24", SequenceTerminator::Normal('~')),
// F3 in kitty protocol diverges from alacritty's terminfo.
NamedKey::F3 => ("13", SequenceTerminator::Normal('~')),
NamedKey::F13 => ("57376", SequenceTerminator::Kitty),
NamedKey::F14 => ("57377", SequenceTerminator::Kitty),
NamedKey::F15 => ("57378", SequenceTerminator::Kitty),
@ -514,6 +487,52 @@ impl SequenceBuilder {
Some(SequenceBase::new(base.into(), terminator))
}
/// Try building from [`NamedKey`].
fn try_build_named_normal(&self, key: &KeyEvent) -> Option<SequenceBase> {
let named = match key.logical_key {
Key::Named(named) => named,
_ => return None,
};
// The default parameter is 1, so we can omit it.
let one_based = if self.modifiers.is_empty() && !self.kitty_event_type { "" } else { "1" };
let (base, terminator) = match named {
NamedKey::PageUp => ("5", SequenceTerminator::Normal('~')),
NamedKey::PageDown => ("6", SequenceTerminator::Normal('~')),
NamedKey::Insert => ("2", SequenceTerminator::Normal('~')),
NamedKey::Delete => ("3", SequenceTerminator::Normal('~')),
NamedKey::Home => (one_based, SequenceTerminator::Normal('H')),
NamedKey::End => (one_based, SequenceTerminator::Normal('F')),
NamedKey::ArrowLeft => (one_based, SequenceTerminator::Normal('D')),
NamedKey::ArrowRight => (one_based, SequenceTerminator::Normal('C')),
NamedKey::ArrowUp => (one_based, SequenceTerminator::Normal('A')),
NamedKey::ArrowDown => (one_based, SequenceTerminator::Normal('B')),
NamedKey::F1 => (one_based, SequenceTerminator::Normal('P')),
NamedKey::F2 => (one_based, SequenceTerminator::Normal('Q')),
NamedKey::F3 => (one_based, SequenceTerminator::Normal('R')),
NamedKey::F4 => (one_based, SequenceTerminator::Normal('S')),
NamedKey::F5 => ("15", SequenceTerminator::Normal('~')),
NamedKey::F6 => ("17", SequenceTerminator::Normal('~')),
NamedKey::F7 => ("18", SequenceTerminator::Normal('~')),
NamedKey::F8 => ("19", SequenceTerminator::Normal('~')),
NamedKey::F9 => ("20", SequenceTerminator::Normal('~')),
NamedKey::F10 => ("21", SequenceTerminator::Normal('~')),
NamedKey::F11 => ("23", SequenceTerminator::Normal('~')),
NamedKey::F12 => ("24", SequenceTerminator::Normal('~')),
NamedKey::F13 => ("25", SequenceTerminator::Normal('~')),
NamedKey::F14 => ("26", SequenceTerminator::Normal('~')),
NamedKey::F15 => ("28", SequenceTerminator::Normal('~')),
NamedKey::F16 => ("29", SequenceTerminator::Normal('~')),
NamedKey::F17 => ("31", SequenceTerminator::Normal('~')),
NamedKey::F18 => ("32", SequenceTerminator::Normal('~')),
NamedKey::F19 => ("33", SequenceTerminator::Normal('~')),
NamedKey::F20 => ("34", SequenceTerminator::Normal('~')),
_ => return None,
};
Some(SequenceBase::new(base.into(), terminator))
}
/// Try building escape from control characters (e.g. Enter) and modifiers.
fn try_build_control_char_or_mod(
&self,
@ -596,7 +615,7 @@ impl SequenceBase {
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SequenceTerminator {
/// The normal key esc sequence terminator defined by xterm/dec.
Normal(char),