mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-24 17:28:40 +00:00
Show path matches inside history items matching the query
This commit is contained in:
parent
1b5ff68c43
commit
d30385f07c
1 changed files with 41 additions and 17 deletions
|
@ -1,4 +1,4 @@
|
|||
use collections::{HashMap, HashSet};
|
||||
use collections::HashMap;
|
||||
use editor::{scroll::autoscroll::Autoscroll, Bias, Editor};
|
||||
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
||||
use gpui::{
|
||||
|
@ -35,13 +35,13 @@ pub struct FileFinderDelegate {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
struct Matches {
|
||||
history: Vec<FoundPath>,
|
||||
history: Vec<(FoundPath, Option<PathMatch>)>,
|
||||
search: Vec<PathMatch>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Match<'a> {
|
||||
History(&'a FoundPath),
|
||||
History(&'a FoundPath, Option<&'a PathMatch>),
|
||||
Search(&'a PathMatch),
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,9 @@ impl Matches {
|
|||
|
||||
fn get(&self, index: usize) -> Option<Match<'_>> {
|
||||
if index < self.history.len() {
|
||||
self.history.get(index).map(Match::History)
|
||||
self.history
|
||||
.get(index)
|
||||
.map(|(path, path_match)| Match::History(path, path_match.as_ref()))
|
||||
} else {
|
||||
self.search
|
||||
.get(index - self.history.len())
|
||||
|
@ -68,16 +70,25 @@ impl Matches {
|
|||
extend_old_matches: bool,
|
||||
) {
|
||||
let matching_history_paths = matching_history_item_paths(history_items, query);
|
||||
new_search_matches.retain(|path_match| !matching_history_paths.contains(&path_match.path));
|
||||
new_search_matches
|
||||
.retain(|path_match| !matching_history_paths.contains_key(&path_match.path));
|
||||
let history_items_to_show = history_items
|
||||
.iter()
|
||||
.filter(|history_item| matching_history_paths.contains(&history_item.project.path))
|
||||
.cloned()
|
||||
.filter_map(|history_item| {
|
||||
Some((
|
||||
history_item.clone(),
|
||||
Some(
|
||||
matching_history_paths
|
||||
.get(&history_item.project.path)?
|
||||
.clone(),
|
||||
),
|
||||
))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
self.history = history_items_to_show;
|
||||
if extend_old_matches {
|
||||
self.search
|
||||
.retain(|path_match| !matching_history_paths.contains(&path_match.path));
|
||||
.retain(|path_match| !matching_history_paths.contains_key(&path_match.path));
|
||||
util::extend_sorted(
|
||||
&mut self.search,
|
||||
new_search_matches.into_iter(),
|
||||
|
@ -93,7 +104,7 @@ impl Matches {
|
|||
fn matching_history_item_paths(
|
||||
history_items: &Vec<FoundPath>,
|
||||
query: &PathLikeWithPosition<FileSearchQuery>,
|
||||
) -> HashSet<Arc<Path>> {
|
||||
) -> HashMap<Arc<Path>, PathMatch> {
|
||||
let history_items_by_worktrees = history_items
|
||||
.iter()
|
||||
.map(|found_path| {
|
||||
|
@ -114,7 +125,7 @@ fn matching_history_item_paths(
|
|||
candidates
|
||||
},
|
||||
);
|
||||
let mut matching_history_paths = HashSet::default();
|
||||
let mut matching_history_paths = HashMap::default();
|
||||
for (worktree, candidates) in history_items_by_worktrees {
|
||||
let max_results = candidates.len() + 1;
|
||||
matching_history_paths.extend(
|
||||
|
@ -126,7 +137,7 @@ fn matching_history_item_paths(
|
|||
max_results,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|path_match| path_match.path),
|
||||
.map(|path_match| (Arc::clone(&path_match.path), path_match)),
|
||||
);
|
||||
}
|
||||
matching_history_paths
|
||||
|
@ -358,7 +369,7 @@ impl FileFinderDelegate {
|
|||
ix: usize,
|
||||
) -> (String, Vec<usize>, String, Vec<usize>) {
|
||||
let (file_name, file_name_positions, full_path, full_path_positions) = match path_match {
|
||||
Match::History(found_path) => {
|
||||
Match::History(found_path, found_path_match) => {
|
||||
let worktree_id = found_path.project.worktree_id;
|
||||
let project_relative_path = &found_path.project.path;
|
||||
let has_worktree = self
|
||||
|
@ -390,14 +401,22 @@ impl FileFinderDelegate {
|
|||
path = Arc::from(absolute_path.as_path());
|
||||
}
|
||||
}
|
||||
self.labels_for_path_match(&PathMatch {
|
||||
|
||||
let mut path_match = PathMatch {
|
||||
score: ix as f64,
|
||||
positions: Vec::new(),
|
||||
worktree_id: worktree_id.to_usize(),
|
||||
path,
|
||||
path_prefix: "".into(),
|
||||
distance_to_relative_ancestor: usize::MAX,
|
||||
})
|
||||
};
|
||||
if let Some(found_path_match) = found_path_match {
|
||||
path_match
|
||||
.positions
|
||||
.extend(found_path_match.positions.iter())
|
||||
}
|
||||
|
||||
self.labels_for_path_match(&path_match)
|
||||
}
|
||||
Match::Search(path_match) => self.labels_for_path_match(path_match),
|
||||
};
|
||||
|
@ -494,6 +513,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
.is_some())
|
||||
})
|
||||
.cloned()
|
||||
.map(|p| (p, None))
|
||||
.collect(),
|
||||
search: Vec::new(),
|
||||
};
|
||||
|
@ -528,7 +548,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
}
|
||||
};
|
||||
match m {
|
||||
Match::History(history_match) => {
|
||||
Match::History(history_match, _) => {
|
||||
let worktree_id = history_match.project.worktree_id;
|
||||
if workspace
|
||||
.project()
|
||||
|
@ -1723,7 +1743,9 @@ mod tests {
|
|||
finder.read_with(cx, |finder, _| {
|
||||
let delegate = finder.delegate();
|
||||
assert_eq!(delegate.matches.history.len(), 1, "Only one history item contains {first_query}, it should be present and others should be filtered out");
|
||||
assert_eq!(delegate.matches.history.first().unwrap(), &FoundPath::new(
|
||||
let history_match = delegate.matches.history.first().unwrap();
|
||||
assert!(history_match.1.is_some(), "Should have path matches for history items after querying");
|
||||
assert_eq!(history_match.0, FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
|
@ -1767,7 +1789,9 @@ mod tests {
|
|||
finder.read_with(cx, |finder, _| {
|
||||
let delegate = finder.delegate();
|
||||
assert_eq!(delegate.matches.history.len(), 1, "Only one history item contains {first_query_again}, it should be present and others should be filtered out, even after non-matching query");
|
||||
assert_eq!(delegate.matches.history.first().unwrap(), &FoundPath::new(
|
||||
let history_match = delegate.matches.history.first().unwrap();
|
||||
assert!(history_match.1.is_some(), "Should have path matches for history items after querying");
|
||||
assert_eq!(history_match.0, FoundPath::new(
|
||||
ProjectPath {
|
||||
worktree_id,
|
||||
path: Arc::from(Path::new("test/first.rs")),
|
||||
|
|
Loading…
Reference in a new issue