diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 71fcfba76363f7d6a3d6d5d37d8f87f3b6a6cdfb..4e11960b6b1a49aa6a774125f05cd0413da0038c 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -980,12 +980,12 @@ impl FileFinderDelegate { .collect::>(); let worktree_count = available_worktree.len(); let mut expect_worktree = available_worktree.first().cloned(); - for worktree in available_worktree { + for worktree in &available_worktree { let worktree_root = worktree.read(cx).root_name(); if worktree_count > 1 { if let Ok(suffix) = query_path.strip_prefix(worktree_root) { query_path = Cow::Owned(suffix.to_owned()); - expect_worktree = Some(worktree); + expect_worktree = Some(worktree.clone()); break; } } @@ -993,7 +993,13 @@ impl FileFinderDelegate { if let Some(FoundPath { ref project, .. }) = self.currently_opened_path { let worktree_id = project.worktree_id; - expect_worktree = self.project.read(cx).worktree_for_id(worktree_id, cx); + let focused_file_in_available_worktree = available_worktree + .iter() + .any(|wt| wt.read(cx).id() == worktree_id); + + if focused_file_in_available_worktree { + expect_worktree = self.project.read(cx).worktree_for_id(worktree_id, cx); + } } if let Some(worktree) = expect_worktree { diff --git a/crates/file_finder/src/file_finder_tests.rs b/crates/file_finder/src/file_finder_tests.rs index b477f0671a49e2c28cd08d4ea6c188f2527ff8ae..59ade17eb797bfc9549e6642f0a0b7375a0df831 100644 --- a/crates/file_finder/src/file_finder_tests.rs +++ b/crates/file_finder/src/file_finder_tests.rs @@ -1260,6 +1260,93 @@ async fn test_create_file_for_multiple_worktrees(cx: &mut TestAppContext) { }); } +#[gpui::test] +async fn test_create_file_focused_file_does_not_belong_to_available_worktrees( + cx: &mut TestAppContext, +) { + let app_state = init_test(cx); + app_state + .fs + .as_fake() + .insert_tree(path!("/roota"), json!({ "the-parent-dira": { "filea": ""}})) + .await; + + app_state + .fs + .as_fake() + .insert_tree(path!("/rootb"), json!({"the-parent-dirb":{ "fileb": ""}})) + .await; + + let project = Project::test( + app_state.fs.clone(), + [path!("/roota").as_ref(), path!("/rootb").as_ref()], + cx, + ) + .await; + + let (multi_workspace, cx) = + cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx)); + let workspace = multi_workspace.read_with(cx, |mw, _| mw.workspace().clone()); + + let (worktree_id_a, worktree_id_b) = cx.read(|cx| { + let worktrees = workspace.read(cx).worktrees(cx).collect::>(); + (worktrees[0].read(cx).id(), worktrees[1].read(cx).id()) + }); + workspace + .update_in(cx, |workspace, window, cx| { + workspace.open_abs_path( + PathBuf::from(path!("/external/external-file.txt")), + OpenOptions { + visible: Some(OpenVisible::None), + ..OpenOptions::default() + }, + window, + cx, + ) + }) + .await + .unwrap(); + + cx.run_until_parked(); + let finder = open_file_picker(&workspace, cx); + + finder + .update_in(cx, |f, window, cx| { + f.delegate + .spawn_search(test_path_position("new-file.txt"), window, cx) + }) + .await; + + cx.run_until_parked(); + finder.update_in(cx, |f, window, cx| { + assert_eq!(f.delegate.matches.len(), 1); + f.delegate.confirm(false, window, cx); // ✓ works + }); + cx.run_until_parked(); + + cx.read(|cx| { + let active_editor = workspace.read(cx).active_item_as::(cx).unwrap(); + + let project_path = active_editor.read(cx).project_path(cx); + + assert!( + project_path.is_some(), + "Active editor should have a project path" + ); + + let project_path = project_path.unwrap(); + + assert!( + project_path.worktree_id == worktree_id_a || project_path.worktree_id == worktree_id_b, + "New file should be created in one of the available worktrees (A or B), \ + not in a directory derived from the external file. Got worktree_id: {:?}", + project_path.worktree_id + ); + + assert_eq!(project_path.path.as_ref(), rel_path("new-file.txt")); + }); +} + #[gpui::test] async fn test_create_file_no_focused_with_multiple_worktrees(cx: &mut TestAppContext) { let app_state = init_test(cx);