From d97adfc540afd3f4947c6641aa63bc13759dac7f Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Thu, 6 Feb 2025 23:18:59 -0500 Subject: [PATCH] Fix pairs of almost-adjacent hunks toggling together (#24355) Release Notes: - Fixed a bug where toggling a diff hunk that immediately precedes another hunk would act on both hunks --- crates/editor/src/editor.rs | 18 ++++++--- crates/editor/src/element.rs | 2 +- crates/multi_buffer/src/multi_buffer.rs | 53 ++++++++++++++++++++----- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index d6ed7d27d9366ab0e1e37304ab8a1b0116462a2d..b2c87d63b5cb96f264f8e2367df121c2d8e267c1 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -12237,11 +12237,19 @@ impl Editor { cx: &mut Context<'_, Editor>, ) { self.buffer.update(cx, |buffer, cx| { - if buffer.has_expanded_diff_hunks_in_ranges(&ranges, cx) { - buffer.collapse_diff_hunks(ranges, cx) - } else { - buffer.expand_diff_hunks(ranges, cx) - } + let expand = !buffer.has_expanded_diff_hunks_in_ranges(&ranges, cx); + buffer.expand_or_collapse_diff_hunks(ranges, expand, cx); + }) + } + + fn toggle_diff_hunks_in_ranges_narrow( + &mut self, + ranges: Vec>, + cx: &mut Context<'_, Editor>, + ) { + self.buffer.update(cx, |buffer, cx| { + let expand = !buffer.has_expanded_diff_hunks_in_ranges(&ranges, cx); + buffer.expand_or_collapse_diff_hunks_narrow(ranges, expand, cx); }) } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index c95b70b26338643671c63307549155304977c1ac..1a56c8954abaa93a3ac525151a8865b1b67afe84 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -559,7 +559,7 @@ impl EditorElement { let mut modifiers = event.modifiers; if let Some(hovered_hunk) = hovered_hunk { - editor.toggle_diff_hunks_in_ranges(vec![hovered_hunk], cx); + editor.toggle_diff_hunks_in_ranges_narrow(vec![hovered_hunk], cx); cx.notify(); return; } else if gutter_hitbox.is_hovered(window) { diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 4f0f3a18bddb6c725c9ccbbdf3c6441d7594dffa..9c80fcedd3ebbaf443d1cce3c5c7ae81a59763d5 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -2376,24 +2376,17 @@ impl MultiBuffer { false } - fn expand_or_collapse_diff_hunks( + fn expand_or_collapse_diff_hunks_internal( &mut self, - ranges: Vec>, + ranges: impl Iterator, ExcerptId)>, expand: bool, cx: &mut Context, ) { self.sync(cx); let mut snapshot = self.snapshot.borrow_mut(); let mut excerpt_edits = Vec::new(); - for range in ranges.iter() { - let end_excerpt_id = range.end.excerpt_id; - let range = range.to_point(&snapshot); - let mut peek_end = range.end; - if range.end.row < snapshot.max_row().0 { - peek_end = Point::new(range.end.row + 1, 0); - }; - - for diff_hunk in snapshot.diff_hunks_in_range(range.start..peek_end) { + 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; } @@ -2428,6 +2421,44 @@ impl MultiBuffer { }); } + pub fn expand_or_collapse_diff_hunks_narrow( + &mut self, + ranges: Vec>, + expand: bool, + cx: &mut Context, + ) { + let snapshot = self.snapshot.borrow().clone(); + self.expand_or_collapse_diff_hunks_internal( + ranges + .iter() + .map(move |range| (range.to_point(&snapshot), range.end.excerpt_id)), + expand, + cx, + ); + } + + pub fn expand_or_collapse_diff_hunks( + &mut self, + ranges: Vec>, + expand: bool, + cx: &mut Context, + ) { + let snapshot = self.snapshot.borrow().clone(); + self.expand_or_collapse_diff_hunks_internal( + ranges.iter().map(move |range| { + let end_excerpt_id = range.end.excerpt_id; + let range = range.to_point(&snapshot); + let mut peek_end = range.end; + if range.end.row < snapshot.max_row().0 { + peek_end = Point::new(range.end.row + 1, 0); + }; + (range.start..peek_end, end_excerpt_id) + }), + expand, + cx, + ); + } + pub fn resize_excerpt( &mut self, id: ExcerptId,