aboutsummaryrefslogtreecommitdiff
path: root/src/app/actions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/actions.rs')
-rw-r--r--src/app/actions.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/app/actions.rs b/src/app/actions.rs
index b7634c3c..f8ae511f 100644
--- a/src/app/actions.rs
+++ b/src/app/actions.rs
@@ -113,6 +113,8 @@ impl AppState {
pub fn switch_workspace(&mut self, idx: usize) {
if idx < self.workspaces.len() {
+ self.selection = None;
+ self.selection_autoscroll = None;
self.active = Some(idx);
self.selected = idx;
let workspace_id = self.workspaces[idx].id.clone();
@@ -196,6 +198,8 @@ impl AppState {
pub fn switch_tab(&mut self, idx: usize) {
if let Some(ws_idx) = self.active {
+ self.selection = None;
+ self.selection_autoscroll = None;
let Some(ws) = self.workspaces.get_mut(ws_idx) else {
return;
};
@@ -470,6 +474,8 @@ impl AppState {
if self.workspaces.is_empty() {
return;
}
+ self.selection = None;
+ self.selection_autoscroll = None;
self.mark_session_dirty();
let terminal_ids = self.terminal_ids_for_workspace(self.selected);
let workspace_id = self.workspaces[self.selected].id.clone();
@@ -590,6 +596,8 @@ impl AppState {
}
pub fn close_pane(&mut self) {
+ self.selection = None;
+ self.selection_autoscroll = None;
self.mark_session_dirty();
let active = self.active;
let terminal_ids = active
@@ -615,6 +623,8 @@ impl AppState {
}
pub fn close_tab(&mut self) {
+ self.selection = None;
+ self.selection_autoscroll = None;
self.mark_session_dirty();
let should_close_workspace = self
.active
@@ -654,6 +664,11 @@ impl AppState {
impl AppState {
pub fn clear_selection(&mut self) {
self.selection = None;
+ self.selection_autoscroll = None;
+ }
+
+ pub(crate) fn stop_selection_autoscroll_state(&mut self) {
+ self.selection_autoscroll = None;
}
pub fn copy_selection(&mut self) {
@@ -682,6 +697,7 @@ impl AppState {
}
self.selection = None;
+ self.selection_autoscroll = None;
}
}
@@ -918,6 +934,15 @@ impl AppState {
return;
};
+ if self
+ .selection
+ .as_ref()
+ .is_some_and(|s| s.pane_id == pane_id)
+ {
+ self.selection = None;
+ self.selection_autoscroll = None;
+ }
+
let pane_terminal_id = self.terminal_id_for_pane(ws_idx, pane_id);
let workspace_terminal_ids = self.terminal_ids_for_workspace(ws_idx);
let should_close_workspace = {
@@ -1340,6 +1365,51 @@ mod tests {
}
#[test]
+ fn pane_died_unrelated_pane_preserves_selection() {
+ // Two workspaces; user is selecting text in workspace 0.
+ // A pane in workspace 1 dies — selection must be preserved.
+ let mut state = app_with_workspaces(&["active", "bg"]);
+ let active_pane = *state.workspaces[0].panes.keys().next().unwrap();
+ let bg_pane = *state.workspaces[1].panes.keys().next().unwrap();
+
+ state.selection = Some(crate::selection::Selection::anchor(active_pane, 0, 0, None));
+ state.selection_autoscroll = Some(crate::app::state::SelectionAutoscroll {
+ direction: crate::app::state::SelectionAutoscrollDirection::Down,
+ last_mouse_screen_col: 0,
+ last_mouse_screen_row: 23,
+ inner_rect: ratatui::layout::Rect::new(0, 0, 80, 24),
+ });
+
+ state.handle_pane_died(bg_pane);
+
+ assert!(state.selection.is_some());
+ assert!(state.selection_autoscroll.is_some());
+ }
+
+ #[test]
+ fn pane_died_same_pane_clears_selection() {
+ let mut state = app_with_workspaces(&["test"]);
+ let first_id = state.workspaces[0].tabs[0].root_pane;
+ let second_id = state.workspaces[0].test_split(Direction::Horizontal);
+
+ state.selection = Some(crate::selection::Selection::anchor(second_id, 0, 0, None));
+ state.selection_autoscroll = Some(crate::app::state::SelectionAutoscroll {
+ direction: crate::app::state::SelectionAutoscrollDirection::Down,
+ last_mouse_screen_col: 0,
+ last_mouse_screen_row: 23,
+ inner_rect: ratatui::layout::Rect::new(0, 0, 80, 24),
+ });
+
+ state.handle_pane_died(second_id);
+
+ // first_id still alive, workspace stays, but selection was on the dying pane
+ assert!(state.selection.is_none());
+ assert!(state.selection_autoscroll.is_none());
+ assert_eq!(state.workspaces[0].panes.len(), 1);
+ assert_eq!(state.workspaces[0].panes.keys().next().unwrap(), &first_id);
+ }
+
+ #[test]
fn state_changed_updates_pane() {
let mut state = app_with_workspaces(&["test"]);
let pane_id = *state.workspaces[0].panes.keys().next().unwrap();