mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 11:01:40 +03:00
Show abs path matches in file finder
This commit is contained in:
parent
b342c92495
commit
dd6e2df2a1
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2522,6 +2522,7 @@ dependencies = [
|
|||||||
name = "file_finder"
|
name = "file_finder"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"collections",
|
"collections",
|
||||||
"ctor",
|
"ctor",
|
||||||
"editor",
|
"editor",
|
||||||
|
@ -23,6 +23,7 @@ theme = { path = "../theme" }
|
|||||||
ui = { path = "../ui" }
|
ui = { path = "../ui" }
|
||||||
workspace = { path = "../workspace" }
|
workspace = { path = "../workspace" }
|
||||||
postage.workspace = true
|
postage.workspace = true
|
||||||
|
anyhow.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -519,6 +519,62 @@ impl FileFinderDelegate {
|
|||||||
|
|
||||||
(file_name, file_name_positions, full_path, path_positions)
|
(file_name, file_name_positions, full_path, path_positions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lookup_absolute_path(
|
||||||
|
&self,
|
||||||
|
query: PathLikeWithPosition<FileSearchQuery>,
|
||||||
|
cx: &mut ViewContext<'_, Picker<Self>>,
|
||||||
|
) -> Task<()> {
|
||||||
|
cx.spawn(|picker, mut cx| async move {
|
||||||
|
let Some((project, fs)) = picker
|
||||||
|
.update(&mut cx, |picker, cx| {
|
||||||
|
let fs = Arc::clone(&picker.delegate.project.read(cx).fs());
|
||||||
|
(picker.delegate.project.clone(), fs)
|
||||||
|
})
|
||||||
|
.log_err()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let query_path = Path::new(query.path_like.path_query());
|
||||||
|
let mut path_matches = Vec::new();
|
||||||
|
match fs.metadata(query_path).await.log_err() {
|
||||||
|
Some(Some(_metadata)) => {
|
||||||
|
let update_result = project
|
||||||
|
.update(&mut cx, |project, cx| {
|
||||||
|
if let Some((worktree, relative_path)) =
|
||||||
|
project.find_local_worktree(query_path, cx)
|
||||||
|
{
|
||||||
|
path_matches.push(PathMatch {
|
||||||
|
score: 0.0,
|
||||||
|
positions: Vec::new(),
|
||||||
|
worktree_id: worktree.read(cx).id().to_usize(),
|
||||||
|
path: Arc::from(relative_path),
|
||||||
|
path_prefix: "".into(),
|
||||||
|
distance_to_relative_ancestor: usize::MAX,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
if update_result.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(None) => {}
|
||||||
|
None => return,
|
||||||
|
}
|
||||||
|
|
||||||
|
picker
|
||||||
|
.update(&mut cx, |picker, cx| {
|
||||||
|
let picker_delegate = &mut picker.delegate;
|
||||||
|
let search_id = util::post_inc(&mut picker_delegate.search_count);
|
||||||
|
picker_delegate.set_search_matches(search_id, false, query, path_matches, cx);
|
||||||
|
|
||||||
|
anyhow::Ok(())
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PickerDelegate for FileFinderDelegate {
|
impl PickerDelegate for FileFinderDelegate {
|
||||||
@ -588,7 +644,12 @@ impl PickerDelegate for FileFinderDelegate {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.expect("infallible");
|
.expect("infallible");
|
||||||
self.spawn_search(query, cx)
|
|
||||||
|
if Path::new(query.path_like.path_query()).is_absolute() {
|
||||||
|
self.lookup_absolute_path(query, cx)
|
||||||
|
} else {
|
||||||
|
self.spawn_search(query, cx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,6 +879,68 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_absolute_paths(cx: &mut TestAppContext) {
|
||||||
|
let app_state = init_test(cx);
|
||||||
|
app_state
|
||||||
|
.fs
|
||||||
|
.as_fake()
|
||||||
|
.insert_tree(
|
||||||
|
"/root",
|
||||||
|
json!({
|
||||||
|
"a": {
|
||||||
|
"file1.txt": "",
|
||||||
|
"b": {
|
||||||
|
"file2.txt": "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||||
|
|
||||||
|
let (picker, workspace, cx) = build_find_picker(project, cx);
|
||||||
|
|
||||||
|
let matching_abs_path = "/root/a/b/file2.txt";
|
||||||
|
picker
|
||||||
|
.update(cx, |picker, cx| {
|
||||||
|
picker
|
||||||
|
.delegate
|
||||||
|
.update_matches(matching_abs_path.to_string(), cx)
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
picker.update(cx, |picker, _| {
|
||||||
|
assert_eq!(
|
||||||
|
collect_search_results(picker),
|
||||||
|
vec![PathBuf::from("a/b/file2.txt")],
|
||||||
|
"Matching abs path should be the only match"
|
||||||
|
)
|
||||||
|
});
|
||||||
|
cx.dispatch_action(SelectNext);
|
||||||
|
cx.dispatch_action(Confirm);
|
||||||
|
cx.read(|cx| {
|
||||||
|
let active_editor = workspace.read(cx).active_item_as::<Editor>(cx).unwrap();
|
||||||
|
assert_eq!(active_editor.read(cx).title(cx), "file2.txt");
|
||||||
|
});
|
||||||
|
|
||||||
|
let mismatching_abs_path = "/root/a/b/file1.txt";
|
||||||
|
picker
|
||||||
|
.update(cx, |picker, cx| {
|
||||||
|
picker
|
||||||
|
.delegate
|
||||||
|
.update_matches(mismatching_abs_path.to_string(), cx)
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
picker.update(cx, |picker, _| {
|
||||||
|
assert_eq!(
|
||||||
|
collect_search_results(picker),
|
||||||
|
Vec::<PathBuf>::new(),
|
||||||
|
"Mismatching abs path should produce no matches"
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_complex_path(cx: &mut TestAppContext) {
|
async fn test_complex_path(cx: &mut TestAppContext) {
|
||||||
let app_state = init_test(cx);
|
let app_state = init_test(cx);
|
||||||
|
Loading…
Reference in New Issue
Block a user