1use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
2
3use crate::keyboard::{KeyCode, KeyEvent, KeyModifiers};
4
5impl<'de> Deserialize<'de> for KeyEvent {
6 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
7 where
8 D: Deserializer<'de>,
9 {
10 let s = String::deserialize(deserializer)?;
11 s.parse().map_err(de::Error::custom)
12 }
13}
14
15fn deserialize_key_or_keys<'de, D>(deserializer: D) -> Result<Vec<KeyEvent>, D::Error>
17where
18 D: Deserializer<'de>,
19{
20 #[derive(Deserialize)]
21 #[serde(untagged)]
22 enum OneOrMany {
23 One(String),
24 Many(Vec<String>),
25 }
26
27 let keys = match OneOrMany::deserialize(deserializer)? {
28 OneOrMany::One(s) => vec![s],
29 OneOrMany::Many(v) => v,
30 };
31
32 keys.into_iter()
33 .map(|s| {
34 s.parse::<KeyEvent>()
35 .map_err(|e| de::Error::custom(format!("Invalid key binding '{s}': {e}")))
36 })
37 .collect()
38}
39
40fn serialize_key_or_keys<S>(keys: &Vec<KeyEvent>, serializer: S) -> Result<S::Ok, S::Error>
42where
43 S: Serializer,
44{
45 if keys.len() == 1 {
46 keys[0].serialize(serializer)
47 } else {
48 keys.serialize(serializer)
49 }
50}
51
52#[derive(Debug, Clone, PartialEq)]
54pub struct Keys(Vec<KeyEvent>);
55
56impl Keys {
57 pub fn new(keys: Vec<KeyEvent>) -> Self {
58 Self(keys)
59 }
60}
61
62impl<'de> Deserialize<'de> for Keys {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: Deserializer<'de>,
66 {
67 deserialize_key_or_keys(deserializer).map(Keys)
68 }
69}
70
71impl Serialize for Keys {
72 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73 where
74 S: Serializer,
75 {
76 serialize_key_or_keys(&self.0, serializer)
77 }
78}
79
80impl std::ops::Deref for Keys {
81 type Target = Vec<KeyEvent>;
82
83 fn deref(&self) -> &Self::Target {
84 &self.0
85 }
86}
87
88impl<'a> IntoIterator for &'a Keys {
89 type Item = &'a KeyEvent;
90 type IntoIter = std::slice::Iter<'a, KeyEvent>;
91
92 fn into_iter(self) -> Self::IntoIter {
93 self.0.iter()
94 }
95}
96
97#[macro_export]
99macro_rules! keys {
100 ($($item:expr),* $(,)?) => {
101 $crate::config::Keys::new(vec![$($item),*])
102 };
103}
104
105#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
106#[serde(deny_unknown_fields)]
107pub struct KeysConfig {
108 #[serde(default)]
109 pub general: KeysGeneral,
111 #[serde(default)]
112 pub search: KeysSearch,
114 #[serde(default)]
115 pub performing_replacement: KeysPerformingReplacement,
117 #[serde(default)]
118 pub results: KeysResults,
120}
121
122#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
123#[serde(deny_unknown_fields, default)]
124pub struct KeysGeneral {
125 pub quit: Keys,
127 pub reset: Keys,
129 pub show_help_menu: Keys,
131}
132
133impl Default for KeysGeneral {
134 fn default() -> Self {
135 Self {
136 quit: keys![KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL)],
137 reset: keys![KeyEvent::new(KeyCode::Char('r'), KeyModifiers::CONTROL)],
138 show_help_menu: keys![KeyEvent::new(KeyCode::Char('h'), KeyModifiers::CONTROL)],
139 }
140 }
141}
142
143#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
144#[serde(deny_unknown_fields, default)]
145pub struct KeysSearch {
146 pub toggle_preview_wrapping: Keys,
148 pub toggle_hidden_files: Keys,
150 pub toggle_multiline: Keys,
152 pub toggle_interpret_escape_sequences: Keys,
154 #[serde(default)]
155 pub fields: KeysSearchFocusFields,
157 #[serde(default)]
158 pub results: KeysSearchFocusResults,
160}
161
162impl Default for KeysSearch {
163 fn default() -> Self {
164 Self {
165 toggle_preview_wrapping: keys![KeyEvent::new(
166 KeyCode::Char('l'),
167 KeyModifiers::CONTROL
168 )],
169 toggle_hidden_files: keys![KeyEvent::new(KeyCode::Char('t'), KeyModifiers::CONTROL)],
170 toggle_multiline: keys![KeyEvent::new(KeyCode::Char('m'), KeyModifiers::ALT)],
171 toggle_interpret_escape_sequences: keys![KeyEvent::new(
172 KeyCode::Char('e'),
173 KeyModifiers::ALT
174 )],
175 fields: KeysSearchFocusFields::default(),
176 results: KeysSearchFocusResults::default(),
177 }
178 }
179}
180
181#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
182#[serde(deny_unknown_fields, default)]
183pub struct KeysSearchFocusFields {
184 pub unlock_prepopulated_fields: Keys,
186 pub trigger_search: Keys,
188 pub focus_next_field: Keys,
190 pub focus_previous_field: Keys,
192}
193
194impl Default for KeysSearchFocusFields {
195 fn default() -> Self {
196 Self {
197 unlock_prepopulated_fields: keys![KeyEvent::new(KeyCode::Char('u'), KeyModifiers::ALT)],
198 trigger_search: keys![KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)],
199 focus_next_field: keys![KeyEvent::new(KeyCode::Tab, KeyModifiers::NONE)],
200 focus_previous_field: keys![KeyEvent::new(KeyCode::Tab, KeyModifiers::SHIFT)],
201 }
202 }
203}
204
205#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
206#[serde(deny_unknown_fields, default)]
207pub struct KeysSearchFocusResults {
208 pub trigger_replacement: Keys,
210 pub back_to_fields: Keys,
212 pub open_in_editor: Keys,
214
215 pub move_down: Keys,
217 pub move_up: Keys,
219 pub move_down_half_page: Keys,
221 pub move_up_half_page: Keys,
223 pub move_down_full_page: Keys,
225 pub move_up_full_page: Keys,
227 pub move_top: Keys,
229 pub move_bottom: Keys,
231
232 pub toggle_selected_inclusion: Keys,
234 pub toggle_all_selected: Keys,
236 pub toggle_multiselect_mode: Keys,
238
239 pub flip_multiselect_direction: Keys,
241}
242
243impl Default for KeysSearchFocusResults {
244 fn default() -> Self {
245 Self {
246 trigger_replacement: keys![KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)],
247 back_to_fields: keys![
248 KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE),
249 KeyEvent::new(KeyCode::Char('o'), KeyModifiers::CONTROL),
250 ],
251 open_in_editor: keys![KeyEvent::new(KeyCode::Char('e'), KeyModifiers::NONE)],
252
253 move_down: keys![
254 KeyEvent::new(KeyCode::Char('j'), KeyModifiers::NONE),
255 KeyEvent::new(KeyCode::Down, KeyModifiers::NONE),
256 KeyEvent::new(KeyCode::Char('n'), KeyModifiers::CONTROL),
257 ],
258 move_up: keys![
259 KeyEvent::new(KeyCode::Char('k'), KeyModifiers::NONE),
260 KeyEvent::new(KeyCode::Up, KeyModifiers::NONE),
261 KeyEvent::new(KeyCode::Char('p'), KeyModifiers::CONTROL),
262 ],
263 move_down_half_page: keys![KeyEvent::new(KeyCode::Char('d'), KeyModifiers::CONTROL)],
264 move_down_full_page: keys![
265 KeyEvent::new(KeyCode::Char('f'), KeyModifiers::CONTROL),
266 KeyEvent::new(KeyCode::PageDown, KeyModifiers::NONE),
267 ],
268 move_up_half_page: keys![KeyEvent::new(KeyCode::Char('u'), KeyModifiers::CONTROL)],
269 move_up_full_page: keys![
270 KeyEvent::new(KeyCode::Char('b'), KeyModifiers::CONTROL),
271 KeyEvent::new(KeyCode::PageUp, KeyModifiers::NONE),
272 ],
273 move_top: keys![KeyEvent::new(KeyCode::Char('g'), KeyModifiers::NONE)],
274 move_bottom: keys![KeyEvent::new(KeyCode::Char('G'), KeyModifiers::NONE)],
275
276 toggle_selected_inclusion: keys![KeyEvent::new(KeyCode::Char(' '), KeyModifiers::NONE)],
277 toggle_all_selected: keys![KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE)],
278 toggle_multiselect_mode: keys![KeyEvent::new(KeyCode::Char('v'), KeyModifiers::NONE)],
279
280 flip_multiselect_direction: keys![KeyEvent::new(KeyCode::Char(';'), KeyModifiers::ALT)],
281 }
282 }
283}
284
285#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
286#[serde(deny_unknown_fields, default)]
287#[derive(Default)]
288pub struct KeysPerformingReplacement {}
289
290#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
291#[serde(deny_unknown_fields, default)]
292pub struct KeysResults {
293 pub scroll_errors_down: Keys,
295 pub scroll_errors_up: Keys,
297 pub quit: Keys,
299}
300
301impl Default for KeysResults {
302 fn default() -> Self {
303 Self {
304 scroll_errors_down: keys![
305 KeyEvent::new(KeyCode::Char('j'), KeyModifiers::NONE),
306 KeyEvent::new(KeyCode::Down, KeyModifiers::NONE),
307 KeyEvent::new(KeyCode::Char('n'), KeyModifiers::CONTROL),
308 ],
309 scroll_errors_up: keys![
310 KeyEvent::new(KeyCode::Char('k'), KeyModifiers::NONE),
311 KeyEvent::new(KeyCode::Up, KeyModifiers::NONE),
312 KeyEvent::new(KeyCode::Char('p'), KeyModifiers::CONTROL),
313 ],
314 quit: keys![
315 KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE),
316 KeyEvent::new(KeyCode::Char('q'), KeyModifiers::NONE),
317 ],
318 }
319 }
320}