From 7a79df7a24520bd59f3daf9c5793b360a7e1a540 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 23 Nov 2021 19:10:15 +0100 Subject: [PATCH] Implement line-wise selection --- crates/editor/src/lib.rs | 47 +++++++++++++++++++++++++++++------ crates/editor/src/movement.rs | 10 ++++---- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/crates/editor/src/lib.rs b/crates/editor/src/lib.rs index 7570252831..159ac76be2 100644 --- a/crates/editor/src/lib.rs +++ b/crates/editor/src/lib.rs @@ -23,7 +23,7 @@ use smallvec::SmallVec; use smol::Timer; use std::{ cell::RefCell, - cmp::{self, Ordering}, + cmp, collections::HashMap, iter, mem, ops::{Range, RangeInclusive}, @@ -683,7 +683,18 @@ impl Editor { end = buffer.anchor_before(range.end.to_point(&display_map)); mode = SelectMode::Word(start.clone()..end.clone()); } - 3 => todo!(), + 3 => { + let position = display_map.clip_point(position, Bias::Left); + let line_start = movement::line_beginning(&display_map, position, false); + let mut next_line_start = line_start.clone(); + *next_line_start.row_mut() += 1; + *next_line_start.column_mut() = 0; + next_line_start = display_map.clip_point(next_line_start, Bias::Right); + + start = buffer.anchor_before(line_start.to_point(&display_map)); + end = buffer.anchor_before(next_line_start.to_point(&display_map)); + mode = SelectMode::Line(start.clone()..end.clone()); + } _ => { start = buffer.anchor_before(0); end = buffer.anchor_before(buffer.len()); @@ -746,7 +757,29 @@ impl Editor { tail = original_buffer_range.start; } } - SelectMode::Line(_) => todo!(), + SelectMode::Line(original_range) => { + let original_display_range = original_range.start.to_display_point(&display_map) + ..original_range.end.to_display_point(&display_map); + let original_buffer_range = original_display_range.start.to_point(&display_map) + ..original_display_range.end.to_point(&display_map); + let line_start = movement::line_beginning(&display_map, position, false); + let mut next_line_start = line_start.clone(); + *next_line_start.row_mut() += 1; + *next_line_start.column_mut() = 0; + next_line_start = display_map.clip_point(next_line_start, Bias::Right); + + if line_start < original_display_range.start { + head = line_start.to_point(&display_map); + } else { + head = next_line_start.to_point(&display_map); + } + + if head <= original_buffer_range.start { + tail = original_buffer_range.end; + } else { + tail = original_buffer_range.start; + } + } SelectMode::All => { return; } @@ -1924,7 +1957,7 @@ impl Editor { let mut selections = self.selections::(cx).collect::>(); for selection in &mut selections { let head = selection.head().to_display_point(&display_map); - let new_head = movement::line_beginning(&display_map, head, true).unwrap(); + let new_head = movement::line_beginning(&display_map, head, true); let cursor = new_head.to_point(&display_map); selection.start = cursor; selection.end = cursor; @@ -1943,7 +1976,7 @@ impl Editor { let mut selections = self.selections::(cx).collect::>(); for selection in &mut selections { let head = selection.head().to_display_point(&display_map); - let new_head = movement::line_beginning(&display_map, head, *toggle_indent).unwrap(); + let new_head = movement::line_beginning(&display_map, head, *toggle_indent); selection.set_head(new_head.to_point(&display_map)); selection.goal = SelectionGoal::None; } @@ -1967,7 +2000,7 @@ impl Editor { { for selection in &mut selections { let head = selection.head().to_display_point(&display_map); - let new_head = movement::line_end(&display_map, head).unwrap(); + let new_head = movement::line_end(&display_map, head); let anchor = new_head.to_point(&display_map); selection.start = anchor.clone(); selection.end = anchor; @@ -1983,7 +2016,7 @@ impl Editor { let mut selections = self.selections::(cx).collect::>(); for selection in &mut selections { let head = selection.head().to_display_point(&display_map); - let new_head = movement::line_end(&display_map, head).unwrap(); + let new_head = movement::line_end(&display_map, head); selection.set_head(new_head.to_point(&display_map)); selection.goal = SelectionGoal::None; } diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index 438846258c..b3d9610e02 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -101,18 +101,18 @@ pub fn line_beginning( map: &DisplayMapSnapshot, point: DisplayPoint, toggle_indent: bool, -) -> Result { +) -> DisplayPoint { let (indent, is_blank) = map.line_indent(point.row()); if toggle_indent && !is_blank && point.column() != indent { - Ok(DisplayPoint::new(point.row(), indent)) + DisplayPoint::new(point.row(), indent) } else { - Ok(DisplayPoint::new(point.row(), 0)) + DisplayPoint::new(point.row(), 0) } } -pub fn line_end(map: &DisplayMapSnapshot, point: DisplayPoint) -> Result { +pub fn line_end(map: &DisplayMapSnapshot, point: DisplayPoint) -> DisplayPoint { let line_end = DisplayPoint::new(point.row(), map.line_len(point.row())); - Ok(map.clip_point(line_end, Bias::Left)) + map.clip_point(line_end, Bias::Left) } pub fn prev_word_boundary(map: &DisplayMapSnapshot, mut point: DisplayPoint) -> DisplayPoint {