@@ -939,20 +939,47 @@ impl FileFinderDelegate {
matches.into_iter(),
extend_old_matches,
);
- let worktree = self.project.read(cx).visible_worktrees(cx).next();
- let filename = query.raw_query.to_string();
- let path = Path::new(&filename);
+ let filename = &query.raw_query;
+ let mut query_path = Path::new(filename);
// add option of creating new file only if path is relative
- if let Some(worktree) = worktree {
+ let available_worktree = self
+ .project
+ .read(cx)
+ .visible_worktrees(cx)
+ .filter(|worktree| !worktree.read(cx).is_single_file())
+ .collect::<Vec<_>>();
+ let worktree_count = available_worktree.len();
+ let mut expect_worktree = available_worktree.first().cloned();
+ for worktree in available_worktree {
+ let worktree_root = worktree
+ .read(cx)
+ .abs_path()
+ .file_name()
+ .map_or(String::new(), |f| f.to_string_lossy().to_string());
+ if worktree_count > 1 && query_path.starts_with(&worktree_root) {
+ query_path = query_path
+ .strip_prefix(&worktree_root)
+ .unwrap_or(query_path);
+ expect_worktree = Some(worktree);
+ break;
+ }
+ }
+
+ 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);
+ }
+
+ if let Some(worktree) = expect_worktree {
let worktree = worktree.read(cx);
- if path.is_relative()
- && worktree.entry_for_path(&path).is_none()
+ if query_path.is_relative()
+ && worktree.entry_for_path(&query_path).is_none()
&& !filename.ends_with("/")
{
self.matches.matches.push(Match::CreateNew(ProjectPath {
worktree_id: worktree.id(),
- path: Arc::from(path),
+ path: Arc::from(query_path),
}));
}
}
@@ -881,6 +881,148 @@ async fn test_single_file_worktrees(cx: &mut TestAppContext) {
picker.update(cx, |f, _| assert_eq!(f.delegate.matches.len(), 0));
}
+#[gpui::test]
+async fn test_create_file_for_multiple_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 (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
+ let (_worktree_id1, worktree_id2) = cx.read(|cx| {
+ let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
+ (
+ WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize),
+ WorktreeId::from_usize(worktrees[1].entity_id().as_u64() as usize),
+ )
+ });
+
+ let b_path = ProjectPath {
+ worktree_id: worktree_id2,
+ path: Arc::from(Path::new(path!("the-parent-dirb/fileb"))),
+ };
+ workspace
+ .update_in(cx, |workspace, window, cx| {
+ workspace.open_path(b_path, None, true, window, cx)
+ })
+ .await
+ .unwrap();
+
+ let finder = open_file_picker(&workspace, cx);
+
+ finder
+ .update_in(cx, |f, window, cx| {
+ f.delegate.spawn_search(
+ test_path_position(path!("the-parent-dirb/filec")),
+ window,
+ cx,
+ )
+ })
+ .await;
+ cx.run_until_parked();
+ finder.update_in(cx, |picker, window, cx| {
+ assert_eq!(picker.delegate.matches.len(), 1);
+ picker.delegate.confirm(false, window, cx)
+ });
+ cx.run_until_parked();
+ cx.read(|cx| {
+ let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
+ let project_path = active_editor.read(cx).project_path(cx);
+ assert_eq!(
+ project_path,
+ Some(ProjectPath {
+ worktree_id: worktree_id2,
+ path: Arc::from(Path::new(path!("the-parent-dirb/filec")))
+ })
+ );
+ });
+}
+
+#[gpui::test]
+async fn test_create_file_no_focused_with_multiple_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 (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
+ let (_worktree_id1, worktree_id2) = cx.read(|cx| {
+ let worktrees = workspace.read(cx).worktrees(cx).collect::<Vec<_>>();
+ (
+ WorktreeId::from_usize(worktrees[0].entity_id().as_u64() as usize),
+ WorktreeId::from_usize(worktrees[1].entity_id().as_u64() as usize),
+ )
+ });
+
+ let finder = open_file_picker(&workspace, cx);
+
+ finder
+ .update_in(cx, |f, window, cx| {
+ f.delegate
+ .spawn_search(test_path_position(path!("rootb/filec")), window, cx)
+ })
+ .await;
+ cx.run_until_parked();
+ finder.update_in(cx, |picker, window, cx| {
+ assert_eq!(picker.delegate.matches.len(), 1);
+ picker.delegate.confirm(false, window, cx)
+ });
+ cx.run_until_parked();
+ cx.read(|cx| {
+ let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
+ let project_path = active_editor.read(cx).project_path(cx);
+ assert_eq!(
+ project_path,
+ Some(ProjectPath {
+ worktree_id: worktree_id2,
+ path: Arc::from(Path::new("filec"))
+ })
+ );
+ });
+}
+
#[gpui::test]
async fn test_path_distance_ordering(cx: &mut TestAppContext) {
let app_state = init_test(cx);