Delete to hard line boundary when deleting to start/end of line

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Nathan Sobo 2022-02-04 10:10:30 -07:00
parent 90a780a604
commit c38fe473cd
2 changed files with 27 additions and 18 deletions

View file

@ -101,7 +101,7 @@ action!(SelectRight);
action!(SelectToPreviousWordBoundary); action!(SelectToPreviousWordBoundary);
action!(SelectToNextWordBoundary); action!(SelectToNextWordBoundary);
action!(SelectToBeginningOfLine, bool); action!(SelectToBeginningOfLine, bool);
action!(SelectToEndOfLine); action!(SelectToEndOfLine, bool);
action!(SelectToBeginning); action!(SelectToBeginning);
action!(SelectToEnd); action!(SelectToEnd);
action!(SelectAll); action!(SelectAll);
@ -212,8 +212,8 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
SelectToBeginningOfLine(true), SelectToBeginningOfLine(true),
Some("Editor"), Some("Editor"),
), ),
Binding::new("cmd-shift-right", SelectToEndOfLine, Some("Editor")), Binding::new("cmd-shift-right", SelectToEndOfLine(true), Some("Editor")),
Binding::new("ctrl-shift-E", SelectToEndOfLine, Some("Editor")), Binding::new("ctrl-shift-E", SelectToEndOfLine(true), Some("Editor")),
Binding::new("cmd-shift-up", SelectToBeginning, Some("Editor")), Binding::new("cmd-shift-up", SelectToBeginning, Some("Editor")),
Binding::new("cmd-shift-down", SelectToEnd, Some("Editor")), Binding::new("cmd-shift-down", SelectToEnd, Some("Editor")),
Binding::new("cmd-a", SelectAll, Some("Editor")), Binding::new("cmd-a", SelectAll, Some("Editor")),
@ -2925,14 +2925,14 @@ impl Editor {
pub fn select_to_beginning_of_line( pub fn select_to_beginning_of_line(
&mut self, &mut self,
SelectToBeginningOfLine(toggle_indent): &SelectToBeginningOfLine, SelectToBeginningOfLine(stop_at_soft_boundaries): &SelectToBeginningOfLine,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut selections = self.local_selections::<Point>(cx); let mut selections = self.local_selections::<Point>(cx);
for selection in &mut selections { for selection in &mut selections {
let head = selection.head().to_display_point(&display_map); 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.set_head(new_head.to_point(&display_map));
selection.goal = SelectionGoal::None; selection.goal = SelectionGoal::None;
} }
@ -2956,7 +2956,7 @@ impl Editor {
{ {
for selection in &mut selections { for selection in &mut selections {
let head = selection.head().to_display_point(&display_map); 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); let anchor = new_head.to_point(&display_map);
selection.start = anchor.clone(); selection.start = anchor.clone();
selection.end = anchor; selection.end = anchor;
@ -2967,12 +2967,16 @@ impl Editor {
self.update_selections(selections, Some(Autoscroll::Fit), cx); self.update_selections(selections, Some(Autoscroll::Fit), cx);
} }
pub fn select_to_end_of_line(&mut self, _: &SelectToEndOfLine, cx: &mut ViewContext<Self>) { pub fn select_to_end_of_line(
&mut self,
SelectToEndOfLine(stop_at_soft_boundaries): &SelectToEndOfLine,
cx: &mut ViewContext<Self>,
) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut selections = self.local_selections::<Point>(cx); let mut selections = self.local_selections::<Point>(cx);
for selection in &mut selections { for selection in &mut selections {
let head = selection.head().to_display_point(&display_map); 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.set_head(new_head.to_point(&display_map));
selection.goal = SelectionGoal::None; selection.goal = SelectionGoal::None;
} }
@ -2981,14 +2985,14 @@ impl Editor {
pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext<Self>) { pub fn delete_to_end_of_line(&mut self, _: &DeleteToEndOfLine, cx: &mut ViewContext<Self>) {
self.start_transaction(cx); 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.delete(&Delete, cx);
self.end_transaction(cx); self.end_transaction(cx);
} }
pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext<Self>) { pub fn cut_to_end_of_line(&mut self, _: &CutToEndOfLine, cx: &mut ViewContext<Self>) {
self.start_transaction(cx); 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.cut(&Cut, cx);
self.end_transaction(cx); self.end_transaction(cx);
} }
@ -5673,7 +5677,7 @@ mod tests {
}); });
view.update(cx, |view, cx| { view.update(cx, |view, cx| {
view.select_to_end_of_line(&SelectToEndOfLine, cx); view.select_to_end_of_line(&SelectToEndOfLine(true), cx);
assert_eq!( assert_eq!(
view.selected_display_ranges(cx), view.selected_display_ranges(cx),
&[ &[

View file

@ -95,7 +95,7 @@ pub fn down(
pub fn line_beginning( pub fn line_beginning(
map: &DisplaySnapshot, map: &DisplaySnapshot,
display_point: DisplayPoint, display_point: DisplayPoint,
toggle_indent: bool, stop_at_soft_boundaries: bool,
) -> DisplayPoint { ) -> DisplayPoint {
let point = display_point.to_point(map); let point = display_point.to_point(map);
let soft_line_start = map.clip_point(DisplayPoint::new(display_point.row(), 0), Bias::Right); 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); .to_display_point(map);
let line_start = map.prev_line_boundary(point).1; 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 soft_line_start
} else if toggle_indent && display_point != indent_start { } else if stop_at_soft_boundaries && display_point != indent_start {
indent_start indent_start
} else { } else {
line_start 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( let soft_line_end = map.clip_point(
DisplayPoint::new(display_point.row(), map.line_len(display_point.row())), DisplayPoint::new(display_point.row(), map.line_len(display_point.row())),
Bias::Left, Bias::Left,
); );
if display_point == soft_line_end { if stop_at_soft_boundaries && display_point != soft_line_end {
map.next_line_boundary(display_point.to_point(map)).1
} else {
soft_line_end soft_line_end
} else {
map.next_line_boundary(display_point.to_point(map)).1
} }
} }