edtui_papier/input/
register.rs

1use std::collections::HashMap;
2
3use crossterm::event::KeyEvent;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    actions::{Action, Execute},
8    EditorMode, EditorState,
9};
10
11#[derive(Clone, Debug, Default)]
12pub struct Register<I>
13where
14    I: Clone + Execute + Serialize + Deserialize<'static>,
15{
16    lookup: Vec<KeyEvent>,
17    register: HashMap<RegisterKey, Action<I>>,
18}
19
20impl<I> Register<I>
21where
22    I: Clone + Execute + Serialize + Deserialize<'static>,
23{
24    /// Constructs a new Register
25    #[must_use]
26    pub fn new() -> Self {
27        Self { lookup: Vec::new(), register: HashMap::new() }
28    }
29
30    /// Insert a new callback to the registry
31    pub fn insert<T: Into<Action<I>>>(&mut self, k: RegisterKey, v: T) {
32        self.register.insert(k, v.into());
33    }
34
35    /// Returns an action for a specific register key, if present.
36    /// Returns an action only if there is an exact match. If there
37    /// are multiple matches or an inexact match, the specified key
38    /// is appended to the lookup vector.
39    /// If there is an exact match or if none of the keys in the registry
40    /// starts with the current sequence, the lookup sequence is reset.
41    #[must_use]
42    pub fn get(&mut self, c: KeyEvent, mode: EditorMode) -> Option<Action<I>> {
43        let key = self.create_register_key(c, mode);
44
45        match self.register.keys().filter(|k| k.mode == key.mode && k.keys.starts_with(&key.keys)).count() {
46            0 => {
47                self.lookup.clear();
48                None
49            },
50            1 => self.register.get(&key).map(|action| {
51                self.lookup.clear();
52                action.clone()
53            }),
54            _ => None,
55        }
56    }
57
58    fn create_register_key(&mut self, c: KeyEvent, mode: EditorMode) -> RegisterKey {
59        self.lookup.push(c);
60        RegisterKey::new(self.lookup.clone(), mode)
61    }
62}
63
64#[derive(Clone, Eq, PartialEq, Hash, Debug)]
65pub struct RegisterKey {
66    pub keys: Vec<KeyEvent>,
67    pub mode: EditorMode,
68}
69
70pub type RegisterCB = fn(&mut EditorState);
71
72#[derive(Clone, Debug)]
73pub struct RegisterVal(pub fn(&mut EditorState));
74
75impl RegisterKey {
76    pub fn new<T>(keys: Vec<T>, mode: EditorMode) -> Self
77    where
78        T: Into<KeyEvent>,
79    {
80        Self { keys: keys.into_iter().map(Into::into).collect(), mode }
81    }
82
83    pub fn n<T>(keys: Vec<T>) -> Self
84    where
85        T: Into<KeyEvent>,
86    {
87        Self::new(keys, EditorMode::Normal)
88    }
89
90    pub fn v<T>(keys: Vec<T>) -> Self
91    where
92        T: Into<KeyEvent>,
93    {
94        Self::new(keys, EditorMode::Visual)
95    }
96
97    pub fn i<T>(keys: Vec<T>) -> Self
98    where
99        T: Into<KeyEvent>,
100    {
101        Self::new(keys, EditorMode::Insert)
102    }
103
104    pub fn s<T>(keys: Vec<T>) -> Self
105    where
106        T: Into<KeyEvent>,
107    {
108        Self::new(keys, EditorMode::Search)
109    }
110
111    pub fn c<T>(keys: Vec<T>) -> Self
112    where
113        T: Into<KeyEvent>,
114    {
115        Self::new(keys, EditorMode::Command)
116    }
117}