crashdump_viewer_lib/
handler.rs1use crate::app::{App, AppResult, ProcessSortColumn, ProcessGroupSortColumn, ProcessViewState, SelectedTab, SortDirection};
16use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
17
18pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
19 match app.selected_tab {
20 SelectedTab::Inspect => match key_event.code {
21 KeyCode::Esc | KeyCode::Char('q') => {
22 app.quit();
23 }
24 KeyCode::Char('c') | KeyCode::Char('C')
25 if key_event.modifiers == KeyModifiers::CONTROL =>
26 {
27 app.quit();
28 }
29 KeyCode::Char('i') | KeyCode::Char('I') => {
30 app.selected_tab = SelectedTab::Process;
31 }
32 KeyCode::Right => app.next_tab(),
33 KeyCode::Left => app.prev_tab(),
34 KeyCode::Char('j') | KeyCode::Down => app.inspect_scroll_state.scroll_down(),
35 KeyCode::Char('k') | KeyCode::Up => app.inspect_scroll_state.scroll_up(),
36 KeyCode::Char('f') | KeyCode::PageDown => app.inspect_scroll_state.scroll_page_down(),
37 KeyCode::Char('b') | KeyCode::PageUp => app.inspect_scroll_state.scroll_page_up(),
38 KeyCode::Char('g') | KeyCode::Home => app.inspect_scroll_state.scroll_to_top(),
39 KeyCode::Char('G') | KeyCode::End => app.inspect_scroll_state.scroll_to_bottom(),
40 KeyCode::Char('?') => {
41 app.show_help = !app.show_help;
42 }
43 _ => {}
44 },
45 SelectedTab::ProcessGroup => {
46 match key_event.code {
47 KeyCode::Esc | KeyCode::Char('q') => app.quit(),
48 KeyCode::Char('c') | KeyCode::Char('C')
49 if key_event.modifiers == KeyModifiers::CONTROL =>
50 {
51 app.quit()
52 }
53 KeyCode::Right => app.next_tab(),
54 KeyCode::Left => app.prev_tab(),
55
56 KeyCode::Down => {
57 if let Some(list) = app.tab_lists.get(&app.selected_tab) {
59 if let Some(table_state) = app.table_states.get_mut(&app.selected_tab) {
61 let amount_items = list.len(); if amount_items == 0 {
63 table_state.select(None);
65 } else if let Some(selected) = table_state.selected() {
66 if selected < amount_items - 1 {
67 table_state.select(Some(selected + 1));
68 } else {
69 table_state.select(Some(0)); }
71 } else {
72 table_state.select(Some(0));
74 }
75 }
76 }
77 }
78 KeyCode::Up => {
79 if let Some(list) = app.tab_lists.get(&app.selected_tab) {
80 if let Some(table_state) = app.table_states.get_mut(&app.selected_tab) {
81 let amount_items = list.len();
82 if amount_items == 0 {
83
84 } else if let Some(selected) = table_state.selected() {
85 if selected > 0 {
86 table_state.select(Some(selected - 1));
87 } else {
88 table_state.select(Some(amount_items - 1));
89 }
90 } else {
91 table_state.select(Some(amount_items - 1));
92 }
93 }
94 }
95 }
96 KeyCode::Char('?') => {
97 app.show_help = !app.show_help;
98 }
99 KeyCode::Char(c) if key_event.modifiers == KeyModifiers::SHIFT => {
100 let mut new_sort_column: Option<ProcessGroupSortColumn> = None;
101 match c {
102 'T' => new_sort_column = Some(ProcessGroupSortColumn::TotalMemorySize),
103 'P' => new_sort_column = Some(ProcessGroupSortColumn::Pid),
104 'N' => new_sort_column = Some(ProcessGroupSortColumn::Name),
105 'C' => new_sort_column = Some(ProcessGroupSortColumn::ChildrenCount),
106 _ => {} }
108 if let Some(sort_col) = new_sort_column {
109 if app.process_group_sort_column == sort_col {
110 app.process_group_sort_direction = match app.process_group_sort_direction {
111 SortDirection::Ascending => SortDirection::Descending,
112 SortDirection::Descending => SortDirection::Ascending,
113 };
114 } else {
115 app.process_group_sort_column = sort_col;
116 match sort_col {
117 ProcessGroupSortColumn::Pid | ProcessGroupSortColumn::Name => {
118 app.process_group_sort_direction = SortDirection::Ascending;
119 }
120 _ => {
121 app.process_group_sort_direction = SortDirection::Descending;
123 }
124 }
125 }
126 app.sort_and_update_process_group_table();
127 }
128 }
129
130
131 _ => {}
132 }
133 }
134 SelectedTab::Process => {
135 match key_event.code {
136 KeyCode::Esc | KeyCode::Char('q') => app.quit(),
137 KeyCode::Char('c') | KeyCode::Char('C')
138 if key_event.modifiers == KeyModifiers::CONTROL =>
139 {
140 app.quit()
141 }
142 KeyCode::Right => app.next_tab(),
143 KeyCode::Left => app.prev_tab(),
144 KeyCode::Down | KeyCode::Char('j') => {
145 if let Some(table_state) = app.table_states.get_mut(&SelectedTab::Process) {
146 if let Some(selected) = table_state.selected() {
147 let amount_items = app.tab_lists[&SelectedTab::Process].len();
148 if selected < amount_items.saturating_sub(1) {
149 table_state.select(Some(selected + 1));
150 } else if amount_items > 0 {
151 table_state.select(Some(0));
152 }
153 } else if !app.tab_lists[&SelectedTab::Process].is_empty() {
154 table_state.select(Some(0));
155 }
156 }
157 }
158 KeyCode::Up | KeyCode::Char('k') => {
159 if let Some(table_state) = app.table_states.get_mut(&SelectedTab::Process) {
160 if let Some(selected) = table_state.selected() {
161 let amount_items = app.tab_lists[&SelectedTab::Process].len();
162 if selected > 0 {
163 table_state.select(Some(selected - 1));
164 } else if amount_items > 0 {
165 table_state.select(Some(amount_items - 1));
166 }
167 } else if !app.tab_lists[&SelectedTab::Process].is_empty() {
168 let amount_items = app.tab_lists[&SelectedTab::Process].len();
169 table_state.select(Some(amount_items - 1));
170 }
171 }
172 }
173 KeyCode::Char('s') => app.process_view_state = ProcessViewState::Stack,
174 KeyCode::Char('h') => app.process_view_state = ProcessViewState::Heap,
175 KeyCode::Char('m') => app.process_view_state = ProcessViewState::MessageQueue,
176 KeyCode::Char('i') | KeyCode::Char('I') => app.selected_tab = SelectedTab::Inspect,
177 KeyCode::Char('?') => {
178 app.show_help = !app.show_help;
179 }
180 KeyCode::Char(c) if key_event.modifiers == KeyModifiers::SHIFT => {
181 let mut new_sort_column: Option<ProcessSortColumn> = None;
182 match c {
183 'Q' => new_sort_column = Some(ProcessSortColumn::MessageQueueLength),
184 'M' => new_sort_column = Some(ProcessSortColumn::Memory),
185 'T' => new_sort_column = Some(ProcessSortColumn::TotalBinVHeap),
186 'B' => new_sort_column = Some(ProcessSortColumn::BinVHeap),
187 'P' => new_sort_column = Some(ProcessSortColumn::Pid),
188 'N' => new_sort_column = Some(ProcessSortColumn::Name),
189 'U' => new_sort_column = Some(ProcessSortColumn::BinVHeapUnused),
190 'O' => new_sort_column = Some(ProcessSortColumn::OldBinVHeap),
191 'V' => new_sort_column = Some(ProcessSortColumn::OldBinVHeapUnused),
192 _ => {} }
194
195 if let Some(sort_col) = new_sort_column {
196 if app.process_sort_column == sort_col {
197 app.process_sort_direction = match app.process_sort_direction {
198 SortDirection::Ascending => SortDirection::Descending,
199 SortDirection::Descending => SortDirection::Ascending,
200 };
201 } else {
202 app.process_sort_column = sort_col;
203 match sort_col {
204 ProcessSortColumn::Pid | ProcessSortColumn::Name => {
205 app.process_sort_direction = SortDirection::Ascending;
206 }
207 _ => {
208 app.process_sort_direction = SortDirection::Descending;
210 }
211 }
212 }
213 app.sort_and_update_process_table();
214 }
215 }
216
217 _ => {} }
219 }
220 _ => {
221 match key_event.code {
223 KeyCode::Esc | KeyCode::Char('q') => app.quit(),
224 KeyCode::Char('c') | KeyCode::Char('C')
225 if key_event.modifiers == KeyModifiers::CONTROL =>
226 {
227 app.quit()
228 }
229 KeyCode::Right => app.next_tab(),
230 KeyCode::Left => app.prev_tab(),
231
232 KeyCode::Down => {
233 if let Some(list) = app.tab_lists.get(&app.selected_tab) {
235 if let Some(table_state) = app.table_states.get_mut(&app.selected_tab) {
237 let amount_items = list.len(); if amount_items == 0 {
239 table_state.select(None);
241 } else if let Some(selected) = table_state.selected() {
242 if selected < amount_items - 1 {
243 table_state.select(Some(selected + 1));
244 } else {
245 table_state.select(Some(0)); }
247 } else {
248 table_state.select(Some(0));
250 }
251 }
252 }
253 }
254 KeyCode::Up => {
255 if let Some(list) = app.tab_lists.get(&app.selected_tab) {
256 if let Some(table_state) = app.table_states.get_mut(&app.selected_tab) {
257 let amount_items = list.len();
258 if amount_items == 0 {
259
260 } else if let Some(selected) = table_state.selected() {
261 if selected > 0 {
262 table_state.select(Some(selected - 1));
263 } else {
264 table_state.select(Some(amount_items - 1));
265 }
266 } else {
267 table_state.select(Some(amount_items - 1));
268 }
269 }
270 }
271 }
272 KeyCode::Char('?') => {
273 app.show_help = !app.show_help;
274 }
275 _ => {}
276 }
277 }
278 }
279 Ok(())
280}