Skip to main content

wedi_core/keymap/
mod.rs

1mod bindings;
2pub mod command;
3
4pub use bindings::handle_key_event;
5pub use command::{Command, Direction};
6
7use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
8use std::collections::HashMap;
9
10/// 可自訂的快捷鍵對映
11#[derive(Default)]
12pub struct Keymap {
13    bindings: HashMap<(KeyCode, KeyModifiers), Command>,
14    selection_overrides: HashMap<(KeyCode, KeyModifiers), Command>,
15}
16
17impl Keymap {
18    /// 綁定快捷鍵到命令
19    pub fn bind(&mut self, key: KeyCode, modifiers: KeyModifiers, command: Command) -> &mut Self {
20        self.bindings.insert((key, modifiers), command);
21        self
22    }
23
24    /// 解除快捷鍵綁定
25    pub fn unbind(&mut self, key: KeyCode, modifiers: KeyModifiers) -> &mut Self {
26        self.bindings.remove(&(key, modifiers));
27        self
28    }
29
30    /// 在選擇模式下綁定快捷鍵
31    pub fn bind_selection(
32        &mut self,
33        key: KeyCode,
34        modifiers: KeyModifiers,
35        command: Command,
36    ) -> &mut Self {
37        self.selection_overrides.insert((key, modifiers), command);
38        self
39    }
40
41    /// 查詢快捷鍵對應的命令
42    pub fn get_command(&self, event: KeyEvent, selection_mode: bool) -> Option<Command> {
43        // 如果是選擇模式,先查詢選擇模式覆蓋
44        if selection_mode {
45            if let Some(cmd) = self.selection_overrides.get(&(event.code, event.modifiers)) {
46                return Some(cmd.clone());
47            }
48        }
49
50        // 查詢普通綁定
51        if let Some(cmd) = self.bindings.get(&(event.code, event.modifiers)) {
52            return Some(cmd.clone());
53        }
54
55        // 回退到原有的硬編碼邏輯(向後相容)
56        handle_key_event(event, selection_mode)
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_custom_keymap() {
66        let mut keymap = Keymap::default();
67        keymap.bind(KeyCode::Char('s'), KeyModifiers::CONTROL, Command::Save);
68
69        let event = KeyEvent::new(KeyCode::Char('s'), KeyModifiers::CONTROL);
70        assert_eq!(keymap.get_command(event, false), Some(Command::Save));
71    }
72
73    #[test]
74    fn test_unbind() {
75        let mut keymap = Keymap::default();
76        keymap.bind(KeyCode::Char('q'), KeyModifiers::CONTROL, Command::Quit);
77        keymap.unbind(KeyCode::Char('q'), KeyModifiers::CONTROL);
78
79        let event = KeyEvent::new(KeyCode::Char('q'), KeyModifiers::CONTROL);
80        // 應該回退到原有綁定
81        assert_eq!(keymap.get_command(event, false), Some(Command::Quit));
82    }
83}