use std::collections::HashMap;
use std::hash::Hash;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyEventKind;
use crossterm::event::KeyModifiers;
use crate::event::MovementCommand;
use super::event::LineEditorEvent;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct KeyCombination {
pub key_kind: KeyEventKind,
pub modifier: KeyModifiers,
pub key_code: KeyCode,
}
impl From<KeyEvent> for KeyCombination {
fn from(key_event: KeyEvent) -> Self {
KeyCombination {
key_kind: key_event.kind,
modifier: key_event.modifiers,
key_code: key_event.code,
}
}
}
pub struct Keybindings {
pub bindings: HashMap<KeyCombination, LineEditorEvent>,
}
impl Default for Keybindings {
fn default() -> Self {
Keybindings {
bindings: HashMap::new(),
}
}
}
impl Keybindings {
pub fn register_binding(&mut self, key_combination: KeyCombination, event: LineEditorEvent) {
self.bindings.insert(key_combination, event);
}
pub fn find_binding(&self, key_combination: KeyCombination) -> Option<LineEditorEvent> {
self.bindings.get(&key_combination).cloned()
}
pub fn keybindings(&self) -> &HashMap<KeyCombination, LineEditorEvent> {
&self.bindings
}
pub fn register_common_control_bindings(&mut self) {
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Enter,
},
LineEditorEvent::Enter,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Esc,
},
LineEditorEvent::Esc,
);
}
pub fn register_common_navigation_bindings(&mut self) {
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Up,
},
LineEditorEvent::Up,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Down,
},
LineEditorEvent::Down,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Left,
},
LineEditorEvent::Left,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Right,
},
LineEditorEvent::Right,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Home,
},
LineEditorEvent::Movement(vec![MovementCommand::MoveToStart]),
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::End,
},
LineEditorEvent::Movement(vec![MovementCommand::MoveToEnd]),
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::CONTROL,
key_code: KeyCode::Left,
},
LineEditorEvent::Movement(vec![MovementCommand::MoveLeftWord]),
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::CONTROL,
key_code: KeyCode::Right,
},
LineEditorEvent::Movement(vec![MovementCommand::MoveRightWord]),
);
}
pub fn register_common_edit_bindings(&mut self) {
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Backspace,
},
LineEditorEvent::Backspace,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::NONE,
key_code: KeyCode::Delete,
},
LineEditorEvent::Delete,
);
}
pub fn register_common_selection_bindings(&mut self) {
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::SHIFT,
key_code: KeyCode::Left,
},
LineEditorEvent::SelectLeft,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::SHIFT,
key_code: KeyCode::Right,
},
LineEditorEvent::SelectRight,
);
self.register_binding(
KeyCombination {
key_kind: KeyEventKind::Press,
modifier: KeyModifiers::CONTROL,
key_code: KeyCode::Char('a'),
},
LineEditorEvent::SelectAll,
);
}
}