From 4c4657515e89fcbf20c814ca99fa55caea832ba4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 3 May 2021 16:13:09 +0200 Subject: [PATCH] Account for folds when moving selections up/down --- zed/src/editor/buffer_view.rs | 87 ++++++++++++++++------------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index f971377af14312ecfa86c0c8506644d3f4861df9..c37ae4818f53def10ff184c35f92d813d62224ed 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -19,6 +19,7 @@ use std::{ cmp::{self, Ordering}, fmt::Write, iter::FromIterator, + mem, ops::Range, path::Path, sync::Arc, @@ -468,23 +469,30 @@ impl BufferView { self.pending_selection.is_some() } - #[cfg(test)] - fn select_ranges<'a, T>(&mut self, ranges: T, ctx: &mut ViewContext) -> Result<()> + fn select_ranges(&mut self, ranges: I, autoscroll: bool, ctx: &mut ViewContext) where - T: IntoIterator>, + I: IntoIterator>, + T: ToOffset, { let buffer = self.buffer.read(ctx); let mut selections = Vec::new(); for range in ranges { + let mut start = range.start.to_offset(buffer).unwrap(); + let mut end = range.end.to_offset(buffer).unwrap(); + let reversed = if start > end { + mem::swap(&mut start, &mut end); + true + } else { + false + }; selections.push(Selection { - start: buffer.anchor_before(range.start)?, - end: buffer.anchor_before(range.end)?, - reversed: false, + start: buffer.anchor_before(start).unwrap(), + end: buffer.anchor_before(end).unwrap(), + reversed, goal_column: None, }); } - self.update_selections(selections, false, ctx); - Ok(()) + self.update_selections(selections, autoscroll, ctx); } #[cfg(test)] @@ -492,8 +500,6 @@ impl BufferView { where T: IntoIterator>, { - use std::mem; - let map = self.display_map.read(ctx); let mut selections = Vec::new(); for range in ranges { @@ -824,10 +830,15 @@ impl BufferView { edits.push((prev_row_start..prev_row_start, text)); edits.push((selection_row_start - 1..selection_row_end, String::new())); - // Move selections to the previous line. + // Move selections up. + let row_delta = buffer_rows.start + - prev_row_display_start + .to_buffer_point(map, Bias::Left, app) + .unwrap() + .row; for range in &mut contiguous_selections { - range.start.row -= 1; - range.end.row -= 1; + range.start.row -= row_delta; + range.end.row -= row_delta; } } new_selection_ranges.extend(contiguous_selections.drain(..)); @@ -838,20 +849,7 @@ impl BufferView { buffer.edit(Some(range), text, Some(ctx)).unwrap(); } }); - - let buffer = self.buffer.read(ctx); - let mut new_selections = Vec::new(); - for range in new_selection_ranges { - let start = cmp::min(range.start, range.end); - let end = cmp::max(range.start, range.end); - new_selections.push(Selection { - start: buffer.anchor_before(start).unwrap(), - end: buffer.anchor_before(end).unwrap(), - reversed: range.start > range.end, - goal_column: None, - }); - } - self.update_selections(new_selections, true, ctx); + self.select_ranges(new_selection_ranges, true, ctx); self.end_transaction(ctx); } @@ -914,10 +912,16 @@ impl BufferView { edits.push((selection_row_start..selection_row_end + 1, String::new())); edits.push((next_row_end..next_row_end, text)); - // Move selections to the next line. + // Move selections down. + let row_delta = next_row_display_end + .to_buffer_point(map, Bias::Right, app) + .unwrap() + .row + - buffer_rows.end + + 1; for range in &mut contiguous_selections { - range.start.row += 1; - range.end.row += 1; + range.start.row += row_delta; + range.end.row += row_delta; } } new_selection_ranges.extend(contiguous_selections.drain(..)); @@ -928,20 +932,7 @@ impl BufferView { buffer.edit(Some(range), text, Some(ctx)).unwrap(); } }); - - let buffer = self.buffer.read(ctx); - let mut new_selections = Vec::new(); - for range in new_selection_ranges { - let start = cmp::min(range.start, range.end); - let end = cmp::max(range.start, range.end); - new_selections.push(Selection { - start: buffer.anchor_before(start).unwrap(), - end: buffer.anchor_before(end).unwrap(), - reversed: range.start > range.end, - goal_column: None, - }); - } - self.update_selections(new_selections, true, ctx); + self.select_ranges(new_selection_ranges, true, ctx); self.end_transaction(ctx); } @@ -2597,14 +2588,14 @@ mod tests { // Cut with three selections. Clipboard text is divided into three slices. view.update(app, |view, ctx| { - view.select_ranges(&[0..4, 8..14, 19..24], ctx).unwrap(); + view.select_ranges(vec![0..4, 8..14, 19..24], false, ctx); view.cut(&(), ctx); }); assert_eq!(view.read(app).text(app.as_ref()), "two four six "); // Paste with three cursors. Each cursor pastes one slice of the clipboard text. view.update(app, |view, ctx| { - view.select_ranges(&[4..4, 9..9, 13..13], ctx).unwrap(); + view.select_ranges(vec![4..4, 9..9, 13..13], false, ctx); view.paste(&(), ctx); }); assert_eq!( @@ -2624,7 +2615,7 @@ mod tests { // match the number of slices in the clipboard, the entire clipboard text // is pasted at each cursor. view.update(app, |view, ctx| { - view.select_ranges(&[0..0, 28..28], ctx).unwrap(); + view.select_ranges(vec![0..0, 28..28], false, ctx); view.insert(&"( ".to_string(), ctx); view.paste(&(), ctx); view.insert(&") ".to_string(), ctx); @@ -2635,7 +2626,7 @@ mod tests { ); view.update(app, |view, ctx| { - view.select_ranges(&[0..0], ctx).unwrap(); + view.select_ranges(vec![0..0], false, ctx); view.insert(&"123\n4567\n89\n".to_string(), ctx); }); assert_eq!(