file_finder: Fix create wrong file in multiple worktree (#33139)
When open multiple worktree, using `file_finder` to create a new file shoud respect current focused worktree. test case: ``` project: worktree A file1 worktree B file2 <- focused ``` when focused `file2`, `ctrl-p` toggle `file_finder` to create `file3` should exists in worktreeB. I try add test case for `CreateNew` in file_finder, but found not worked, if you help me, I can try add this test case. Release Notes: - Fixed file finder selecting wrong worktree when creating a file
This commit is contained in:
parent
6848073c38
commit
630a326a07
2 changed files with 176 additions and 7 deletions
|
@ -939,20 +939,47 @@ impl FileFinderDelegate {
|
||||||
matches.into_iter(),
|
matches.into_iter(),
|
||||||
extend_old_matches,
|
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
|
// 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);
|
let worktree = worktree.read(cx);
|
||||||
if path.is_relative()
|
if query_path.is_relative()
|
||||||
&& worktree.entry_for_path(&path).is_none()
|
&& worktree.entry_for_path(&query_path).is_none()
|
||||||
&& !filename.ends_with("/")
|
&& !filename.ends_with("/")
|
||||||
{
|
{
|
||||||
self.matches.matches.push(Match::CreateNew(ProjectPath {
|
self.matches.matches.push(Match::CreateNew(ProjectPath {
|
||||||
worktree_id: worktree.id(),
|
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));
|
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]
|
#[gpui::test]
|
||||||
async fn test_path_distance_ordering(cx: &mut TestAppContext) {
|
async fn test_path_distance_ordering(cx: &mut TestAppContext) {
|
||||||
let app_state = init_test(cx);
|
let app_state = init_test(cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue