diff --git a/README.md b/README.md index 9d4bb10..280e564 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ less-intuitive mouse controls are: | k/Up arrow | Move up | | H/Shift+Tab | Select previous tab | | L/Tab | Select next tab | +| F1-F5 | Select tab by position | | ` (Backtick) | Set volume 0% | | 1 | Set volume 10% | | 2 | Set volume 20% | @@ -183,14 +184,23 @@ keybindings = [ ] ``` +F1-F5 already select a tab by position by default. To remap that to +different keys instead (e.g. if F-keys are intercepted by your terminal or +window manager): + ```toml keybindings = [ - # Use F-keys to select tabs - { key = { F = 1 }, action = { SelectTab = 0 } }, - { key = { F = 2 }, action = { SelectTab = 1 } }, - { key = { F = 3 }, action = { SelectTab = 2 } }, - { key = { F = 4 }, action = { SelectTab = 3 } }, - { key = { F = 5 }, action = { SelectTab = 4 } }, + # Free up F1-F5 and use Alt+1 through Alt+5 for tab selection instead + { key = { F = 1 }, action = "Nothing" }, + { key = { F = 2 }, action = "Nothing" }, + { key = { F = 3 }, action = "Nothing" }, + { key = { F = 4 }, action = "Nothing" }, + { key = { F = 5 }, action = "Nothing" }, + { key = { Char = "1" }, modifiers = "ALT", action = { SelectTab = 0 } }, + { key = { Char = "2" }, modifiers = "ALT", action = { SelectTab = 1 } }, + { key = { Char = "3" }, modifiers = "ALT", action = { SelectTab = 2 } }, + { key = { Char = "4" }, modifiers = "ALT", action = { SelectTab = 3 } }, + { key = { Char = "5" }, modifiers = "ALT", action = { SelectTab = 4 } }, ] ``` diff --git a/src/config/keybinding.rs b/src/config/keybinding.rs index 73334e7..c0c453a 100644 --- a/src/config/keybinding.rs +++ b/src/config/keybinding.rs @@ -36,6 +36,16 @@ impl Keybinding { Action::TabLeft, ), (event(KeyCode::Tab), Action::TabRight), + // F1-F5 jump straight to a tab by position, regardless of how + // many tabs are actually configured - SelectTab already + // silently no-ops on an out-of-range index (see + // Action::handle), so binding all 5 unconditionally is safe + // even with `tabs` set to fewer than 5 entries. + (event(KeyCode::F(1)), Action::SelectTab(0)), + (event(KeyCode::F(2)), Action::SelectTab(1)), + (event(KeyCode::F(3)), Action::SelectTab(2)), + (event(KeyCode::F(4)), Action::SelectTab(3)), + (event(KeyCode::F(5)), Action::SelectTab(4)), (event(KeyCode::Char('`')), Action::SetAbsoluteVolume(0.00)), (event(KeyCode::Char('1')), Action::SetAbsoluteVolume(0.10)), (event(KeyCode::Char('2')), Action::SetAbsoluteVolume(0.20)), @@ -123,3 +133,22 @@ impl Keybinding { bindings } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn fkey_defaults_select_tabs_by_position() { + let defaults = Keybinding::defaults(); + let event = |code| KeyEvent::new(code, KeyModifiers::NONE); + + for (fkey, tab_index) in [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4)] { + assert_eq!( + defaults.get(&event(KeyCode::F(fkey))), + Some(&Action::SelectTab(tab_index)), + "F{fkey} should default to selecting tab {tab_index}" + ); + } + } +} diff --git a/wiremix.toml b/wiremix.toml index 218653b..ba88a3f 100644 --- a/wiremix.toml +++ b/wiremix.toml @@ -121,9 +121,15 @@ keybindings = [ { key = { Char = "0" }, action = { SetAbsoluteVolume = 1.00 } }, # Open the help menu { key = { Char = "?" }, action = "Help" }, - # There are two actions which don't have default bindings: - # 1. "Nothing": Do nothing - can effectively delete a default keybinding - # 2. { SelectTab = N }: Open the Nth tab + # Select a tab by position (Playback/Recording/Output/Input/Configuration, + # or whatever order/subset `tabs` above is set to) + { key = { F = 1 }, action = { SelectTab = 0 } }, + { key = { F = 2 }, action = { SelectTab = 1 } }, + { key = { F = 3 }, action = { SelectTab = 2 } }, + { key = { F = 4 }, action = { SelectTab = 3 } }, + { key = { F = 5 }, action = { SelectTab = 4 } }, + # "Nothing" is an action with no default binding - it can be used to + # effectively delete a default keybinding by rebinding its key to it ]