From 37318444d362fd5a3a6f38e96399d1d07875887b Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Fri, 19 Jan 2024 01:29:12 -0500 Subject: [PATCH 1/2] Add keyboard shortcuts to cycle tabs --- src/config.rs | 6 ++++++ src/main.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/config.rs b/src/config.rs index 422b72d..4f74ba7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -35,6 +35,8 @@ pub enum Action { ToggleSettingsPage, ToggleWordWrap, Undo, + TabNext, + TabPrev, } impl Action { @@ -55,6 +57,8 @@ impl Action { Self::Redo => Message::Redo, Self::Save => Message::Save, Self::SelectAll => Message::SelectAll, + Self::TabNext => Message::TabNext, + Self::TabPrev => Message::TabPrev, Self::ToggleGitManagement => Message::ToggleContextPage(ContextPage::GitManagement), Self::ToggleProjectSearch => Message::ToggleContextPage(ContextPage::ProjectSearch), Self::ToggleSettingsPage => Message::ToggleContextPage(ContextPage::Settings), @@ -131,6 +135,8 @@ impl KeyBind { bind!([Ctrl], Comma, ToggleSettingsPage); bind!([Alt], Z, ToggleWordWrap); bind!([Ctrl], Z, Undo); + bind!([Ctrl], PageUp, TabNext); + bind!([Ctrl], PageDown, TabPrev); keybinds } diff --git a/src/main.rs b/src/main.rs index ad928d3..f03327b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -216,6 +216,8 @@ pub enum Message { TabClose(segmented_button::Entity), TabContextAction(segmented_button::Entity, Action), TabContextMenu(segmented_button::Entity, Option), + TabNext, + TabPrev, TabSetCursor(segmented_button::Entity, Cursor), TabWidth(u16), Todo, @@ -1639,6 +1641,38 @@ impl Application for App { tab.context_menu = position_opt; } } + Message::TabNext => { + let len = self.tab_model.iter().count(); + // Next tab position. Wraps around to 0 (the first tab) if the last tab is active. + let pos = self + .tab_model + .position(self.tab_model.active()) + .map(|i| (i as usize + 1) % len) + .expect("at least one tab is always open"); + + let entity = self.tab_model.iter().nth(pos); + if let Some(entity) = entity { + return self.update(Message::TabActivate(entity)); + } + } + Message::TabPrev => { + let pos = self + .tab_model + .position(self.tab_model.active()) + .and_then(|i| (i as usize).checked_sub(1)) + .unwrap_or_else(|| { + self.tab_model + .iter() + .count() + .checked_sub(1) + .unwrap_or_default() + }); + + let entity = self.tab_model.iter().nth(pos); + if let Some(entity) = entity { + return self.update(Message::TabActivate(entity)); + } + } Message::TabSetCursor(entity, cursor) => { if let Some(Tab::Editor(tab)) = self.tab_model.data::(entity) { let mut editor = tab.editor.lock().unwrap(); From e4db4c0dcde158bb0478407caf637bbbca4d8a94 Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Sat, 20 Jan 2024 20:45:49 -0500 Subject: [PATCH 2/2] Add shortcut to jump to tabs; ctrl + n --- src/config.rs | 26 ++++++++++++++++++++++++-- src/main.rs | 16 ++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 4f74ba7..53b0927 100644 --- a/src/config.rs +++ b/src/config.rs @@ -30,6 +30,7 @@ pub enum Action { Redo, Save, SelectAll, + TabJump(usize), ToggleGitManagement, ToggleProjectSearch, ToggleSettingsPage, @@ -57,6 +58,7 @@ impl Action { Self::Redo => Message::Redo, Self::Save => Message::Save, Self::SelectAll => Message::SelectAll, + Self::TabJump(n) => Message::TabActivateJump(*n), Self::TabNext => Message::TabNext, Self::TabPrev => Message::TabPrev, Self::ToggleGitManagement => Message::ToggleContextPage(ContextPage::GitManagement), @@ -114,6 +116,17 @@ impl KeyBind { Action::$action, ); }}; + + // Match enums with a payload + ([$($modifier:ident),+ $(,)?], $key_code:ident, $action:ident($($arg:expr)*)) => {{ + keybinds.insert( + KeyBind { + modifiers: vec![$(Modifier::$modifier),+], + key_code: KeyCode::$key_code, + }, + Action::$action($($arg)*), + ); + }}; } bind!([Ctrl], W, CloseFile); @@ -130,13 +143,22 @@ impl KeyBind { bind!([Ctrl, Shift], Z, Redo); bind!([Ctrl], S, Save); bind!([Ctrl], A, SelectAll); + bind!([Ctrl], Key1, TabJump(0)); + bind!([Ctrl], Key2, TabJump(1)); + bind!([Ctrl], Key3, TabJump(2)); + bind!([Ctrl], Key4, TabJump(3)); + bind!([Ctrl], Key5, TabJump(4)); + bind!([Ctrl], Key6, TabJump(5)); + bind!([Ctrl], Key7, TabJump(6)); + bind!([Ctrl], Key8, TabJump(7)); + bind!([Ctrl], Key9, TabJump(8)); + bind!([Ctrl], PageUp, TabNext); + bind!([Ctrl], PageDown, TabPrev); bind!([Ctrl, Shift], G, ToggleGitManagement); bind!([Ctrl, Shift], F, ToggleProjectSearch); bind!([Ctrl], Comma, ToggleSettingsPage); bind!([Alt], Z, ToggleWordWrap); bind!([Ctrl], Z, Undo); - bind!([Ctrl], PageUp, TabNext); - bind!([Ctrl], PageDown, TabPrev); keybinds } diff --git a/src/main.rs b/src/main.rs index f03327b..dd4a604 100644 --- a/src/main.rs +++ b/src/main.rs @@ -212,6 +212,7 @@ pub enum Message { SystemThemeModeChange(cosmic_theme::ThemeMode), SyntaxTheme(usize, bool), TabActivate(segmented_button::Entity), + TabActivateJump(usize), TabChanged(segmented_button::Entity), TabClose(segmented_button::Entity), TabContextAction(segmented_button::Entity, Action), @@ -1599,6 +1600,21 @@ impl Application for App { self.tab_model.activate(entity); return self.update_tab(); } + Message::TabActivateJump(pos) => { + // Length is always at least one, so there shouldn't be a division by zero + let len = self.tab_model.iter().count(); + // + let pos = if pos >= 8 || pos > len - 1 { + len - 1 + } else { + pos % len + }; + + let entity = self.tab_model.iter().nth(pos); + if let Some(entity) = entity { + return self.update(Message::TabActivate(entity)); + } + } Message::TabChanged(entity) => { if let Some(Tab::Editor(tab)) = self.tab_model.data::(entity) { let mut title = tab.title();