From 0586770e35eb131955df10378bd97aed4b992937 Mon Sep 17 00:00:00 2001 From: ath3 Date: Sat, 13 Nov 2021 04:29:20 +0100 Subject: [PATCH] Add trim_selections command --- book/src/keymap.md | 1 + helix-term/src/commands.rs | 29 +++++++++++++++++++++++++++++ helix-term/src/keymap.rs | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index c544a472ebbbe..565be580749dd 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -88,6 +88,7 @@ | `s` | Select all regex matches inside selections | `select_regex` | | `S` | Split selection into subselections on regex matches | `split_selection` | | `Alt-s` | Split selection on newlines | `split_selection_on_newline` | +| `_` | Trim whitespace from selections | `trim_selections` | | `;` | Collapse selection onto a single cursor | `collapse_selection` | | `Alt-;` | Flip selection cursor and anchor | `flip_selections` | | `,` | Keep only the primary selection | `keep_primary_selection` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 48fd0ee01690f..2bd4c2ff282ef 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -272,6 +272,7 @@ impl Command { // TODO: different description ? goto_line_end_newline, "Goto line end", goto_first_nonwhitespace, "Goto first non-blank in line", + trim_selections, "Trim whitespace from selections", extend_to_line_start, "Extend to line start", extend_to_line_end, "Extend to line end", extend_to_line_end_newline, "Extend to line end", @@ -584,6 +585,34 @@ fn goto_first_nonwhitespace(cx: &mut Context) { doc.set_selection(view.id, selection); } +fn trim_selections(cx: &mut Context) { + let (view, doc) = current!(cx.editor); + let text = doc.text().slice(..); + + static END_REGEX: Lazy = Lazy::new(|| Regex::new(r"\S\s+$").unwrap()); + + let selection = doc.selection(view.id).clone().transform(|range| { + let mut start = range.from(); + let mut end = range.to(); + let start_byte = text.char_to_byte(start); + + start += text + .chars_at(start) + .position(|x| !x.is_whitespace()) + .unwrap_or(0); + + if let Some(pos) = END_REGEX.find(&range.fragment(text)) { + end = text.byte_to_char(start_byte + pos.start()) + 1; + } + if range.anchor < range.head { + Range::new(start, end) + } else { + Range::new(end, start) + } + }); + doc.set_selection(view.id, selection); +} + fn goto_window(cx: &mut Context, align: Align) { let (view, doc) = current!(cx.editor); diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index e3e0199571449..a95e8ecc3fd30 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -602,7 +602,7 @@ impl Default for Keymaps { // "Q" => replay_macro, // & align selections - // _ trim selections + "_" => trim_selections, "(" => rotate_selections_backward, ")" => rotate_selections_forward,