@@ -385,19 +385,44 @@ impl TerminalPanel {
}
self.serialize(cx);
}
- &pane::Event::Split(direction) => {
- let fut = self.new_pane_with_cloned_active_terminal(window, cx);
- let pane = pane.clone();
- cx.spawn_in(window, async move |panel, cx| {
- let Some(new_pane) = fut.await else {
+ &pane::Event::Split {
+ direction,
+ clone_active_item,
+ } => {
+ if clone_active_item {
+ let fut = self.new_pane_with_cloned_active_terminal(window, cx);
+ let pane = pane.clone();
+ cx.spawn_in(window, async move |panel, cx| {
+ let Some(new_pane) = fut.await else {
+ return;
+ };
+ panel
+ .update_in(cx, |panel, window, cx| {
+ panel.center.split(&pane, &new_pane, direction).log_err();
+ window.focus(&new_pane.focus_handle(cx));
+ })
+ .ok();
+ })
+ .detach();
+ } else {
+ let Some(item) = pane.update(cx, |pane, cx| pane.take_active_item(window, cx))
+ else {
return;
};
- _ = panel.update_in(cx, |panel, window, cx| {
- panel.center.split(&pane, &new_pane, direction).log_err();
- window.focus(&new_pane.focus_handle(cx));
+ let Ok(project) = self
+ .workspace
+ .update(cx, |workspace, _| workspace.project().clone())
+ else {
+ return;
+ };
+ let new_pane =
+ new_terminal_pane(self.workspace.clone(), project, false, window, cx);
+ new_pane.update(cx, |pane, cx| {
+ pane.add_item(item, true, true, None, window, cx);
});
- })
- .detach();
+ self.center.split(&pane, &new_pane, direction).log_err();
+ window.focus(&new_pane.focus_handle(cx));
+ }
}
pane::Event::Focus => {
self.active_pane = pane.clone();
@@ -206,14 +206,22 @@ actions!(
JoinAll,
/// Reopens the most recently closed item.
ReopenClosedItem,
- /// Splits the pane to the left.
+ /// Splits the pane to the left, cloning the current item.
SplitLeft,
- /// Splits the pane upward.
+ /// Splits the pane upward, cloning the current item.
SplitUp,
- /// Splits the pane to the right.
+ /// Splits the pane to the right, cloning the current item.
SplitRight,
- /// Splits the pane downward.
+ /// Splits the pane downward, cloning the current item.
SplitDown,
+ /// Splits the pane to the left, moving the current item.
+ SplitAndMoveLeft,
+ /// Splits the pane upward, moving the current item.
+ SplitAndMoveUp,
+ /// Splits the pane to the right, moving the current item.
+ SplitAndMoveRight,
+ /// Splits the pane downward, moving the current item.
+ SplitAndMoveDown,
/// Splits the pane horizontally.
SplitHorizontal,
/// Splits the pane vertically.
@@ -257,7 +265,10 @@ pub enum Event {
RemovedItem {
item: Box<dyn ItemHandle>,
},
- Split(SplitDirection),
+ Split {
+ direction: SplitDirection,
+ clone_active_item: bool,
+ },
ItemPinned,
ItemUnpinned,
JoinAll,
@@ -288,9 +299,13 @@ impl fmt::Debug for Event {
.debug_struct("RemovedItem")
.field("item", &item.item_id())
.finish(),
- Event::Split(direction) => f
+ Event::Split {
+ direction,
+ clone_active_item,
+ } => f
.debug_struct("Split")
.field("direction", direction)
+ .field("clone_active_item", clone_active_item)
.finish(),
Event::JoinAll => f.write_str("JoinAll"),
Event::JoinIntoNext => f.write_str("JoinIntoNext"),
@@ -1776,6 +1791,16 @@ impl Pane {
})
}
+ pub fn take_active_item(
+ &mut self,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> Option<Box<dyn ItemHandle>> {
+ let item = self.active_item()?;
+ self.remove_item(item.item_id(), false, false, window, cx);
+ Some(item)
+ }
+
pub fn remove_item(
&mut self,
item_id: EntityId,
@@ -2222,7 +2247,19 @@ impl Pane {
}
pub fn split(&mut self, direction: SplitDirection, cx: &mut Context<Self>) {
- cx.emit(Event::Split(direction));
+ cx.emit(Event::Split {
+ direction,
+ clone_active_item: true,
+ });
+ }
+
+ pub fn split_and_move(&mut self, direction: SplitDirection, cx: &mut Context<Self>) {
+ if self.items.len() > 1 {
+ cx.emit(Event::Split {
+ direction,
+ clone_active_item: false,
+ });
+ }
}
pub fn toolbar(&self) -> &Entity<Toolbar> {
@@ -3566,6 +3603,18 @@ impl Render for Pane {
.on_action(
cx.listener(|pane, _: &SplitDown, _, cx| pane.split(SplitDirection::Down, cx)),
)
+ .on_action(cx.listener(|pane, _: &SplitAndMoveUp, _, cx| {
+ pane.split_and_move(SplitDirection::Up, cx)
+ }))
+ .on_action(cx.listener(|pane, _: &SplitAndMoveDown, _, cx| {
+ pane.split_and_move(SplitDirection::Down, cx)
+ }))
+ .on_action(cx.listener(|pane, _: &SplitAndMoveLeft, _, cx| {
+ pane.split_and_move(SplitDirection::Left, cx)
+ }))
+ .on_action(cx.listener(|pane, _: &SplitAndMoveRight, _, cx| {
+ pane.split_and_move(SplitDirection::Right, cx)
+ }))
.on_action(cx.listener(|_, _: &JoinIntoNext, _, cx| {
cx.emit(Event::JoinIntoNext);
}))
@@ -3929,8 +3929,15 @@ impl Workspace {
item: item.boxed_clone(),
});
}
- pane::Event::Split(direction) => {
- self.split_and_clone(pane.clone(), *direction, window, cx);
+ pane::Event::Split {
+ direction,
+ clone_active_item,
+ } => {
+ if *clone_active_item {
+ self.split_and_clone(pane.clone(), *direction, window, cx);
+ } else {
+ self.split_and_move(pane.clone(), *direction, window, cx);
+ }
}
pane::Event::JoinIntoNext => {
self.join_pane_into_next(pane.clone(), window, cx);
@@ -4044,6 +4051,24 @@ impl Workspace {
new_pane
}
+ pub fn split_and_move(
+ &mut self,
+ pane: Entity<Pane>,
+ direction: SplitDirection,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ let Some(item) = pane.update(cx, |pane, cx| pane.take_active_item(window, cx)) else {
+ return;
+ };
+ let new_pane = self.add_pane(window, cx);
+ new_pane.update(cx, |pane, cx| {
+ pane.add_item(item, true, true, None, window, cx)
+ });
+ self.center.split(&pane, &new_pane, direction).unwrap();
+ cx.notify();
+ }
+
pub fn split_and_clone(
&mut self,
pane: Entity<Pane>,