summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authora-kenji <aks.kenji@protonmail.com>2021-05-07 10:09:26 +0200
committera-kenji <aks.kenji@protonmail.com>2021-05-07 10:51:35 +0200
commit79a4f76e93dd25c4eb71af18885b4c043807b78c (patch)
tree5aef2bcbd57fc2630ca1e01ab038fa0e9c697da3
parent23450a708c48d4f0bf65db81425168734fc85487 (diff)
Add more Functionality to Unbind
The default keybinds can be unbound either for a specific mode, or for every mode. It supports either a list of `keybinds`, or a bool indicating that every keybind should be unbound: ``` keybinds: unbind: true ``` Will unbind every default binding. ``` keybinds: unbind: [ Ctrl: 'p'] ``` Will unbind every default `^P` binding for each mode. ``` keybinds: normal: - unbind: true ``` Will unbind every default keybind for the `normal` mode. ``` keybinds: normal: - unbind: [ Alt: 'n', Ctrl: 'g'] ``` Will unbind every default keybind for `n` and `^g` for the `normal` mode.
-rw-r--r--docs/MANPAGE.md28
-rw-r--r--src/client/layout.rs2
-rw-r--r--src/common/input/keybinds.rs131
-rw-r--r--src/common/input/unit/keybinds_test.rs653
4 files changed, 800 insertions, 14 deletions
diff --git a/docs/MANPAGE.md b/docs/MANPAGE.md
index 6ef937c13..8f9f45b5c 100644
--- a/docs/MANPAGE.md
+++ b/docs/MANPAGE.md
@@ -101,6 +101,34 @@ where "normal" stands for a mode name (see MODES section), "action" part
specifies the actions to be executed by Zellij (see ACTIONS section) and "key"
is used to list keys or key combinations bound to given actions (see KEYS).
+The default keybinds can be unbound either for a specific mode, or for every mode.
+It supports either a list of `keybinds`, or a bool indicating that every keybind
+should be unbound:
+
+```
+keybinds:
+ unbind: true
+```
+Will unbind every default binding.
+
+```
+keybinds:
+ unbind: [ Ctrl: 'p']
+```
+Will unbind every default `^P` binding for each mode.
+```
+keybinds:
+ normal:
+ - unbind: true
+```
+Will unbind every default keybind for the `normal` mode.
+```
+keybinds:
+ normal:
+ - unbind: [ Alt: 'n', Ctrl: 'g']
+```
+Will unbind every default keybind for `n` and `^g` for the `normal` mode.
+
ACTIONS
-------
diff --git a/src/client/layout.rs b/src/client/layout.rs
index ca1adb4dc..3648ece90 100644
--- a/src/client/layout.rs
+++ b/src/client/layout.rs
@@ -206,7 +206,7 @@ impl Layout {
}
// It wants to use Path here, but that doesn't compile.
- #[warn(clippy::ptr_arg)]
+ #[allow(clippy::ptr_arg)]
pub fn from_defaults(layout_path: &PathBuf, data_dir: &Path) -> Self {
Self::new(
&data_dir
diff --git a/src/common/input/keybinds.rs b/src/common/input/keybinds.rs
index 9842fbe27..20f2de89a 100644
--- a/src/common/input/keybinds.rs
+++ b/src/common/input/keybinds.rs
@@ -30,7 +30,14 @@ pub struct KeybindsFromYaml {
enum KeyActionUnbind {
KeyAction(KeyActionFromYaml),
// TODO: use the enum
- //Unbind(UnbindFromYaml),
+ Unbind(UnbindFromYaml),
+}
+
+/// Intermediate struct used for deserialisation
+#[derive(Clone, Debug, PartialEq, Deserialize)]
+struct KeyActionUnbindFromYaml {
+ keybinds: Vec<KeyActionFromYaml>,
+ unbind: Unbind,
}
/// Intermediate struct used for deserialisation
@@ -41,7 +48,7 @@ pub struct KeyActionFromYaml {
}
/// Intermediate struct used for deserialisation
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
+#[derive(Clone, Debug, PartialEq, Deserialize)]
struct UnbindFromYaml {
unbind: Unbind,
}
@@ -51,16 +58,19 @@ struct UnbindFromYaml {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
#[serde(untagged)]
enum Unbind {
+ // This is the correct order, don't rearrange!
+ // Suspected Bug in the untagged macro.
+ // 1. Keys
+ Keys(Vec<Key>),
+ // 2. All
All(bool),
- // TODO@a-kenji: use the enum
- //Keys(Vec<Key>),
}
impl Default for Keybinds {
+ // Use once per codepath
+ // TODO investigate why
fn default() -> Keybinds {
- config::Config::from_default_assets()
- .expect("Keybinds from default assets Error")
- .keybinds
+ Self::from_default_assets()
}
}
@@ -69,11 +79,18 @@ impl Keybinds {
Keybinds(HashMap::<InputMode, ModeKeybinds>::new())
}
+ fn from_default_assets() -> Keybinds {
+ config::Config::from_default_assets()
+ .expect("Keybinds from default assets Error!")
+ .keybinds
+ }
+
+ /// Entrypoint from the config module
pub fn get_default_keybinds_with_config(from_yaml: Option<KeybindsFromYaml>) -> Keybinds {
let default_keybinds = match from_yaml.clone() {
Some(keybinds) => match keybinds.unbind {
Unbind::All(true) => Keybinds::new(),
- Unbind::All(false) => Keybinds::default(),
+ Unbind::All(false) | Unbind::Keys(_) => Keybinds::unbind(keybinds),
},
None => Keybinds::default(),
};
@@ -85,6 +102,71 @@ impl Keybinds {
}
}
+ /// Unbinds the default keybindings in relation to their mode
+ fn unbind(from_yaml: KeybindsFromYaml) -> Keybinds {
+ let mut keybind_config = Self::new();
+ let mut unbind_config: HashMap<InputMode, Unbind> = HashMap::new();
+ let keybinds_from_yaml = from_yaml.keybinds;
+
+ for mode in InputMode::iter() {
+ if let Some(keybinds) = keybinds_from_yaml.get(&mode) {
+ for keybind in keybinds.iter() {
+ match keybind {
+ KeyActionUnbind::Unbind(unbind) => {
+ unbind_config.insert(mode, unbind.unbind.clone());
+ }
+ KeyActionUnbind::KeyAction(key_action_from_yaml) => {
+ keybind_config
+ .0
+ .insert(mode, ModeKeybinds::from(key_action_from_yaml.clone()));
+ }
+ }
+ }
+ }
+ }
+
+ let mut default = Self::default().unbind_mode(unbind_config);
+
+ // Toplevel Unbinds
+ if let Unbind::Keys(_) = from_yaml.unbind {
+ let mut unbind_config: HashMap<InputMode, Unbind> = HashMap::new();
+ for mode in InputMode::iter() {
+ unbind_config.insert(mode, from_yaml.unbind.clone());
+ }
+ default = default.unbind_mode(unbind_config);
+ };
+
+ default.merge_keybinds(keybind_config)
+ }
+
+ /// Unbind [`Key`] bindings respective to their mode
+ fn unbind_mode(&self, unbind: HashMap<InputMode, Unbind>) -> Keybinds {
+ let mut keybinds = Keybinds::new();
+
+ for mode in InputMode::iter() {
+ if let Some(unbind) = unbind.get(&mode) {
+ match unbind {
+ Unbind::All(true) => {}
+ Unbind::Keys(keys) => {
+ if let Some(defaults) = self.0.get(&mode) {
+ keybinds
+ .0
+ .insert(mode, defaults.clone().unbind_keys(keys.to_vec()));
+ }
+ }
+ Unbind::All(false) => {
+ if let Some(defaults) = self.0.get(&mode) {
+ keybinds.0.insert(mode, defaults.clone());
+ }
+ }
+ }
+ } else if let Some(defaults) = self.0.get(&mode) {
+ keybinds.0.insert(mode, defaults.clone());
+ }
+ }
+ keybinds
+ }
+
/// Merges two Keybinds structs into one Keybinds struct
/// `other` overrides the ModeKeybinds of `self`.
fn merge_keybinds(&self, other: Keybinds) -> Keybinds {
@@ -142,6 +224,15 @@ impl ModeKeybinds {
merged.0.extend(other.0);
merged
}
+
+ /// Remove [`Key`]'s from [`ModeKeybinds`]
+ fn unbind_keys(self, unbind: Vec<Key>) -> Self {
+ let mut keymap = self;
+ for key in unbind {
+ keymap.0.remove(&key);
+ }
+ keymap
+ }
}
impl From<KeybindsFromYaml> for Keybinds {
@@ -161,27 +252,41 @@ impl From<KeybindsFromYaml> for Keybinds {
}
}
-/// For each `Key` assigned to `Action`s,
-/// map the `Action`s to the key
+/// For each [`Key`] assigned to [`Action`]s,
+/// map the [`Action`]s to the [`Key`]
impl From<KeyActionFromYaml> for ModeKeybinds {
fn from(key_action: KeyActionFromYaml) -> ModeKeybinds {
- let keys = key_action.key;
let actions = key_action.action;
ModeKeybinds(
- keys.into_iter()
+ key_action
+ .key
+ .into_iter()
.map(|k| (k, actions.clone()))
.collect::<HashMap<Key, Vec<Action>>>(),
)
}
}
-// Currently an enum for future use
impl From<KeyActionUnbind> for ModeKeybinds {
fn from(key_action_unbind: KeyActionUnbind) -> ModeKeybinds {
match key_action_unbind {
KeyActionUnbind::KeyAction(key_action) => ModeKeybinds::from(key_action),
+ KeyActionUnbind::Unbind(_) => ModeKeybinds::new(),
+ }
+ }
+}
+
+impl From<Vec<KeyActionFromYaml>> for ModeKeybinds {
+ fn from(key_action_from_yaml: Vec<KeyActionFromYaml>) -> ModeKeybinds {
+ let mut mode_keybinds = ModeKeybinds::new();
+
+ for keybind in key_action_from_yaml {
+ for key in keybind.key {
+ mode_keybinds.0.insert(key, keybind.action.clone());
+ }
}
+ mode_keybinds
}
}
diff --git a/src/common/input/unit/keybinds_test.rs b/src/common/input/unit/keybinds_test.rs
index e0d78b624..4767fc157 100644
--- a/src/common/input/unit/keybinds_test.rs
+++ b/src/common/input/unit/keybinds_test.rs
@@ -136,6 +136,7 @@ fn toplevel_unbind_unbinds_all() {
assert_eq!(keybinds_from_yaml, Keybinds::new());
}
+#[test]
fn no_unbind_unbinds_none() {
let from_yaml = KeybindsFromYaml {
unbind: Unbind::All(false),
@@ -144,5 +145,657 @@ fn no_unbind_unbinds_none() {
let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+ assert_eq!(keybinds_from_yaml, Keybinds::default());
+}
+
+#[test]
+fn last_keybind_is_taken() {
+ let actions_1 = vec![Action::NoOp, Action::NewTab];
+ let keyaction_1 = KeyActionFromYaml {
+ action: actions_1.clone(),
+ key: vec![Key::F(1), Key::Backspace, Key::Char('t')],
+ };
+ let actions_2 = vec![Action::GoToTab(1)];
+ let keyaction_2 = KeyActionFromYaml {
+ action: actions_2.clone(),
+ key: vec![Key::F(1), Key::Backspace, Key::Char('t')],
+ };
+
+ let mut expected = ModeKeybinds::new();
+ expected.0.insert(Key::F(1), actions_2.clone());
+ expected.0.insert(Key::Backspace, actions_2.clone());
+ expected.0.insert(Key::Char('t'), actions_2);
+
+ assert_eq!(expected, ModeKeybinds::from(vec![keyaction_1, keyaction_2]));
+}
+
+#[test]
+fn last_keybind_overwrites() {
+ let actions_1 = vec![Action::NoOp, Action::NewTab];
+ let keyaction_1 = KeyActionFromYaml {
+ action: actions_1.clone(),
+ key: vec![Key::F(1), Key::Backspace, Key::Char('t')],
+ };
+ let actions_2 = vec![Action::GoToTab(1)];
+ let keyaction_2 = KeyActionFromYaml {
+ action: actions_2.clone(),
+ key: vec![Key::F(1), Key::Char('t')],
+ };
+
+ let mut expected = ModeKeybinds::new();
+ expected.0.insert(Key::F(1), actions_2.clone());
+ expected.0.insert(Key::Backspace, actions_1.clone());
+ expected.0.insert(Key::Char('t'), actions_2);
+
+ assert_eq!(expected, ModeKeybinds::from(vec![keyaction_1, keyaction_2]));
+}
+
+#[test]
+fn unbind_single_mode() {
+ let unbind = Unbind::All(true);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbinds = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds);
+
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(false),
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let result = keybinds.0.get(&InputMode::Normal);
+ assert!(result.is_none());
+}
+
+#[test]
+fn unbind_multiple_modes() {
+ let unbind = Unbind::All(true);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbinds = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds.clone());
+ keys.insert(InputMode::Pane, key_action_unbinds);
+
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(false),
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let normal = keybinds.0.get(&InputMode::Normal);
+ let pane = keybinds.0.get(&InputMode::Pane);
+ assert!(normal.is_none());
+ assert!(pane.is_none());
+}
+
+#[test]
+fn unbind_single_keybind_single_mode() {
+ let unbind = Unbind::Keys(vec![Key::Alt('n')]);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbinds = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds);
+
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(false),
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let mode_keybinds = keybinds.0.get(&InputMode::Normal);
+ let result = mode_keybinds
+ .expect("Mode shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ assert!(result.is_none());
+}
+
+#[test]
+fn unbind_single_keybind_multiple_modes() {
+ let unbind_n = Unbind::Keys(vec![Key::Alt('n')]);
+ let unbind_h = Unbind::Keys(vec![Key::Alt('h')]);
+ let unbind_from_yaml_n = UnbindFromYaml { unbind: unbind_n };
+ let unbind_from_yaml_h = UnbindFromYaml { unbind: unbind_h };
+ let key_action_unbinds_n = vec![KeyActionUnbind::Unbind(unbind_from_yaml_n)];
+ let key_action_unbinds_h = vec![KeyActionUnbind::Unbind(unbind_from_yaml_h)];
+
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds_n);
+ keys.insert(InputMode::Pane, key_action_unbinds_h);
+
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(false),
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let normal = keybinds.0.get(&InputMode::Normal);
+ let pane = keybinds.0.get(&InputMode::Pane);
+ let result_normal = normal
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_pane = pane.expect("Mode shouldn't be empty").0.get(&Key::Alt('h'));
+ assert!(result_normal.is_none());
+ assert!(result_pane.is_none());
+}
+
+#[test]
+fn unbind_multiple_keybinds_single_mode() {
+ let unbind = Unbind::Keys(vec![Key::Alt('n'), Key::Ctrl('p')]);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbinds = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds);
+
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(false),
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let mode_keybinds = keybinds.0.get(&InputMode::Normal);
+ let result_n = mode_keybinds
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_p = mode_keybinds
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Ctrl('p'));
+ assert!(result_n.is_none());
+ assert!(result_p.is_none());
+}
+
+#[test]
+fn unbind_multiple_keybinds_multiple_modes() {
+ let unbind_normal = Unbind::Keys(vec![Key::Alt('n'), Key::Ctrl('p')]);
+ let unbind_resize = Unbind::Keys(vec![Key::Char('h'), Key::Ctrl('r')]);
+ let unbind_from_yaml_normal = UnbindFromYaml {
+ unbind: unbind_normal,
+ };
+ let unbind_from_yaml_resize = UnbindFromYaml {
+ unbind: unbind_resize,
+ };
+ let key_action_unbinds_normal = vec![KeyActionUnbind::Unbind(unbind_from_yaml_normal)];
+ let key_action_unbinds_resize = vec![KeyActionUnbind::Unbind(unbind_from_yaml_resize)];
+
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds_normal);
+ keys.insert(InputMode::Resize, key_action_unbinds_resize);
+
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(false),
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let mode_keybinds_normal = keybinds.0.get(&InputMode::Normal);
+ let mode_keybinds_resize = keybinds.0.get(&InputMode::Resize);
+ let result_normal_1 = mode_keybinds_normal
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_normal_2 = mode_keybinds_normal
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Ctrl('p'));
+ let result_resize_1 = mode_keybinds_resize
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Char('h'));
+ let result_resize_2 = mode_keybinds_resize
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Ctrl('r'));
+ assert!(result_normal_1.is_none());
+ assert!(result_resize_1.is_none());
+ assert!(result_normal_2.is_none());
+ assert!(result_resize_2.is_none());
+}
+
+#[test]
+fn unbind_multiple_keybinds_all_modes() {
+ let unbind = Unbind::Keys(vec![Key::Alt('n'), Key::Alt('h')]);
+ let keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ let keybinds_from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind,
+ };
+
+ let keybinds = Keybinds::unbind(keybinds_from_yaml);
+ let mode_keybinds_normal = keybinds.0.get(&InputMode::Normal);
+ let mode_keybinds_resize = keybinds.0.get(&InputMode::Resize);
+ let result_normal_1 = mode_keybinds_normal
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_normal_2 = mode_keybinds_normal
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Ctrl('h'));
+ let result_resize_1 = mode_keybinds_resize
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Char('n'));
+ let result_resize_2 = mode_keybinds_resize
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Ctrl('h'));
+ assert!(result_normal_1.is_none());
+ assert!(result_resize_1.is_none());
+ assert!(result_normal_2.is_none());
+ assert!(result_resize_2.is_none());
+}
+
+#[test]
+fn unbind_all_toplevel_single_key_single_mode() {
+ let unbind = Unbind::Keys(vec![Key::Alt('h')]);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbinds_normal = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds_normal);
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(true),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+ assert_eq!(keybinds_from_yaml, Keybinds::new());
+}
+
+#[test]
+fn unbind_all_toplevel_single_key_multiple_modes() {
+ let unbind_n = Unbind::Keys(vec![Key::Alt('n')]);
+ let unbind_h = Unbind::Keys(vec![Key::Alt('h')]);
+ let unbind_from_yaml_n = UnbindFromYaml { unbind: unbind_n };
+ let unbind_from_yaml_h = UnbindFromYaml { unbind: unbind_h };
+ let key_action_unbinds_normal = vec![KeyActionUnbind::Unbind(unbind_from_yaml_n)];
+ let key_action_unbinds_pane = vec![KeyActionUnbind::Unbind(unbind_from_yaml_h)];
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds_normal);
+ keys.insert(InputMode::Pane, key_action_unbinds_pane);
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(true),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+ assert_eq!(keybinds_from_yaml, Keybinds::new());
+}
+
+#[test]
+fn unbind_all_toplevel_multiple_key_multiple_modes() {
+ let unbind_n = Unbind::Keys(vec![Key::Alt('n'), Key::Ctrl('p')]);
+ let unbind_h = Unbind::Keys(vec![Key::Alt('h'), Key::Ctrl('t')]);
+ let unbind_from_yaml_n = UnbindFromYaml { unbind: unbind_n };
+ let unbind_from_yaml_h = UnbindFromYaml { unbind: unbind_h };
+ let key_action_unbinds_normal = vec![KeyActionUnbind::Unbind(unbind_from_yaml_n)];
+ let key_action_unbinds_pane = vec![KeyActionUnbind::Unbind(unbind_from_yaml_h)];
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds_normal);
+ keys.insert(InputMode::Pane, key_action_unbinds_pane);
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(true),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
assert_eq!(keybinds_from_yaml, Keybinds::new());
}
+
+#[test]
+fn unbind_all_toplevel_all_key_multiple_modes() {
+ let unbind = Unbind::All(true);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbinds_normal = vec![KeyActionUnbind::Unbind(unbind_from_yaml.clone())];
+ let key_action_unbinds_pane = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbinds_normal);
+ keys.insert(InputMode::Pane, key_action_unbinds_pane);
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::All(true),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+ assert_eq!(keybinds_from_yaml, Keybinds::new());
+}
+
+#[test]
+fn unbind_single_keybind_all_modes() {
+ let keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::Keys(vec![Key::Alt('n')]),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+
+ let result_normal = keybinds_from_yaml
+ .0
+ .get(&InputMode::Normal)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_pane = keybinds_from_yaml
+ .0
+ .get(&InputMode::Pane)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_resize = keybinds_from_yaml
+ .0
+ .get(&InputMode::Resize)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_tab = keybinds_from_yaml
+ .0
+ .get(&InputMode::Tab)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+
+ assert!(result_normal.is_none());
+ assert!(result_pane.is_none());
+ assert!(result_resize.is_none());
+ assert!(result_tab.is_none());
+}
+
+#[test]
+fn unbind_single_toplevel_single_key_single_mode_identical() {
+ let unbind = Unbind::Keys(vec![Key::Alt('n')]);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbind = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbind);
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::Keys(vec![Key::Alt('n')]),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+
+ let result_normal = keybinds_from_yaml
+ .0
+ .get(&InputMode::Normal)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_pane = keybinds_from_yaml
+ .0
+ .get(&InputMode::Pane)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_resize = keybinds_from_yaml
+ .0
+ .get(&InputMode::Resize)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_tab = keybinds_from_yaml
+ .0
+ .get(&InputMode::Tab)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+
+ assert!(result_normal.is_none());
+ assert!(result_pane.is_none());
+ assert!(result_resize.is_none());
+ assert!(result_tab.is_none());
+}
+
+#[test]
+fn unbind_single_toplevel_single_key_single_mode_differing() {
+ let unbind = Unbind::Keys(vec![Key::Alt('l')]);
+ let unbind_from_yaml = UnbindFromYaml { unbind };
+ let key_action_unbind = vec![KeyActionUnbind::Unbind(unbind_from_yaml)];
+ let mut keys = HashMap::<InputMode, Vec<KeyActionUnbind>>::new();
+ keys.insert(InputMode::Normal, key_action_unbind);
+ let from_yaml = KeybindsFromYaml {
+ keybinds: keys,
+ unbind: Unbind::Keys(vec![Key::Alt('n')]),
+ };
+
+ let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
+
+ let result_normal_n = keybinds_from_yaml
+ .0
+ .get(&InputMode::Normal)
+ .expect("ModeKeybinds shouldn't be empty")
+ .0
+ .get(&Key::Alt('n'));
+ let result_normal_l = keybinds_from_yaml
+