Add tab context menu
This commit is contained in:
parent
035189a2a1
commit
67cb046298
3 changed files with 311 additions and 58 deletions
|
@ -402,7 +402,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
||||||
for item_event in T::to_item_events(event).into_iter() {
|
for item_event in T::to_item_events(event).into_iter() {
|
||||||
match item_event {
|
match item_event {
|
||||||
ItemEvent::CloseItem => {
|
ItemEvent::CloseItem => {
|
||||||
Pane::close_item(workspace, pane, item.id(), cx)
|
Pane::close_item_by_id(workspace, pane, item.id(), cx)
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,24 @@ use util::ResultExt;
|
||||||
#[derive(Clone, Deserialize, PartialEq)]
|
#[derive(Clone, Deserialize, PartialEq)]
|
||||||
pub struct ActivateItem(pub usize);
|
pub struct ActivateItem(pub usize);
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct CloseItemById {
|
||||||
|
pub item_id: usize,
|
||||||
|
pub pane: WeakViewHandle<Pane>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct CloseItemsToTheLeftById {
|
||||||
|
pub item_id: usize,
|
||||||
|
pub pane: WeakViewHandle<Pane>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct CloseItemsToTheRightById {
|
||||||
|
pub item_id: usize,
|
||||||
|
pub pane: WeakViewHandle<Pane>,
|
||||||
|
}
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
pane,
|
pane,
|
||||||
[
|
[
|
||||||
|
@ -57,12 +75,6 @@ actions!(
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
|
||||||
pub struct CloseItem {
|
|
||||||
pub item_id: usize,
|
|
||||||
pub pane: WeakViewHandle<Pane>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct MoveItem {
|
pub struct MoveItem {
|
||||||
pub item_id: usize,
|
pub item_id: usize,
|
||||||
|
@ -92,11 +104,21 @@ pub struct DeployDockMenu;
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct DeployNewMenu;
|
pub struct DeployNewMenu;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct DeployTabContextMenu {
|
||||||
|
pub position: Vector2F,
|
||||||
|
pub item_id: usize,
|
||||||
|
pub pane: WeakViewHandle<Pane>,
|
||||||
|
}
|
||||||
|
|
||||||
impl_actions!(pane, [GoBack, GoForward, ActivateItem]);
|
impl_actions!(pane, [GoBack, GoForward, ActivateItem]);
|
||||||
impl_internal_actions!(
|
impl_internal_actions!(
|
||||||
pane,
|
pane,
|
||||||
[
|
[
|
||||||
CloseItem,
|
CloseItemById,
|
||||||
|
CloseItemsToTheLeftById,
|
||||||
|
CloseItemsToTheRightById,
|
||||||
|
DeployTabContextMenu,
|
||||||
DeploySplitMenu,
|
DeploySplitMenu,
|
||||||
DeployNewMenu,
|
DeployNewMenu,
|
||||||
DeployDockMenu,
|
DeployDockMenu,
|
||||||
|
@ -127,14 +149,34 @@ pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_async_action(Pane::close_items_to_the_left);
|
cx.add_async_action(Pane::close_items_to_the_left);
|
||||||
cx.add_async_action(Pane::close_items_to_the_right);
|
cx.add_async_action(Pane::close_items_to_the_right);
|
||||||
cx.add_async_action(Pane::close_all_items);
|
cx.add_async_action(Pane::close_all_items);
|
||||||
cx.add_async_action(|workspace: &mut Workspace, action: &CloseItem, cx| {
|
cx.add_async_action(|workspace: &mut Workspace, action: &CloseItemById, cx| {
|
||||||
let pane = action.pane.upgrade(cx)?;
|
let pane = action.pane.upgrade(cx)?;
|
||||||
let task = Pane::close_item(workspace, pane, action.item_id, cx);
|
let task = Pane::close_item_by_id(workspace, pane, action.item_id, cx);
|
||||||
Some(cx.foreground().spawn(async move {
|
Some(cx.foreground().spawn(async move {
|
||||||
task.await?;
|
task.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
cx.add_async_action(
|
||||||
|
|workspace: &mut Workspace, action: &CloseItemsToTheLeftById, cx| {
|
||||||
|
let pane = action.pane.upgrade(cx)?;
|
||||||
|
let task = Pane::close_items_to_the_left_by_id(workspace, pane, action.item_id, cx);
|
||||||
|
Some(cx.foreground().spawn(async move {
|
||||||
|
task.await?;
|
||||||
|
Ok(())
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cx.add_async_action(
|
||||||
|
|workspace: &mut Workspace, action: &CloseItemsToTheRightById, cx| {
|
||||||
|
let pane = action.pane.upgrade(cx)?;
|
||||||
|
let task = Pane::close_items_to_the_right_by_id(workspace, pane, action.item_id, cx);
|
||||||
|
Some(cx.foreground().spawn(async move {
|
||||||
|
task.await?;
|
||||||
|
Ok(())
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
);
|
||||||
cx.add_action(
|
cx.add_action(
|
||||||
|workspace,
|
|workspace,
|
||||||
MoveItem {
|
MoveItem {
|
||||||
|
@ -168,6 +210,7 @@ pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action(Pane::deploy_split_menu);
|
cx.add_action(Pane::deploy_split_menu);
|
||||||
cx.add_action(Pane::deploy_dock_menu);
|
cx.add_action(Pane::deploy_dock_menu);
|
||||||
cx.add_action(Pane::deploy_new_menu);
|
cx.add_action(Pane::deploy_new_menu);
|
||||||
|
cx.add_action(Pane::deploy_tab_context_menu);
|
||||||
cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
|
cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
|
||||||
Pane::reopen_closed_item(workspace, cx).detach();
|
Pane::reopen_closed_item(workspace, cx).detach();
|
||||||
});
|
});
|
||||||
|
@ -214,6 +257,7 @@ pub struct Pane {
|
||||||
nav_history: Rc<RefCell<NavHistory>>,
|
nav_history: Rc<RefCell<NavHistory>>,
|
||||||
toolbar: ViewHandle<Toolbar>,
|
toolbar: ViewHandle<Toolbar>,
|
||||||
tab_bar_context_menu: TabBarContextMenu,
|
tab_bar_context_menu: TabBarContextMenu,
|
||||||
|
tab_context_menu: ViewHandle<ContextMenu>,
|
||||||
docked: Option<DockAnchor>,
|
docked: Option<DockAnchor>,
|
||||||
_background_actions: BackgroundActions,
|
_background_actions: BackgroundActions,
|
||||||
_workspace_id: usize,
|
_workspace_id: usize,
|
||||||
|
@ -319,6 +363,7 @@ impl Pane {
|
||||||
kind: TabBarContextMenuKind::New,
|
kind: TabBarContextMenuKind::New,
|
||||||
handle: context_menu,
|
handle: context_menu,
|
||||||
},
|
},
|
||||||
|
tab_context_menu: cx.add_view(ContextMenu::new),
|
||||||
docked,
|
docked,
|
||||||
_background_actions: background_actions,
|
_background_actions: background_actions,
|
||||||
_workspace_id: workspace_id,
|
_workspace_id: workspace_id,
|
||||||
|
@ -742,9 +787,7 @@ impl Pane {
|
||||||
let pane = pane_handle.read(cx);
|
let pane = pane_handle.read(cx);
|
||||||
let active_item_id = pane.items[pane.active_item_index].id();
|
let active_item_id = pane.items[pane.active_item_index].id();
|
||||||
|
|
||||||
let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
|
let task = Self::close_item_by_id(workspace, pane_handle, active_item_id, cx);
|
||||||
item_id == active_item_id
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(cx.foreground().spawn(async move {
|
Some(cx.foreground().spawn(async move {
|
||||||
task.await?;
|
task.await?;
|
||||||
|
@ -752,6 +795,17 @@ impl Pane {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn close_item_by_id(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
pane: ViewHandle<Pane>,
|
||||||
|
item_id_to_close: usize,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
Self::close_items(workspace, pane, cx, move |view_id| {
|
||||||
|
view_id == item_id_to_close
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close_inactive_items(
|
pub fn close_inactive_items(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
_: &CloseInactiveItems,
|
_: &CloseInactiveItems,
|
||||||
|
@ -804,15 +858,7 @@ impl Pane {
|
||||||
let pane = pane_handle.read(cx);
|
let pane = pane_handle.read(cx);
|
||||||
let active_item_id = pane.items[pane.active_item_index].id();
|
let active_item_id = pane.items[pane.active_item_index].id();
|
||||||
|
|
||||||
let item_ids: Vec<_> = pane
|
let task = Self::close_items_to_the_left_by_id(workspace, pane_handle, active_item_id, cx);
|
||||||
.items()
|
|
||||||
.take_while(|item| item.id() != active_item_id)
|
|
||||||
.map(|item| item.id())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
|
|
||||||
item_ids.contains(&item_id)
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(cx.foreground().spawn(async move {
|
Some(cx.foreground().spawn(async move {
|
||||||
task.await?;
|
task.await?;
|
||||||
|
@ -820,6 +866,29 @@ impl Pane {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn close_items_to_the_left_by_id(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
pane: ViewHandle<Pane>,
|
||||||
|
item_id: usize,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
let item_ids: Vec<_> = pane
|
||||||
|
.read(cx)
|
||||||
|
.items()
|
||||||
|
.take_while(|item| item.id() != item_id)
|
||||||
|
.map(|item| item.id())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let task = Self::close_items(workspace, pane, cx, move |item_id| {
|
||||||
|
item_ids.contains(&item_id)
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.foreground().spawn(async move {
|
||||||
|
task.await?;
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close_items_to_the_right(
|
pub fn close_items_to_the_right(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
_: &CloseItemsToTheRight,
|
_: &CloseItemsToTheRight,
|
||||||
|
@ -829,16 +898,7 @@ impl Pane {
|
||||||
let pane = pane_handle.read(cx);
|
let pane = pane_handle.read(cx);
|
||||||
let active_item_id = pane.items[pane.active_item_index].id();
|
let active_item_id = pane.items[pane.active_item_index].id();
|
||||||
|
|
||||||
let item_ids: Vec<_> = pane
|
let task = Self::close_items_to_the_right_by_id(workspace, pane_handle, active_item_id, cx);
|
||||||
.items()
|
|
||||||
.rev()
|
|
||||||
.take_while(|item| item.id() != active_item_id)
|
|
||||||
.map(|item| item.id())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
|
|
||||||
item_ids.contains(&item_id)
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(cx.foreground().spawn(async move {
|
Some(cx.foreground().spawn(async move {
|
||||||
task.await?;
|
task.await?;
|
||||||
|
@ -846,6 +906,30 @@ impl Pane {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn close_items_to_the_right_by_id(
|
||||||
|
workspace: &mut Workspace,
|
||||||
|
pane: ViewHandle<Pane>,
|
||||||
|
item_id: usize,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
let item_ids: Vec<_> = pane
|
||||||
|
.read(cx)
|
||||||
|
.items()
|
||||||
|
.rev()
|
||||||
|
.take_while(|item| item.id() != item_id)
|
||||||
|
.map(|item| item.id())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let task = Self::close_items(workspace, pane, cx, move |item_id| {
|
||||||
|
item_ids.contains(&item_id)
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.foreground().spawn(async move {
|
||||||
|
task.await?;
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close_all_items(
|
pub fn close_all_items(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
_: &CloseAllItems,
|
_: &CloseAllItems,
|
||||||
|
@ -861,17 +945,6 @@ impl Pane {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_item(
|
|
||||||
workspace: &mut Workspace,
|
|
||||||
pane: ViewHandle<Pane>,
|
|
||||||
item_id_to_close: usize,
|
|
||||||
cx: &mut ViewContext<Workspace>,
|
|
||||||
) -> Task<Result<()>> {
|
|
||||||
Self::close_items(workspace, pane, cx, move |view_id| {
|
|
||||||
view_id == item_id_to_close
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn close_items(
|
pub fn close_items(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
pane: ViewHandle<Pane>,
|
pane: ViewHandle<Pane>,
|
||||||
|
@ -1207,6 +1280,65 @@ impl Pane {
|
||||||
self.tab_bar_context_menu.kind = TabBarContextMenuKind::New;
|
self.tab_bar_context_menu.kind = TabBarContextMenuKind::New;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deploy_tab_context_menu(
|
||||||
|
&mut self,
|
||||||
|
action: &DeployTabContextMenu,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
let target_item_id = action.item_id;
|
||||||
|
let target_pane = action.pane.clone();
|
||||||
|
let active_item_id = self.items[self.active_item_index].id();
|
||||||
|
let is_active_item = target_item_id == active_item_id;
|
||||||
|
|
||||||
|
let mut options = Vec::new();
|
||||||
|
|
||||||
|
// TODO: Explain why we are doing this - for the key bindings
|
||||||
|
options.push(if is_active_item {
|
||||||
|
ContextMenuItem::item("Close Active Item", CloseActiveItem)
|
||||||
|
} else {
|
||||||
|
ContextMenuItem::item(
|
||||||
|
"Close Inactive Item",
|
||||||
|
CloseItemById {
|
||||||
|
item_id: target_item_id,
|
||||||
|
pane: target_pane.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
// This should really be called "close others" and the behaviour should be dynamically based on the tab the action is ran on. Currenlty, this is a weird action because you can run it on a non-active tab and it will close everything by the actual active tab
|
||||||
|
options.push(ContextMenuItem::item(
|
||||||
|
"Close Inactive Items",
|
||||||
|
CloseInactiveItems,
|
||||||
|
));
|
||||||
|
options.push(ContextMenuItem::item("Close Clean Items", CloseCleanItems));
|
||||||
|
options.push(if is_active_item {
|
||||||
|
ContextMenuItem::item("Close Items To The Left", CloseItemsToTheLeft)
|
||||||
|
} else {
|
||||||
|
ContextMenuItem::item(
|
||||||
|
"Close Items To The Left",
|
||||||
|
CloseItemsToTheLeftById {
|
||||||
|
item_id: target_item_id,
|
||||||
|
pane: target_pane.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
options.push(if is_active_item {
|
||||||
|
ContextMenuItem::item("Close Items To The Right", CloseItemsToTheRight)
|
||||||
|
} else {
|
||||||
|
ContextMenuItem::item(
|
||||||
|
"Close Items To The Right",
|
||||||
|
CloseItemsToTheRightById {
|
||||||
|
item_id: target_item_id,
|
||||||
|
pane: target_pane.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
options.push(ContextMenuItem::item("Close All Items", CloseAllItems));
|
||||||
|
|
||||||
|
self.tab_context_menu.update(cx, |menu, cx| {
|
||||||
|
menu.show(action.position, AnchorCorner::TopLeft, options, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toolbar(&self) -> &ViewHandle<Toolbar> {
|
pub fn toolbar(&self) -> &ViewHandle<Toolbar> {
|
||||||
&self.toolbar
|
&self.toolbar
|
||||||
}
|
}
|
||||||
|
@ -1277,13 +1409,22 @@ impl Pane {
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Middle, {
|
.on_click(MouseButton::Middle, {
|
||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
|
let pane = pane.clone();
|
||||||
move |_, cx: &mut EventContext| {
|
move |_, cx: &mut EventContext| {
|
||||||
cx.dispatch_action(CloseItem {
|
cx.dispatch_action(CloseItemById {
|
||||||
item_id: item.id(),
|
item_id: item.id(),
|
||||||
pane: pane.clone(),
|
pane: pane.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.on_down(MouseButton::Right, move |e, cx| {
|
||||||
|
let item = item.clone();
|
||||||
|
cx.dispatch_action(DeployTabContextMenu {
|
||||||
|
position: e.position,
|
||||||
|
item_id: item.id(),
|
||||||
|
pane: pane.clone(),
|
||||||
|
});
|
||||||
|
})
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1454,7 +1595,7 @@ impl Pane {
|
||||||
.on_click(MouseButton::Left, {
|
.on_click(MouseButton::Left, {
|
||||||
let pane = pane.clone();
|
let pane = pane.clone();
|
||||||
move |_, cx| {
|
move |_, cx| {
|
||||||
cx.dispatch_action(CloseItem {
|
cx.dispatch_action(CloseItemById {
|
||||||
item_id,
|
item_id,
|
||||||
pane: pane.clone(),
|
pane: pane.clone(),
|
||||||
})
|
})
|
||||||
|
@ -1624,6 +1765,7 @@ impl View for Pane {
|
||||||
.flex(1., true)
|
.flex(1., true)
|
||||||
.boxed()
|
.boxed()
|
||||||
})
|
})
|
||||||
|
.with_child(ChildView::new(&self.tab_context_menu, cx).boxed())
|
||||||
.boxed()
|
.boxed()
|
||||||
} else {
|
} else {
|
||||||
enum EmptyPane {}
|
enum EmptyPane {}
|
||||||
|
@ -2219,14 +2361,14 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
add_labled_item(&workspace, &pane, "A", cx);
|
add_labeled_item(&workspace, &pane, "A", false, cx);
|
||||||
add_labled_item(&workspace, &pane, "B", cx);
|
add_labeled_item(&workspace, &pane, "B", false, cx);
|
||||||
add_labled_item(&workspace, &pane, "C", cx);
|
add_labeled_item(&workspace, &pane, "C", false, cx);
|
||||||
add_labled_item(&workspace, &pane, "D", cx);
|
add_labeled_item(&workspace, &pane, "D", false, cx);
|
||||||
assert_item_labels(&pane, ["A", "B", "C", "D*"], cx);
|
assert_item_labels(&pane, ["A", "B", "C", "D*"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| pane.activate_item(1, false, false, cx));
|
pane.update(cx, |pane, cx| pane.activate_item(1, false, false, cx));
|
||||||
add_labled_item(&workspace, &pane, "1", cx);
|
add_labeled_item(&workspace, &pane, "1", false, cx);
|
||||||
assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx);
|
assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx);
|
||||||
|
|
||||||
workspace.update(cx, |workspace, cx| {
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
@ -2257,14 +2399,125 @@ mod tests {
|
||||||
assert_item_labels(&pane, ["A*"], cx);
|
assert_item_labels(&pane, ["A*"], cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_labled_item(
|
#[gpui::test]
|
||||||
|
async fn test_close_inactive_items(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||||
|
Settings::test_async(cx);
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
|
||||||
|
let project = Project::test(fs, None, cx).await;
|
||||||
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
|
set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
|
||||||
|
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::close_inactive_items(workspace, &CloseInactiveItems, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
assert_item_labels(&pane, ["C*"], cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_close_clean_items(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||||
|
Settings::test_async(cx);
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
|
||||||
|
let project = Project::test(fs, None, cx).await;
|
||||||
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
|
add_labeled_item(&workspace, &pane, "A", true, cx);
|
||||||
|
add_labeled_item(&workspace, &pane, "B", false, cx);
|
||||||
|
add_labeled_item(&workspace, &pane, "C", false, cx);
|
||||||
|
add_labeled_item(&workspace, &pane, "D", false, cx);
|
||||||
|
add_labeled_item(&workspace, &pane, "E", false, cx);
|
||||||
|
assert_item_labels(&pane, ["A", "B", "C", "D", "E*"], cx);
|
||||||
|
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::close_clean_items(workspace, &CloseCleanItems, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
assert_item_labels(&pane, ["A*"], cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_close_items_to_the_left(
|
||||||
|
deterministic: Arc<Deterministic>,
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
) {
|
||||||
|
Settings::test_async(cx);
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
|
||||||
|
let project = Project::test(fs, None, cx).await;
|
||||||
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
|
set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
|
||||||
|
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::close_items_to_the_left(workspace, &CloseItemsToTheLeft, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
assert_item_labels(&pane, ["C*", "D", "E"], cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_close_items_to_the_right(
|
||||||
|
deterministic: Arc<Deterministic>,
|
||||||
|
cx: &mut TestAppContext,
|
||||||
|
) {
|
||||||
|
Settings::test_async(cx);
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
|
||||||
|
let project = Project::test(fs, None, cx).await;
|
||||||
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
|
set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
|
||||||
|
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::close_items_to_the_right(workspace, &CloseItemsToTheRight, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_close_all_items(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||||
|
Settings::test_async(cx);
|
||||||
|
let fs = FakeFs::new(cx.background());
|
||||||
|
|
||||||
|
let project = Project::test(fs, None, cx).await;
|
||||||
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
|
add_labeled_item(&workspace, &pane, "A", false, cx);
|
||||||
|
add_labeled_item(&workspace, &pane, "B", false, cx);
|
||||||
|
add_labeled_item(&workspace, &pane, "C", false, cx);
|
||||||
|
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
||||||
|
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::close_all_items(workspace, &CloseAllItems, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
assert_item_labels(&pane, [], cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_labeled_item(
|
||||||
workspace: &ViewHandle<Workspace>,
|
workspace: &ViewHandle<Workspace>,
|
||||||
pane: &ViewHandle<Pane>,
|
pane: &ViewHandle<Pane>,
|
||||||
label: &str,
|
label: &str,
|
||||||
|
is_dirty: bool,
|
||||||
cx: &mut TestAppContext,
|
cx: &mut TestAppContext,
|
||||||
) -> Box<ViewHandle<TestItem>> {
|
) -> Box<ViewHandle<TestItem>> {
|
||||||
workspace.update(cx, |workspace, cx| {
|
workspace.update(cx, |workspace, cx| {
|
||||||
let labeled_item = Box::new(cx.add_view(|_| TestItem::new().with_label(label)));
|
let labeled_item =
|
||||||
|
Box::new(cx.add_view(|_| TestItem::new().with_label(label).with_dirty(is_dirty)));
|
||||||
|
|
||||||
Pane::add_item(
|
Pane::add_item(
|
||||||
workspace,
|
workspace,
|
||||||
|
|
|
@ -1548,7 +1548,7 @@ mod tests {
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
let editor3_id = editor3.id();
|
let editor3_id = editor3.id();
|
||||||
drop(editor3);
|
drop(editor3);
|
||||||
Pane::close_item(workspace, workspace.active_pane().clone(), editor3_id, cx)
|
Pane::close_item_by_id(workspace, workspace.active_pane().clone(), editor3_id, cx)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1581,7 +1581,7 @@ mod tests {
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
let editor2_id = editor2.id();
|
let editor2_id = editor2.id();
|
||||||
drop(editor2);
|
drop(editor2);
|
||||||
Pane::close_item(workspace, workspace.active_pane().clone(), editor2_id, cx)
|
Pane::close_item_by_id(workspace, workspace.active_pane().clone(), editor2_id, cx)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1731,7 +1731,7 @@ mod tests {
|
||||||
// Close all the pane items in some arbitrary order.
|
// Close all the pane items in some arbitrary order.
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
Pane::close_item(workspace, pane.clone(), file1_item_id, cx)
|
Pane::close_item_by_id(workspace, pane.clone(), file1_item_id, cx)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1739,7 +1739,7 @@ mod tests {
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
Pane::close_item(workspace, pane.clone(), file4_item_id, cx)
|
Pane::close_item_by_id(workspace, pane.clone(), file4_item_id, cx)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1747,7 +1747,7 @@ mod tests {
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
Pane::close_item(workspace, pane.clone(), file2_item_id, cx)
|
Pane::close_item_by_id(workspace, pane.clone(), file2_item_id, cx)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1755,7 +1755,7 @@ mod tests {
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
Pane::close_item(workspace, pane.clone(), file3_item_id, cx)
|
Pane::close_item_by_id(workspace, pane.clone(), file3_item_id, cx)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue