From 4e2dac5f80e97d3a55e5fb8364de05e509228d47 Mon Sep 17 00:00:00 2001 From: postsolar <120750161+postsolar@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:05:50 +0200 Subject: [PATCH] Add `unbind_default_keys` config option Based on https://github.com/helix-editor/helix/pull/2733/ --- book/src/remapping.md | 18 ++++++++++++++++++ helix-term/src/config.rs | 14 ++++++++++++-- helix-term/src/keymap.rs | 17 +++++++++-------- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/book/src/remapping.md b/book/src/remapping.md index d762c6add4fc..544faa977da4 100644 --- a/book/src/remapping.md +++ b/book/src/remapping.md @@ -75,5 +75,23 @@ Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes Keys can be disabled by binding them to the `no_op` command. +To remove all default bindings, `unbind-default-keys = true` can be added to the top level configuration. + +```toml +unbind_default_keys = true + +# Only these normal mode bindings will be used +[keys.normal] +n = "normal_mode" +t = "goto_definition" + +# remember to add bindings to return to normal mode +[keys.select] +esc = "normal_mode" + +[keys.insert] +esc = "normal_mode" +``` + A list of commands is available in the [Keymap](https://docs.helix-editor.com/keymap.html) documentation and in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs) at the invocation of `static_commands!` macro and the `TypableCommandList`. diff --git a/helix-term/src/config.rs b/helix-term/src/config.rs index bcba8d8e1d45..9372cd1d8764 100644 --- a/helix-term/src/config.rs +++ b/helix-term/src/config.rs @@ -20,6 +20,8 @@ pub struct Config { #[serde(deny_unknown_fields)] pub struct ConfigRaw { pub theme: Option, + #[serde(default)] + pub unbind_default_keys: bool, pub keys: Option>, pub editor: Option, } @@ -66,7 +68,11 @@ impl Config { local.and_then(|file| toml::from_str(&file).map_err(ConfigLoadError::BadConfig)); let res = match (global_config, local_config) { (Ok(global), Ok(local)) => { - let mut keys = keymap::default(); + let mut keys; + match local.unbind_default_keys { + true => keys = HashMap::default(), + false => keys = keymap::default(), + } if let Some(global_keys) = global.keys { merge_keys(&mut keys, global_keys) } @@ -96,7 +102,11 @@ impl Config { return Err(ConfigLoadError::BadConfig(err)) } (Ok(config), Err(_)) | (Err(_), Ok(config)) => { - let mut keys = keymap::default(); + let mut keys; + match config.unbind_default_keys { + true => keys = HashMap::default(), + false => keys = keymap::default(), + } if let Some(keymap) = config.keys { merge_keys(&mut keys, keymap); } diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 975274ed1d73..cb3d3c63a547 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -318,7 +318,10 @@ impl Keymaps { pub fn get(&mut self, mode: Mode, key: KeyEvent) -> KeymapResult { // TODO: remove the sticky part and look up manually let keymaps = &*self.map(); - let keymap = &keymaps[&mode]; + let keymap = match keymaps.get(&mode) { + Some(keymap) => keymap, + None => return KeymapResult::NotFound, + }; if key!(Esc) == key { if !self.state.is_empty() { @@ -373,14 +376,12 @@ impl Default for Keymaps { } } -/// Merge default config keys with user overwritten keys for custom user config. +/// Merge existing config keys with user overwritten keys. pub fn merge_keys(dst: &mut HashMap, mut delta: HashMap) { - for (mode, keys) in dst { - keys.merge_nodes( - delta - .remove(mode) - .unwrap_or_else(|| KeyTrie::Node(KeyTrieNode::default())), - ) + for (mode, keys) in delta.drain() { + dst.entry(mode) + .or_insert(KeyTrie::Node(KeyTrieNode::default())) + .merge_nodes(keys) } }