1use std::sync::LazyLock;
2
3use config::{Config, Environment, File};
4use crossterm::event::KeyCode;
5
6pub enum Action {
7 Up,
8 Down,
9 PageUp,
10 PageDown,
11 HalfPageUp,
12 HalfPageDown,
13 Search,
14 SelectLink,
15 SelectLinkAlt,
16 SelectDetails,
17 SearchNext,
18 SearchPrevious,
19 Edit,
20 Hover,
21 Enter,
22 Escape,
23 ToTop,
24 ToBottom,
25 Help,
26 Back,
27 ToFileTree,
28 Sort,
29 None,
30}
31
32#[derive(Debug)]
33pub struct KeyConfig {
34 pub up: char,
35 pub down: char,
36 pub page_up: char,
37 pub page_down: char,
38 pub half_page_up: char,
39 pub half_page_down: char,
40 pub search: char,
41 pub search_next: char,
42 pub search_previous: char,
43 pub select_link: char,
44 pub select_link_alt: char,
45 pub select_details: char,
46 pub edit: char,
47 pub hover: char,
48 pub top: char,
49 pub bottom: char,
50 pub back: char,
51 pub file_tree: char,
52 pub sort: char,
53}
54
55#[must_use]
56pub fn key_to_action(key: KeyCode) -> Action {
57 match key {
58 KeyCode::Char(c) => {
59 if c == KEY_CONFIG.up {
60 return Action::Up;
61 }
62
63 if c == KEY_CONFIG.down {
64 return Action::Down;
65 }
66
67 if c == KEY_CONFIG.page_up {
68 return Action::PageUp;
69 }
70
71 if c == KEY_CONFIG.page_down {
72 return Action::PageDown;
73 }
74
75 if c == KEY_CONFIG.half_page_up {
76 return Action::HalfPageUp;
77 }
78
79 if c == KEY_CONFIG.half_page_down {
80 return Action::HalfPageDown;
81 }
82
83 if c == KEY_CONFIG.search || c == '/' {
84 return Action::Search;
85 }
86
87 if c == KEY_CONFIG.select_link {
88 return Action::SelectLink;
89 }
90
91 if c == KEY_CONFIG.select_link_alt {
92 return Action::SelectLinkAlt;
93 }
94
95 if c == KEY_CONFIG.select_details {
96 return Action::SelectDetails;
97 }
98
99 if c == KEY_CONFIG.search_next {
100 return Action::SearchNext;
101 }
102
103 if c == KEY_CONFIG.search_previous {
104 return Action::SearchPrevious;
105 }
106
107 if c == KEY_CONFIG.edit {
108 return Action::Edit;
109 }
110
111 if c == KEY_CONFIG.hover {
112 return Action::Hover;
113 }
114
115 if c == KEY_CONFIG.top {
116 return Action::ToTop;
117 }
118
119 if c == KEY_CONFIG.bottom {
120 return Action::ToBottom;
121 }
122
123 if c == KEY_CONFIG.back {
124 return Action::Back;
125 }
126
127 if c == KEY_CONFIG.file_tree {
128 return Action::ToFileTree;
129 }
130
131 if c == KEY_CONFIG.sort {
132 return Action::Sort;
133 }
134
135 if c == '?' {
136 return Action::Help;
137 }
138
139 Action::None
140 }
141 KeyCode::Up => Action::Up,
142 KeyCode::Down => Action::Down,
143 KeyCode::PageUp => Action::PageUp,
144 KeyCode::PageDown => Action::PageDown,
145 KeyCode::Right => Action::PageDown,
146 KeyCode::Left => Action::PageUp,
147 KeyCode::Enter => Action::Enter,
148 KeyCode::Esc => Action::Escape,
149 _ => Action::None,
150 }
151}
152
153pub static KEY_CONFIG: LazyLock<KeyConfig> = LazyLock::new(|| {
154 let config_dir = dirs::home_dir().unwrap();
155 let config_file = config_dir.join(".config").join("mdt").join("config.toml");
156 let settings = Config::builder()
157 .add_source(File::with_name(config_file.to_str().unwrap()).required(false))
158 .add_source(Environment::with_prefix("MDT").separator("_"))
159 .build()
160 .unwrap();
161
162 KeyConfig {
163 up: settings.get::<char>("up").unwrap_or('k'),
164 down: settings.get::<char>("down").unwrap_or('j'),
165 page_up: settings.get::<char>("page_up").unwrap_or('u'),
166 page_down: settings.get::<char>("page_down").unwrap_or('d'),
167 half_page_up: settings.get::<char>("half_page_up").unwrap_or('h'),
168 half_page_down: settings.get::<char>("half_page_down").unwrap_or('l'),
169 search: settings.get::<char>("search").unwrap_or('f'),
170 select_link: settings.get::<char>("select_link").unwrap_or('s'),
171 select_link_alt: settings.get::<char>("select_link_alt").unwrap_or('S'),
172 select_details: settings.get::<char>("select_details").unwrap_or('D'),
173 search_next: settings.get::<char>("search_next").unwrap_or('n'),
174 search_previous: settings.get::<char>("search_previous").unwrap_or('N'),
175 edit: settings.get::<char>("edit").unwrap_or('e'),
176 hover: settings.get::<char>("hover").unwrap_or('K'),
177 top: settings.get::<char>("top").unwrap_or('g'),
178 bottom: settings.get::<char>("bottom").unwrap_or('G'),
179 back: settings.get::<char>("back").unwrap_or('b'),
180 file_tree: settings.get::<char>("file_tree").unwrap_or('t'),
181 sort: settings.get::<char>("sort").unwrap_or('o'),
182 }
183});