diff options
Diffstat (limited to 'src/app.rs')
-rw-r--r-- | src/app.rs | 1837 |
1 files changed, 3 insertions, 1834 deletions
@@ -7,17 +7,12 @@ mod process_killer; pub mod query; pub mod widgets; -use std::{ - cmp::{max, min}, - collections::HashMap, - time::Instant, -}; +use std::{collections::HashMap, time::Instant}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseEvent}; use fxhash::FxHashMap; use indextree::{Arena, NodeId}; -use unicode_segmentation::GraphemeCursor; -use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; +use unicode_width::UnicodeWidthStr; pub use data_farmer::*; use data_harvester::{processes, temperature}; @@ -26,8 +21,7 @@ use layout_manager::*; pub use widgets::*; use crate::{ - canvas, - constants::{self, MAX_SIGNAL}, + canvas, constants, units::data_units::DataUnit, utils::error::{BottomError, Result}, BottomEvent, Pid, @@ -35,8 +29,6 @@ use crate::{ use self::event::{ComponentEventResult, EventResult, ReturnSignal}; -const MAX_SEARCH_LENGTH: usize = 200; - #[derive(Debug, Clone)] pub enum AxisScaling { Log, @@ -152,12 +144,6 @@ pub struct AppState { pub widget_map: HashMap<u64, BottomWidget>, pub current_widget: BottomWidget, - last_key_press: Instant, - - awaiting_second_char: bool, - - second_char: Option<char>, - pub basic_mode_use_percent: bool, pub is_force_redraw: bool, @@ -214,9 +200,6 @@ impl AppState { basic_table_widget_state: Default::default(), widget_map: Default::default(), current_widget: Default::default(), - last_key_press: Instant::now(), - awaiting_second_char: Default::default(), - second_char: Default::default(), basic_mode_use_percent: Default::default(), is_force_redraw: Default::default(), is_determining_widget_boundary: Default::default(), @@ -533,11 +516,6 @@ impl AppState { ) } - fn reset_multi_tap_keys(&mut self) { - self.awaiting_second_char = false; - self.second_char = None; - } - fn is_in_dialog(&self) -> bool { self.delete_dialog_state.is_showing_dd } @@ -629,376 +607,6 @@ impl AppState { } } - pub fn on_slash(&mut self) { - if !self.ignore_normal_keybinds() { - match &self.current_widget.widget_type { - BottomWidgetType::Proc | BottomWidgetType::ProcSort => { - // Toggle on - if let Some(proc_widget_state) = self.proc_state.get_mut_widget_state( - self.current_widget.widget_id - - match &self.current_widget.widget_type { - BottomWidgetType::ProcSort => 2, - _ => 0, - }, - ) { - proc_widget_state - .process_search_state - .search_state - .is_enabled = true; - self.move_widget_selection(&WidgetDirection::Down); - self.is_force_redraw = true; - } - } - _ => {} - } - } - } - - pub fn toggle_sort(&mut self) { - match &self.current_widget.widget_type { - BottomWidgetType::Proc | BottomWidgetType::ProcSort => { - let widget_id = self.current_widget.widget_id - - match &self.current_widget.widget_type { - BottomWidgetType::Proc => 0, - BottomWidgetType::ProcSort => 2, - _ => 0, - }; - - if let Some(proc_widget_state) = self.proc_state.get_mut_widget_state(widget_id) { - // Open up sorting dialog for that specific proc widget. - // TODO: It might be a decent idea to allow sorting ALL? I dunno. - - proc_widget_state.is_sort_open = !proc_widget_state.is_sort_open; - if proc_widget_state.is_sort_open { - // If it just opened, move left - proc_widget_state - .columns - .set_to_sorted_index_from_type(&proc_widget_state.process_sorting_type); - self.move_widget_selection(&WidgetDirection::Left); - } else { - // Otherwise, move right if currently on the sort widget - if let BottomWidgetType::ProcSort = self.current_widget.widget_type { - self.move_widget_selection(&WidgetDirection::Right); - } - } - } - - self.is_force_redraw = true; - } - _ => {} - } - } - - pub fn invert_sort(&mut self) { - match &self.current_widget.widget_type { - BottomWidgetType::Proc | BottomWidgetType::ProcSort => { - let widget_id = self.current_widget.widget_id - - match &self.current_widget.widget_type { - BottomWidgetType::Proc => 0, - BottomWidgetType::ProcSort => 2, - _ => 0, - }; - - if let Some(proc_widget_state) = self.proc_state.get_mut_widget_state(widget_id) { - proc_widget_state.is_process_sort_descending = - !proc_widget_state.is_process_sort_descending; - - self.proc_state.force_update = Some(widget_id); - } - } - _ => {} - } - } - - pub fn toggle_percentages(&mut self) { - match &self.current_widget.widget_type { - BottomWidgetType::BasicMem => { - self.basic_mode_use_percent = !self.basic_mode_use_percent; // Oh god this is so lazy. - } - BottomWidgetType::Proc => { - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&self.current_widget.widget_id) - { - proc_widget_state - .columns - .toggle(&processes::ProcessSorting::Mem); - if let Some(mem_percent_state) = proc_widget_state - .columns - .toggle(&processes::ProcessSorting::MemPercent) - { - if proc_widget_state.process_sorting_type - == processes::ProcessSorting::MemPercent - || proc_widget_state.process_sorting_type - == processes::ProcessSorting::Mem - { - if mem_percent_state { - proc_widget_state.process_sorting_type = - processes::ProcessSorting::MemPercent; - } else { - proc_widget_state.process_sorting_type = - processes::ProcessSorting::Mem; - } - } - } - - proc_widget_state.requires_redraw = true; - self.proc_state.force_update = Some(self.current_widget.widget_id); - } - } - _ => {} - } - } - - pub fn toggle_ignore_case(&mut self) { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget && proc_widget_state.is_search_enabled() { - proc_widget_state - .process_search_state - .search_toggle_ignore_case(); - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } - } - - pub fn toggle_search_whole_word(&mut self) { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget && proc_widget_state.is_search_enabled() { - proc_widget_state - .process_search_state - .search_toggle_whole_word(); - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } - } - - pub fn toggle_search_regex(&mut self) { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget && proc_widget_state.is_search_enabled() { - proc_widget_state.process_search_state.search_toggle_regex(); - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } - } - - pub fn toggle_tree_mode(&mut self) { - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id)) - { - proc_widget_state.is_tree_mode = !proc_widget_state.is_tree_mode; - - // FIXME: For consistency, either disable tree mode if grouped, or allow grouped mode if in tree mode. - if proc_widget_state.is_tree_mode { - // Disable grouping if so! - proc_widget_state.is_grouped = false; - - proc_widget_state - .columns - .try_enable(&processes::ProcessSorting::State); - - #[cfg(target_family = "unix")] - proc_widget_state - .columns - .try_enable(&processes::ProcessSorting::User); - - proc_widget_state - .columns - .try_disable(&processes::ProcessSorting::Count); - - proc_widget_state - .columns - .try_enable(&processes::ProcessSorting::Pid); - - // We enabled... set PID sort type to ascending. - proc_widget_state.process_sorting_type = processes::ProcessSorting::Pid; - proc_widget_state.is_process_sort_descending = false; - } - - self.proc_state.force_update = Some(self.current_widget.widget_id); - proc_widget_state.requires_redraw = true; - } - } - - /// One of two functions allowed to run while in a dialog... - pub fn on_enter(&mut self) { - if self.delete_dialog_state.is_showing_dd { - if self.dd_err.is_some() { - self.close_dd(); - } else if self.delete_dialog_state.selected_signal != KillSignal::Cancel { - // If within dd... - if self.dd_err.is_none() { - // Also ensure that we didn't just fail a dd... - let dd_result = self.kill_highlighted_process(); - self.delete_dialog_state.scroll_pos = 0; - self.delete_dialog_state.selected_signal = KillSignal::default(); - - // Check if there was an issue... if so, inform the user. - if let Err(dd_err) = dd_result { - self.dd_err = Some(dd_err.to_string()); - } else { - self.delete_dialog_state.is_showing_dd = false; - } - } - } else { - self.delete_dialog_state.scroll_pos = 0; - self.delete_dialog_state.selected_signal = KillSignal::default(); - self.delete_dialog_state.is_showing_dd = false; - } - self.is_force_redraw = true; - } else if !self.is_in_dialog() { - if let BottomWidgetType::ProcSort = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 2)) - { - proc_widget_state.update_sorting_with_columns(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 2); - self.toggle_sort(); - } - } - } - } - - pub fn on_delete(&mut self) { - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget { - if proc_widget_state - .process_search_state - .search_state - .is_enabled - && proc_widget_state.get_search_cursor_position() - < proc_widget_state - .process_search_state - .search_state - .current_search_query - .len() - { - let current_cursor = proc_widget_state.get_search_cursor_position(); - proc_widget_state - .search_walk_forward(proc_widget_state.get_search_cursor_position()); - - let _removed_chars: String = proc_widget_state - .process_search_state - .search_state - .current_search_query - .drain(current_cursor..proc_widget_state.get_search_cursor_position()) - .collect(); - - proc_widget_state - .process_search_state - .search_state - .grapheme_cursor = GraphemeCursor::new( - current_cursor, - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - true, - ); - - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } else { - self.start_killing_process() - } - } - } - } - - pub fn on_backspace(&mut self) { - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget - && proc_widget_state - .process_search_state - .search_state - .is_enabled - && proc_widget_state.get_search_cursor_position() > 0 - { - let current_cursor = proc_widget_state.get_search_cursor_position(); - proc_widget_state - .search_walk_back(proc_widget_state.get_search_cursor_position()); - - let removed_chars: String = proc_widget_state - .process_search_state - .search_state - .current_search_query - .drain(proc_widget_state.get_search_cursor_position()..current_cursor) - .collect(); - - proc_widget_state - .process_search_state - .search_state - .grapheme_cursor = GraphemeCursor::new( - proc_widget_state.get_search_cursor_position(), - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - true, - ); - - proc_widget_state - .process_search_state - .search_state - .char_cursor_position -= UnicodeWidthStr::width(removed_chars.as_str()); - - proc_widget_state - .process_search_state - .search_state - .cursor_direction = CursorDirection::Left; - - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } - } - } - - pub fn get_process_filter(&self, widget_id: u64) -> &Option<query::Query> { - if let Some(process_widget_state) = self.proc_state.widget_states.get(&widget_id) { - &process_widget_state.process_search_state.search_state.query - } else { - &None - } - } - #[cfg(target_family = "unix")] pub fn on_number(&mut self, number_char: char) { if self.delete_dialog_state.is_showing_dd { @@ -1033,48 +641,6 @@ impl AppState { } } - pub fn on_up_key(&mut self) { - if !self.is_in_dialog() { - self.decrement_position_count(); - } else if self.help_dialog.is_showing() { - self.help_scroll_up(); - } else if self.delete_dialog_state.is_showing_dd { - #[cfg(target_os = "windows")] - self.on_right_key(); - #[cfg(target_family = "unix")] - { - if self.app_config_fields.is_advanced_kill { - self.on_left_key(); - } else { - self.on_right_key(); - } - } - return; - } - self.reset_multi_tap_keys(); - } - - pub fn on_down_key(&mut self) { - if !self.is_in_dialog() { - self.increment_position_count(); - } else if self.help_dialog.is_showing() { - self.help_scroll_down(); - } else if self.delete_dialog_state.is_showing_dd { - #[cfg(target_os = "windows")] - self.on_left_key(); - #[cfg(target_family = "unix")] - { - if self.app_config_fields.is_advanced_kill { - self.on_right_key(); - } else { - self.on_left_key(); - } - } - return; - } - self.reset_multi_tap_keys(); - } - pub fn on_left_key(&mut self) { if !self.is_in_dialog() { match self.current_widget.widget_type { @@ -1221,206 +787,6 @@ impl AppState { } } - pub fn on_page_up(&mut self) { - if self.delete_dialog_state.is_showing_dd { - let mut new_signal = match self.delete_dialog_state.selected_signal { - KillSignal::Cancel => 0, - KillSignal::Kill(signal) => max(signal, 8) - 8, - }; - if new_signal > 23 && new_signal < 33 { - new_signal -= 2; - } - self.delete_dialog_state.selected_signal = match new_signal { - 0 => KillSignal::Cancel, - sig => KillSignal::Kill(sig), - }; - } - } - - pub fn on_page_down(&mut self) { - if self.delete_dialog_state.is_showing_dd { - let mut new_signal = match self.delete_dialog_state.selected_signal { - KillSignal::Cancel => 8, - KillSignal::Kill(signal) => min(signal + 8, MAX_SIGNAL), - }; - if new_signal > 31 && new_signal < 42 { - new_signal += 2; - } - self.delete_dialog_state.selected_signal = KillSignal::Kill(new_signal); - } - } - - pub fn skip_cursor_beginning(&mut self) { - if !self.ignore_normal_keybinds() { - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget { - proc_widget_state - .process_search_state - .search_state - .grapheme_cursor = GraphemeCursor::new( - 0, - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - true, - ); - proc_widget_state - .process_search_state - .search_state - .char_cursor_position = 0; - proc_widget_state - .process_search_state - .search_state - .cursor_direction = CursorDirection::Left; - } - } - } - } - } - - pub fn skip_cursor_end(&mut self) { - if !self.ignore_normal_keybinds() { - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget { - proc_widget_state - .process_search_state - .search_state - .grapheme_cursor = GraphemeCursor::new( - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - true, - ); - proc_widget_state - .process_search_state - .search_state - .char_cursor_position = UnicodeWidthStr::width( - proc_widget_state - .process_search_state - .search_state - .current_search_query - .as_str(), - ); - proc_widget_state - .process_search_state - .search_state - .cursor_direction = CursorDirection::Right; - } - } - } - } - } - - pub fn clear_search(&mut self) { - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - proc_widget_state.clear_search(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } - } - - pub fn clear_previous_word(&mut self) { - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - // Traverse backwards from the current cursor location until you hit non-whitespace characters, - // then continue to traverse (and delete) backwards until you hit a whitespace character. Halt. - - // So... first, let's get our current cursor position using graphemes... - let end_index = proc_widget_state.get_char_cursor_position(); - - // Then, let's crawl backwards until we hit our location, and store the "head"... - let query = proc_widget_state.get_current_search_query(); - let mut start_index = 0; - let mut saw_non_whitespace = false; - - for (itx, c) in query - .chars() - .rev() - .enumerate() - .skip(query.len() - end_index) - { - if c.is_whitespace() { - if saw_non_whitespace { - start_index = query.len() - itx; - break; - } - } else { - saw_non_whitespace = true; - } - } - - let removed_chars: String = proc_widget_state - .process_search_state - .search_state - .current_search_query - .drain(start_index..end_index) - .collect(); - - proc_widget_state - .process_search_state - .search_state - .grapheme_cursor = GraphemeCursor::new( - start_index, - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - true, - ); - - proc_widget_state - .process_search_state - .search_state - .char_cursor_position -= UnicodeWidthStr::width(removed_chars.as_str()); - - proc_widget_state - .process_search_state - .search_state - .cursor_direction = CursorDirection::Left; - - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - - // Now, convert this range into a String-friendly range and remove it all at once! - - // Now make sure to also update our current cursor positions... - - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - } - } - } - pub fn start_killing_process(&mut self) { todo!() @@ -1461,294 +827,6 @@ impl AppState { // } } - pub fn on_char_key(&mut self, caught_char: char) { - // Skip control code chars - if caught_char.is_control() { - return; - } - - // Forbid any char key presses when showing a dialog box... - if !self.ignore_normal_keybinds() { - let current_key_press_inst = Instant::now(); - if current_key_press_inst - .duration_since(self.last_key_press) - .as_millis() - > constants::MAX_KEY_TIMEOUT_IN_MILLISECONDS as u128 - { - self.reset_multi_tap_keys(); - } - self.last_key_press = current_key_press_inst; - - if let BottomWidgetType::ProcSearch = self.current_widget.widget_type { - let is_in_search_widget = self.is_in_search_widget(); - if let Some(proc_widget_state) = self - .proc_state - .widget_states - .get_mut(&(self.current_widget.widget_id - 1)) - { - if is_in_search_widget - && proc_widget_state.is_search_enabled() - && UnicodeWidthStr::width( - proc_widget_state - .process_search_state - .search_state - .current_search_query - .as_str(), - ) <= MAX_SEARCH_LENGTH - { - proc_widget_state - .process_search_state - .search_state - .current_search_query - .insert(proc_widget_state.get_search_cursor_position(), caught_char); - - proc_widget_state - .process_search_state - .search_state - .grapheme_cursor = GraphemeCursor::new( - proc_widget_state.get_search_cursor_position(), - proc_widget_state - .process_search_state - .search_state - .current_search_query - .len(), - true, - ); - proc_widget_state - .search_walk_forward(proc_widget_state.get_search_cursor_position()); - - proc_widget_state - .process_search_state - .search_state - .char_cursor_position += - UnicodeWidthChar::width(caught_char).unwrap_or(0); - - proc_widget_state.update_query(); - self.proc_state.force_update = Some(self.current_widget.widget_id - 1); - proc_widget_state - .process_search_state - .search_state - .cursor_direction = CursorDirection::Right; - - return; - } - } - } - self.handle_char(caught_char); - } else if self.help_dialog.is_showing() { - match caught_char { - '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => {} - 'j' | 'k' | 'g' | 'G' => self.handle_char(caught_char), - _ => {} - } - } else if self.delete_dialog_state.is_showing_dd { - match caught_char { - 'h' => self.on_left_key(), - 'j' => self.on_down_key(), - 'k' => self.on_up_key(), - 'l' => self.on_right_key(), - #[cfg(target_family = "unix")] - '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => { - self.on_number(caught_char) - } - 'u' => self.on_page_up(), - 'd' => self.on_page_down(), - 'g' => { - let mut is_first_g = true; - if let Some(second_char) = self.second_char { - if self.awaiting_second_char && second_char == 'g' { - is_first_g = false; - self.awaiting_second_char = false; - self.second_char = None; - self.skip_to_first(); - } - } - - if is_first_g { - self.awaiting_second_char = true; - self.second_char = Some('g'); - } - } - 'G' => self.skip_to_last(), - _ => {} - } - } - } - - fn handle_char(&mut self, caught_char: char) { - match caught_char { - '/' => { - self.on_slash(); - } - 'd' => { - if let BottomWidgetType::Proc = self.current_widget.widget_type { - let mut is_first_d = true; - if let Some(second_char) = self.second_char { - if self.awaiting_second_char && second_char == 'd' { - is_first_d = false; - self.awaiting_second_char = false; - self.second_char = None; - - self.start_killing_process(); - } - } - - if is_first_d { - self.awaiting_second_char = true; - self.second_char = Some('d'); - } - } - } - 'g' => { - let mut is_first_g = true; - if let Some(second_char) = self.second_char { - if self.awaiting_second_char && second_char == 'g' { - is_first_g = false; - self.awaiting_second_char = false; - self.second_char = None; - self.skip_to_first(); - } - } - - if is_first_g { - self.awaiting_second_char = true; - self.second_char = Some('g'); - } - } - 'G' => self.skip_to_last(), - 'k' => self.on_up_key(), - 'j' => self.on_down_key(), - 'f' => {} - 'C' => { - // self.open_config(), - } - 'c' => { - if let BottomWidgetType::Proc = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .get_mut_widget_state(self.current_widget.widget_id) - { - proc_widget_state - .columns - .set_to_sorted_index_from_type(&processes::ProcessSorting::CpuPercent); - proc_widget_state.update_sorting_with_columns(); - self.proc_state.force_update = Some(self.current_widget.widget_id); - } - } - } - 'm' => { - if let BottomWidgetType::Proc = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .get_mut_widget_state(self.current_widget.widget_id) - { - proc_widget_state.columns.set_to_sorted_index_from_type( - &(if proc_widget_state - .columns - .is_enabled(&processes::ProcessSorting::MemPercent) - { - processes::ProcessSorting::MemPercent - } else { - processes::ProcessSorting::Mem - }), - ); - proc_widget_state.update_sorting_with_columns(); - self.proc_state.force_update = Some(self.current_widget.widget_id); - } - } - } - 'p' => { - if let BottomWidgetType::Proc = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .get_mut_widget_state(self.current_widget.widget_id) - { - // Skip if grouped - if !proc_widget_state.is_grouped { - proc_widget_state - .columns - .set_to_sorted_index_from_type(&processes::ProcessSorting::Pid); - proc_widget_state.update_sorting_with_columns(); - self.proc_state.force_update = Some(self.current_widget.widget_id); - } - } - } - } - 'P' => { - if let BottomWidgetType::Proc = self.current_widget.widget_type { - if let Some(proc_widget_state) = self - .proc_state - .get_mut_widget_state(self.current_widget.widget_id) - { - proc_widget_state.is_using_command = !proc_widget_state.is_using_command; - |