Fix panic or bad hunks when expanding hunks w/ multiple ranges in 1 hunk (#28117)

Release Notes:

- Fixed a crash that could happen when expanding diff hunks with
multiple cursors in one hunk.
This commit is contained in:
Max Brunsfeld 2025-04-04 12:22:02 -07:00 committed by GitHub
parent 2747915569
commit 156dd32a35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 59 additions and 0 deletions

View file

@ -2649,11 +2649,15 @@ impl MultiBuffer {
self.sync(cx);
let mut snapshot = self.snapshot.borrow_mut();
let mut excerpt_edits = Vec::new();
let mut last_hunk_row = None;
for (range, end_excerpt_id) in ranges {
for diff_hunk in snapshot.diff_hunks_in_range(range) {
if diff_hunk.excerpt_id.cmp(&end_excerpt_id, &snapshot).is_gt() {
continue;
}
if last_hunk_row.map_or(false, |row| row >= diff_hunk.row_range.start) {
continue;
}
let start = Anchor::in_buffer(
diff_hunk.excerpt_id,
diff_hunk.buffer_id,
@ -2666,6 +2670,7 @@ impl MultiBuffer {
);
let start = snapshot.excerpt_offset_for_anchor(&start);
let end = snapshot.excerpt_offset_for_anchor(&end);
last_hunk_row = Some(diff_hunk.row_range.start);
excerpt_edits.push(text::Edit {
old: start..end,
new: start..end,

View file

@ -1380,6 +1380,7 @@ fn test_repeatedly_expand_a_diff_hunk(cx: &mut TestAppContext) {
"
one
four
five
six
"
);
@ -1413,6 +1414,7 @@ fn test_repeatedly_expand_a_diff_hunk(cx: &mut TestAppContext) {
+ TWO
+ THREE
four
- five
+ FIVE
six
"
@ -1440,6 +1442,58 @@ fn test_repeatedly_expand_a_diff_hunk(cx: &mut TestAppContext) {
+ TWO
+ THREE
four
- five
+ FIVE
six
"
),
);
// Now collapse all diff hunks
multibuffer.update(cx, |multibuffer, cx| {
multibuffer.collapse_diff_hunks(vec![Anchor::min()..Anchor::max()], cx);
});
assert_new_snapshot(
&multibuffer,
&mut snapshot,
&mut subscription,
cx,
indoc!(
"
one
TWO
THREE
four
FIVE
six
"
),
);
// Expand the hunks again, but this time provide two ranges that are both within the same hunk
// Target the first hunk which is between "one" and "four"
multibuffer.update(cx, |multibuffer, cx| {
multibuffer.expand_diff_hunks(
vec![
snapshot.anchor_before(Point::new(4, 0))..snapshot.anchor_before(Point::new(4, 0)),
snapshot.anchor_before(Point::new(4, 2))..snapshot.anchor_before(Point::new(4, 2)),
],
cx,
);
});
assert_new_snapshot(
&multibuffer,
&mut snapshot,
&mut subscription,
cx,
indoc!(
"
one
TWO
THREE
four
- five
+ FIVE
six
"