multi_buffer: Fix up some anchor checks (#43454)

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-11-25 13:41:19 +00:00
committed by GitHub
parent a359a5a1f2
commit f8965317c3
15 changed files with 154 additions and 58 deletions
+31 -12
View File
@@ -5076,8 +5076,7 @@ impl MultiBufferSnapshot {
excerpt_id: ExcerptId,
text_anchor: Range<text::Anchor>,
) -> Option<Range<Anchor>> {
let excerpt_id = self.latest_excerpt_id(excerpt_id);
let excerpt = self.excerpt(excerpt_id)?;
let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?;
Some(
self.anchor_in_excerpt_(excerpt, text_anchor.start)?
@@ -5092,8 +5091,7 @@ impl MultiBufferSnapshot {
excerpt_id: ExcerptId,
text_anchor: text::Anchor,
) -> Option<Anchor> {
let excerpt_id = self.latest_excerpt_id(excerpt_id);
let excerpt = self.excerpt(excerpt_id)?;
let excerpt = self.excerpt(self.latest_excerpt_id(excerpt_id))?;
self.anchor_in_excerpt_(excerpt, text_anchor)
}
@@ -5130,7 +5128,8 @@ impl MultiBufferSnapshot {
}
pub fn can_resolve(&self, anchor: &Anchor) -> bool {
if anchor.excerpt_id == ExcerptId::min() || anchor.excerpt_id == ExcerptId::max() {
if *anchor == Anchor::min() || anchor.excerpt_id == ExcerptId::max() {
// todo(lw): should be `!self.is_empty()`
true
} else if let Some(excerpt) = self.excerpt(anchor.excerpt_id) {
excerpt.buffer.can_resolve(&anchor.text_anchor)
@@ -5791,8 +5790,8 @@ impl MultiBufferSnapshot {
.and_then(|(buffer, _)| buffer.file())
}
pub fn language_at<T: ToOffset>(&self, point: T) -> Option<&Arc<Language>> {
self.point_to_buffer_offset(point)
pub fn language_at<T: ToOffset>(&self, offset: T) -> Option<&Arc<Language>> {
self.point_to_buffer_offset(offset)
.and_then(|(buffer, offset)| buffer.language_at(offset))
}
@@ -5992,13 +5991,27 @@ impl MultiBufferSnapshot {
theme: Option<&SyntaxTheme>,
) -> Option<(BufferId, Vec<OutlineItem<Anchor>>)> {
let anchor = self.anchor_before(offset);
let excerpt_id = anchor.excerpt_id;
let excerpt = self.excerpt(excerpt_id)?;
let buffer_id = excerpt.buffer_id;
let excerpt @ &Excerpt {
id: excerpt_id,
buffer_id,
ref buffer,
..
} = self.excerpt(anchor.excerpt_id)?;
if cfg!(debug_assertions) {
match anchor.buffer_id {
// we clearly are hitting this according to sentry, but in what situations can this occur?
Some(anchor_buffer_id) => {
assert_eq!(
anchor_buffer_id, buffer_id,
"anchor {anchor:?} does not match with resolved excerpt {excerpt:?}"
)
}
None => assert_eq!(anchor, Anchor::max()),
}
};
Some((
buffer_id,
excerpt
.buffer
buffer
.symbols_containing(anchor.text_anchor, theme)
.into_iter()
.flat_map(|item| {
@@ -6114,6 +6127,12 @@ impl MultiBufferSnapshot {
}
}
/// Returns the excerpt for the given id. The returned excerpt is guaranteed
/// to have the same excerpt id as the one passed in, with the exception of
/// `ExcerptId::max()`.
///
/// Callers of this function should generally use the resulting excerpt's `id` field
/// afterwards.
fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> {
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(());
let locator = self.excerpt_locator_for_id(excerpt_id);