From 151767a5e39a5775cde3c710c5940249133b1c50 Mon Sep 17 00:00:00 2001 From: replcat Date: Tue, 24 Sep 2024 23:37:04 +1000 Subject: [PATCH] Support kitty key modifiers in keybindings (#13906) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description hi hi, this makes the parsing of modifier key combos in config more general, and adds support for additional kitty keyboard protocol modifiers. It seems that support for [kitty keys](https://sw.kovidgoyal.net/kitty/keyboard-protocol) had already been added to nushell in https://github.com/nushell/nushell/pull/10540, and this was the only missing piece to making them available in keybindings. # User-Facing Changes - keybindings in config can include the super, hyper and meta modifiers (e.g. `modifier: super`, `modifier: shift_super`, etc.), and these modifiers will work in supporting terminals (kitty, foot, wezterm, alacritty...) - all permutations of snake_cased modifier combinations now behave equivalently for the purpose of describing keybindings in config (e.g. `control_alt_shift` was previously supported where `shift_control_alt` was a config error — now they're the same) # Tests None of this looks to be tested at the moment. I only found a smoke test under the nu-cli crate, and I couldn't break tests elsewhere by stuffing around with modifier handling. Works on my machine, though! ✨🌈 --- crates/nu-cli/src/reedline_config.rs | 41 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/crates/nu-cli/src/reedline_config.rs b/crates/nu-cli/src/reedline_config.rs index 6c3d457612..dacdca3cae 100644 --- a/crates/nu-cli/src/reedline_config.rs +++ b/crates/nu-cli/src/reedline_config.rs @@ -761,28 +761,29 @@ fn add_parsed_keybinding( keybinding: &ParsedKeybinding, config: &Config, ) -> Result<(), ShellError> { - let modifier = match keybinding + let modifier_string = keybinding .modifier .to_expanded_string("", config) - .to_ascii_lowercase() - .as_str() - { - "control" => KeyModifiers::CONTROL, - "shift" => KeyModifiers::SHIFT, - "alt" => KeyModifiers::ALT, - "none" => KeyModifiers::NONE, - "shift_alt" | "alt_shift" => KeyModifiers::SHIFT | KeyModifiers::ALT, - "control_shift" | "shift_control" => KeyModifiers::CONTROL | KeyModifiers::SHIFT, - "control_alt" | "alt_control" => KeyModifiers::CONTROL | KeyModifiers::ALT, - "control_alt_shift" | "control_shift_alt" => { - KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT - } - _ => { - return Err(ShellError::UnsupportedConfigValue { - expected: "CONTROL, SHIFT, ALT or NONE".to_string(), - value: keybinding.modifier.to_abbreviated_string(config), - span: keybinding.modifier.span(), - }) + .to_ascii_lowercase(); + + let mut modifier = KeyModifiers::NONE; + if modifier_string != "none" { + for part in modifier_string.split('_') { + match part { + "control" => modifier |= KeyModifiers::CONTROL, + "shift" => modifier |= KeyModifiers::SHIFT, + "alt" => modifier |= KeyModifiers::ALT, + "super" => modifier |= KeyModifiers::SUPER, + "hyper" => modifier |= KeyModifiers::HYPER, + "meta" => modifier |= KeyModifiers::META, + _ => { + return Err(ShellError::UnsupportedConfigValue { + expected: "CONTROL, SHIFT, ALT, SUPER, HYPER, META or NONE".to_string(), + value: keybinding.modifier.to_abbreviated_string(config), + span: keybinding.modifier.span(), + }) + } + } } };