workspace: Do not reuse window for sub directory (only for root directory and sub files) (#24560)

Closes #10232

Context:

We have three ways to open files or dirs in Zed: `zed`, `zed --new`, and
`zed --add`. `--new` forces the project to open in a new window, while
`--add` forces it to open in an existing window (even if the dir isn’t a
subdir of an existing project or the file isn’t part of it).

Using just `zed` tries to open it in an existing window based on similar
logic of `--add`, but if no related project is found the dir, opens in a
new window.

Problem:

Right now, subdirs that are part of an existing project open in the
existing window when using `zed`. By default, subdirs should open in a
new window instead. If someone wants to open it in the existing window,
they can explicitly use `--add`. After this PR, only root dir and files
will focus on existing window, when `zed ` is used.

Fix:

For the `zed` case, we’ve filtered out subdirs in the logic that assigns
them to an existing window.

Release Notes:

- Fixed an issue where subdirectories of an already opened project, when
opened via the terminal, would open in the existing project instead of a
new window.
This commit is contained in:
smit 2025-02-13 03:37:39 +05:30 committed by GitHub
parent c771ca49e1
commit 5dc3c237eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 58 deletions

View file

@ -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()
}