mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
workspace: Add ctrl-w x support for vim (#42792)
Adds support for the vim CTRL-W x keybinding, which swaps the active
pane with the next adjacent one, prioritizing column over row and next
over previous. Upon swap, the pane which was swapped with is activated
(this is the vim behavior).
See also
ca6a260ef1/runtime/doc/windows.txt (L514C1-L521C24)
Release Notes:
- Added ctrl-w x keybinding in Vim mode, which swaps the active window
with the next adjacent one (aligning with Vim behavior)
**Vim behavior**
https://github.com/user-attachments/assets/435a8b52-5d1c-4d4b-964e-4f0f3c9aca31
https://github.com/user-attachments/assets/7aa40014-1eac-4cce-858f-516cd06d13f6
**Zed behavior**
https://github.com/user-attachments/assets/2431e860-4e11-45c6-a3f2-08f1a9b610c1
https://github.com/user-attachments/assets/30432d9d-5db1-4650-af30-232b1340229c
Note: There is a discrepancy where in Vim, if vertical and horizontal
splits are mixed, swapping from a column with a single window does not
work (see the vertical video), whilst in Zed it does. However, I don't
see a good reason as to why this should not be supported and would argue
that it makes more sense to keep the clear priority swap behavior,
instead of adding a workaround to supports such cases.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
04e92fb2d2
commit
2df5993eb0
3 changed files with 28 additions and 0 deletions
|
|
@ -857,6 +857,8 @@
|
|||
"ctrl-w shift-right": "workspace::SwapPaneRight",
|
||||
"ctrl-w shift-up": "workspace::SwapPaneUp",
|
||||
"ctrl-w shift-down": "workspace::SwapPaneDown",
|
||||
"ctrl-w x": "workspace::SwapPaneAdjacent",
|
||||
"ctrl-w ctrl-x": "workspace::SwapPaneAdjacent",
|
||||
"ctrl-w shift-h": "workspace::MovePaneLeft",
|
||||
"ctrl-w shift-l": "workspace::MovePaneRight",
|
||||
"ctrl-w shift-k": "workspace::MovePaneUp",
|
||||
|
|
|
|||
|
|
@ -963,6 +963,15 @@ impl SplitDirection {
|
|||
Self::Down | Self::Right => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opposite(&self) -> SplitDirection {
|
||||
match self {
|
||||
Self::Down => Self::Up,
|
||||
Self::Up => Self::Down,
|
||||
Self::Left => Self::Right,
|
||||
Self::Right => Self::Left,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod element {
|
||||
|
|
|
|||
|
|
@ -437,6 +437,8 @@ actions!(
|
|||
SwapPaneUp,
|
||||
/// Swaps the current pane with the one below.
|
||||
SwapPaneDown,
|
||||
// Swaps the current pane with the first available adjacent pane (searching in order: below, above, right, left) and activates that pane.
|
||||
SwapPaneAdjacent,
|
||||
/// Move the current pane to be at the far left.
|
||||
MovePaneLeft,
|
||||
/// Move the current pane to be at the far right.
|
||||
|
|
@ -5823,6 +5825,21 @@ impl Workspace {
|
|||
.on_action(cx.listener(|workspace, _: &SwapPaneDown, _, cx| {
|
||||
workspace.swap_pane_in_direction(SplitDirection::Down, cx)
|
||||
}))
|
||||
.on_action(cx.listener(|workspace, _: &SwapPaneAdjacent, window, cx| {
|
||||
const DIRECTION_PRIORITY: [SplitDirection; 4] = [
|
||||
SplitDirection::Down,
|
||||
SplitDirection::Up,
|
||||
SplitDirection::Right,
|
||||
SplitDirection::Left,
|
||||
];
|
||||
for dir in DIRECTION_PRIORITY {
|
||||
if workspace.find_pane_in_direction(dir, cx).is_some() {
|
||||
workspace.swap_pane_in_direction(dir, cx);
|
||||
workspace.activate_pane_in_direction(dir.opposite(), window, cx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}))
|
||||
.on_action(cx.listener(|workspace, _: &MovePaneLeft, _, cx| {
|
||||
workspace.move_pane_to_border(SplitDirection::Left, cx)
|
||||
}))
|
||||
|
|
|
|||
Loading…
Reference in a new issue