diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c12525bb2a5c6b46cd6b4fabc9599e3b6cdfd25d..c1d26476544ecf5db51a9c7b358ad12c84aa168f 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -210,6 +210,8 @@ actions!( ActivateNextPane, /// Activates the previous pane in the workspace. ActivatePreviousPane, + /// Activates the last pane in the workspace. + ActivateLastPane, /// Switches to the next window. ActivateNextWindow, /// Switches to the previous window. @@ -4331,6 +4333,11 @@ impl Workspace { } } + pub fn activate_last_pane(&mut self, window: &mut Window, cx: &mut App) { + let last_pane = self.center.last_pane(); + window.focus(&last_pane.focus_handle(cx), cx); + } + pub fn activate_pane_in_direction( &mut self, direction: SplitDirection, @@ -6381,6 +6388,9 @@ impl Workspace { .on_action(cx.listener(|workspace, _: &ActivateNextPane, window, cx| { workspace.activate_next_pane(window, cx) })) + .on_action(cx.listener(|workspace, _: &ActivateLastPane, window, cx| { + workspace.activate_last_pane(window, cx) + })) .on_action( cx.listener(|workspace, _: &ActivateNextWindow, _window, cx| { workspace.activate_next_window(cx) @@ -6403,9 +6413,6 @@ impl Workspace { .on_action(cx.listener(|workspace, _: &ActivatePaneDown, window, cx| { workspace.activate_pane_in_direction(SplitDirection::Down, window, cx) })) - .on_action(cx.listener(|workspace, _: &ActivateNextPane, window, cx| { - workspace.activate_next_pane(window, cx) - })) .on_action(cx.listener( |workspace, action: &MoveItemToPaneInDirection, window, cx| { workspace.move_item_to_pane_in_direction(action, window, cx) @@ -10552,6 +10559,57 @@ mod tests { }); } + #[gpui::test] + async fn test_activate_last_pane(cx: &mut gpui::TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + let project = Project::test(fs, [], cx).await; + let (workspace, cx) = + cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx)); + + workspace.update_in(cx, |workspace, window, cx| { + let first_item = cx.new(|cx| { + TestItem::new(cx).with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]) + }); + workspace.add_item_to_active_pane(Box::new(first_item), None, true, window, cx); + workspace.split_pane( + workspace.active_pane().clone(), + SplitDirection::Right, + window, + cx, + ); + workspace.split_pane( + workspace.active_pane().clone(), + SplitDirection::Right, + window, + cx, + ); + }); + + let (first_pane_id, target_last_pane_id) = workspace.update(cx, |workspace, _cx| { + let panes = workspace.center.panes(); + assert!(panes.len() >= 2); + ( + panes.first().expect("at least one pane").entity_id(), + panes.last().expect("at least one pane").entity_id(), + ) + }); + + workspace.update_in(cx, |workspace, window, cx| { + workspace.activate_pane_at_index(&ActivatePane(0), window, cx); + }); + workspace.update(cx, |workspace, _| { + assert_eq!(workspace.active_pane().entity_id(), first_pane_id); + assert_ne!(workspace.active_pane().entity_id(), target_last_pane_id); + }); + + cx.dispatch_action(ActivateLastPane); + + workspace.update(cx, |workspace, _| { + assert_eq!(workspace.active_pane().entity_id(), target_last_pane_id); + }); + } + #[gpui::test] async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) { init_test(cx);