Alexandre Pasmantier 7a85728da6
refactor(config)!: simplify keybindings configuration syntax (#404)
BREAKING CHANGE: mode keybindings dropped in favor of a global table

**What this means in practice:**
```toml
[keybindings.Channel]
quit = ["esc", "ctrl-c"]
# ...

[keybindings.RemoteControl]
quit = ["esc", "ctrl-c"]
# ...

[keybindings.SendToChannel]
quit = ["esc", "ctrl-c"]
# ...
```
are being replaced with
```toml
[keybindings]
quit = ["esc", "ctrl-c"]
# ...
```

Mode keybindings were I believe a premature optimization which only
brought additional complexity and redundancy to the code and did not
provide any real functionality in the current state of things for end
users.
2025-03-19 01:35:29 +01:00

51 lines
1.4 KiB
Rust

use rustc_hash::FxHashMap;
use std::ops::Deref;
use crate::action::Action;
use crate::config::{Binding, KeyBindings};
use crate::event::Key;
#[derive(Default, Debug)]
/// A keymap is a set of mappings of keys to actions for every mode.
///
/// # Example:
/// ```ignore
/// Keymap {
/// Key::Char('j') => Action::MoveDown,
/// Key::Char('k') => Action::MoveUp,
/// Key::Char('q') => Action::Quit,
/// }
/// ```
pub struct Keymap(pub FxHashMap<Key, Action>);
impl Deref for Keymap {
type Target = FxHashMap<Key, Action>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<&KeyBindings> for Keymap {
/// Convert a `KeyBindings` into a `Keymap`.
///
/// This essentially "reverses" the inner `KeyBindings` structure, so that each mode keymap is
/// indexed by its keys instead of the actions so as to be used as a routing table for incoming
/// key events.
fn from(keybindings: &KeyBindings) -> Self {
let mut keymap = FxHashMap::default();
for (action, binding) in keybindings.iter() {
match binding {
Binding::SingleKey(key) => {
keymap.insert(*key, action.clone());
}
Binding::MultipleKeys(keys) => {
for key in keys {
keymap.insert(*key, action.clone());
}
}
}
}
Self(keymap)
}
}