From b0ad2cd0e46f05fda4f4a6694a3ddf5da2c33041 Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Sun, 25 Jun 2023 13:50:37 -0400 Subject: [PATCH] feat(command): select_all_children_in_selection --- helix-term/src/commands.rs | 54 ++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 2a54955e7843..fa5a4f6e8ca0 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -26,7 +26,7 @@ use helix_core::{ syntax::{BlockCommentToken, LanguageServerFeature}, text_annotations::TextAnnotations, textobject, - tree_sitter::Node, + tree_sitter::{Node, Tree}, unicode::width::UnicodeWidthChar, visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeGraphemes, RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction, @@ -428,6 +428,7 @@ impl MappableCommand { select_prev_sibling, "Select previous sibling the in syntax tree", select_all_siblings, "Select all siblings of the current node", select_all_children, "Select all children of the current node", + select_all_children_in_selection, "Select all children of the current node that are contained in the current selection", jump_forward, "Jump forward on jumplist", jump_backward, "Jump backward on jumplist", save_selection, "Save current selection to jumplist", @@ -4769,17 +4770,39 @@ pub fn extend_parent_node_start(cx: &mut Context) { move_node_bound_impl(cx, Direction::Backward, Movement::Extend) } +fn select_all_impl(editor: &mut Editor, select_fn: F) +where + F: Fn(&Tree, RopeSlice, Selection) -> Selection, +{ + let (view, doc) = current!(editor); + + if let Some(syntax) = doc.syntax() { + let text = doc.text().slice(..); + let current_selection = doc.selection(view.id); + let selection = select_fn(syntax.tree(), text, current_selection.clone()); + doc.set_selection(view.id, selection); + } +} + fn select_all_siblings(cx: &mut Context) { let motion = |editor: &mut Editor| { - let (view, doc) = current!(editor); + select_all_impl(editor, object::select_all_siblings); + }; - if let Some(syntax) = doc.syntax() { - let text = doc.text().slice(..); - let current_selection = doc.selection(view.id); - let selection = - object::select_all_siblings(syntax.tree(), text, current_selection.clone()); - doc.set_selection(view.id, selection); - } + cx.editor.apply_motion(motion); +} + +fn select_all_children_in_selection(cx: &mut Context) { + let motion = |editor: &mut Editor| { + select_all_impl(editor, |tree, text, selection| { + let all_children = object::select_all_children(tree, text, selection.clone()); + + if selection.contains(&all_children) { + all_children + } else { + selection + } + }); }; cx.editor.apply_motion(motion); @@ -4787,19 +4810,10 @@ fn select_all_siblings(cx: &mut Context) { fn select_all_children(cx: &mut Context) { let motion = |editor: &mut Editor| { - let (view, doc) = current!(editor); - - if let Some(syntax) = doc.syntax() { - let text = doc.text().slice(..); - let current_selection = doc.selection(view.id); - let selection = - object::select_all_children(syntax.tree(), text, current_selection.clone()); - doc.set_selection(view.id, selection); - } + select_all_impl(editor, object::select_all_children); }; - motion(cx.editor); - cx.editor.last_motion = Some(Motion(Box::new(motion))); + cx.editor.apply_motion(motion); } fn match_brackets(cx: &mut Context) {