From 7f54706cab9c64139e382936303a484c9c2726d3 Mon Sep 17 00:00:00 2001 From: TrMen <31260183+TrMen@users.noreply.github.com> Date: Fri, 5 May 2023 12:38:28 +0200 Subject: [PATCH] Allow binding of CTRL+ALT+, CTRL+ALT+SHIFT+, and (#580) Combinations like `Ctrl+Alt+a` could not be mapped previously, since some non-us keyboard layouts use those combinations for sending characters like `@`. Now, first check if there a binding was defined using that combination, else interpret as raw characters. This should not affect those special keyboard layouts, since they would be sending `Ctrl+Alt+`, rather than what would be on the US layout. E.g. - Map `Ctrl+Alt+a` to an action - `Ctrl+Alt+a` on (some) german keyboards would send `@` - A german layout pressing those keys would send a key combination of `Ctrl+Alt+@`, so they are unaffected by this change (they would have to specifically map `Ctrl+Alt+@`) - For any layout actually sending `Ctrl+Alt+a`, they get the mapped action This also allows the user to bind a keybinding without modifiers. This affects emacs mode and vi insert mode (vi normal mode already allows such keybindings). --- src/edit_mode/emacs.rs | 38 +++++++++++++++++++++----------------- src/edit_mode/vi/mod.rs | 38 +++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/edit_mode/emacs.rs b/src/edit_mode/emacs.rs index 7609280..35aa6db 100644 --- a/src/edit_mode/emacs.rs +++ b/src/edit_mode/emacs.rs @@ -127,24 +127,28 @@ impl EditMode for Emacs { _ => c.to_ascii_lowercase(), }; - if modifier == KeyModifiers::NONE - || modifier == KeyModifiers::SHIFT - || modifier == KeyModifiers::CONTROL | KeyModifiers::ALT - || modifier - == KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT - { - ReedlineEvent::Edit(vec![EditCommand::InsertChar( - if modifier == KeyModifiers::SHIFT { - c.to_ascii_uppercase() + self.keybindings + .find_binding(modifier, KeyCode::Char(c)) + .unwrap_or_else(|| { + if modifier == KeyModifiers::NONE + || modifier == KeyModifiers::SHIFT + || modifier == KeyModifiers::CONTROL | KeyModifiers::ALT + || modifier + == KeyModifiers::CONTROL + | KeyModifiers::ALT + | KeyModifiers::SHIFT + { + ReedlineEvent::Edit(vec![EditCommand::InsertChar( + if modifier == KeyModifiers::SHIFT { + c.to_ascii_uppercase() + } else { + c + }, + )]) } else { - c - }, - )]) - } else { - self.keybindings - .find_binding(modifier, KeyCode::Char(c)) - .unwrap_or(ReedlineEvent::None) - } + ReedlineEvent::None + } + }) } _ => self .keybindings diff --git a/src/edit_mode/vi/mod.rs b/src/edit_mode/vi/mod.rs index 12d95e6..4428c64 100644 --- a/src/edit_mode/vi/mod.rs +++ b/src/edit_mode/vi/mod.rs @@ -111,24 +111,28 @@ impl EditMode for Vi { _ => c.to_ascii_lowercase(), }; - if modifier == KeyModifiers::NONE - || modifier == KeyModifiers::SHIFT - || modifier == KeyModifiers::CONTROL | KeyModifiers::ALT - || modifier - == KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT - { - ReedlineEvent::Edit(vec![EditCommand::InsertChar( - if modifier == KeyModifiers::SHIFT { - c.to_ascii_uppercase() + self.insert_keybindings + .find_binding(modifier, KeyCode::Char(c)) + .unwrap_or_else(|| { + if modifier == KeyModifiers::NONE + || modifier == KeyModifiers::SHIFT + || modifier == KeyModifiers::CONTROL | KeyModifiers::ALT + || modifier + == KeyModifiers::CONTROL + | KeyModifiers::ALT + | KeyModifiers::SHIFT + { + ReedlineEvent::Edit(vec![EditCommand::InsertChar( + if modifier == KeyModifiers::SHIFT { + c.to_ascii_uppercase() + } else { + c + }, + )]) } else { - c - }, - )]) - } else { - self.insert_keybindings - .find_binding(modifier, KeyCode::Char(c)) - .unwrap_or(ReedlineEvent::None) - } + ReedlineEvent::None + } + }) } (_, KeyModifiers::NONE, KeyCode::Esc) => { self.cache.clear();