file_finder: Display single files already opened (#39911)

Closes https://github.com/zed-industries/zed/issues/24670

(Follow up of https://github.com/zed-industries/zed/pull/36856) cc
@ConradIrwin Thanks for your help

Release Notes:

Fixed: Keep non project files when filtering in File finder

---------

Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
Coenen Benjamin
2025-10-15 19:50:37 +03:00
committed by GitHub
co-authored by Kirill Bulatov
parent 6f97d74ff9
commit ce2259ce51
3 changed files with 71 additions and 3 deletions
+3 -1
View File
@@ -866,7 +866,9 @@ impl FileFinderDelegate {
let worktrees = self
.project
.read(cx)
.visible_worktrees(cx)
.worktree_store()
.read(cx)
.visible_worktrees_and_single_files(cx)
.collect::<Vec<_>>();
let include_root_name = worktrees.len() > 1;
let candidate_sets = worktrees
+59 -2
View File
@@ -8,7 +8,7 @@ use pretty_assertions::{assert_eq, assert_matches};
use project::{FS_WATCH_LATENCY, RemoveOptions};
use serde_json::json;
use util::{path, rel_path::rel_path};
use workspace::{AppState, CloseActiveItem, OpenOptions, ToggleFileFinder, Workspace};
use workspace::{AppState, CloseActiveItem, OpenOptions, ToggleFileFinder, Workspace, open_paths};
#[ctor::ctor]
fn init_logger() {
@@ -2337,7 +2337,6 @@ async fn test_search_results_refreshed_on_worktree_updates(cx: &mut gpui::TestAp
assert_match_at_position(finder, 1, "main.rs");
assert_match_at_position(finder, 2, "rs");
});
// Delete main.rs
app_state
.fs
@@ -2370,6 +2369,64 @@ async fn test_search_results_refreshed_on_worktree_updates(cx: &mut gpui::TestAp
});
}
#[gpui::test]
async fn test_search_results_refreshed_on_standalone_file_creation(cx: &mut gpui::TestAppContext) {
let app_state = init_test(cx);
app_state
.fs
.as_fake()
.insert_tree(
"/src",
json!({
"lib.rs": "// Lib file",
"main.rs": "// Bar file",
"read.me": "// Readme file",
}),
)
.await;
app_state
.fs
.as_fake()
.insert_tree(
"/test",
json!({
"new.rs": "// New file",
}),
)
.await;
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
cx.update(|_, cx| {
open_paths(
&[PathBuf::from(path!("/test/new.rs"))],
app_state,
workspace::OpenOptions::default(),
cx,
)
})
.await
.unwrap();
assert_eq!(cx.update(|_, cx| cx.windows().len()), 1);
let initial_history = open_close_queried_buffer("new", 1, "new.rs", &workspace, cx).await;
assert_eq!(
initial_history.first().unwrap().absolute,
PathBuf::from(path!("/test/new.rs")),
"Should show 1st opened item in the history when opening the 2nd item"
);
let history_after_first = open_close_queried_buffer("lib", 1, "lib.rs", &workspace, cx).await;
assert_eq!(
history_after_first.first().unwrap().absolute,
PathBuf::from(path!("/test/new.rs")),
"Should show 1st opened item in the history when opening the 2nd item"
);
}
#[gpui::test]
async fn test_search_results_refreshed_on_adding_and_removing_worktrees(
cx: &mut gpui::TestAppContext,
+9
View File
@@ -138,6 +138,15 @@ impl WorktreeStore {
.filter(|worktree| worktree.read(cx).is_visible())
}
/// Iterates through all user-visible worktrees (directories and files that appear in the project panel) and other, invisible single files that could appear e.g. due to drag and drop.
pub fn visible_worktrees_and_single_files<'a>(
&'a self,
cx: &'a App,
) -> impl 'a + DoubleEndedIterator<Item = Entity<Worktree>> {
self.worktrees()
.filter(|worktree| worktree.read(cx).is_visible() || worktree.read(cx).is_single_file())
}
pub fn worktree_for_id(&self, id: WorktreeId, cx: &App) -> Option<Entity<Worktree>> {
self.worktrees()
.find(|worktree| worktree.read(cx).id() == id)