aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorMatouš Dzivjak2022-01-06 02:12:02 +0000
committerGitHub2022-01-06 02:12:02 +0000
commit2e02a1d6bc004212033b9c4e5ed0de0fd880796c (patch)
treee73a695e58ddf7242d3cab282b93dd1ad9488ee5 /helix-term
parent66afbc9fff1ec5947ea5718f7817887aa0c853c8 (diff)
feat(commands): shrink_selection (#1340)
* feat(commands): shrink_selection Add `shrink_selection` command that can be used to shrink previously expanded selection. To make `shrink_selection` work it was necessary to add selection history to the Document since we want to shrink the selection towards the syntax tree node that was initially selected. Selection history is cleared any time the user changes selection other way than by `expand_selection`. This ensures that we don't get some funky edge cases when user calls `shrink_selection`. Related: https://github.com/helix-editor/helix/discussions/1328 * Refactor shrink_selection, move history to view * Remove useless comment * Add default key mapping for extend&shrink selection * Rework contains_selection method * Shrink selection without expand selects first child
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs36
-rw-r--r--helix-term/src/keymap.rs2
2 files changed, 37 insertions, 1 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index bf12b122..5c26a5b2 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -362,6 +362,7 @@ impl MappableCommand {
rotate_selection_contents_forward, "Rotate selection contents forward",
rotate_selection_contents_backward, "Rotate selections contents backward",
expand_selection, "Expand selection to parent syntax node",
+ shrink_selection, "Shrink selection to previously expanded syntax node",
jump_forward, "Jump forward on jumplist",
jump_backward, "Jump backward on jumplist",
save_selection, "Save the current selection to the jumplist",
@@ -5467,6 +5468,7 @@ fn rotate_selection_contents(cx: &mut Context, direction: Direction) {
doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id);
}
+
fn rotate_selection_contents_forward(cx: &mut Context) {
rotate_selection_contents(cx, Direction::Forward)
}
@@ -5482,7 +5484,39 @@ fn expand_selection(cx: &mut Context) {
if let Some(syntax) = doc.syntax() {
let text = doc.text().slice(..);
- let selection = object::expand_selection(syntax, text, doc.selection(view.id));
+
+ let current_selection = doc.selection(view.id);
+
+ // save current selection so it can be restored using shrink_selection
+ view.object_selections.push(current_selection.clone());
+
+ let selection = object::expand_selection(syntax, text, current_selection);
+ doc.set_selection(view.id, selection);
+ }
+ };
+ motion(cx.editor);
+ cx.editor.last_motion = Some(Motion(Box::new(motion)));
+}
+
+fn shrink_selection(cx: &mut Context) {
+ let motion = |editor: &mut Editor| {
+ let (view, doc) = current!(editor);
+ let current_selection = doc.selection(view.id);
+ // try to restore previous selection
+ if let Some(prev_selection) = view.object_selections.pop() {
+ if current_selection.contains(&prev_selection) {
+ // allow shrinking the selection only if current selection contains the previous object selection
+ doc.set_selection(view.id, prev_selection);
+ return;
+ } else {
+ // clear existing selection as they can't be shrinked to anyway
+ view.object_selections.clear();
+ }
+ }
+ // if not previous selection, shrink to first child
+ if let Some(syntax) = doc.syntax() {
+ let text = doc.text().slice(..);
+ let selection = object::shrink_selection(syntax, text, current_selection);
doc.set_selection(view.id, selection);
}
};
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 72833212..49f8469a 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -569,11 +569,13 @@ impl Default for Keymaps {
"d" => goto_prev_diag,
"D" => goto_first_diag,
"space" => add_newline_above,
+ "o" => shrink_selection,
},
"]" => { "Right bracket"
"d" => goto_next_diag,
"D" => goto_last_diag,
"space" => add_newline_below,
+ "o" => expand_selection,
},
"/" => search,