From c7796331542f4355a392073e56807e1f74b532a4 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 29 Jul 2021 10:43:09 -0600 Subject: [PATCH] Make unfolding inclusive If the range *touches* the fold, we unfold. This was needed to fix the behavior for unfolding at the current selection position. Previously, there was some kind of translation issue that was allowing us to accidentally work the way we wanted without this. Co-Authored-By: Antonio Scandurra --- zed/src/editor.rs | 17 +++++++---------- zed/src/editor/display_map/fold_map.rs | 15 +++++++++++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/zed/src/editor.rs b/zed/src/editor.rs index 7977cba56e..c36d0dad6c 100644 --- a/zed/src/editor.rs +++ b/zed/src/editor.rs @@ -1020,11 +1020,8 @@ impl Editor { // Cut the text from the selected rows and paste it at the start of the previous line. if display_rows.start != 0 { let start = Point::new(buffer_rows.start, 0).to_offset(buffer); - let end = Point::new( - buffer_rows.end - 1, - buffer.line_len(buffer_rows.end - 1), - ) - .to_offset(buffer); + let end = Point::new(buffer_rows.end - 1, buffer.line_len(buffer_rows.end - 1)) + .to_offset(buffer); let prev_row_display_start = DisplayPoint::new(display_rows.start - 1, 0); let prev_row_buffer_start = display_map.prev_row_boundary(prev_row_display_start).1; @@ -3842,25 +3839,25 @@ mod tests { view.update(cx, |view, cx| { view.split_selection_into_lines(&(), cx); - assert_eq!(view.text(cx), "aa…bbb\nccc…eeee\nfffff\nggggg\n…i"); + assert_eq!(view.text(cx), "aaaaa\nbbbbb\nccc…eeee\nfffff\nggggg\n…i"); assert_eq!( view.selection_ranges(cx), [ DisplayPoint::new(0, 1)..DisplayPoint::new(0, 1), DisplayPoint::new(0, 2)..DisplayPoint::new(0, 2), - DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0), - DisplayPoint::new(4, 4)..DisplayPoint::new(4, 4) + DisplayPoint::new(2, 0)..DisplayPoint::new(2, 0), + DisplayPoint::new(5, 4)..DisplayPoint::new(5, 4) ] ); }); view.update(cx, |view, cx| { - view.select_display_ranges(&[DisplayPoint::new(4, 0)..DisplayPoint::new(0, 1)], cx) + view.select_display_ranges(&[DisplayPoint::new(5, 0)..DisplayPoint::new(0, 1)], cx) .unwrap(); view.split_selection_into_lines(&(), cx); assert_eq!( view.text(cx), - "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\n…i" + "aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii" ); assert_eq!( view.selection_ranges(cx), diff --git a/zed/src/editor/display_map/fold_map.rs b/zed/src/editor/display_map/fold_map.rs index bdc5523150..b8ab39cce1 100644 --- a/zed/src/editor/display_map/fold_map.rs +++ b/zed/src/editor/display_map/fold_map.rs @@ -154,7 +154,7 @@ impl<'a> FoldMapWriter<'a> { let buffer = self.0.buffer.read(cx).snapshot(); for range in ranges.into_iter() { // Remove intersecting folds and add their ranges to edits that are passed to apply_edits. - let mut folds_cursor = intersecting_folds(&buffer, &self.0.folds, range); + let mut folds_cursor = intersecting_folds(&buffer, &self.0.folds, range, true); while let Some(fold) = folds_cursor.item() { let offset_range = fold.0.start.to_offset(&buffer)..fold.0.end.to_offset(&buffer); edits.push(buffer::Edit { @@ -590,7 +590,7 @@ impl Snapshot { where T: ToOffset, { - let mut folds = intersecting_folds(&self.buffer_snapshot, &self.folds, range); + let mut folds = intersecting_folds(&self.buffer_snapshot, &self.folds, range, false); iter::from_fn(move || { let item = folds.item().map(|f| &f.0); folds.next(&self.buffer_snapshot); @@ -722,6 +722,7 @@ fn intersecting_folds<'a, T>( buffer: &'a buffer::Snapshot, folds: &'a SumTree, range: Range, + inclusive: bool, ) -> FilterCursor<'a, impl 'a + Fn(&FoldSummary) -> bool, Fold, usize> where T: ToOffset, @@ -730,8 +731,14 @@ where let end = buffer.anchor_after(range.end.to_offset(buffer)); folds.filter::<_, usize>( move |summary| { - start.cmp(&summary.max_end, buffer).unwrap() == Ordering::Less - && end.cmp(&summary.min_start, buffer).unwrap() == Ordering::Greater + let start_cmp = start.cmp(&summary.max_end, buffer).unwrap(); + let end_cmp = end.cmp(&summary.min_start, buffer).unwrap(); + + if inclusive { + start_cmp <= Ordering::Equal && end_cmp >= Ordering::Equal + } else { + start_cmp == Ordering::Less && end_cmp == Ordering::Greater + } }, buffer, )