From 01554367f00f7c39ad17163cd5922a069284844a Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Mon, 11 Oct 2021 01:15:39 -0600 Subject: Make keybindings more consistent with libtermkey --- alacritty/src/config/bindings.rs | 12 ++++++--- alacritty/src/config/ui_config.rs | 2 +- alacritty/src/input.rs | 55 +++++++++++++++++++++++---------------- 3 files changed, 42 insertions(+), 27 deletions(-) (limited to 'alacritty') diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 9f4bbaee..dc648541 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -1,5 +1,6 @@ #![allow(clippy::enum_glob_use)] +use log::{trace}; use std::fmt::{self, Debug, Display}; use bitflags::bitflags; @@ -47,16 +48,21 @@ pub type KeyBinding = Binding; /// Bindings that are triggered by a mouse button. pub type MouseBinding = Binding; -impl Binding { +impl Binding { #[inline] pub fn is_triggered_by(&self, mode: BindingMode, mods: ModifiersState, input: &T) -> bool { // Check input first since bindings are stored in one big list. This is // the most likely item to fail so prioritizing it here allows more // checks to be short circuited. - self.trigger == *input + if self.trigger == *input && self.mods == mods && mode.contains(self.mode) - && !mode.intersects(self.notmode) + && !mode.intersects(self.notmode) { + trace!("Hit trigger on {:#?}, {:#?}", input, mode); + true + } else { + false + } } #[inline] diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index 3ce02161..f05b243c 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -173,7 +173,7 @@ fn deserialize_bindings<'a, D, T>( ) -> Result>, D::Error> where D: Deserializer<'a>, - T: Copy + Eq, + T: Copy + Eq + std::fmt::Debug, Binding: Deserialize<'a>, { let values = Vec::::deserialize(deserializer)?; diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index a3b9fdf9..7851b6e4 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -790,36 +790,45 @@ impl> Processor { self.ctx.clear_selection(); let utf8_len = c.len_utf8(); - let mut char_bytes = Vec::with_capacity(utf8_len); let mut all_bytes = Vec::new(); - unsafe { - char_bytes.set_len(utf8_len); - c.encode_utf8(&mut char_bytes[..]); - } - if self.ctx.config().ui_config.alt_send_esc - && *self.ctx.received_count() == 0 - && self.ctx.modifiers().alt() - { - all_bytes.push(b'\x1b'); - } + let shift = self.ctx.modifiers().shift(); + let alt = self.ctx.modifiers().alt(); + let ctrl = self.ctx.modifiers().ctrl(); + let logo = self.ctx.modifiers().logo(); - if self.ctx.modifiers().logo() - { - // In this case, either the Hyper or Windows key is held down, in - // this case prepend with '^[[2;8~', whic is . THis - // is better keybinding in Vim. - all_bytes.append(&mut vec![b'\x1b', b'[', b'2', b';', b'8', b'~']); + fn encode_extended_ctrl_char(c: char) -> bool { + return ! c.is_ascii_control() + || c == '\n' + || c == '\r' + || c == '\x07'; } - if self.ctx.modifiers().ctrl() && utf8_len > 1 { - // In this case, it's a multibyte character that also has CTRL - // down. This prepends said character with '^[[1;8H', which - // is . This is for even better keybinding in vim. - all_bytes.append(&mut vec![b'\x1b', b'[', b'1', b';', b'8', b'H']); + if ((shift || alt || encode_extended_ctrl_char(c)) && ctrl) || logo { + // Special, extended character code + let modifier_code = + 1 + (shift as u32) + (alt as u32) * 2 + (ctrl as u32) * 4 + (logo as u32) * 8; + + let out = format!("\x1b[{};{}u", c as u32, modifier_code); + all_bytes.append(&mut out.into_bytes()); + } else { + let mut char_bytes = Vec::with_capacity(utf8_len); + + unsafe { + char_bytes.set_len(utf8_len); + c.encode_utf8(&mut char_bytes[..]); + } + + if self.ctx.config().ui_config.alt_send_esc + && *self.ctx.received_count() == 0 + && alt + { + all_bytes.push(b'\x1b'); + } + + all_bytes.append(&mut char_bytes); } - all_bytes.append(&mut char_bytes); self.ctx.write_to_pty(all_bytes); *self.ctx.received_count() += 1; -- cgit