diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-07 01:19:39 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-07 01:20:13 +0300 |
| commit | 17e2b2b878ca9b8cad60fd26baef549479c13081 (patch) | |
| tree | afc5947934ee3dd382805952605224de4c77ce13 /src/app/input/navigate.rs | |
| parent | 4f22e9a73ba4d9029468e078235c5f5ce629d179 (diff) | |
fix: honor prefix in copy mode
refs #681
Based on PR #1092 by @reobin.
Co-authored-by: Robin Gagnon <me@reobin.dev>
Diffstat (limited to 'src/app/input/navigate.rs')
| -rw-r--r-- | src/app/input/navigate.rs | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs index f4719ace..6accb22f 100644 --- a/src/app/input/navigate.rs +++ b/src/app/input/navigate.rs @@ -36,11 +36,20 @@ pub(crate) enum ActionContext { } impl App { + fn cancel_copy_mode_if_active(&mut self) { + if self.state.copy_mode.is_some() { + self.state.cancel_copy_mode(&self.terminal_runtimes); + } + } + pub(crate) fn handle_prefix_key(&mut self, raw_key: TerminalKey) { let key = raw_key.as_key_event(); self.state.update_dismissed = true; if self.state.is_prefix_key(raw_key) { + if self.state.copy_mode_pane_is_focused() { + self.state.cancel_copy_mode(&self.terminal_runtimes); + } if !self.pass_through_key_to_focused_pane(raw_key) { leave_command_mode(&mut self.state); } @@ -55,9 +64,19 @@ impl App { if let Some(action) = action_for_key(&self.state, raw_key, BindingDispatch::Prefix) { if action == NavigateAction::EditScrollback { let previous_mode = self.state.mode; + self.cancel_copy_mode_if_active(); self.launch_focused_scrollback_editor(); finish_action_context(&mut self.state, ActionContext::Prefix, previous_mode); + } else if action == NavigateAction::CopyMode { + self.cancel_copy_mode_if_active(); + self.execute_tui_navigate_action(action, ActionContext::Prefix); + } else if copy_mode_survives_prefix_action(action) { + self.execute_tui_navigate_action(action, ActionContext::Prefix); + if self.state.copy_mode.is_some() { + self.state.sync_copy_mode_with_focus(); + } } else { + self.cancel_copy_mode_if_active(); self.execute_tui_navigate_action(action, ActionContext::Prefix); } self.selection_autoscroll_deadline = None; @@ -65,6 +84,7 @@ impl App { } 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; } @@ -1249,6 +1269,29 @@ pub(crate) enum NavigateAction { OpenNavigator, } +fn copy_mode_survives_prefix_action(action: NavigateAction) -> bool { + matches!( + action, + NavigateAction::SwitchWorkspace(_) + | NavigateAction::SwitchTab(_) + | NavigateAction::FocusAgent(_) + | NavigateAction::PreviousWorkspace + | NavigateAction::NextWorkspace + | NavigateAction::PreviousAgent + | NavigateAction::NextAgent + | NavigateAction::PreviousTab + | NavigateAction::NextTab + | NavigateAction::FocusPaneLeft + | NavigateAction::FocusPaneDown + | NavigateAction::FocusPaneUp + | NavigateAction::FocusPaneRight + | NavigateAction::CyclePaneNext + | NavigateAction::CyclePanePrevious + | NavigateAction::LastPane + | NavigateAction::OpenNotificationTarget + ) +} + fn indexed_navigation_action( state: &AppState, key: TerminalKey, @@ -1645,10 +1688,12 @@ fn finish_custom_command_context( } fn leave_command_mode(state: &mut AppState) { - state.mode = if state.active.is_some() { - Mode::Terminal + if state.copy_mode_pane_is_focused() { + state.mode = Mode::Copy; + } else if state.active.is_some() { + state.mode = Mode::Terminal; } else { - Mode::Navigate + state.mode = Mode::Navigate; }; } |
