1pub mod key;
3pub mod register;
4
5use std::fmt::Debug;
6
7use crossterm::event::{KeyCode, KeyEvent};
8use serde::{Deserialize, Serialize};
9
10use self::{
11 key::Key,
12 register::{Register, RegisterKey},
13};
14use crate::{
15 actions::{
16 motion::MoveWordForwardEnd, search::StartSearch, Action, Append, AppendCharToSearch, AppendNewline, Composed,
17 CopySelection, Custom, DeleteChar, DeleteLine, DeleteSelection, Execute, FindNext, FindPrevious, InsertChar,
18 InsertNewline, LineBreak, MoveBackward, MoveDown, MoveForward, MoveToEnd, MoveToFirst, MoveToStart, MoveUp,
19 MoveWordBackward, MoveWordForwardStart, Paste, Redo, RemoveChar, RemoveCharFromSearch, SelectBetween,
20 StopSearch, SwitchMode, TriggerSearch, Undo,
21 },
22 debug::log_to_file,
23 state::command::CommandState,
24 EditorMode, EditorState,
25};
26
27#[derive(Clone, Debug)]
28pub struct Input<I>
29where
30 I: Clone + Execute + Serialize + for<'de> Deserialize<'de> + Default,
31{
32 pub register: Register<I>,
33 pub command: CommandState<I>,
34}
35
36impl<I> Default for Input<I>
37where
38 I: Clone + Execute + Serialize + for<'de> Deserialize<'de> + Default,
39{
40 #[allow(clippy::too_many_lines)]
41 fn default() -> Self {
42 let mut r = Register::<I>::new();
43
44 r.insert(RegisterKey::i(vec![Key::Esc]), Action::SwitchMode(SwitchMode(EditorMode::Normal)));
46 r.insert(RegisterKey::v(vec![Key::Esc]), SwitchMode(EditorMode::Normal));
47
48 r.insert(RegisterKey::n(vec![Key::Char('i')]), SwitchMode(EditorMode::Insert));
50
51 r.insert(RegisterKey::n(vec![Key::Char('v')]), SwitchMode(EditorMode::Visual));
53
54 r.insert(RegisterKey::n(vec![Key::Char('/')]), StartSearch);
56 r.insert(RegisterKey::s(vec![Key::Enter]), TriggerSearch);
58 r.insert(RegisterKey::n(vec![Key::Char('n')]), FindNext);
60 r.insert(RegisterKey::n(vec![Key::Char('N')]), FindPrevious);
62 r.insert(RegisterKey::s(vec![Key::Esc]), StopSearch);
64 r.insert(RegisterKey::s(vec![Key::Backspace]), RemoveCharFromSearch);
66
67 r.insert(RegisterKey::n(vec![Key::Char('a')]), Append);
69
70 r.insert(RegisterKey::n(vec![Key::Char('l')]), MoveForward(1));
72 r.insert(RegisterKey::n(vec![Key::Right]), MoveForward(1));
73 r.insert(RegisterKey::v(vec![Key::Char('l')]), MoveForward(1));
74 r.insert(RegisterKey::v(vec![Key::Right]), MoveForward(1));
75 r.insert(RegisterKey::i(vec![Key::Right]), MoveForward(1));
76
77 r.insert(RegisterKey::n(vec![Key::Char('h')]), MoveBackward(1));
79 r.insert(RegisterKey::n(vec![Key::Left]), MoveBackward(1));
80 r.insert(RegisterKey::v(vec![Key::Char('h')]), MoveBackward(1));
81 r.insert(RegisterKey::v(vec![Key::Left]), MoveBackward(1));
82 r.insert(RegisterKey::i(vec![Key::Left]), MoveBackward(1));
83
84 r.insert(RegisterKey::n(vec![Key::Char('k')]), MoveUp(1));
86 r.insert(RegisterKey::n(vec![Key::Up]), MoveUp(1));
87 r.insert(RegisterKey::v(vec![Key::Char('k')]), MoveUp(1));
88 r.insert(RegisterKey::v(vec![Key::Up]), MoveUp(1));
89 r.insert(RegisterKey::i(vec![Key::Up]), MoveUp(1));
90
91 r.insert(RegisterKey::n(vec![Key::Char('j')]), MoveDown(1));
93 r.insert(RegisterKey::n(vec![Key::Down]), MoveDown(1));
94 r.insert(RegisterKey::v(vec![Key::Char('j')]), MoveDown(1));
95 r.insert(RegisterKey::v(vec![Key::Down]), MoveDown(1));
96 r.insert(RegisterKey::i(vec![Key::Down]), MoveDown(1));
97
98 r.insert(RegisterKey::n(vec![Key::Char('w')]), MoveWordForwardStart(1));
100 r.insert(RegisterKey::n(vec![Key::Char('e')]), MoveWordForwardEnd(1));
101 r.insert(RegisterKey::n(vec![Key::Char('b')]), MoveWordBackward(1));
102 r.insert(RegisterKey::v(vec![Key::Char('w')]), MoveWordForwardStart(1));
103 r.insert(RegisterKey::v(vec![Key::Char('e')]), MoveWordForwardEnd(1));
104 r.insert(RegisterKey::v(vec![Key::Char('b')]), MoveWordBackward(1));
105
106 r.insert(RegisterKey::n(vec![Key::Char('0')]), MoveToStart());
108 r.insert(RegisterKey::n(vec![Key::Char('_')]), MoveToFirst());
109 r.insert(RegisterKey::n(vec![Key::Char('$')]), MoveToEnd());
110 r.insert(RegisterKey::v(vec![Key::Char('0')]), MoveToStart());
111 r.insert(RegisterKey::v(vec![Key::Char('_')]), MoveToFirst());
112 r.insert(RegisterKey::v(vec![Key::Char('$')]), MoveToEnd());
113
114 r.insert(
116 RegisterKey::n(vec![Key::Char('I')]),
117 Composed::new(MoveToFirst()).chain(SwitchMode(EditorMode::Insert)),
118 );
119 r.insert(RegisterKey::n(vec![Key::Char('A')]), Composed::new(MoveToEnd()).chain(Append));
120
121 r.insert(
123 RegisterKey::n(vec![Key::Char('o')]),
124 Composed::new(AppendNewline(1)).chain(SwitchMode(EditorMode::Insert)),
125 );
126 r.insert(
127 RegisterKey::n(vec![Key::Char('O')]),
128 Composed::new(InsertNewline(1)).chain(SwitchMode(EditorMode::Insert)),
129 );
130
131 r.insert(RegisterKey::i(vec![Key::Enter]), LineBreak(1));
133
134 r.insert(RegisterKey::n(vec![Key::Char('x')]), RemoveChar(1));
136
137 r.insert(RegisterKey::i(vec![Key::Backspace]), DeleteChar(1));
139
140 r.insert(RegisterKey::n(vec![Key::Char('d'), Key::Char('d')]), DeleteLine(1));
142
143 r.insert(RegisterKey::v(vec![Key::Char('d')]), DeleteSelection);
145
146 r.insert(
148 RegisterKey::n(vec![Key::Char('c'), Key::Char('i'), Key::Char('w')]),
149 SelectBetween(vec![('(', ')'), ('[', ']'), ('{', '}'), ('<', '>'), ('"', '"'), ('\'', '\'')]),
150 );
151
152 r.insert(RegisterKey::n(vec![Key::Char('u')]), Undo);
154
155 r.insert(RegisterKey::n(vec![Key::Char('r')]), Redo);
157
158 r.insert(RegisterKey::v(vec![Key::Char('y')]), CopySelection);
160
161 r.insert(RegisterKey::n(vec![Key::Char('p')]), Paste);
163 r.insert(RegisterKey::v(vec![Key::Char('p')]), Paste);
164
165 Self { register: r, command: CommandState::default() }
166 }
167}
168
169impl<I> Input<I>
170where
171 I: Clone + Execute + Serialize + for<'de> Deserialize<'de> + Default + Debug,
172{
173 pub fn on_key<T>(&mut self, key: T, state: &mut EditorState) -> Option<Custom<I>>
174 where
175 T: Into<KeyEvent> + Copy,
176 {
177 let mode = state.mode;
178 match key.into().code {
186 KeyCode::Char(c) if mode == EditorMode::Insert => InsertChar(c).execute(state),
188 KeyCode::Char(c) if mode == EditorMode::Search => AppendCharToSearch(c).execute(state),
190
191 KeyCode::Char(':') if mode == EditorMode::Normal => {
192 self.command.clear();
193 state.command = self.command.input.clone();
194 state.mode = EditorMode::Command;
195 },
196 KeyCode::Char(c) if mode == EditorMode::Command => {
197 self.command.push_char(c);
198 log_to_file(format!("Command: {}", self.command.input));
199 state.command = self.command.input.clone();
200 },
201 KeyCode::Backspace if mode == EditorMode::Command => {
202 self.command.remove_char();
203 state.command = self.command.input.clone();
204 },
205 KeyCode::Esc if mode == EditorMode::Command => {
206 self.command.clear();
207 state.command = self.command.input.clone();
208 state.mode = EditorMode::Normal;
209 },
210 KeyCode::Enter if mode == EditorMode::Command => {
211 let commands = self.command.available_commands.clone();
212 log_to_file(format!("Commands: {:?}", commands));
213 let command =
214 commands.iter().find(|c| c.name == self.command.input || c.aliases.contains(&self.command.input));
215 log_to_file(format!("Command: {:?}", command.clone()));
216 state.mode = EditorMode::Normal;
217 self.command.clear();
218 state.command = self.command.input.clone();
219 if let Some(command) = command {
220 return Some(Custom((command.action)(self.command.input.clone())));
221 }
222 },
223
224 _ => {
226 if let Some(mut action) = self.register.get(key.into(), mode) {
227 match action {
228 Action::Custom(action) => return Some(action),
229 _ => action.execute(state),
230 }
231 }
232 },
233 }
234 None
235 }
236}