Skip to content

Commit

Permalink
Don't use kitty sequences outside protocol
Browse files Browse the repository at this point in the history
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 alacritty#7623.
  • Loading branch information
kchibisov committed Jan 30, 2024
1 parent 7c046f5 commit fe7b22a
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions alacritty/src/config/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
91 changes: 55 additions & 36 deletions alacritty/src/input/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit fe7b22a

Please sign in to comment.