Merge pull request #275 from a-kenji/unbind-default-keys

Unbind default keys
This commit is contained in:
a-kenji 2021-04-17 15:21:12 +02:00 committed by GitHub
commit d5be5e3a84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 309 additions and 16 deletions

View file

@ -45,8 +45,11 @@ An example file can be found under `example/config.yaml`.
Zellij will look for a file `/zellij/config.yaml` in the default configuration location of your os. Zellij will look for a file `/zellij/config.yaml` in the default configuration location of your os.
To pass a config file directly to zellij run it either with: * To ignore the default config file location:
`cargo run -- config [FILE]` or `zellij config [FILE]`. `zellij config --clean` or `cargo make run -- config --clean`
* To pass a config file directly to zellij run it either with:
`zellij config [FILE]` or `cargo make run -- config [FILE]` .
The structure is as follows: The structure is as follows:
``` ```
@ -77,6 +80,13 @@ keybinds:
``` ```
Will create a new tab on pressing either the `c` or the `d` key. Will create a new tab on pressing either the `c` or the `d` key.
* It is possible to unbind the default Keybindings:
```
keybinds:
unbind: true
```
# What is the current status of the project? # What is the current status of the project?
Zellij is in the last stages of being VT compatible. As much as modern terminals are. Zellij is in the last stages of being VT compatible. As much as modern terminals are.

5
example/README.md Normal file
View file

@ -0,0 +1,5 @@
# Special considerations when using the configuration:
While trying to bind the newline character in the Config, use double quotes:
`Ctrl: "\n"` instead of `Ctrl: '\n'`

211
example/default.yaml Normal file
View file

@ -0,0 +1,211 @@
---
keybinds:
unbind: true
normal:
- action: [SwitchToMode: Locked,]
key: [Ctrl: 'g',]
- action: [SwitchToMode: Pane,]
key: [Ctrl: 'p',]
- action: [SwitchToMode: Resize,]
key: [Ctrl: 'r',]
- action: [SwitchToMode: Tab,]
key: [Ctrl: 't',]
- action: [SwitchToMode: Scroll,]
key: [Ctrl: 's',]
- action: [Quit,]
key: [Ctrl: 'q',]
- action: [NewPane: ]
key: [ Alt: 'n',]
- action: [MoveFocus: Left,]
key: [ Alt: 'h',]
- action: [MoveFocus: Right,]
key: [ Alt: 'l',]
- action: [MoveFocus: Down,]
key: [ Alt: 'j',]
- action: [MoveFocus: Up,]
key: [ Alt: 'k',]
- action: [FocusPreviousPane,]
key: [ Alt: '[',]
- action: [FocusNextPane,]
key: [ Alt: ']',]
locked:
- action: [SwitchToMode: Normal,]
key: [Ctrl: 'g',]
resize:
- action: [SwitchToMode: Locked,]
key: [Ctrl: 'g']
- action: [SwitchToMode: Pane,]
key: [Ctrl: 'p', ]
- action: [SwitchToMode: Tab,]
key: [Ctrl: 't', ]
- action: [SwitchToMode: Normal,]
key: [Ctrl: 'r', Char: "\n", Char: ' ',]
- action: [SwitchToMode: Scroll,]
key: [Ctrl: 's']
- action: [Quit]
key: [Ctrl: 'q']
- action: [Resize: Left,]
key: [Char: 'h', Left, ]
- action: [Resize: Down,]
key: [Char: 'h', Down, ]
- action: [Resize: Up,]
key: [Char: 'h', Up, ]
- action: [Resize: Right,]
key: [Char: 'h', Right, ]
- action: [NewPane: ,]
key: [ Alt: 'n',]
- action: [MoveFocus: Left,]
key: [ Alt: 'h', Left,]
- action: [MoveFocus: Right,]
key: [ Alt: 'l', Right,]
- action: [MoveFocus: Down,]
key: [ Alt: 'j', Down,]
- action: [MoveFocus: Up,]
key: [ Alt: 'k', Up,]
- action: [FocusPreviousPane,]
key: [ Alt: '[',]
- action: [FocusNextPane,]
key: [ Alt: ']',]
pane:
- action: [SwitchToMode: Locked,]
key: [Ctrl: 'g']
- action: [SwitchToMode: Pane,]
key: [Ctrl: 'p', ]
- action: [SwitchToMode: Tab,]
key: [Ctrl: 't', ]
- action: [SwitchToMode: Normal,]
key: [Ctrl: 'r', Char: "\n", Char: ' ',]
- action: [SwitchToMode: Scroll,]
key: [Ctrl: 's']
- action: [Quit,]
key: [Ctrl: 'q',]
- action: [MoveFocus: Left,]
key: [ Alt: 'h', Left,]
- action: [MoveFocus: Right,]
key: [ Alt: 'l', Right,]
- action: [MoveFocus: Down,]
key: [ Alt: 'j', Down,]
- action: [MoveFocus: Up,]
key: [ Alt: 'k', Up,]
- action: [SwitchFocus,]
key: [Char: 'p']
- action: [NewPane: ,]
key: [Char: 'n', Alt: 'n',]
- action: [NewPane: Down,]
key: [Char: 'd', ]
- action: [NewPane: Right,]
key: [Char: 'r', ]
- action: [CloseFocus,]
key: [Char: 'x', ]
- action: [ToggleFocusFullscreen,]
key: [Char: 'f', ]
- action: [FocusPreviousPane,]
key: [ Alt: '[',]
- action: [FocusNextPane,]
key: [ Alt: ']',]
tab:
- action: [SwitchToMode: Locked,]
key: [Ctrl: 'g']
- action: [SwitchToMode: Pane,]
key: [Ctrl: 'p', ]
- action: [SwitchToMode: Normal,]
key: [Ctrl: 'r', Ctrl: 't', Char: "\n", Char: ' ',]
- action: [SwitchToMode: Scroll,]
key: [Ctrl: 's']
- action: [SwitchToMode: RenameTab, TabNameInput: [0],]
key: [Char: 'r']
- action: [Quit,]
key: [Ctrl: 'q',]
- action: [FocusPreviousPane,]
key: [ Alt: '[',]
- action: [FocusNextPane,]
key: [ Alt: ']',]
- action: [GoToPreviousTab,]
key: [ Char: 'h',]
- action: [GoToNextTab,]
key: [ Char: 'l', ]
- action: [GoToNextTab,]
key: [ Char: 'j', ]
- action: [GoToPreviousTab,]
key: [ Char: 'k', ]
- action: [NewTab,]
key: [ Char: 'n', ]
- action: [CloseTab,]
key: [ Char: 'x', ]
- action: [MoveFocus: Left,]
key: [ Alt: 'h',]
- action: [MoveFocus: Right,]
key: [ Alt: 'l', ]
- action: [MoveFocus: Down,]
key: [ Alt: 'j', ]
- action: [MoveFocus: Up,]
key: [ Alt: 'k', ]
- action: [GoToTab: 1,]
key: [ Char: '1', ]
- action: [GoToTab: 2,]
key: [ Char: '2', ]
- action: [GoToTab: 3,]
key: [ Char: '3', ]
- action: [GoToTab: 4,]
key: [ Char: '4', ]
- action: [GoToTab: 5,]
key: [ Char: '5', ]
- action: [GoToTab: 6,]
key: [ Char: '6', ]
- action: [GoToTab: 7,]
key: [ Char: '7', ]
- action: [GoToTab: 8,]
key: [ Char: '8', ]
- action: [GoToTab: 9,]
key: [ Char: '9', ]
scroll:
- action: [SwitchToMode: Normal,]
key: [Ctrl: 'r', Ctrl: 's', Char: ' ',
Char: "\n",]
- action: [SwitchToMode: Tab,]
key: [Ctrl: 't', ]
- action: [SwitchToMode: Locked,]
key: [Ctrl: 'g', ]
- action: [SwitchToMode: Pane,]
key: [Ctrl: 'p', ]
- action: [Quit,]
key: [Ctrl: 'q',]
- action: [ScrollDown,]
key: [Char: 'j', Down,]
- action: [ScrollUp,]
key: [Char: 'k', Up,]
- action: [NewPane: ,]
key: [ Alt: 'n',]
- action: [MoveFocus: Left,]
key: [ Alt: 'h',]
- action: [MoveFocus: Right,]
key: [ Alt: 'l',]
- action: [MoveFocus: Down,]
key: [ Alt: 'j',]
- action: [MoveFocus: Up,]
key: [ Alt: 'k',]
- action: [FocusPreviousPane,]
key: [ Alt: '[',]
- action: [FocusNextPane,]
key: [ Alt: ']',]
renametab:
- action: [SwitchToMode: Normal,]
key: [Ctrl: 'r', Ctrl: 's', Char: ' ', Char: 'g',]
- action: [SwitchToMode: Tab,]
key: [Char: "\n",]
- action: [TabNameInput: [27] , SwitchToMode: Tab,]
key: [Esc,]
- action: [NewPane: ,]
key: [ Alt: 'n',]
- action: [MoveFocus: Left,]
key: [ Alt: 'h',]
- action: [MoveFocus: Right,]
key: [ Alt: 'l',]
- action: [MoveFocus: Down,]
key: [ Alt: 'j',]
- action: [MoveFocus: Up,]
key: [ Alt: 'k',]
- action: [FocusPreviousPane,]
key: [ Alt: '[',]
- action: [FocusNextPane,]
key: [ Alt: ']',]

View file

@ -7,14 +7,30 @@ use serde::Deserialize;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use zellij_tile::data::*; use zellij_tile::data::*;
/// Used in the config struct
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Keybinds(HashMap<InputMode, ModeKeybinds>); pub struct Keybinds(HashMap<InputMode, ModeKeybinds>);
#[derive(Clone, Debug, Default, PartialEq)] #[derive(Clone, Debug, Default, PartialEq)]
pub struct ModeKeybinds(HashMap<Key, Vec<Action>>); pub struct ModeKeybinds(HashMap<Key, Vec<Action>>);
/// Intermediate struct used for deserialisation /// Intermediate struct used for deserialisation
/// Used in the config file.
#[derive(Clone, Debug, PartialEq, Deserialize)] #[derive(Clone, Debug, PartialEq, Deserialize)]
pub struct KeybindsFromYaml(HashMap<InputMode, Vec<KeyActionFromYaml>>); pub struct KeybindsFromYaml {
#[serde(flatten)]
keybinds: HashMap<InputMode, Vec<KeyActionUnbind>>,
#[serde(default)]
unbind: Unbind,
}
/// Intermediate enum used for deserialisation
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(untagged)]
enum KeyActionUnbind {
KeyAction(KeyActionFromYaml),
// TODO: use the enum
//Unbind(UnbindFromYaml),
}
/// Intermediate struct used for deserialisation /// Intermediate struct used for deserialisation
#[derive(Clone, Debug, PartialEq, Deserialize)] #[derive(Clone, Debug, PartialEq, Deserialize)]
@ -23,6 +39,22 @@ pub struct KeyActionFromYaml {
key: Vec<Key>, key: Vec<Key>,
} }
/// Intermediate struct used for deserialisation
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
struct UnbindFromYaml {
unbind: Unbind,
}
/// List of keys, for which to disable their respective default actions
/// `All` is a catch all, and will disable the default actions for all keys.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
#[serde(untagged)]
enum Unbind {
All(bool),
// TODO@a-kenji: use the enum
//Keys(Vec<Key>),
}
impl Default for Keybinds { impl Default for Keybinds {
fn default() -> Keybinds { fn default() -> Keybinds {
let mut defaults = Keybinds::new(); let mut defaults = Keybinds::new();
@ -41,9 +73,16 @@ impl Keybinds {
Keybinds(HashMap::<InputMode, ModeKeybinds>::new()) Keybinds(HashMap::<InputMode, ModeKeybinds>::new())
} }
pub fn get_default_keybinds_with_config(keybinds: Option<KeybindsFromYaml>) -> Keybinds { pub fn get_default_keybinds_with_config(from_yaml: Option<KeybindsFromYaml>) -> Keybinds {
let default_keybinds = Keybinds::default(); let default_keybinds = match from_yaml.clone() {
if let Some(keybinds) = keybinds { Some(keybinds) => match keybinds.unbind {
Unbind::All(true) => Keybinds::new(),
Unbind::All(false) => Keybinds::default(),
},
None => Keybinds::default(),
};
if let Some(keybinds) = from_yaml {
default_keybinds.merge_keybinds(Keybinds::from(keybinds)) default_keybinds.merge_keybinds(Keybinds::from(keybinds))
} else { } else {
default_keybinds default_keybinds
@ -383,7 +422,7 @@ impl From<KeybindsFromYaml> for Keybinds {
for mode in InputMode::iter() { for mode in InputMode::iter() {
let mut mode_keybinds = ModeKeybinds::new(); let mut mode_keybinds = ModeKeybinds::new();
for key_action in keybinds_from_yaml.0.get(&mode).iter() { for key_action in keybinds_from_yaml.keybinds.get(&mode).iter() {
for keybind in key_action.iter() { for keybind in key_action.iter() {
mode_keybinds = mode_keybinds.merge(ModeKeybinds::from(keybind.clone())); mode_keybinds = mode_keybinds.merge(ModeKeybinds::from(keybind.clone()));
} }
@ -409,6 +448,21 @@ impl From<KeyActionFromYaml> for ModeKeybinds {
} }
} }
// 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),
}
}
}
impl Default for Unbind {
fn default() -> Unbind {
Unbind::All(false)
}
}
// The unit test location. // The unit test location.
#[cfg(test)] #[cfg(test)]
#[path = "./unit/keybinds_test.rs"] #[path = "./unit/keybinds_test.rs"]

View file

@ -124,12 +124,25 @@ fn from_keyaction_from_yaml_to_mode_keybindings() {
assert_eq!(expected, ModeKeybinds::from(keyaction)); assert_eq!(expected, ModeKeybinds::from(keyaction));
} }
//#[test] #[test]
//fn from_keybinds_from_yaml_to_keybinds(){ fn toplevel_unbind_unbinds_all() {
//let mut keybinds_from_yaml = KeybindsFromYaml(HashMap<InputMode, Vec<KeyActionFromYaml>>); let from_yaml = KeybindsFromYaml {
//let actions = vec![Action::NoOp, Action::GoToTab(1), ]; unbind: Unbind::All(true),
//let keyaction = KeyActionFromYaml { keybinds: HashMap::new(),
//action : actions.clone(), };
//key : vec![ Key::F(1), Key::Backspace , Key::Char('t'), ],
//}; let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
//}
assert_eq!(keybinds_from_yaml, Keybinds::new());
}
fn no_unbind_unbinds_none() {
let from_yaml = KeybindsFromYaml {
unbind: Unbind::All(false),
keybinds: HashMap::new(),
};
let keybinds_from_yaml = Keybinds::get_default_keybinds_with_config(Some(from_yaml));
assert_eq!(keybinds_from_yaml, Keybinds::new());
}