Fix panic when editing diff (#24298)

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2025-02-05 12:14:02 -07:00 committed by GitHub
parent 9369b72475
commit 44a7614a74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 110 additions and 15 deletions

View file

@ -1424,24 +1424,19 @@ impl MultiBuffer {
cx: &mut Context<Self>,
) {
let buffer_snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
let (mut insert_after, excerpt_ids) =
if let Some(existing) = self.buffers_by_path.get(&path) {
(*existing.last().unwrap(), existing.clone())
} else {
(
self.buffers_by_path
let mut insert_after = self
.buffers_by_path
.range(..path.clone())
.next_back()
.map(|(_, value)| *value.last().unwrap())
.unwrap_or(ExcerptId::min()),
Vec::default(),
)
};
.unwrap_or(ExcerptId::min());
let existing = self.buffers_by_path.get(&path).cloned().unwrap_or_default();
let (new, _) = build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
let mut new_iter = new.into_iter().peekable();
let mut existing_iter = excerpt_ids.into_iter().peekable();
let mut existing_iter = existing.into_iter().peekable();
let mut new_excerpt_ids = Vec::new();
let mut to_remove = Vec::new();
@ -1495,7 +1490,6 @@ impl MultiBuffer {
// maybe merge overlapping excerpts?
// it's hard to distinguish between a manually expanded excerpt, and one that
// got smaller because of a missing diff.
//
if existing_start == new.context.start && existing_end == new.context.end {
new_excerpt_ids.append(&mut self.insert_excerpts_after(
insert_after,

View file

@ -1578,6 +1578,107 @@ fn test_repeatedly_expand_a_diff_hunk(cx: &mut TestAppContext) {
);
}
#[gpui::test]
fn test_set_excerpts_for_buffer_ordering(cx: &mut TestAppContext) {
let buf1 = cx.new(|cx| {
Buffer::local(
indoc! {
"zero
one
two
two.five
three
four
five
six
seven
eight
nine
ten
eleven
",
},
cx,
)
});
let path1: PathKey = PathKey::namespaced("0", Path::new("/"));
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
multibuffer.update(cx, |multibuffer, cx| {
multibuffer.set_excerpts_for_path(
path1.clone(),
buf1.clone(),
vec![
Point::row_range(1..2),
Point::row_range(6..7),
Point::row_range(11..12),
],
1,
cx,
);
});
assert_excerpts_match(
&multibuffer,
cx,
indoc! {
"-----
zero
one
two
two.five
-----
four
five
six
seven
-----
nine
ten
eleven
"
},
);
buf1.update(cx, |buffer, cx| buffer.edit([(0..5, "")], None, cx));
multibuffer.update(cx, |multibuffer, cx| {
multibuffer.set_excerpts_for_path(
path1.clone(),
buf1.clone(),
vec![
Point::row_range(0..2),
Point::row_range(5..6),
Point::row_range(10..11),
],
1,
cx,
);
});
assert_excerpts_match(
&multibuffer,
cx,
indoc! {
"-----
one
two
two.five
three
-----
four
five
six
seven
-----
nine
ten
eleven
"
},
);
}
#[gpui::test]
fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) {
let buf1 = cx.new(|cx| {