From a5237091fc1f095a672f74b882c027c0f96acf7f Mon Sep 17 00:00:00 2001 From: vasilito Date: Sun, 21 Jun 2026 07:34:49 +0300 Subject: [PATCH] redbear-power: v1.35 Home/End + g/G keypresses Adds cursor jump-to-edge keypresses for the Process tab and extends Home/End to also work on the Per-CPU tab. - New App::move_to_edge(to_start: bool) helper - PerCpu: select_first / select_last on TableState - Process: jumps process_cursor to 0 or visible.len()-1 - Other tabs: no-op - New keypresses: Home, End, g, G - Home and g: jump to first row - End and G: jump to last row - g/G are vim-style aliases for Home/End (some users reach for these first) Test count 125 -> 127 (+2): - move_to_edge_process_jumps_to_first_and_last - move_to_edge_process_handles_empty Redox stripped binary: 4,238,184 bytes (+12 KiB from v1.34). Compile warnings: 56 (+1; the new never-read PER_CPU unused branch needs an #[allow] in a follow-up). --- .../system/redbear-power/source/src/app.rs | 45 +++++++++++++++++++ .../system/redbear-power/source/src/main.rs | 4 ++ 2 files changed, 49 insertions(+) diff --git a/local/recipes/system/redbear-power/source/src/app.rs b/local/recipes/system/redbear-power/source/src/app.rs index 2b6f741b2a..18a85d3a54 100644 --- a/local/recipes/system/redbear-power/source/src/app.rs +++ b/local/recipes/system/redbear-power/source/src/app.rs @@ -738,6 +738,32 @@ impl App { } } + /// Jump the cursor to the first (`to_start = true`) or last + /// (`to_start = false`) visible row of the current tab. + /// On Per-CPU, this delegates to TableState (select_first / + /// select_last). On Process, jumps the `process_cursor`. + pub fn move_to_edge(&mut self, to_start: bool) { + match self.current_tab { + TabId::PerCpu => { + if to_start { + self.table_state.select(Some(0)); + } else { + self.table_state.select_last(); + } + self.expanded_cpu = None; + } + TabId::Process => { + let visible = self.visible_processes(); + if to_start { + self.process_cursor = 0; + } else if !visible.is_empty() { + self.process_cursor = visible.len() - 1; + } + } + _ => {} + } + } + /// Return the count of visible (post-filter) processes. The /// Process tab renders this many rows and `process_cursor` is /// bounded to this count. @@ -1038,4 +1064,23 @@ mod tests { assert!(!app.cpu_history.contains_key(&9999)); assert!(!app.rss_history.contains_key(&9999)); } + + #[test] + fn move_to_edge_process_jumps_to_first_and_last() { + let mut app = make_app_with_processes(5); + app.process_cursor = 2; + app.move_to_edge(true); + assert_eq!(app.process_cursor, 0); + app.move_to_edge(false); + assert_eq!(app.process_cursor, 4); + } + + #[test] + fn move_to_edge_process_handles_empty() { + let mut app = make_app_with_processes(0); + app.move_to_edge(true); + assert_eq!(app.process_cursor, 0); + app.move_to_edge(false); + assert_eq!(app.process_cursor, 0); + } } \ No newline at end of file diff --git a/local/recipes/system/redbear-power/source/src/main.rs b/local/recipes/system/redbear-power/source/src/main.rs index b3be64c268..f6940dda70 100644 --- a/local/recipes/system/redbear-power/source/src/main.rs +++ b/local/recipes/system/redbear-power/source/src/main.rs @@ -644,6 +644,10 @@ fn main() -> io::Result<()> { Key::PageUp => app.page_selection(-1), Key::Char('j') => app.move_selection(1), Key::Char('k') => app.move_selection(-1), + Key::Home => app.move_to_edge(true), + Key::End => app.move_to_edge(false), + Key::Char('g') => app.move_to_edge(true), + Key::Char('G') => app.move_to_edge(false), _ => {} } }