Fix invalid anchors in breadcrumbs (#38687)
Release Notes: - (nightly only) Fix panic when your cursor abuts a multibyte character
This commit is contained in:
@@ -3756,11 +3756,9 @@ impl BufferSnapshot {
|
||||
theme: Option<&SyntaxTheme>,
|
||||
) -> Vec<OutlineItem<Anchor>> {
|
||||
let position = position.to_offset(self);
|
||||
let mut items = self.outline_items_containing(
|
||||
position.saturating_sub(1)..self.len().min(position + 1),
|
||||
false,
|
||||
theme,
|
||||
);
|
||||
let start = self.clip_offset(position.saturating_sub(1), Bias::Left);
|
||||
let end = self.clip_offset(position + 1, Bias::Right);
|
||||
let mut items = self.outline_items_containing(start..end, false, theme);
|
||||
let mut prev_depth = None;
|
||||
items.retain(|item| {
|
||||
let result = prev_depth.is_none_or(|prev_depth| item.depth > prev_depth);
|
||||
|
||||
@@ -1052,6 +1052,21 @@ async fn test_symbols_containing(cx: &mut gpui::TestAppContext) {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
let (text, offsets) = marked_text_offsets(
|
||||
&"
|
||||
// ˇ😅 //
|
||||
fn test() {
|
||||
}
|
||||
"
|
||||
.unindent(),
|
||||
);
|
||||
let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(Arc::new(rust_lang()), cx));
|
||||
let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
|
||||
|
||||
// note, it would be nice to actually return the method test in this
|
||||
// case, but primarily asserting we don't crash because of the multibyte character.
|
||||
assert_eq!(snapshot.symbols_containing(offsets[0], None), vec![]);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
||||
@@ -6156,8 +6156,9 @@ impl MultiBufferSnapshot {
|
||||
let anchor = self.anchor_before(offset);
|
||||
let excerpt_id = anchor.excerpt_id;
|
||||
let excerpt = self.excerpt(excerpt_id)?;
|
||||
let buffer_id = excerpt.buffer_id;
|
||||
Some((
|
||||
excerpt.buffer_id,
|
||||
buffer_id,
|
||||
excerpt
|
||||
.buffer
|
||||
.symbols_containing(anchor.text_anchor, theme)
|
||||
@@ -6165,22 +6166,15 @@ impl MultiBufferSnapshot {
|
||||
.flat_map(|item| {
|
||||
Some(OutlineItem {
|
||||
depth: item.depth,
|
||||
range: self.anchor_in_excerpt(excerpt_id, item.range.start)?
|
||||
..self.anchor_in_excerpt(excerpt_id, item.range.end)?,
|
||||
range: Anchor::range_in_buffer(excerpt_id, buffer_id, item.range),
|
||||
text: item.text,
|
||||
highlight_ranges: item.highlight_ranges,
|
||||
name_ranges: item.name_ranges,
|
||||
body_range: item.body_range.and_then(|body_range| {
|
||||
Some(
|
||||
self.anchor_in_excerpt(excerpt_id, body_range.start)?
|
||||
..self.anchor_in_excerpt(excerpt_id, body_range.end)?,
|
||||
)
|
||||
body_range: item.body_range.map(|body_range| {
|
||||
Anchor::range_in_buffer(excerpt_id, buffer_id, body_range)
|
||||
}),
|
||||
annotation_range: item.annotation_range.and_then(|body_range| {
|
||||
Some(
|
||||
self.anchor_in_excerpt(excerpt_id, body_range.start)?
|
||||
..self.anchor_in_excerpt(excerpt_id, body_range.end)?,
|
||||
)
|
||||
annotation_range: item.annotation_range.map(|body_range| {
|
||||
Anchor::range_in_buffer(excerpt_id, buffer_id, body_range)
|
||||
}),
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user