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 <me@as-cii.com>
This commit is contained in:
Nathan Sobo 2021-07-29 10:43:09 -06:00 committed by Max Brunsfeld
parent 38d4662a4e
commit c779633154
2 changed files with 18 additions and 14 deletions

View File

@ -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), "aabbb\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\ni"
"aaaaa\nbbbbb\nccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiii"
);
assert_eq!(
view.selection_ranges(cx),

View File

@ -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<Fold>,
range: Range<T>,
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,
)