From c38fe473cd4410552a05083e6894311ef4150624 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 4 Feb 2022 10:10:30 -0700 Subject: [PATCH] Delete to hard line boundary when deleting to start/end of line Co-Authored-By: Antonio Scandurra --- crates/editor/src/editor.rs | 26 +++++++++++++++----------- crates/editor/src/movement.rs | 19 ++++++++++++------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8916b8ab52f42d7d2b2c625ef855ab0f8f4f572f..bd8ab3d9f87e052b3b2fc488d7c44dc625ff50a1 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -101,7 +101,7 @@ action!(SelectRight); action!(SelectToPreviousWordBoundary); action!(SelectToNextWordBoundary); action!(SelectToBeginningOfLine, bool); -action!(SelectToEndOfLine); +action!(SelectToEndOfLine, bool); action!(SelectToBeginning); action!(SelectToEnd); action!(SelectAll); @@ -212,8 +212,8 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec, ) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let mut selections = self.local_selections::(cx); 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); + let new_head = movement::line_beginning(&display_map, head, *stop_at_soft_boundaries); selection.set_head(new_head.to_point(&display_map)); selection.goal = SelectionGoal::None; } @@ -2956,7 +2956,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); + let new_head = movement::line_end(&display_map, head, true); let anchor = new_head.to_point(&display_map); selection.start = anchor.clone(); selection.end = anchor; @@ -2967,12 +2967,16 @@ impl Editor { self.update_selections(selections, Some(Autoscroll::Fit), cx); } - pub fn select_to_end_of_line(&mut self, _: &SelectToEndOfLine, cx: &mut ViewContext) { + pub fn select_to_end_of_line( + &mut self, + SelectToEndOfLine(stop_at_soft_boundaries): &SelectToEndOfLine, + cx: &mut ViewContext, + ) { let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let mut selections = self.local_selections::(cx); for selection in &mut selections { let head = selection.head().to_display_point(&display_map); - let new_head = movement::line_end(&display_map, head); + let new_head = movement::line_end(&display_map, head, *stop_at_soft_boundaries); selection.set_head(new_head.to_point(&display_map)); selection.goal = SelectionGoal::None; } @@ -2981,14 +2985,14 @@ impl Editor { pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext) { self.start_transaction(cx); - self.select_to_end_of_line(&SelectToEndOfLine, cx); + self.select_to_end_of_line(&SelectToEndOfLine(false), cx); self.delete(&Delete, cx); self.end_transaction(cx); } pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext) { self.start_transaction(cx); - self.select_to_end_of_line(&SelectToEndOfLine, cx); + self.select_to_end_of_line(&SelectToEndOfLine(false), cx); self.cut(&Cut, cx); self.end_transaction(cx); } @@ -5673,7 +5677,7 @@ mod tests { }); view.update(cx, |view, cx| { - view.select_to_end_of_line(&SelectToEndOfLine, cx); + view.select_to_end_of_line(&SelectToEndOfLine(true), cx); assert_eq!( view.selected_display_ranges(cx), &[ diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index b67f147ca69075004ab4b57ad487b0387706d518..287ad34dc87e6687e7041f027b93ed205621ef99 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -95,7 +95,7 @@ pub fn down( pub fn line_beginning( map: &DisplaySnapshot, display_point: DisplayPoint, - toggle_indent: bool, + stop_at_soft_boundaries: bool, ) -> DisplayPoint { let point = display_point.to_point(map); let soft_line_start = map.clip_point(DisplayPoint::new(display_point.row(), 0), Bias::Right); @@ -106,24 +106,29 @@ pub fn line_beginning( .to_display_point(map); let line_start = map.prev_line_boundary(point).1; - if display_point != soft_line_start { + if stop_at_soft_boundaries && soft_line_start > indent_start && display_point != soft_line_start + { soft_line_start - } else if toggle_indent && display_point != indent_start { + } else if stop_at_soft_boundaries && display_point != indent_start { indent_start } else { line_start } } -pub fn line_end(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint { +pub fn line_end( + map: &DisplaySnapshot, + display_point: DisplayPoint, + stop_at_soft_boundaries: bool, +) -> DisplayPoint { let soft_line_end = map.clip_point( DisplayPoint::new(display_point.row(), map.line_len(display_point.row())), Bias::Left, ); - if display_point == soft_line_end { - map.next_line_boundary(display_point.to_point(map)).1 - } else { + if stop_at_soft_boundaries && display_point != soft_line_end { soft_line_end + } else { + map.next_line_boundary(display_point.to_point(map)).1 } }