diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 979cfa72ff..9e813bcb78 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -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::>(); let include_root_name = worktrees.len() > 1; let candidate_sets = worktrees diff --git a/crates/file_finder/src/file_finder_tests.rs b/crates/file_finder/src/file_finder_tests.rs index 00b47bf44e..b59d59e239 100644 --- a/crates/file_finder/src/file_finder_tests.rs +++ b/crates/file_finder/src/file_finder_tests.rs @@ -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, diff --git a/crates/project/src/worktree_store.rs b/crates/project/src/worktree_store.rs index 8e18a8085d..5da8fe2d00 100644 --- a/crates/project/src/worktree_store.rs +++ b/crates/project/src/worktree_store.rs @@ -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> { + 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> { self.worktrees() .find(|worktree| worktree.read(cx).id() == id)