1use crate::{
2 ui::{Key, KeyModifiers},
3 InnerAction,
4};
5
6use super::{LineDirection, Magnitude};
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq)]
10pub enum InputAction {
11 Delete(Magnitude, LineDirection),
14 MoveCursor(Magnitude, LineDirection),
16 Write(char),
19}
20
21impl InnerAction for InputAction {
22 type Config = ();
23
24 fn from_key(key: Key, _config: &()) -> Option<Self>
25 where
26 Self: Sized,
27 {
28 let action = match key {
29 Key::Backspace => Self::Delete(Magnitude::Char, LineDirection::Left),
30 Key::Char('h', m) if m.contains(KeyModifiers::CONTROL) => {
31 return None;
35 }
36
37 Key::Delete(m) if m.contains(KeyModifiers::CONTROL) => {
38 Self::Delete(Magnitude::Word, LineDirection::Right)
39 }
40 Key::Delete(_) => Self::Delete(Magnitude::Char, LineDirection::Right),
41
42 Key::Home => Self::MoveCursor(Magnitude::Line, LineDirection::Left),
43 Key::Left(m) if m.contains(KeyModifiers::CONTROL) => {
44 Self::MoveCursor(Magnitude::Word, LineDirection::Left)
45 }
46 Key::Left(_) => Self::MoveCursor(Magnitude::Char, LineDirection::Left),
47
48 Key::End => Self::MoveCursor(Magnitude::Line, LineDirection::Right),
49 Key::Right(m) if m.contains(KeyModifiers::CONTROL) => {
50 Self::MoveCursor(Magnitude::Word, LineDirection::Right)
51 }
52 Key::Right(_) => Self::MoveCursor(Magnitude::Char, LineDirection::Right),
53
54 Key::Char(c, _) => Self::Write(c),
55 _ => return None,
56 };
57
58 Some(action)
59 }
60}
61
62#[cfg(test)]
63mod test {
64 use super::*;
65
66 #[test]
67 fn backspace_results_in_delete_char_left() {
68 assert_eq!(
69 InputAction::from_key(Key::Backspace, &()),
70 Some(InputAction::Delete(Magnitude::Char, LineDirection::Left))
71 );
72 }
73
74 #[test]
75 fn delete_results_in_delete_char_right() {
76 assert_eq!(
77 InputAction::from_key(Key::Delete(KeyModifiers::NONE), &()),
78 Some(InputAction::Delete(Magnitude::Char, LineDirection::Right))
79 );
80 }
81
82 #[test]
83 fn ctrl_delete_results_in_delete_word_right() {
84 assert_eq!(
85 InputAction::from_key(Key::Delete(KeyModifiers::CONTROL), &()),
86 Some(InputAction::Delete(Magnitude::Word, LineDirection::Right))
87 );
88 }
89
90 #[test]
91 fn ctrl_backspace_does_nothing() {
92 assert_eq!(
96 InputAction::from_key(Key::Char('h', KeyModifiers::CONTROL), &()),
97 None
98 );
99 }
100
101 #[test]
102 fn horizontal_arrows_results_in_move_cursor_char() {
103 assert_eq!(
104 InputAction::from_key(Key::Left(KeyModifiers::NONE), &()),
105 Some(InputAction::MoveCursor(
106 Magnitude::Char,
107 LineDirection::Left
108 ))
109 );
110 assert_eq!(
111 InputAction::from_key(Key::Right(KeyModifiers::NONE), &()),
112 Some(InputAction::MoveCursor(
113 Magnitude::Char,
114 LineDirection::Right
115 ))
116 );
117 }
118
119 #[test]
120 fn vertical_arrows_do_nothing() {
121 assert_eq!(
122 InputAction::from_key(Key::Up(KeyModifiers::NONE), &()),
123 None
124 );
125 assert_eq!(
126 InputAction::from_key(Key::Down(KeyModifiers::NONE), &()),
127 None
128 );
129 }
130
131 #[test]
132 fn home_moves_to_beginning_of_line() {
133 assert_eq!(
134 InputAction::from_key(Key::Home, &()),
135 Some(InputAction::MoveCursor(
136 Magnitude::Line,
137 LineDirection::Left
138 ))
139 );
140 }
141
142 #[test]
143 fn end_moves_to_end_of_line() {
144 assert_eq!(
145 InputAction::from_key(Key::End, &()),
146 Some(InputAction::MoveCursor(
147 Magnitude::Line,
148 LineDirection::Right
149 ))
150 );
151 }
152
153 #[test]
154 fn arrows_with_ctrl_move_by_word() {
155 assert_eq!(
156 InputAction::from_key(Key::Left(KeyModifiers::CONTROL), &()),
157 Some(InputAction::MoveCursor(
158 Magnitude::Word,
159 LineDirection::Left
160 ))
161 );
162 assert_eq!(
163 InputAction::from_key(Key::Right(KeyModifiers::CONTROL), &()),
164 Some(InputAction::MoveCursor(
165 Magnitude::Word,
166 LineDirection::Right
167 ))
168 );
169 }
170
171 #[test]
172 fn chars_generate_write_actions() {
173 assert_eq!(
174 InputAction::from_key(Key::Char('a', KeyModifiers::NONE), &()),
175 Some(InputAction::Write('a'))
176 );
177 assert_eq!(
178 InputAction::from_key(Key::Char('a', KeyModifiers::SHIFT), &()),
179 Some(InputAction::Write('a'))
180 );
181 assert_eq!(
182 InputAction::from_key(Key::Char('∑', KeyModifiers::NONE), &()),
183 Some(InputAction::Write('∑'))
184 );
185 assert_eq!(
186 InputAction::from_key(Key::Char('ã', KeyModifiers::SHIFT), &()),
187 Some(InputAction::Write('ã'))
188 );
189 assert_eq!(
190 InputAction::from_key(Key::Char('❤', KeyModifiers::SHIFT), &()),
191 Some(InputAction::Write('❤'))
192 );
193 assert_eq!(
194 InputAction::from_key(Key::Char('ç', KeyModifiers::SHIFT), &()),
195 Some(InputAction::Write('ç'))
196 );
197 assert_eq!(
198 InputAction::from_key(Key::Char('ñ', KeyModifiers::SHIFT), &()),
199 Some(InputAction::Write('ñ'))
200 );
201 }
202
203 #[test]
204 fn page_up_and_down_do_nothing() {
205 assert_eq!(
206 InputAction::from_key(Key::PageUp(KeyModifiers::NONE), &()),
207 None
208 );
209 assert_eq!(
210 InputAction::from_key(Key::PageDown(KeyModifiers::NONE), &()),
211 None
212 );
213 }
214}