Detailed changes
@@ -1931,7 +1931,8 @@ impl RecentProjectsDelegate {
.workspaces()
.find(|ws| ws.read(cx).database_id() == Some(workspace_id));
if let Some(workspace) = workspace {
- multi_workspace.remove_group(&workspace, window, cx);
+ multi_workspace
+ .remove_group_containing_workspace(&workspace, window, cx);
}
})
.log_err();
@@ -793,13 +793,6 @@ impl Sidebar {
let should_load_threads = !is_collapsed || !query.is_empty();
let is_active = group.workspaces.contains(&active_workspace);
- // Pick a representative workspace for the group: prefer the active
- // workspace if it belongs to this group, otherwise use the main
- // repo workspace (not a linked worktree).
- let representative_workspace = Some(&active_workspace)
- .filter(|_| is_active)
- .unwrap_or_else(|| group.main_workspace(cx));
-
// Collect live thread infos from all workspaces in this group.
let live_infos: Vec<_> = group
.workspaces
@@ -854,23 +847,21 @@ impl Sidebar {
// Load threads from linked git worktrees whose
// canonical paths belong to this group.
- let linked_worktree_queries = group
+ let linked_worktree_paths = group
.workspaces
- .iter()
- .flat_map(|ws| root_repository_snapshots(ws, cx))
- .filter(|snapshot| !snapshot.is_linked_worktree())
- .flat_map(|snapshot| {
- snapshot
- .linked_worktrees()
- .iter()
- .filter(|wt| {
- project_groups.group_owns_worktree(group, &path_list, &wt.path)
+ .first()
+ .map(|workspace| {
+ root_repository_snapshots(workspace, cx)
+ .flat_map(|repo| {
+ repo.linked_worktrees
+ .iter()
+ .map(|worktree| worktree.path.clone())
})
- .map(|wt| PathList::new(std::slice::from_ref(&wt.path)))
.collect::<Vec<_>>()
- });
+ })
+ .unwrap_or_default();
- for worktree_path_list in linked_worktree_queries {
+ for worktree_path_list in linked_worktree_paths {
for row in thread_store
.read(cx)
.entries_for_path(&worktree_path_list)
@@ -1584,7 +1575,8 @@ impl Sidebar {
if let Some(mw) = multi_workspace_for_worktree.upgrade() {
let ws = workspace_for_remove_worktree.clone();
mw.update(cx, |multi_workspace, cx| {
- multi_workspace.remove_group(&ws, window, cx);
+ multi_workspace
+ .remove_group_containing_workspace(&ws, window, cx);
});
}
} else {
@@ -1657,7 +1649,8 @@ impl Sidebar {
if let Some(mw) = multi_workspace_for_remove.upgrade() {
let ws = workspace_for_remove.clone();
mw.update(cx, |multi_workspace, cx| {
- multi_workspace.remove_group(&ws, window, cx);
+ multi_workspace
+ .remove_group_containing_workspace(&ws, window, cx);
});
}
})
@@ -516,7 +516,7 @@ async fn test_workspace_lifecycle(cx: &mut TestAppContext) {
// Remove the second workspace
multi_workspace.update_in(cx, |mw, window, cx| {
let workspace = mw.workspaces().nth(1).unwrap().clone();
- mw.remove_group(&workspace, window, cx);
+ mw.remove_group_containing_workspace(&workspace, window, cx);
});
cx.run_until_parked();
@@ -5061,7 +5061,7 @@ mod property_test {
Operation::RemoveWorkspace { index } => {
let removed = multi_workspace.update_in(cx, |mw, window, cx| {
let workspace = mw.workspaces().nth(index).unwrap().clone();
- mw.remove_group(&workspace, window, cx)
+ mw.remove_group_containing_workspace(&workspace, window, cx)
});
if removed {
state.workspace_paths.remove(index);
@@ -23,6 +23,7 @@ use ui::{ContextMenu, right_click_menu};
const SIDEBAR_RESIZE_HANDLE_SIZE: Pixels = px(6.0);
+use crate::SerializedWorkspaceLocation;
use crate::{
CloseIntent, CloseWindow, DockPosition, Event as WorkspaceEvent, Item, ModalView, OpenMode,
Panel, Workspace, WorkspaceId, client_side_decorations,
@@ -255,6 +256,17 @@ impl ProjectGroupKey {
host,
}
}
+
+ pub fn from_location_and_paths(location: SerializedWorkspaceLocation, paths: PathList) -> Self {
+ let host = match location {
+ SerializedWorkspaceLocation::Local => None,
+ SerializedWorkspaceLocation::Remote(options) => Some(options),
+ };
+ Self {
+ main_worktree_paths: paths,
+ host,
+ }
+ }
}
pub struct MultiWorkspace {
@@ -447,6 +459,10 @@ impl MultiWorkspace {
&self.project_groups
}
+ pub fn project_group_keys(&self) -> impl Iterator<Item = &ProjectGroupKey> {
+ self.project_groups.iter().map(|group| &group.key)
+ }
+
pub fn open_sidebar(&mut self, cx: &mut Context<Self>) {
self.sidebar_open = true;
let sidebar_focus_handle = self.sidebar.as_ref().map(|s| s.focus_handle(cx));
@@ -908,7 +924,8 @@ impl MultiWorkspace {
}
/// Removes the group that contains this workspace.
- pub fn remove_group(
+ #[deprecated = "use remove_group instead"]
+ pub fn remove_group_containing_workspace(
&mut self,
workspace: &Entity<Workspace>,
window: &mut Window,
@@ -921,11 +938,33 @@ impl MultiWorkspace {
else {
return false;
};
+ self.remove_group_at_index(group_ix, window, cx);
+ true
+ }
+ pub fn remove_group(
+ &mut self,
+ key: ProjectGroupKey,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> bool {
+ let Some(group_ix) = self.project_groups.iter_mut().position(|g| g.key == key) else {
+ return false;
+ };
+ self.remove_group_at_index(group_ix, window, cx);
+ true
+ }
+
+ fn remove_group_at_index(
+ &mut self,
+ group_ix: usize,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
let removed_group = self.project_groups.remove(group_ix);
// If we removed the active workspace, pick a new one.
- let app_state = workspace.read(cx).app_state().clone();
+ let app_state = self.active_workspace.read(cx).app_state().clone();
if removed_group.workspaces.contains(&self.active_workspace) {
let workspace = self.workspaces().next();
if let Some(workspace) = workspace {
@@ -958,8 +997,6 @@ impl MultiWorkspace {
cx.emit(MultiWorkspaceEvent::WorkspaceRemoved);
cx.emit(MultiWorkspaceEvent::ActiveWorkspaceChanged);
cx.notify();
-
- true
}
pub fn move_workspace_to_new_window(
@@ -969,7 +1006,7 @@ impl MultiWorkspace {
cx: &mut Context<Self>,
) {
let workspace = workspace.clone();
- if !self.remove_group(&workspace, window, cx) {
+ if !self.remove_group_containing_workspace(&workspace, window, cx) {
return;
}
@@ -2561,7 +2561,7 @@ mod tests {
.nth(1)
.expect("no workspace at index 1")
.clone();
- mw.remove_group(&ws, window, cx);
+ mw.remove_group_containing_workspace(&ws, window, cx);
});
cx.run_until_parked();
@@ -4248,7 +4248,7 @@ mod tests {
.nth(1)
.expect("no workspace at index 1")
.clone();
- mw.remove_group(&ws, window, cx);
+ mw.remove_group_containing_workspace(&ws, window, cx);
});
cx.run_until_parked();
@@ -4363,7 +4363,7 @@ mod tests {
.nth(1)
.expect("no workspace at index 1")
.clone();
- mw.remove_group(&ws, window, cx);
+ mw.remove_group_containing_workspace(&ws, window, cx);
});
cx.run_until_parked();
@@ -4451,7 +4451,7 @@ mod tests {
.nth(1)
.expect("no workspace at index 1")
.clone();
- mw.remove_group(&ws, window, cx);
+ mw.remove_group_containing_workspace(&ws, window, cx);
});
// Simulate the quit handler pattern: collect flush tasks + pending