Fix inline assistant not working at the start/end of a file (#13384)

This was due to a bug in the `MultiBufferSnapshot::excerpts_in_ranges`
method. As part of this, I took the chance to rewrite that logic and
simplify it a bit.

Release Notes:

- N/A
This commit is contained in:
Antonio Scandurra 2024-06-22 10:38:00 +02:00 committed by GitHub
parent fe7d53cb96
commit ed9f6e2141
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3817,52 +3817,35 @@ impl MultiBufferSnapshot {
ranges: impl IntoIterator<Item = Range<Anchor>>, ranges: impl IntoIterator<Item = Range<Anchor>>,
) -> impl Iterator<Item = (ExcerptId, &BufferSnapshot, Range<usize>)> { ) -> impl Iterator<Item = (ExcerptId, &BufferSnapshot, Range<usize>)> {
let mut ranges = ranges.into_iter().map(|range| range.to_offset(self)); let mut ranges = ranges.into_iter().map(|range| range.to_offset(self));
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>();
let mut next_range = move |cursor: &mut Cursor<Excerpt, usize>| { cursor.next(&());
let range = ranges.next(); let mut current_range = ranges.next();
if let Some(range) = range.as_ref() {
cursor.seek_forward(&range.start, Bias::Right, &());
}
range
};
let mut range = next_range(&mut cursor);
iter::from_fn(move || { iter::from_fn(move || {
if range.is_none() { let range = current_range.clone()?;
return None; if range.start >= cursor.end(&()) {
} cursor.seek_forward(&range.start, Bias::Right, &());
if range.start == self.len() {
if *cursor.start() >= range.as_ref().unwrap().end { cursor.prev(&());
range = next_range(&mut cursor);
if range.is_none() {
return None;
} }
} }
cursor.item().map(|excerpt| { let excerpt = cursor.item()?;
let multibuffer_excerpt = MultiBufferExcerpt::new(&excerpt, *cursor.start()); let range_start_in_excerpt = cmp::max(range.start, *cursor.start());
let range_end_in_excerpt = if excerpt.has_trailing_newline {
cmp::min(range.end, cursor.end(&()) - 1)
} else {
cmp::min(range.end, cursor.end(&()))
};
let buffer_range = MultiBufferExcerpt::new(excerpt, *cursor.start())
.map_range_to_buffer(range_start_in_excerpt..range_end_in_excerpt);
let multibuffer_excerpt_range = multibuffer_excerpt if range.end > cursor.end(&()) {
.map_range_from_buffer(excerpt.range.context.to_offset(&excerpt.buffer));
let overlap_range = cmp::max(
range.as_ref().unwrap().start,
multibuffer_excerpt_range.start,
)
..cmp::min(range.as_ref().unwrap().end, multibuffer_excerpt_range.end);
let overlap_range = multibuffer_excerpt.map_range_to_buffer(overlap_range);
if multibuffer_excerpt_range.end <= range.as_ref().unwrap().end {
cursor.next(&()); cursor.next(&());
} else { } else {
range = next_range(&mut cursor); current_range = ranges.next();
} }
(excerpt.id, &excerpt.buffer, overlap_range) Some((excerpt.id, &excerpt.buffer, buffer_range))
})
}) })
} }