Skip to content

Commit e351148

Browse files
authored
Fix bugs in expanding diff hunk (#18885)
Release Notes: - Fixed an issue where diff hunks at the boundaries of multi buffer excerpts could not be expanded
1 parent b0a9005 commit e351148

File tree

3 files changed

+85
-54
lines changed

3 files changed

+85
-54
lines changed

crates/editor/src/editor_tests.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11715,6 +11715,60 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut gpui::TestAppContext)
1171511715
);
1171611716
}
1171711717

11718+
#[gpui::test]
11719+
async fn test_expand_diff_hunk_at_excerpt_boundary(cx: &mut gpui::TestAppContext) {
11720+
init_test(cx, |_| {});
11721+
11722+
let base = "aaa\nbbb\nccc\nddd\neee\nfff\nggg\n";
11723+
let text = "aaa\nBBB\nBB2\nccc\nDDD\nEEE\nfff\nggg\n";
11724+
11725+
let buffer = cx.new_model(|cx| {
11726+
let mut buffer = Buffer::local(text.to_string(), cx);
11727+
buffer.set_diff_base(Some(base.into()), cx);
11728+
buffer
11729+
});
11730+
11731+
let multi_buffer = cx.new_model(|cx| {
11732+
let mut multibuffer = MultiBuffer::new(ReadWrite);
11733+
multibuffer.push_excerpts(
11734+
buffer.clone(),
11735+
[
11736+
ExcerptRange {
11737+
context: Point::new(0, 0)..Point::new(2, 0),
11738+
primary: None,
11739+
},
11740+
ExcerptRange {
11741+
context: Point::new(5, 0)..Point::new(7, 0),
11742+
primary: None,
11743+
},
11744+
],
11745+
cx,
11746+
);
11747+
multibuffer
11748+
});
11749+
11750+
let editor = cx.add_window(|cx| Editor::new(EditorMode::Full, multi_buffer, None, true, cx));
11751+
let mut cx = EditorTestContext::for_editor(editor, cx).await;
11752+
cx.run_until_parked();
11753+
11754+
cx.update_editor(|editor, cx| editor.expand_all_hunk_diffs(&Default::default(), cx));
11755+
cx.executor().run_until_parked();
11756+
11757+
cx.assert_diff_hunks(
11758+
"
11759+
aaa
11760+
- bbb
11761+
+ BBB
11762+
11763+
- ddd
11764+
- eee
11765+
+ EEE
11766+
fff
11767+
"
11768+
.unindent(),
11769+
);
11770+
}
11771+
1171811772
#[gpui::test]
1171911773
async fn test_edits_around_expanded_insertion_hunks(
1172011774
executor: BackgroundExecutor,

crates/editor/src/hunk_diff.rs

Lines changed: 31 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -209,19 +209,20 @@ impl Editor {
209209

210210
retain
211211
});
212-
for remaining_hunk in hunks_to_toggle {
213-
let remaining_hunk_point_range =
214-
Point::new(remaining_hunk.row_range.start.0, 0)
215-
..Point::new(remaining_hunk.row_range.end.0, 0);
212+
for hunk in hunks_to_toggle {
213+
let remaining_hunk_point_range = Point::new(hunk.row_range.start.0, 0)
214+
..Point::new(hunk.row_range.end.0, 0);
215+
let hunk_start = snapshot
216+
.buffer_snapshot
217+
.anchor_before(remaining_hunk_point_range.start);
218+
let hunk_end = snapshot
219+
.buffer_snapshot
220+
.anchor_in_excerpt(hunk_start.excerpt_id, hunk.buffer_range.end)
221+
.unwrap();
216222
hunks_to_expand.push(HoveredHunk {
217-
status: hunk_status(&remaining_hunk),
218-
multi_buffer_range: snapshot
219-
.buffer_snapshot
220-
.anchor_before(remaining_hunk_point_range.start)
221-
..snapshot
222-
.buffer_snapshot
223-
.anchor_after(remaining_hunk_point_range.end),
224-
diff_base_byte_range: remaining_hunk.diff_base_byte_range.clone(),
223+
status: hunk_status(&hunk),
224+
multi_buffer_range: hunk_start..hunk_end,
225+
diff_base_byte_range: hunk.diff_base_byte_range.clone(),
225226
});
226227
}
227228

@@ -246,33 +247,22 @@ impl Editor {
246247
hunk: &HoveredHunk,
247248
cx: &mut ViewContext<'_, Editor>,
248249
) -> Option<()> {
249-
let multi_buffer_snapshot = self.buffer().read(cx).snapshot(cx);
250+
let buffer = self.buffer.clone();
251+
let multi_buffer_snapshot = buffer.read(cx).snapshot(cx);
250252
let hunk_range = hunk.multi_buffer_range.clone();
251-
let hunk_point_range = hunk_range.to_point(&multi_buffer_snapshot);
252-
253-
let buffer = self.buffer().clone();
254-
let snapshot = self.snapshot(cx);
255253
let (diff_base_buffer, deleted_text_lines) = buffer.update(cx, |buffer, cx| {
256-
let hunk = buffer_diff_hunk(&snapshot.buffer_snapshot, hunk_point_range.clone())?;
257-
let mut buffer_ranges = buffer.range_to_buffer_ranges(hunk_point_range, cx);
258-
if buffer_ranges.len() == 1 {
259-
let (buffer, _, _) = buffer_ranges.pop()?;
260-
let diff_base_buffer = diff_base_buffer
261-
.or_else(|| self.current_diff_base_buffer(&buffer, cx))
262-
.or_else(|| create_diff_base_buffer(&buffer, cx))?;
263-
let buffer = buffer.read(cx);
264-
let deleted_text_lines = buffer.diff_base().map(|diff_base| {
265-
let diff_start_row = diff_base
266-
.offset_to_point(hunk.diff_base_byte_range.start)
267-
.row;
268-
let diff_end_row = diff_base.offset_to_point(hunk.diff_base_byte_range.end).row;
269-
270-
diff_end_row - diff_start_row
271-
})?;
272-
Some((diff_base_buffer, deleted_text_lines))
273-
} else {
274-
None
275-
}
254+
let buffer = buffer.buffer(hunk_range.start.buffer_id?)?;
255+
let diff_base_buffer = diff_base_buffer
256+
.or_else(|| self.current_diff_base_buffer(&buffer, cx))
257+
.or_else(|| create_diff_base_buffer(&buffer, cx))?;
258+
let deleted_text_lines = buffer.read(cx).diff_base().map(|diff_base| {
259+
let diff_start_row = diff_base
260+
.offset_to_point(hunk.diff_base_byte_range.start)
261+
.row;
262+
let diff_end_row = diff_base.offset_to_point(hunk.diff_base_byte_range.end).row;
263+
diff_end_row - diff_start_row
264+
})?;
265+
Some((diff_base_buffer, deleted_text_lines))
276266
})?;
277267

278268
let block_insert_index = match self.expanded_hunks.hunks.binary_search_by(|probe| {
@@ -1128,21 +1118,6 @@ fn editor_with_deleted_text(
11281118
(editor_height, editor)
11291119
}
11301120

1131-
fn buffer_diff_hunk(
1132-
buffer_snapshot: &MultiBufferSnapshot,
1133-
row_range: Range<Point>,
1134-
) -> Option<MultiBufferDiffHunk> {
1135-
let mut hunks = buffer_snapshot.git_diff_hunks_in_range(
1136-
MultiBufferRow(row_range.start.row)..MultiBufferRow(row_range.end.row),
1137-
);
1138-
let hunk = hunks.next()?;
1139-
let second_hunk = hunks.next();
1140-
if second_hunk.is_none() {
1141-
return Some(hunk);
1142-
}
1143-
None
1144-
}
1145-
11461121
impl DisplayDiffHunk {
11471122
pub fn start_display_row(&self) -> DisplayRow {
11481123
match self {
@@ -1209,7 +1184,10 @@ pub fn diff_hunk_to_display(
12091184
let hunk_end_point = Point::new(hunk_end_row.0, 0);
12101185

12111186
let multi_buffer_start = snapshot.buffer_snapshot.anchor_before(hunk_start_point);
1212-
let multi_buffer_end = snapshot.buffer_snapshot.anchor_after(hunk_end_point);
1187+
let multi_buffer_end = snapshot
1188+
.buffer_snapshot
1189+
.anchor_in_excerpt(multi_buffer_start.excerpt_id, hunk.buffer_range.end)
1190+
.unwrap();
12131191
let end = hunk_end_point.to_display_point(snapshot).row();
12141192

12151193
DisplayDiffHunk::Unfolded {

crates/language/src/buffer.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,6 @@ impl Buffer {
11561156
this.non_text_state_update_count += 1;
11571157
if let Some(BufferDiffBase::PastBufferVersion { rope, .. }) = &mut this.diff_base {
11581158
*rope = diff_base_rope;
1159-
cx.emit(BufferEvent::DiffBaseChanged);
11601159
}
11611160
cx.emit(BufferEvent::DiffUpdated);
11621161
})

0 commit comments

Comments
 (0)