project search: Fix search results not being highlighted (#18273)
Closes #18254 Closes #18219 Closes #17690 This fixes the project search not highlighting all results. The problem was relatively simple, even though it took a while to find it: we inserted multiple excerpts concurrently and the order in the multi-buffer ended up being wrong. Sorting the resulting `match_ranges` fixed the problem, but as it turns out, we can do a better job by moving the concurrency into the method on the MultiBuffer. Performance is the same, but now the problem is fixed. Release Notes: - Fixed search results in project-wide search not being highlighted consistently and navigation sometimes being broken (#18254, #18219, #17690) --------- Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
parent
f019ad563f
commit
93a4295f66
2 changed files with 163 additions and 130 deletions
|
@ -263,54 +263,35 @@ impl ProjectSearch {
|
|||
|
||||
let mut limit_reached = false;
|
||||
while let Some(results) = matches.next().await {
|
||||
let tasks = results
|
||||
.into_iter()
|
||||
.map(|result| {
|
||||
let this = this.clone();
|
||||
|
||||
cx.spawn(|mut cx| async move {
|
||||
match result {
|
||||
project::search::SearchResult::Buffer { buffer, ranges } => {
|
||||
let mut match_ranges_rx =
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.excerpts.update(cx, |excerpts, cx| {
|
||||
excerpts.stream_excerpts_with_context_lines(
|
||||
buffer,
|
||||
ranges,
|
||||
editor::DEFAULT_MULTIBUFFER_CONTEXT,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
})?;
|
||||
|
||||
let mut match_ranges = vec![];
|
||||
while let Some(range) = match_ranges_rx.next().await {
|
||||
match_ranges.push(range);
|
||||
}
|
||||
anyhow::Ok((match_ranges, false))
|
||||
}
|
||||
project::search::SearchResult::LimitReached => {
|
||||
anyhow::Ok((vec![], true))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let result_ranges = futures::future::join_all(tasks).await;
|
||||
let mut combined_ranges = vec![];
|
||||
for (ranges, result_limit_reached) in result_ranges.into_iter().flatten() {
|
||||
combined_ranges.extend(ranges);
|
||||
if result_limit_reached {
|
||||
limit_reached = result_limit_reached;
|
||||
let mut buffers_with_ranges = Vec::with_capacity(results.len());
|
||||
for result in results {
|
||||
match result {
|
||||
project::search::SearchResult::Buffer { buffer, ranges } => {
|
||||
buffers_with_ranges.push((buffer, ranges));
|
||||
}
|
||||
project::search::SearchResult::LimitReached => {
|
||||
limit_reached = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let match_ranges = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
this.excerpts.update(cx, |excerpts, cx| {
|
||||
excerpts.push_multiple_excerpts_with_context_lines(
|
||||
buffers_with_ranges,
|
||||
editor::DEFAULT_MULTIBUFFER_CONTEXT,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
})
|
||||
.ok()?
|
||||
.await;
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
if !combined_ranges.is_empty() {
|
||||
this.no_results = Some(false);
|
||||
this.match_ranges.extend(combined_ranges);
|
||||
cx.notify();
|
||||
}
|
||||
this.no_results = Some(false);
|
||||
this.match_ranges.extend(match_ranges);
|
||||
cx.notify();
|
||||
})
|
||||
.ok()?;
|
||||
}
|
||||
|
@ -2745,7 +2726,7 @@ pub mod tests {
|
|||
search_view
|
||||
.results_editor
|
||||
.update(cx, |editor, cx| editor.display_text(cx)),
|
||||
"\n\n\nconst TWO: usize = one::ONE + one::ONE;\n\n\n\n\nconst ONE: usize = 1;\n",
|
||||
"\n\n\nconst ONE: usize = 1;\n\n\n\n\nconst TWO: usize = one::ONE + one::ONE;\n",
|
||||
"New search in directory should have a filter that matches a certain directory"
|
||||
);
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue