Use new multibuffer excerpts in project search (#27893)

Follow-up of https://github.com/zed-industries/zed/pull/27876
Closes https://github.com/zed-industries/zed/issues/13513

Release Notes:

- Improved multi buffer excerpts to merge when expanded

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Kirill Bulatov 2025-04-02 16:57:40 -06:00 committed by GitHub
parent b4af5b2ce0
commit 8a6ed4a2ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 154 additions and 207 deletions

View file

@ -9,7 +9,7 @@ use editor::{
Anchor, Editor, EditorElement, EditorEvent, EditorSettings, EditorStyle, MAX_TAB_TITLE_LEN,
MultiBuffer, actions::SelectAll, items::active_match_index, scroll::Autoscroll,
};
use futures::StreamExt;
use futures::{StreamExt, stream::FuturesOrdered};
use gpui::{
Action, AnyElement, AnyView, App, Axis, Context, Entity, EntityId, EventEmitter, FocusHandle,
Focusable, Global, Hsla, InteractiveElement, IntoElement, KeyContext, ParentElement, Point,
@ -260,16 +260,18 @@ impl ProjectSearch {
self.search_id += 1;
self.active_query = Some(query);
self.match_ranges.clear();
self.pending_search = Some(cx.spawn(async move |this, cx| {
self.pending_search = Some(cx.spawn(async move |project_search, cx| {
let mut matches = pin!(search.ready_chunks(1024));
let this = this.upgrade()?;
this.update(cx, |this, cx| {
this.match_ranges.clear();
this.excerpts.update(cx, |this, cx| this.clear(cx));
this.no_results = Some(true);
this.limit_reached = false;
})
.ok()?;
project_search
.update(cx, |project_search, cx| {
project_search.match_ranges.clear();
project_search
.excerpts
.update(cx, |excerpts, cx| excerpts.clear(cx));
project_search.no_results = Some(true);
project_search.limit_reached = false;
})
.ok()?;
let mut limit_reached = false;
while let Some(results) = matches.next().await {
@ -285,35 +287,43 @@ impl ProjectSearch {
}
}
let match_ranges = this
.update(cx, |this, cx| {
this.excerpts.update(cx, |excerpts, cx| {
excerpts.push_multiple_excerpts_with_context_lines(
buffers_with_ranges,
editor::DEFAULT_MULTIBUFFER_CONTEXT,
cx,
)
})
let excerpts = project_search
.update(cx, |project_search, _| project_search.excerpts.clone())
.ok()?;
let mut new_ranges = excerpts
.update(cx, |excerpts, cx| {
buffers_with_ranges
.into_iter()
.map(|(buffer, ranges)| {
excerpts.set_anchored_excerpts_for_path(
buffer,
ranges,
editor::DEFAULT_MULTIBUFFER_CONTEXT,
cx,
)
})
.collect::<FuturesOrdered<_>>()
})
.ok()?
.await;
.ok()?;
while let Some(new_ranges) = new_ranges.next().await {
project_search
.update(cx, |project_search, _| {
project_search.match_ranges.extend(new_ranges);
})
.ok()?;
}
}
this.update(cx, |this, cx| {
this.match_ranges.extend(match_ranges);
project_search
.update(cx, |project_search, cx| {
if !project_search.match_ranges.is_empty() {
project_search.no_results = Some(false);
}
project_search.limit_reached = limit_reached;
project_search.pending_search.take();
cx.notify();
})
.ok()?;
}
this.update(cx, |this, cx| {
if !this.match_ranges.is_empty() {
this.no_results = Some(false);
}
this.limit_reached = limit_reached;
this.pending_search.take();
cx.notify();
})
.ok()?;
None
}));