diff --git a/crates/buffer_diff/src/buffer_diff.rs b/crates/buffer_diff/src/buffer_diff.rs index 8442325535..837d50899c 100644 --- a/crates/buffer_diff/src/buffer_diff.rs +++ b/crates/buffer_diff/src/buffer_diff.rs @@ -56,8 +56,8 @@ pub enum DiffHunkSecondaryStatus { /// A diff hunk resolved to rows in the buffer. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DiffHunk { - /// The buffer range, expressed in terms of rows. - pub row_range: Range, + /// The buffer range as points. + pub range: Range, /// The range in the buffer to which this hunk corresponds. pub buffer_range: Range, /// The range in the buffer's diff base text to which this hunk corresponds. @@ -362,6 +362,7 @@ impl BufferDiffInner { pending_hunks = secondary.pending_hunks.clone(); } + let max_point = buffer.max_point(); let mut summaries = buffer.summaries_for_anchors_with_payload::(anchor_iter); iter::from_fn(move || loop { let (start_point, (start_anchor, start_base)) = summaries.next()?; @@ -371,7 +372,7 @@ impl BufferDiffInner { continue; } - if end_point.column > 0 { + if end_point.column > 0 && end_point < max_point { end_point.row += 1; end_point.column = 0; end_anchor = buffer.anchor_before(end_point); @@ -416,7 +417,7 @@ impl BufferDiffInner { } return Some(DiffHunk { - row_range: start_point.row..end_point.row, + range: start_point..end_point, diff_base_byte_range: start_base..end_base, buffer_range: start_anchor..end_anchor, secondary_status, @@ -442,14 +443,9 @@ impl BufferDiffInner { let hunk = cursor.item()?; let range = hunk.buffer_range.to_point(buffer); - let end_row = if range.end.column > 0 { - range.end.row + 1 - } else { - range.end.row - }; Some(DiffHunk { - row_range: range.start.row..end_row, + range, diff_base_byte_range: hunk.diff_base_byte_range.clone(), buffer_range: hunk.buffer_range.clone(), // The secondary status is not used by callers of this method. @@ -1136,12 +1132,10 @@ pub fn assert_hunks( let actual_hunks = diff_hunks .map(|hunk| { ( - hunk.row_range.clone(), + hunk.range.clone(), &diff_base[hunk.diff_base_byte_range.clone()], buffer - .text_for_range( - Point::new(hunk.row_range.start, 0)..Point::new(hunk.row_range.end, 0), - ) + .text_for_range(hunk.range.clone()) .collect::(), hunk.status(), ) @@ -1150,7 +1144,14 @@ pub fn assert_hunks( let expected_hunks: Vec<_> = expected_hunks .iter() - .map(|(r, s, h, status)| (r.clone(), *s, h.to_string(), *status)) + .map(|(r, old_text, new_text, status)| { + ( + Point::new(r.start, 0)..Point::new(r.end, 0), + *old_text, + new_text.to_string(), + *status, + ) + }) .collect(); assert_eq!(actual_hunks, expected_hunks); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 240117e250..965e8a1123 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -13733,7 +13733,7 @@ impl Editor { buffer_range: hunk.buffer_range, diff_base_byte_range: hunk.diff_base_byte_range, secondary_status: hunk.secondary_status, - row_range: 0..0, // unused + range: Point::zero()..Point::zero(), // unused }) .collect::>(), &buffer_snapshot, @@ -16041,9 +16041,9 @@ impl Editor { if let Some(buffer) = multi_buffer.buffer(buffer_id) { buffer.update(cx, |buffer, cx| { buffer.edit( - changes.into_iter().map(|(range, text)| { - (range, text.to_string().map(Arc::::from)) - }), + changes + .into_iter() + .map(|(range, text)| (range, text.to_string())), None, cx, ); @@ -17161,17 +17161,14 @@ impl EditorSnapshot { for hunk in self.buffer_snapshot.diff_hunks_in_range( Point::new(query_rows.start.0, 0)..Point::new(query_rows.end.0, 0), ) { - // Deleted hunk is an empty row range, no caret can be placed there and Zed allows to revert it - // when the caret is just above or just below the deleted hunk. - let allow_adjacent = hunk.status().is_deleted(); - let related_to_selection = if allow_adjacent { - hunk.row_range.overlaps(&query_rows) - || hunk.row_range.start == query_rows.end - || hunk.row_range.end == query_rows.start - } else { - hunk.row_range.overlaps(&query_rows) - }; - if related_to_selection { + // Include deleted hunks that are adjacent to the query range, because + // otherwise they would be missed. + let mut intersects_range = hunk.row_range.overlaps(&query_rows); + if hunk.status().is_deleted() { + intersects_range |= hunk.row_range.start == query_rows.end; + intersects_range |= hunk.row_range.end == query_rows.start; + } + if intersects_range { if !processed_buffer_rows .entry(hunk.buffer_id) .or_default() diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index d789546a62..964342ba1b 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -3498,17 +3498,12 @@ impl MultiBufferSnapshot { if hunk.is_created_file() && !self.all_diff_hunks_expanded { return None; } - Some(( - Point::new(hunk.row_range.start, 0)..Point::new(hunk.row_range.end, 0), - hunk, - )) + Some((hunk.range.clone(), hunk)) }), ) }) .filter_map(move |(range, hunk, excerpt)| { - if range.start != range.end - && range.end == query_range.start - && !hunk.row_range.is_empty() + if range.start != range.end && range.end == query_range.start && !hunk.range.is_empty() { return None; } @@ -3841,12 +3836,12 @@ impl MultiBufferSnapshot { &excerpt.buffer, ) { let hunk_range = hunk.buffer_range.to_offset(&excerpt.buffer); - if hunk.row_range.end >= buffer_end_row { + if hunk.range.end >= Point::new(buffer_end_row, 0) { continue; } - let hunk_start = Point::new(hunk.row_range.start, 0); - let hunk_end = Point::new(hunk.row_range.end, 0); + let hunk_start = hunk.range.start; + let hunk_end = hunk.range.end; cursor.seek_to_buffer_position_in_current_excerpt(&DimensionPair { key: hunk_range.start, diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index 194a1758b2..d0e34e1980 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -2274,7 +2274,7 @@ impl ReferenceMultibuffer { } if !hunk.buffer_range.start.is_valid(&buffer) { - log::trace!("skipping hunk with deleted start: {:?}", hunk.row_range); + log::trace!("skipping hunk with deleted start: {:?}", hunk.range); continue; }