Allow buffer search to search deleted hunks (#23632)

Closes #ISSUE

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2025-01-28 14:48:16 -07:00 committed by GitHub
parent 22afec32cf
commit 1973bf5268
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 80 additions and 50 deletions

View file

@ -1507,8 +1507,9 @@ impl SearchableItem for Editor {
search_within_ranges search_within_ranges
}; };
for (search_buffer, search_range, excerpt_id) in for range in search_within_ranges {
buffer.ranges_to_buffer_ranges(search_within_ranges.into_iter()) for (search_buffer, search_range, excerpt_id, deleted_hunk_anchor) in
buffer.range_to_buffer_ranges_with_deleted_hunks(range)
{ {
ranges.extend( ranges.extend(
query query
@ -1516,18 +1517,33 @@ impl SearchableItem for Editor {
.await .await
.into_iter() .into_iter()
.map(|match_range| { .map(|match_range| {
let start = if let Some(deleted_hunk_anchor) = deleted_hunk_anchor {
search_buffer.anchor_after(search_range.start + match_range.start); let start = search_buffer
let end = .anchor_after(search_range.start + match_range.start);
search_buffer.anchor_before(search_range.start + match_range.end); let end = search_buffer
.anchor_before(search_range.start + match_range.end);
Anchor {
diff_base_anchor: Some(start),
..deleted_hunk_anchor
}..Anchor {
diff_base_anchor: Some(end),
..deleted_hunk_anchor
}
} else {
let start = search_buffer
.anchor_after(search_range.start + match_range.start);
let end = search_buffer
.anchor_before(search_range.start + match_range.end);
Anchor::range_in_buffer( Anchor::range_in_buffer(
excerpt_id, excerpt_id,
search_buffer.remote_id(), search_buffer.remote_id(),
start..end, start..end,
) )
}
}), }),
); );
} }
}
ranges ranges
}) })

View file

@ -3376,6 +3376,49 @@ impl MultiBufferSnapshot {
result result
} }
pub fn range_to_buffer_ranges_with_deleted_hunks<T: ToOffset>(
&self,
range: Range<T>,
) -> impl Iterator<Item = (&BufferSnapshot, Range<usize>, ExcerptId, Option<Anchor>)> + '_ {
let start = range.start.to_offset(&self);
let end = range.end.to_offset(&self);
let mut cursor = self.cursor::<usize>();
cursor.seek(&start);
std::iter::from_fn(move || {
let region = cursor.region()?;
if region.range.start > end {
return None;
}
let start_overshoot = start.saturating_sub(region.range.start);
let end_overshoot = end.saturating_sub(region.range.start);
let start = region
.buffer_range
.end
.min(region.buffer_range.start + start_overshoot);
let end = region
.buffer_range
.end
.min(region.buffer_range.start + end_overshoot);
let region_excerpt_id = region.excerpt.id;
let deleted_hunk_anchor = if region.is_main_buffer {
None
} else {
Some(self.anchor_before(region.range.start))
};
let result = (
region.buffer,
start..end,
region_excerpt_id,
deleted_hunk_anchor,
);
cursor.next();
Some(result)
})
}
/// Retrieves buffer metadata for the given range, and converts it into multi-buffer /// Retrieves buffer metadata for the given range, and converts it into multi-buffer
/// coordinates. /// coordinates.
/// ///
@ -4205,36 +4248,7 @@ impl MultiBufferSnapshot {
where where
D: TextDimension + Ord + Sub<D, Output = D>, D: TextDimension + Ord + Sub<D, Output = D>,
{ {
let mut cursor = self.excerpts.cursor::<ExcerptSummary>(&()); self.summaries_for_anchors([anchor])[0]
let locator = self.excerpt_locator_for_id(anchor.excerpt_id);
cursor.seek(locator, Bias::Left, &());
if cursor.item().is_none() {
cursor.next(&());
}
let mut excerpt_position = D::from_text_summary(&cursor.start().text);
if let Some(excerpt) = cursor.item() {
if excerpt.id == anchor.excerpt_id {
let excerpt_buffer_start =
excerpt.range.context.start.summary::<D>(&excerpt.buffer);
let excerpt_buffer_end = excerpt.range.context.end.summary::<D>(&excerpt.buffer);
let buffer_position = cmp::min(
excerpt_buffer_end,
anchor.text_anchor.summary::<D>(&excerpt.buffer),
);
if buffer_position > excerpt_buffer_start {
excerpt_position.add_assign(&(buffer_position - excerpt_buffer_start));
}
}
}
let mut diff_transforms_cursor = self
.diff_transforms
.cursor::<(ExcerptDimension<D>, OutputDimension<D>)>(&());
diff_transforms_cursor.seek(&ExcerptDimension(excerpt_position), Bias::Left, &());
self.resolve_summary_for_anchor(anchor, excerpt_position, &mut diff_transforms_cursor)
} }
fn resolve_summary_for_anchor<D>( fn resolve_summary_for_anchor<D>(