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