@@ -95,7 +95,10 @@ use task_store::TaskStore;
use terminals::Terminals;
use text::{Anchor, BufferId};
use toolchain_store::EmptyToolchainStore;
-use util::{paths::compare_paths, ResultExt as _};
+use util::{
+ paths::{compare_paths, SanitizedPath},
+ ResultExt as _,
+};
use worktree::{CreatedEntry, Snapshot, Traversal};
use worktree_store::{WorktreeStore, WorktreeStoreEvent};
@@ -1484,22 +1487,37 @@ impl Project {
.and_then(|worktree| worktree.read(cx).status_for_file(&project_path.path))
}
- pub fn visibility_for_paths(&self, paths: &[PathBuf], cx: &App) -> Option<bool> {
+ pub fn visibility_for_paths(
+ &self,
+ paths: &[PathBuf],
+ metadatas: &[Metadata],
+ exclude_sub_dirs: bool,
+ cx: &App,
+ ) -> Option<bool> {
paths
.iter()
- .map(|path| self.visibility_for_path(path, cx))
+ .zip(metadatas)
+ .map(|(path, metadata)| self.visibility_for_path(path, metadata, exclude_sub_dirs, cx))
.max()
.flatten()
}
- pub fn visibility_for_path(&self, path: &Path, cx: &App) -> Option<bool> {
+ pub fn visibility_for_path(
+ &self,
+ path: &Path,
+ metadata: &Metadata,
+ exclude_sub_dirs: bool,
+ cx: &App,
+ ) -> Option<bool> {
+ let sanitized_path = SanitizedPath::from(path);
+ let path = sanitized_path.as_path();
self.worktrees(cx)
.filter_map(|worktree| {
let worktree = worktree.read(cx);
- worktree
- .as_local()?
- .contains_abs_path(path)
- .then(|| worktree.is_visible())
+ let abs_path = worktree.as_local()?.abs_path();
+ let contains = path == abs_path
+ || (path.starts_with(abs_path) && (!exclude_sub_dirs || !metadata.is_dir));
+ contains.then(|| worktree.is_visible())
})
.max()
}
@@ -5958,7 +5958,6 @@ pub struct OpenOptions {
pub replace_window: Option<WindowHandle<Workspace>>,
pub env: Option<HashMap<String, String>>,
}
-
#[allow(clippy::type_complexity)]
pub fn open_paths(
abs_paths: &[PathBuf],
@@ -5976,58 +5975,65 @@ pub fn open_paths(
let mut best_match = None;
let mut open_visible = OpenVisible::All;
- if open_options.open_new_workspace != Some(true) {
- for window in local_workspace_windows(cx) {
- if let Ok(workspace) = window.read(cx) {
- let m = workspace
- .project
- .read(cx)
- .visibility_for_paths(&abs_paths, cx);
- if m > best_match {
- existing = Some(window);
- best_match = m;
- } else if best_match.is_none() && open_options.open_new_workspace == Some(false) {
- existing = Some(window)
- }
- }
- }
- }
-
cx.spawn(move |mut cx| async move {
- if open_options.open_new_workspace.is_none() && existing.is_none() {
- let all_files = abs_paths.iter().map(|path| app_state.fs.metadata(path));
- if futures::future::join_all(all_files)
+ if open_options.open_new_workspace != Some(true) {
+ let all_paths = abs_paths.iter().map(|path| app_state.fs.metadata(path));
+ let all_metadatas = futures::future::join_all(all_paths)
.await
.into_iter()
.filter_map(|result| result.ok().flatten())
- .all(|file| !file.is_dir)
- {
- cx.update(|cx| {
- if let Some(window) = cx
- .active_window()
- .and_then(|window| window.downcast::<Workspace>())
- {
- if let Ok(workspace) = window.read(cx) {
- let project = workspace.project().read(cx);
- if project.is_local() && !project.is_via_collab() {
- existing = Some(window);
- open_visible = OpenVisible::None;
- return;
- }
+ .collect::<Vec<_>>();
+
+ cx.update(|cx| {
+ for window in local_workspace_windows(&cx) {
+ if let Ok(workspace) = window.read(&cx) {
+ let m = workspace.project.read(&cx).visibility_for_paths(
+ &abs_paths,
+ &all_metadatas,
+ open_options.open_new_workspace == None,
+ cx,
+ );
+ if m > best_match {
+ existing = Some(window);
+ best_match = m;
+ } else if best_match.is_none()
+ && open_options.open_new_workspace == Some(false)
+ {
+ existing = Some(window)
}
}
- for window in local_workspace_windows(cx) {
- if let Ok(workspace) = window.read(cx) {
- let project = workspace.project().read(cx);
- if project.is_via_collab() {
- continue;
+ }
+ })?;
+
+ if open_options.open_new_workspace.is_none() && existing.is_none() {
+ if all_metadatas.iter().all(|file| !file.is_dir) {
+ cx.update(|cx| {
+ if let Some(window) = cx
+ .active_window()
+ .and_then(|window| window.downcast::<Workspace>())
+ {
+ if let Ok(workspace) = window.read(cx) {
+ let project = workspace.project().read(cx);
+ if project.is_local() && !project.is_via_collab() {
+ existing = Some(window);
+ open_visible = OpenVisible::None;
+ return;
+ }
}
- existing = Some(window);
- open_visible = OpenVisible::None;
- break;
}
- }
- })?;
+ for window in local_workspace_windows(cx) {
+ if let Ok(workspace) = window.read(cx) {
+ let project = workspace.project().read(cx);
+ if project.is_via_collab() {
+ continue;
+ }
+ existing = Some(window);
+ open_visible = OpenVisible::None;
+ break;
+ }
+ }
+ })?;
+ }
}
}
@@ -1335,11 +1335,6 @@ impl LocalWorktree {
&self.fs
}
- pub fn contains_abs_path(&self, path: &Path) -> bool {
- let path = SanitizedPath::from(path);
- path.starts_with(&self.abs_path)
- }
-
pub fn is_path_private(&self, path: &Path) -> bool {
!self.share_private_files && self.settings.is_path_private(path)
}