1use crossterm::event::{
2 KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MediaKeyCode, ModifierKeyCode,
3};
4use serde::{Deserialize, Serialize};
5
6use crate::RegisterKeySettings;
7
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(default)]
10#[derive(RegisterKeySettings!)]
11pub struct KeySettings {
12 pub up: KeyEvent,
13 pub down: KeyEvent,
14 pub left: KeyEvent,
15 pub right: KeyEvent,
16
17 pub next: KeyEvent,
18 pub previous: KeyEvent,
19
20 pub page_up: KeyEvent,
21 pub page_down: KeyEvent,
22
23 pub goto_start: KeyEvent,
24 pub goto_end: KeyEvent,
25
26 pub quit: KeyEvent,
27 pub save_and_quit: KeyEvent,
28 pub save_as: KeyEvent,
29 pub save: KeyEvent,
30 pub open: KeyEvent,
31
32 pub help: KeyEvent,
33 pub log: KeyEvent,
34 pub run: KeyEvent,
35 pub find_text: KeyEvent,
36 pub find_symbol: KeyEvent,
37 pub edit_comment: KeyEvent,
38 pub find_comment: KeyEvent,
39 pub patch_text: KeyEvent,
40 pub patch_assembly: KeyEvent,
41 pub jump: KeyEvent,
42 pub change_view: KeyEvent,
43 pub change_selected_pane: KeyEvent,
44 pub fullscreen: KeyEvent,
45
46 pub confirm: KeyEvent,
47 pub close_popup: KeyEvent,
48
49 pub new_line: KeyEvent,
50 pub clear_log: KeyEvent,
51
52 pub undo: KeyEvent,
53 pub redo: KeyEvent,
54}
55
56impl KeySettings {
57 pub fn key_code_to_string(code: KeyCode) -> String {
58 match code {
59 KeyCode::Backspace => "Backspace".to_string(),
60 KeyCode::Enter => "Enter".to_string(),
61 KeyCode::Left => "Left".to_string(),
62 KeyCode::Right => "Right".to_string(),
63 KeyCode::Up => "Up".to_string(),
64 KeyCode::Down => "Down".to_string(),
65 KeyCode::Home => "Home".to_string(),
66 KeyCode::End => "End".to_string(),
67 KeyCode::PageUp => "PageUp".to_string(),
68 KeyCode::PageDown => "PageDown".to_string(),
69 KeyCode::Tab => "Tab".to_string(),
70 KeyCode::BackTab => "BackTab".to_string(),
71 KeyCode::Delete => "Delete".to_string(),
72 KeyCode::Insert => "Insert".to_string(),
73 KeyCode::F(n) => format!("F{}", n),
74 KeyCode::Char(c) => c.to_string(),
75 KeyCode::Null => "Null".to_string(),
76 KeyCode::Esc => "Esc".to_string(),
77 KeyCode::CapsLock => "CapsLock".to_string(),
78 KeyCode::ScrollLock => "ScrollLock".to_string(),
79 KeyCode::NumLock => "NumLock".to_string(),
80 KeyCode::PrintScreen => "PrintScreen".to_string(),
81 KeyCode::Pause => "Pause".to_string(),
82 KeyCode::Menu => "Menu".to_string(),
83 KeyCode::KeypadBegin => "KeypadBegin".to_string(),
84 KeyCode::Media(mcode) => match mcode {
85 MediaKeyCode::Play => "Media(Play)".to_string(),
86 MediaKeyCode::Pause => "Media(Pause)".to_string(),
87 MediaKeyCode::PlayPause => "Media(PlayPause)".to_string(),
88 MediaKeyCode::Reverse => "Media(Reverse)".to_string(),
89 MediaKeyCode::Stop => "Media(Stop)".to_string(),
90 MediaKeyCode::FastForward => "Media(FastForward)".to_string(),
91 MediaKeyCode::Rewind => "Media(Rewind)".to_string(),
92 MediaKeyCode::TrackNext => "Media(TrackNext)".to_string(),
93 MediaKeyCode::TrackPrevious => "Media(TrackPrevious)".to_string(),
94 MediaKeyCode::Record => "Media(Record)".to_string(),
95 MediaKeyCode::LowerVolume => "Media(LowerVolume)".to_string(),
96 MediaKeyCode::RaiseVolume => "Media(RaiseVolume)".to_string(),
97 MediaKeyCode::MuteVolume => "Media(MuteVolume)".to_string(),
98 },
99 KeyCode::Modifier(modifier) => match modifier {
100 ModifierKeyCode::LeftShift => "Modifier(LeftShift)".to_string(),
101 ModifierKeyCode::LeftControl => "Modifier(LeftControl)".to_string(),
102 ModifierKeyCode::LeftAlt => "Modifier(LeftAlt)".to_string(),
103 ModifierKeyCode::LeftSuper => "Modifier(LeftSuper)".to_string(),
104 ModifierKeyCode::LeftHyper => "Modifier(LeftHyper)".to_string(),
105 ModifierKeyCode::LeftMeta => "Modifier(LeftMeta)".to_string(),
106 ModifierKeyCode::RightShift => "Modifier(RightShift)".to_string(),
107 ModifierKeyCode::RightControl => "Modifier(RightControl)".to_string(),
108 ModifierKeyCode::RightAlt => "Modifier(RightAlt)".to_string(),
109 ModifierKeyCode::RightSuper => "Modifier(RightSuper)".to_string(),
110 ModifierKeyCode::RightHyper => "Modifier(RightHyper)".to_string(),
111 ModifierKeyCode::RightMeta => "Modifier(RightMeta)".to_string(),
112 ModifierKeyCode::IsoLevel3Shift => "Modifier(IsoLevel3Shift)".to_string(),
113 ModifierKeyCode::IsoLevel5Shift => "Modifier(IsoLevel5Shift)".to_string(),
114 },
115 }
116 }
117
118 pub fn string_to_key_code(string: &str) -> Result<KeyCode, String> {
119 match string {
120 "Backspace" => Ok(KeyCode::Backspace),
121 "Enter" => Ok(KeyCode::Enter),
122 "Left" => Ok(KeyCode::Left),
123 "Right" => Ok(KeyCode::Right),
124 "Up" => Ok(KeyCode::Up),
125 "Down" => Ok(KeyCode::Down),
126 "Home" => Ok(KeyCode::Home),
127 "End" => Ok(KeyCode::End),
128 "PageUp" => Ok(KeyCode::PageUp),
129 "PageDown" => Ok(KeyCode::PageDown),
130 "Tab" => Ok(KeyCode::Tab),
131 "BackTab" => Ok(KeyCode::BackTab),
132 "Delete" => Ok(KeyCode::Delete),
133 "Insert" => Ok(KeyCode::Insert),
134 "F1" => Ok(KeyCode::F(1)),
135 "F2" => Ok(KeyCode::F(2)),
136 "F3" => Ok(KeyCode::F(3)),
137 "F4" => Ok(KeyCode::F(4)),
138 "F5" => Ok(KeyCode::F(5)),
139 "F6" => Ok(KeyCode::F(6)),
140 "F7" => Ok(KeyCode::F(7)),
141 "F8" => Ok(KeyCode::F(8)),
142 "F9" => Ok(KeyCode::F(9)),
143 "F10" => Ok(KeyCode::F(10)),
144 "F11" => Ok(KeyCode::F(11)),
145 "F12" => Ok(KeyCode::F(12)),
146 c if c.len() == 1 && c.chars().next().is_some() => {
147 Ok(KeyCode::Char(c.chars().next().unwrap()))
148 }
149 "Null" => Ok(KeyCode::Null),
150 "Esc" => Ok(KeyCode::Esc),
151 "CapsLock" => Ok(KeyCode::CapsLock),
152 "ScrollLock" => Ok(KeyCode::ScrollLock),
153 "NumLock" => Ok(KeyCode::NumLock),
154 "PrintScreen" => Ok(KeyCode::PrintScreen),
155 "Pause" => Ok(KeyCode::Pause),
156 "Menu" => Ok(KeyCode::Menu),
157 "KeypadBegin" => Ok(KeyCode::KeypadBegin),
158 "Media(Play)" => Ok(KeyCode::Media(MediaKeyCode::Play)),
159 "Media(Pause)" => Ok(KeyCode::Media(MediaKeyCode::Pause)),
160 "Media(PlayPause)" => Ok(KeyCode::Media(MediaKeyCode::PlayPause)),
161 "Media(Reverse)" => Ok(KeyCode::Media(MediaKeyCode::Reverse)),
162 "Media(Stop)" => Ok(KeyCode::Media(MediaKeyCode::Stop)),
163 "Media(FastForward)" => Ok(KeyCode::Media(MediaKeyCode::FastForward)),
164 "Media(Rewind)" => Ok(KeyCode::Media(MediaKeyCode::Rewind)),
165 "Media(TrackNext)" => Ok(KeyCode::Media(MediaKeyCode::TrackNext)),
166 "Media(TrackPrevious)" => Ok(KeyCode::Media(MediaKeyCode::TrackPrevious)),
167 "Media(Record)" => Ok(KeyCode::Media(MediaKeyCode::Record)),
168 "Media(LowerVolume)" => Ok(KeyCode::Media(MediaKeyCode::LowerVolume)),
169 "Media(RaiseVolume)" => Ok(KeyCode::Media(MediaKeyCode::RaiseVolume)),
170 "Media(MuteVolume)" => Ok(KeyCode::Media(MediaKeyCode::MuteVolume)),
171 "Modifier(LeftShift)" => Ok(KeyCode::Modifier(ModifierKeyCode::LeftShift)),
172 "Modifier(LeftControl)" => Ok(KeyCode::Modifier(ModifierKeyCode::LeftControl)),
173 "Modifier(LeftAlt)" => Ok(KeyCode::Modifier(ModifierKeyCode::LeftAlt)),
174 "Modifier(LeftSuper)" => Ok(KeyCode::Modifier(ModifierKeyCode::LeftSuper)),
175 "Modifier(LeftHyper)" => Ok(KeyCode::Modifier(ModifierKeyCode::LeftHyper)),
176 "Modifier(LeftMeta)" => Ok(KeyCode::Modifier(ModifierKeyCode::LeftMeta)),
177 "Modifier(RightShift)" => Ok(KeyCode::Modifier(ModifierKeyCode::RightShift)),
178 "Modifier(RightControl)" => Ok(KeyCode::Modifier(ModifierKeyCode::RightControl)),
179 "Modifier(RightAlt)" => Ok(KeyCode::Modifier(ModifierKeyCode::RightAlt)),
180 "Modifier(RightSuper)" => Ok(KeyCode::Modifier(ModifierKeyCode::RightSuper)),
181 "Modifier(RightHyper)" => Ok(KeyCode::Modifier(ModifierKeyCode::RightHyper)),
182 "Modifier(RightMeta)" => Ok(KeyCode::Modifier(ModifierKeyCode::RightMeta)),
183 "Modifier(IsoLevel3Shift)" => Ok(KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift)),
184 "Modifier(IsoLevel5Shift)" => Ok(KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift)),
185 _ => Err(format!("Invalid KeyCode: {}", string)),
186 }
187 }
188
189 pub fn key_event_kind_to_string(kind: KeyEventKind) -> String {
190 match kind {
191 KeyEventKind::Press => "Press".to_string(),
192 KeyEventKind::Repeat => "Repeat".to_string(),
193 KeyEventKind::Release => "Release".to_string(),
194 }
195 }
196
197 pub fn string_to_key_event_kind(string: &str) -> Result<KeyEventKind, String> {
198 match string {
199 "Press" => Ok(KeyEventKind::Press),
200 "Repeat" => Ok(KeyEventKind::Repeat),
201 "Release" => Ok(KeyEventKind::Release),
202 _ => Err(format!("Invalid KeyEventKind: {}", string)),
203 }
204 }
205}
206
207impl Default for KeySettings {
208 fn default() -> Self {
209 Self {
210 up: KeyEvent::new(KeyCode::Up, KeyModifiers::empty()),
211 down: KeyEvent::new(KeyCode::Down, KeyModifiers::empty()),
212 left: KeyEvent::new(KeyCode::Left, KeyModifiers::empty()),
213 right: KeyEvent::new(KeyCode::Right, KeyModifiers::empty()),
214
215 next: KeyEvent::new(KeyCode::Right, KeyModifiers::CONTROL),
216 previous: KeyEvent::new(KeyCode::Left, KeyModifiers::CONTROL),
217
218 page_up: KeyEvent::new(KeyCode::PageUp, KeyModifiers::empty()),
219 page_down: KeyEvent::new(KeyCode::PageDown, KeyModifiers::empty()),
220
221 goto_start: KeyEvent::new(KeyCode::Home, KeyModifiers::empty()),
222 goto_end: KeyEvent::new(KeyCode::End, KeyModifiers::empty()),
223
224 quit: KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL),
225 save_and_quit: KeyEvent::new(KeyCode::Char('x'), KeyModifiers::CONTROL),
226 save_as: KeyEvent::new(KeyCode::Char('a'), KeyModifiers::CONTROL),
227 save: KeyEvent::new(KeyCode::Char('s'), KeyModifiers::CONTROL),
228 open: KeyEvent::new(KeyCode::Char('o'), KeyModifiers::CONTROL),
229
230 help: KeyEvent::new(KeyCode::Char('h'), KeyModifiers::empty()),
231 log: KeyEvent::new(KeyCode::Char('l'), KeyModifiers::empty()),
232 run: KeyEvent::new(KeyCode::Char(' '), KeyModifiers::empty()),
233 find_text: KeyEvent::new(KeyCode::Char('/'), KeyModifiers::empty()),
234 find_symbol: KeyEvent::new(KeyCode::Char('s'), KeyModifiers::empty()),
235 edit_comment: KeyEvent::new(KeyCode::Char(';'), KeyModifiers::empty()),
236 find_comment: KeyEvent::new(KeyCode::Char(':'), KeyModifiers::empty()),
237 patch_text: KeyEvent::new(KeyCode::Char('t'), KeyModifiers::empty()),
238 patch_assembly: KeyEvent::new(KeyCode::Char('p'), KeyModifiers::empty()),
239 jump: KeyEvent::new(KeyCode::Char('j'), KeyModifiers::empty()),
240 change_view: KeyEvent::new(KeyCode::Char('v'), KeyModifiers::CONTROL),
241 change_selected_pane: KeyEvent::new(KeyCode::Char('v'), KeyModifiers::empty()),
242 fullscreen: KeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL),
243
244 confirm: KeyEvent::new(KeyCode::Enter, KeyModifiers::empty()),
245 close_popup: KeyEvent::new(KeyCode::Esc, KeyModifiers::empty()),
246
247 new_line: KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT),
248 clear_log: KeyEvent::new(KeyCode::Delete, KeyModifiers::empty()),
249
250 undo: KeyEvent::new(KeyCode::Char('z'), KeyModifiers::CONTROL),
251 redo: KeyEvent::new(KeyCode::Char('y'), KeyModifiers::CONTROL),
252 }
253 }
254}