aboutsummaryrefslogtreecommitdiff
path: root/src/app/input/navigate.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-08-01 04:27:50 +0300
committerGitHub <noreply@github.com>2026-08-01 04:27:50 +0300
commitb76adc155d979705a353fd6dc87c702f9dfc6c22 (patch)
treef613254e0cfbfd2b4450a6a5f3ee7c0ba8136976 /src/app/input/navigate.rs
parent8d190eddda2c74afa3dc043f8ec8020ffd7b5a94 (diff)
fix(input): preserve native key lifecycle across routing (#2142)
refs #2077 Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/app/input/navigate.rs')
-rw-r--r--src/app/input/navigate.rs75
1 files changed, 40 insertions, 35 deletions
diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs
index 93dfe77d..6d0f7f22 100644
--- a/src/app/input/navigate.rs
+++ b/src/app/input/navigate.rs
@@ -31,14 +31,14 @@ pub(crate) fn terminal_direct_navigation_action(
pub(crate) fn terminal_direct_non_indexed_navigation_action(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
) -> Option<NavigateAction> {
non_indexed_action_for_key(state, key, BindingDispatch::Direct)
}
pub(crate) fn terminal_direct_indexed_navigation_action(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
) -> Option<NavigateAction> {
indexed_navigation_action(state, key, BindingDispatch::Direct)
}
@@ -65,7 +65,7 @@ impl App {
return;
}
- if self.state.is_prefix_key(raw_key) {
+ if self.state.is_prefix_key(&raw_key) {
if self.state.copy_mode_pane_is_focused() {
self.state.cancel_copy_mode(&self.terminal_runtimes);
}
@@ -81,20 +81,20 @@ impl App {
}
if let Some(action) =
- non_indexed_action_for_key(&self.state, raw_key, BindingDispatch::Prefix)
+ non_indexed_action_for_key(&self.state, &raw_key, BindingDispatch::Prefix)
{
self.execute_prefix_key_action(action);
return;
}
- if let Some(binding) = command_for_key(&self.state, raw_key, BindingDispatch::Prefix) {
+ if let Some(binding) = command_for_key(&self.state, &raw_key, BindingDispatch::Prefix) {
self.cancel_copy_mode_if_active();
self.launch_custom_command(binding, ActionContext::Prefix);
return;
}
if let Some(action) =
- indexed_navigation_action(&self.state, raw_key, BindingDispatch::Prefix)
+ indexed_navigation_action(&self.state, &raw_key, BindingDispatch::Prefix)
{
self.execute_prefix_key_action(action);
return;
@@ -128,7 +128,7 @@ impl App {
let key = raw_key.as_key_event();
self.state.update_dismissed = true;
- if key.code == KeyCode::Esc || self.state.is_prefix_key(raw_key) {
+ if key.code == KeyCode::Esc || self.state.is_prefix_key(&raw_key) {
leave_navigate_mode(&mut self.state);
return;
}
@@ -138,7 +138,7 @@ impl App {
.keybinds
.navigate
.workspace_up
- .matches_direct_key(raw_key)
+ .matches_direct_key(&raw_key)
{
self.state.move_selected_workspace_by_visible_delta(-1);
return;
@@ -148,18 +148,18 @@ impl App {
.keybinds
.navigate
.workspace_down
- .matches_direct_key(raw_key)
+ .matches_direct_key(&raw_key)
{
self.state.move_selected_workspace_by_visible_delta(1);
return;
}
- if let Some(action) = navigate_reserved_action_for_key(&self.state, raw_key) {
+ if let Some(action) = navigate_reserved_action_for_key(&self.state, &raw_key) {
self.execute_tui_navigate_action(action, ActionContext::Navigate);
return;
}
- if let Some(action) = navigate_mode_non_indexed_action_for_key(&self.state, raw_key) {
+ if let Some(action) = navigate_mode_non_indexed_action_for_key(&self.state, &raw_key) {
if action == NavigateAction::EditScrollback {
self.launch_focused_scrollback_editor();
} else {
@@ -169,12 +169,12 @@ impl App {
return;
}
- if let Some(binding) = command_for_key(&self.state, raw_key, BindingDispatch::Prefix) {
+ if let Some(binding) = command_for_key(&self.state, &raw_key, BindingDispatch::Prefix) {
self.launch_custom_command(binding, ActionContext::Navigate);
return;
}
- if let Some(action) = navigate_mode_indexed_action_for_key(&self.state, raw_key) {
+ if let Some(action) = navigate_mode_indexed_action_for_key(&self.state, &raw_key) {
self.execute_tui_navigate_action(action, ActionContext::Navigate);
self.selection_autoscroll_deadline = None;
}
@@ -773,7 +773,7 @@ impl App {
return false;
};
- let bytes = rt.encode_terminal_key(key);
+ let bytes = rt.encode_terminal_key(key.clone());
if bytes.is_empty() || rt.try_send_bytes(Bytes::from(bytes)).is_err() {
return false;
}
@@ -1136,7 +1136,7 @@ pub(crate) enum BindingDispatch {
pub(crate) fn command_for_key(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
dispatch: BindingDispatch,
) -> Option<crate::config::CustomCommandKeybind> {
state
@@ -1150,7 +1150,7 @@ pub(crate) fn command_for_key(
.cloned()
}
-fn unmodified_digit_for_key(key: TerminalKey) -> Option<char> {
+fn unmodified_digit_for_key(key: &TerminalKey) -> Option<char> {
('1'..='9').find(|digit| {
crate::config::terminal_key_matches_combo(
key,
@@ -1164,7 +1164,7 @@ fn unmodified_digit_for_key(key: TerminalKey) -> Option<char> {
#[cfg(test)]
pub(super) fn handle_navigate_reserved_key(state: &mut AppState, key: TerminalKey) -> bool {
- if let Some(c) = unmodified_digit_for_key(key) {
+ if let Some(c) = unmodified_digit_for_key(&key) {
let idx = (c as usize) - ('1' as usize);
if let Some(ws_idx) = state.workspace_at_visible_position(idx) {
state.switch_workspace(ws_idx);
@@ -1203,7 +1203,12 @@ pub(super) fn handle_navigate_reserved_key(state: &mut AppState, key: TerminalKe
}
}
- if state.keybinds.navigate.workspace_up.matches_direct_key(key) {
+ if state
+ .keybinds
+ .navigate
+ .workspace_up
+ .matches_direct_key(&key)
+ {
state.move_selected_workspace_by_visible_delta(-1);
return true;
}
@@ -1211,24 +1216,24 @@ pub(super) fn handle_navigate_reserved_key(state: &mut AppState, key: TerminalKe
.keybinds
.navigate
.workspace_down
- .matches_direct_key(key)
+ .matches_direct_key(&key)
{
state.move_selected_workspace_by_visible_delta(1);
return true;
}
- if state.keybinds.navigate.pane_left.matches_direct_key(key) {
+ if state.keybinds.navigate.pane_left.matches_direct_key(&key) {
state.navigate_pane(NavDirection::Left);
return true;
}
- if state.keybinds.navigate.pane_down.matches_direct_key(key) {
+ if state.keybinds.navigate.pane_down.matches_direct_key(&key) {
state.navigate_pane(NavDirection::Down);
return true;
}
- if state.keybinds.navigate.pane_up.matches_direct_key(key) {
+ if state.keybinds.navigate.pane_up.matches_direct_key(&key) {
state.navigate_pane(NavDirection::Up);
return true;
}
- if state.keybinds.navigate.pane_right.matches_direct_key(key) {
+ if state.keybinds.navigate.pane_right.matches_direct_key(&key) {
state.navigate_pane(NavDirection::Right);
return true;
}
@@ -1236,7 +1241,7 @@ pub(super) fn handle_navigate_reserved_key(state: &mut AppState, key: TerminalKe
false
}
-fn navigate_reserved_action_for_key(state: &AppState, key: TerminalKey) -> Option<NavigateAction> {
+fn navigate_reserved_action_for_key(state: &AppState, key: &TerminalKey) -> Option<NavigateAction> {
if let Some(c) = unmodified_digit_for_key(key) {
return Some(NavigateAction::SwitchWorkspace(
(c as usize) - ('1' as usize),
@@ -1303,12 +1308,12 @@ pub(crate) fn handle_navigate_key(state: &mut AppState, key: KeyEvent) {
state.update_dismissed = true;
let terminal_key = TerminalKey::from(key);
- if state.is_prefix_key(terminal_key) || key.code == KeyCode::Esc {
+ if state.is_prefix_key(&terminal_key) || key.code == KeyCode::Esc {
leave_navigate_mode(state);
return;
}
- if handle_navigate_reserved_key(state, terminal_key) {
+ if handle_navigate_reserved_key(state, terminal_key.clone()) {
return;
}
@@ -1396,7 +1401,7 @@ fn copy_mode_survives_prefix_action(action: NavigateAction) -> bool {
fn indexed_navigation_action(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
dispatch: BindingDispatch,
) -> Option<NavigateAction> {
let kb = &state.keybinds;
@@ -1440,7 +1445,7 @@ fn indexed_navigation_action(
fn action_matches(
bindings: &crate::config::ActionKeybinds,
- key: TerminalKey,
+ key: &TerminalKey,
dispatch: BindingDispatch,
) -> bool {
match dispatch {
@@ -1455,13 +1460,13 @@ fn action_for_key(
key: TerminalKey,
dispatch: BindingDispatch,
) -> Option<NavigateAction> {
- non_indexed_action_for_key(state, key, dispatch)
- .or_else(|| indexed_navigation_action(state, key, dispatch))
+ non_indexed_action_for_key(state, &key, dispatch)
+ .or_else(|| indexed_navigation_action(state, &key, dispatch))
}
fn non_indexed_action_for_key(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
dispatch: BindingDispatch,
) -> Option<NavigateAction> {
let kb = &state.keybinds;
@@ -1536,7 +1541,7 @@ fn navigate_mode_action_for_key(state: &AppState, key: TerminalKey) -> Option<Na
fn navigate_mode_non_indexed_action_for_key(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
) -> Option<NavigateAction> {
let action = non_indexed_action_for_key(state, key, BindingDispatch::Prefix)?;
if matches!(
@@ -1553,7 +1558,7 @@ fn navigate_mode_non_indexed_action_for_key(
fn navigate_mode_indexed_action_for_key(
state: &AppState,
- key: TerminalKey,
+ key: &TerminalKey,
) -> Option<NavigateAction> {
indexed_navigation_action(state, key, BindingDispatch::Prefix)
}
@@ -2719,9 +2724,9 @@ command = "echo literal"
state.keybinds = config.keybinds();
let key = TerminalKey::new(KeyCode::Char('!'), KeyModifiers::empty());
- assert!(command_for_key(&state, key, BindingDispatch::Prefix).is_some());
+ assert!(command_for_key(&state, &key, BindingDispatch::Prefix).is_some());
assert_eq!(
- indexed_navigation_action(&state, key, BindingDispatch::Prefix),
+ indexed_navigation_action(&state, &key, BindingDispatch::Prefix),
Some(NavigateAction::SwitchWorkspace(0))
);
}