use std::collections::HashMap;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use crate::action::Token;
mod tables;
pub use tables::{
GOTO_BINDINGS, LEADER_DEFAULTS, OBJECT_BINDINGS, OP_PENDING_BINDINGS, Z_BINDINGS,
};
pub const LEADER: char = ' ';
pub struct Binding {
pub key: KeyCode,
pub aliases: &'static [KeyCode],
pub token: Token,
pub label: &'static str,
}
impl Binding {
pub(crate) fn matches(&self, code: KeyCode) -> bool {
self.key == code || self.aliases.contains(&code)
}
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
pub struct KeySig {
pub code: KeyCode,
pub modifiers: KeyModifiers,
}
impl KeySig {
pub fn new(code: KeyCode, modifiers: KeyModifiers) -> Self {
let modifiers = if matches!(code, KeyCode::Char(_)) {
modifiers - KeyModifiers::SHIFT
} else {
modifiers
};
Self { code, modifiers }
}
pub fn from_event(key: KeyEvent) -> Self {
Self::new(key.code, key.modifiers)
}
}
pub struct Keymap {
pub initial: HashMap<KeySig, Token>,
pub leader: HashMap<KeySig, Token>,
}
impl Keymap {
pub fn empty() -> Self {
Self {
initial: HashMap::new(),
leader: HashMap::new(),
}
}
pub fn vim_default() -> Self {
let mut m = Self::empty();
m.install_vim_defaults();
m
}
pub fn bind_initial(&mut self, sig: KeySig, token: Token) {
self.initial.insert(sig, token);
}
pub fn bind_leader(&mut self, sig: KeySig, token: Token) {
self.leader.insert(sig, token);
}
}