1use super::{KeyCode, KeyEvent, KeyModifiers};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub enum Movement {
7 Up,
9 Down,
11 Left,
13 Right,
15 PageUp,
17 PageDown,
19 Home,
21 End,
23 NextWord,
25 PrevWord,
27}
28
29impl Movement {
30 pub fn try_from_key(key: KeyEvent) -> Option<Movement> {
35 let movement = match key.code {
36 KeyCode::Left
37 if key
38 .modifiers
39 .intersects(KeyModifiers::CONTROL | KeyModifiers::ALT) =>
40 {
41 Movement::PrevWord
42 }
43 KeyCode::Char('b') if key.modifiers.contains(KeyModifiers::ALT) => Movement::PrevWord,
44
45 KeyCode::Right
46 if key
47 .modifiers
48 .intersects(KeyModifiers::CONTROL | KeyModifiers::ALT) =>
49 {
50 Movement::NextWord
51 }
52 KeyCode::Char('f') if key.modifiers.contains(KeyModifiers::ALT) => Movement::NextWord,
53
54 KeyCode::Up => Movement::Up,
55 KeyCode::Char('k') => Movement::Up,
56
57 KeyCode::Down => Movement::Down,
58 KeyCode::Char('j') => Movement::Down,
59
60 KeyCode::Left => Movement::Left,
61 KeyCode::Char('h') => Movement::Left,
62 KeyCode::Char('b') if key.modifiers.contains(KeyModifiers::CONTROL) => Movement::Left,
63
64 KeyCode::Right => Movement::Right,
65 KeyCode::Char('l') => Movement::Right,
66 KeyCode::Char('f') if key.modifiers.contains(KeyModifiers::CONTROL) => Movement::Right,
67
68 KeyCode::PageUp => Movement::PageUp,
69 KeyCode::PageDown => Movement::PageDown,
70
71 KeyCode::Home => Movement::Home,
72 KeyCode::Char('g') => Movement::Home,
73 KeyCode::Char('a') if key.modifiers.contains(KeyModifiers::CONTROL) => Movement::Home,
74
75 KeyCode::End => Movement::End,
76 KeyCode::Char('G') => Movement::End,
77 KeyCode::Char('e') if key.modifiers.contains(KeyModifiers::CONTROL) => Movement::End,
78 _ => return None,
79 };
80
81 Some(movement)
82 }
83}
84
85#[test]
86fn test_movement() {
87 assert_eq!(
88 Movement::try_from_key(KeyEvent::new(KeyCode::Left, KeyModifiers::empty())),
89 Some(Movement::Left)
90 );
91 assert_eq!(
92 Movement::try_from_key(KeyEvent::new(KeyCode::Char('h'), KeyModifiers::empty())),
93 Some(Movement::Left)
94 );
95 assert_eq!(
96 Movement::try_from_key(KeyEvent::new(KeyCode::Char('b'), KeyModifiers::CONTROL)),
97 Some(Movement::Left)
98 );
99
100 assert_eq!(
101 Movement::try_from_key(KeyEvent::new(KeyCode::Left, KeyModifiers::CONTROL,)),
102 Some(Movement::PrevWord)
103 );
104 assert_eq!(
105 Movement::try_from_key(KeyEvent::new(KeyCode::Left, KeyModifiers::ALT)),
106 Some(Movement::PrevWord)
107 );
108 assert_eq!(
109 Movement::try_from_key(KeyEvent::new(KeyCode::Char('b'), KeyModifiers::ALT)),
110 Some(Movement::PrevWord)
111 );
112
113 assert_eq!(
114 Movement::try_from_key(KeyEvent::new(KeyCode::Right, KeyModifiers::empty())),
115 Some(Movement::Right)
116 );
117 assert_eq!(
118 Movement::try_from_key(KeyEvent::new(KeyCode::Char('l'), KeyModifiers::empty())),
119 Some(Movement::Right)
120 );
121 assert_eq!(
122 Movement::try_from_key(KeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL)),
123 Some(Movement::Right)
124 );
125
126 assert_eq!(
127 Movement::try_from_key(KeyEvent::new(KeyCode::Right, KeyModifiers::CONTROL)),
128 Some(Movement::NextWord)
129 );
130 assert_eq!(
131 Movement::try_from_key(KeyEvent::new(KeyCode::Right, KeyModifiers::ALT)),
132 Some(Movement::NextWord)
133 );
134 assert_eq!(
135 Movement::try_from_key(KeyEvent::new(KeyCode::Char('f'), KeyModifiers::ALT)),
136 Some(Movement::NextWord)
137 );
138
139 assert_eq!(
140 Movement::try_from_key(KeyEvent::new(KeyCode::Up, KeyModifiers::empty())),
141 Some(Movement::Up)
142 );
143 assert_eq!(
144 Movement::try_from_key(KeyEvent::new(KeyCode::Char('k'), KeyModifiers::empty())),
145 Some(Movement::Up)
146 );
147
148 assert_eq!(
149 Movement::try_from_key(KeyEvent::new(KeyCode::Down, KeyModifiers::empty())),
150 Some(Movement::Down)
151 );
152 assert_eq!(
153 Movement::try_from_key(KeyEvent::new(KeyCode::Char('j'), KeyModifiers::empty())),
154 Some(Movement::Down)
155 );
156
157 assert_eq!(
158 Movement::try_from_key(KeyEvent::new(KeyCode::PageDown, KeyModifiers::empty())),
159 Some(Movement::PageDown)
160 );
161 assert_eq!(
162 Movement::try_from_key(KeyEvent::new(KeyCode::PageUp, KeyModifiers::empty())),
163 Some(Movement::PageUp)
164 );
165
166 assert_eq!(
167 Movement::try_from_key(KeyEvent::new(KeyCode::Home, KeyModifiers::empty())),
168 Some(Movement::Home)
169 );
170 assert_eq!(
171 Movement::try_from_key(KeyEvent::new(KeyCode::Char('g'), KeyModifiers::empty())),
172 Some(Movement::Home)
173 );
174 assert_eq!(
175 Movement::try_from_key(KeyEvent::new(KeyCode::Char('a'), KeyModifiers::CONTROL)),
176 Some(Movement::Home)
177 );
178
179 assert_eq!(
180 Movement::try_from_key(KeyEvent::new(KeyCode::End, KeyModifiers::empty())),
181 Some(Movement::End)
182 );
183 assert_eq!(
184 Movement::try_from_key(KeyEvent::new(KeyCode::Char('G'), KeyModifiers::empty())),
185 Some(Movement::End)
186 );
187 assert_eq!(
188 Movement::try_from_key(KeyEvent::new(KeyCode::Char('e'), KeyModifiers::CONTROL)),
189 Some(Movement::End)
190 );
191}