Add SwapPaneInDirection

Add keybindings for vim (and non-vim)
This commit is contained in:
Conrad Irwin 2023-09-26 21:59:21 -06:00
parent e9e558d8c8
commit 37b6e1cbb7
4 changed files with 107 additions and 9 deletions

View file

@ -506,6 +506,22 @@
"cmd-k cmd-down": [
"workspace::ActivatePaneInDirection",
"Down"
],
"cmd-k shift-left": [
"workspace::SwapPaneInDirection",
"Left"
],
"cmd-k shift-right": [
"workspace::SwapPaneInDirection",
"Right"
],
"cmd-k shift-up": [
"workspace::SwapPaneInDirection",
"Up"
],
"cmd-k shift-down": [
"workspace::SwapPaneInDirection",
"Down"
]
}
},

View file

@ -316,6 +316,38 @@
"workspace::ActivatePaneInDirection",
"Down"
],
"ctrl-w shift-left": [
"workspace::SwapPaneInDirection",
"Left"
],
"ctrl-w shift-right": [
"workspace::SwapPaneInDirection",
"Right"
],
"ctrl-w shift-up": [
"workspace::SwapPaneInDirection",
"Up"
],
"ctrl-w shift-down": [
"workspace::SwapPaneInDirection",
"Down"
],
"ctrl-w shift-h": [
"workspace::SwapPaneInDirection",
"Left"
],
"ctrl-w shift-l": [
"workspace::SwapPaneInDirection",
"Right"
],
"ctrl-w shift-k": [
"workspace::SwapPaneInDirection",
"Up"
],
"ctrl-w shift-j": [
"workspace::SwapPaneInDirection",
"Down"
],
"ctrl-w g t": "pane::ActivateNextItem",
"ctrl-w ctrl-g t": "pane::ActivateNextItem",
"ctrl-w g shift-t": "pane::ActivatePrevItem",

View file

@ -84,6 +84,13 @@ impl PaneGroup {
}
}
pub fn swap(&mut self, from: &ViewHandle<Pane>, to: &ViewHandle<Pane>) {
match &mut self.root {
Member::Pane(_) => {}
Member::Axis(axis) => axis.swap(from, to),
};
}
pub(crate) fn render(
&self,
project: &ModelHandle<Project>,
@ -428,6 +435,21 @@ impl PaneAxis {
}
}
fn swap(&mut self, from: &ViewHandle<Pane>, to: &ViewHandle<Pane>) {
for member in self.members.iter_mut() {
match member {
Member::Axis(axis) => axis.swap(from, to),
Member::Pane(pane) => {
if pane == from {
*member = Member::Pane(to.clone());
} else if pane == to {
*member = Member::Pane(from.clone())
}
}
}
}
}
fn bounding_box_for_pane(&self, pane: &ViewHandle<Pane>) -> Option<RectF> {
debug_assert!(self.members.len() == self.bounding_boxes.borrow().len());

View file

@ -157,6 +157,9 @@ pub struct ActivatePane(pub usize);
#[derive(Clone, Deserialize, PartialEq)]
pub struct ActivatePaneInDirection(pub SplitDirection);
#[derive(Clone, Deserialize, PartialEq)]
pub struct SwapPaneInDirection(pub SplitDirection);
#[derive(Clone, Deserialize, PartialEq)]
pub struct NewFileInDirection(pub SplitDirection);
@ -233,6 +236,7 @@ impl_actions!(
[
ActivatePane,
ActivatePaneInDirection,
SwapPaneInDirection,
NewFileInDirection,
Toast,
OpenTerminal,
@ -318,6 +322,12 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
},
);
cx.add_action(
|workspace: &mut Workspace, action: &SwapPaneInDirection, cx| {
workspace.swap_pane_in_direction(action.0, cx)
},
);
cx.add_action(|workspace: &mut Workspace, _: &ToggleLeftDock, cx| {
workspace.toggle_dock(DockPosition::Left, cx);
});
@ -2236,11 +2246,32 @@ impl Workspace {
direction: SplitDirection,
cx: &mut ViewContext<Self>,
) {
let bounding_box = match self.center.bounding_box_for_pane(&self.active_pane) {
Some(coordinates) => coordinates,
None => {
return;
}
if let Some(pane) = self.find_pane_in_direction(direction, cx) {
cx.focus(pane);
}
}
pub fn swap_pane_in_direction(
&mut self,
direction: SplitDirection,
cx: &mut ViewContext<Self>,
) {
if let Some(to) = self
.find_pane_in_direction(direction, cx)
.map(|pane| pane.clone())
{
self.center.swap(&self.active_pane.clone(), &to);
cx.notify();
}
}
fn find_pane_in_direction(
&mut self,
direction: SplitDirection,
cx: &mut ViewContext<Self>,
) -> Option<&ViewHandle<Pane>> {
let Some(bounding_box) = self.center.bounding_box_for_pane(&self.active_pane) else {
return None;
};
let cursor = self.active_pane.read(cx).pixel_position_of_cursor(cx);
let center = match cursor {
@ -2256,10 +2287,7 @@ impl Workspace {
SplitDirection::Up => vec2f(center.x(), bounding_box.origin_y() - distance_to_next),
SplitDirection::Down => vec2f(center.x(), bounding_box.max_y() + distance_to_next),
};
if let Some(pane) = self.center.pane_at_pixel_position(target) {
cx.focus(pane);
}
self.center.pane_at_pixel_position(target)
}
fn handle_pane_focused(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {