From 61113127e0536ee581bb89822902f9ad96ff96b1 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 30 Jan 2024 10:33:25 -0500 Subject: [PATCH 1/4] Added kakoune's A-S command --- helix-term/src/commands.rs | 15 +++++++++++++++ helix-term/src/keymap/default.rs | 1 + 2 files changed, 16 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 4df3278b8bba..ef5dd3e45d52 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -278,6 +278,7 @@ impl MappableCommand { half_page_up, "Move half page up", half_page_down, "Move half page down", select_all, "Select whole document", + select_first_and_last_chars, "Select first and last characters of each selection", select_regex, "Select all regex matches inside selections", split_selection, "Split selections on regex matches", split_selection_on_newline, "Split selection on newlines", @@ -1811,6 +1812,20 @@ fn select_all(cx: &mut Context) { doc.set_selection(view.id, Selection::single(0, end)) } +fn select_first_and_last_chars(cx: &mut Context) { + let (view, doc) = current!(cx.editor); + + let selection = doc.selection(view.id).clone().transform_iter(|range| { + vec![ + Range::new(range.anchor, range.anchor + 1), + Range::new(range.head - 1, range.head) + ] + .into_iter() + }); + + doc.set_selection(view.id, selection); +} + fn select_regex(cx: &mut Context) { let reg = cx.register.unwrap_or('/'); ui::regex_prompt( diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs index 763ed4ae71ce..6a35581a774a 100644 --- a/helix-term/src/keymap/default.rs +++ b/helix-term/src/keymap/default.rs @@ -78,6 +78,7 @@ pub fn default() -> HashMap { "s" => select_regex, + "A-S" => select_first_and_last_chars, "A-s" => split_selection_on_newline, "A-minus" => merge_selections, "A-_" => merge_consecutive_selections, From 0311256d347c14c1b7e640a19a0d124b0209805b Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 30 Jan 2024 10:35:48 -0500 Subject: [PATCH 2/4] Small formatting change --- helix-term/src/commands.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ef5dd3e45d52..b075bab95547 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1818,9 +1818,9 @@ fn select_first_and_last_chars(cx: &mut Context) { let selection = doc.selection(view.id).clone().transform_iter(|range| { vec![ Range::new(range.anchor, range.anchor + 1), - Range::new(range.head - 1, range.head) + Range::new(range.head - 1, range.head), ] - .into_iter() + .into_iter() }); doc.set_selection(view.id, selection); From 091ec45740af6a6c2ce1f44a0bf0b30f249e643d Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 30 Jan 2024 12:17:17 -0500 Subject: [PATCH 3/4] Updated to use grapheme helpers --- book/src/keymap.md | 67 +++++++++++++++++++------------------- helix-term/src/commands.rs | 7 ++-- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index a3e41666f3fd..94314c1e005e 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -108,39 +108,40 @@ Normal mode is the default mode when you launch helix. You can return to it from ### Selection manipulation -| Key | Description | Command | -| ----- | ----------- | ------- | -| `s` | Select all regex matches inside selections | `select_regex` | -| `S` | Split selection into sub selections on regex matches | `split_selection` | -| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | -| `Alt-minus` | Merge selections | `merge_selections` | -| `Alt-_` | Merge consecutive selections | `merge_consecutive_selections` | -| `&` | Align selection in columns | `align_selections` | -| `_` | Trim whitespace from the selection | `trim_selections` | -| `;` | Collapse selection onto a single cursor | `collapse_selection` | -| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | -| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | -| `,` | Keep only the primary selection | `keep_primary_selection` | -| `Alt-,` | Remove the primary selection | `remove_primary_selection` | -| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | -| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | -| `(` | Rotate main selection backward | `rotate_selections_backward` | -| `)` | Rotate main selection forward | `rotate_selections_forward` | -| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | -| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | -| `%` | Select entire file | `select_all` | -| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | -| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | -| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | -| `J` | Join lines inside selection | `join_selections` | -| `Alt-J` | Join lines inside selection and select the inserted space | `join_selections_space` | -| `K` | Keep selections matching the regex | `keep_selections` | -| `Alt-K` | Remove selections matching the regex | `remove_selections` | -| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | -| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | -| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | -| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | -| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | +| Key | Description | Command | +|----------------------| ----------- | ------- | +| `s` | Select all regex matches inside selections | `select_regex` | +| `S` | Split selection into sub selections on regex matches | `split_selection` | +| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | +| `Alt-S` | Select first and last characters of each selection | `select_first_and_last_chars` | +| `Alt-minus` | Merge selections | `merge_selections` | +| `Alt-_` | Merge consecutive selections | `merge_consecutive_selections` | +| `&` | Align selection in columns | `align_selections` | +| `_` | Trim whitespace from the selection | `trim_selections` | +| `;` | Collapse selection onto a single cursor | `collapse_selection` | +| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | +| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | +| `,` | Keep only the primary selection | `keep_primary_selection` | +| `Alt-,` | Remove the primary selection | `remove_primary_selection` | +| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | +| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | +| `(` | Rotate main selection backward | `rotate_selections_backward` | +| `)` | Rotate main selection forward | `rotate_selections_forward` | +| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | +| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | +| `%` | Select entire file | `select_all` | +| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | +| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | +| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | +| `J` | Join lines inside selection | `join_selections` | +| `Alt-J` | Join lines inside selection and select the inserted space | `join_selections_space` | +| `K` | Keep selections matching the regex | `keep_selections` | +| `Alt-K` | Remove selections matching the regex | `remove_selections` | +| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | +| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | +| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | +| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | +| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | ### Search diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index b075bab95547..24c77dcfc715 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1814,11 +1814,12 @@ fn select_all(cx: &mut Context) { fn select_first_and_last_chars(cx: &mut Context) { let (view, doc) = current!(cx.editor); + let text = doc.text().slice(..); let selection = doc.selection(view.id).clone().transform_iter(|range| { - vec![ - Range::new(range.anchor, range.anchor + 1), - Range::new(range.head - 1, range.head), + [ + Range::new(range.from(), graphemes::next_grapheme_boundary(text, range.from())), + Range::new(graphemes::prev_grapheme_boundary(text, range.to()), range.to()) ] .into_iter() }); From 0c5e27724424268c86ee519c12efafe8dfc9221c Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 30 Jan 2024 13:44:41 -0500 Subject: [PATCH 4/4] Change to Range::point and fix keymap formatting --- book/src/keymap.md | 68 +++++++++++++++++++------------------- helix-term/src/commands.rs | 4 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 94314c1e005e..f5e9f104dd7c 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -108,40 +108,40 @@ Normal mode is the default mode when you launch helix. You can return to it from ### Selection manipulation -| Key | Description | Command | -|----------------------| ----------- | ------- | -| `s` | Select all regex matches inside selections | `select_regex` | -| `S` | Split selection into sub selections on regex matches | `split_selection` | -| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | -| `Alt-S` | Select first and last characters of each selection | `select_first_and_last_chars` | -| `Alt-minus` | Merge selections | `merge_selections` | -| `Alt-_` | Merge consecutive selections | `merge_consecutive_selections` | -| `&` | Align selection in columns | `align_selections` | -| `_` | Trim whitespace from the selection | `trim_selections` | -| `;` | Collapse selection onto a single cursor | `collapse_selection` | -| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | -| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | -| `,` | Keep only the primary selection | `keep_primary_selection` | -| `Alt-,` | Remove the primary selection | `remove_primary_selection` | -| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | -| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | -| `(` | Rotate main selection backward | `rotate_selections_backward` | -| `)` | Rotate main selection forward | `rotate_selections_forward` | -| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | -| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | -| `%` | Select entire file | `select_all` | -| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | -| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | -| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | -| `J` | Join lines inside selection | `join_selections` | -| `Alt-J` | Join lines inside selection and select the inserted space | `join_selections_space` | -| `K` | Keep selections matching the regex | `keep_selections` | -| `Alt-K` | Remove selections matching the regex | `remove_selections` | -| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | -| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | -| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | -| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | -| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | +| Key | Description | Command | +| ----- | ----------- | ------- | +| `s` | Select all regex matches inside selections | `select_regex` | +| `S` | Split selection into sub selections on regex matches | `split_selection` | +| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | +| `Alt-S` | Select first and last characters of each selection | `select_first_and_last_chars` | +| `Alt-minus` | Merge selections | `merge_selections` | +| `Alt-_` | Merge consecutive selections | `merge_consecutive_selections` | +| `&` | Align selection in columns | `align_selections` | +| `_` | Trim whitespace from the selection | `trim_selections` | +| `;` | Collapse selection onto a single cursor | `collapse_selection` | +| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | +| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | +| `,` | Keep only the primary selection | `keep_primary_selection` | +| `Alt-,` | Remove the primary selection | `remove_primary_selection` | +| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | +| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | +| `(` | Rotate main selection backward | `rotate_selections_backward` | +| `)` | Rotate main selection forward | `rotate_selections_forward` | +| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | +| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | +| `%` | Select entire file | `select_all` | +| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | +| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | +| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | +| `J` | Join lines inside selection | `join_selections` | +| `Alt-J` | Join lines inside selection and select the inserted space | `join_selections_space` | +| `K` | Keep selections matching the regex | `keep_selections` | +| `Alt-K` | Remove selections matching the regex | `remove_selections` | +| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | +| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | +| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | +| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | +| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | ### Search diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 24c77dcfc715..25d4da21a848 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1818,8 +1818,8 @@ fn select_first_and_last_chars(cx: &mut Context) { let selection = doc.selection(view.id).clone().transform_iter(|range| { [ - Range::new(range.from(), graphemes::next_grapheme_boundary(text, range.from())), - Range::new(graphemes::prev_grapheme_boundary(text, range.to()), range.to()) + Range::point(range.from()), + Range::point(graphemes::prev_grapheme_boundary(text, range.to())), ] .into_iter() });