From 8bfe5eed736fa1c3ecc16251ee0399078edc8c01 Mon Sep 17 00:00:00 2001 From: Daniel Poulin Date: Mon, 9 May 2022 23:48:37 -0400 Subject: [PATCH] Add shrink equivalent of extend_to_line_bounds --- helix-term/src/commands.rs | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 07d805cad3f2e..6aa071a1935b8 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -247,6 +247,7 @@ impl MappableCommand { extend_line, "Select current line, if already selected, extend to next line", extend_line_above, "Select current line, if already selected, extend to previous line", extend_to_line_bounds, "Extend selection to line bounds (line-wise selection)", + shrink_to_line_bounds, "Shrink selection to line bounds (line-wise selection)", delete_selection, "Delete selection", delete_selection_noyank, "Delete selection, without yanking", change_selection, "Change selection (delete and enter insert mode)", @@ -1937,6 +1938,46 @@ fn extend_to_line_bounds(cx: &mut Context) { ); } +fn shrink_to_line_bounds(cx: &mut Context) { + let (view, doc) = current!(cx.editor); + + doc.set_selection( + view.id, + doc.selection(view.id).clone().transform(|range| { + let text = doc.text(); + + let (start_line, end_line) = range.line_range(text.slice(..)); + + // Do nothing if the selection is within one line to prevent + // conditional logic for the behavior of this command + if start_line == end_line { + return range; + } + + let mut start = text.line_to_char(start_line); + + // line_to_char gives us the start position of the line, so + // we need to get the start position of the next line, then + // backtrack to get the end position of the last line. + let mut end = text.line_to_char(end_line + 1) - 1; + + if start != range.from() { + start = text.line_to_char((start_line + 1).min(text.len_lines())); + } + + if end != range.to() { + end = text.line_to_char(end_line).saturating_sub(1); + } + + if range.anchor <= range.head { + Range::new(start, end) + } else { + Range::new(end, start) + } + }), + ); +} + enum Operation { Delete, Change,