From 855a0dee0d945b496b72f703735020791d420d1c Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 12 Jan 2022 09:02:35 -0600 Subject: [PATCH 1/9] add select_next_sibling and select_prev_sibling commands --- helix-core/src/object.rs | 65 ++++++++++++++++++++++++++++++++++++++ helix-term/src/commands.rs | 36 +++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index 3363e20bcc04..09ea8d958cfc 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -1,4 +1,5 @@ use crate::{Range, RopeSlice, Selection, Syntax}; +use tree_sitter::Node; pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { let tree = syntax.tree(); @@ -59,3 +60,67 @@ pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) } }) } + +pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { + let tree = syntax.tree(); + + selection.clone().transform(|range| { + let from = text.char_to_byte(range.from()); + let to = text.char_to_byte(range.to()); + + let sibling = match tree + .root_node() + .descendant_for_byte_range(from, to) + .and_then(find_next_sibling) + { + Some(sibling) => sibling, + None => return range, + }; + + let from = text.byte_to_char(sibling.start_byte()); + let to = text.byte_to_char(sibling.end_byte()); + + if range.head < range.anchor { + Range::new(to, from) + } else { + Range::new(from, to) + } + }) +} + +fn find_next_sibling(node: Node) -> Option { + node.next_sibling() + .or_else(|| node.parent().and_then(find_next_sibling)) +} + +pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { + let tree = syntax.tree(); + + selection.clone().transform(|range| { + let from = text.char_to_byte(range.from()); + let to = text.char_to_byte(range.to()); + + let sibling = match tree + .root_node() + .descendant_for_byte_range(from, to) + .and_then(find_prev_sibling) + { + Some(sibling) => sibling, + None => return range, + }; + + let from = text.byte_to_char(sibling.start_byte()); + let to = text.byte_to_char(sibling.end_byte()); + + if range.head < range.anchor { + Range::new(to, from) + } else { + Range::new(from, to) + } + }) +} + +fn find_prev_sibling(node: Node) -> Option { + node.prev_sibling() + .or_else(|| node.parent().and_then(find_prev_sibling)) +} diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 5c26a5b2a5f5..95f21d99b944 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -363,6 +363,8 @@ impl MappableCommand { 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", + select_next_sibling, "Select the next sibling in the syntax tree", + select_prev_sibling, "Select the previous sibling in the syntax tree", jump_forward, "Jump forward on jumplist", jump_backward, "Jump backward on jumplist", save_selection, "Save the current selection to the jumplist", @@ -5524,6 +5526,40 @@ fn shrink_selection(cx: &mut Context) { cx.editor.last_motion = Some(Motion(Box::new(motion))); } +fn select_next_sibling(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_next_sibling(syntax, text, current_selection); + doc.set_selection(view.id, selection); + } + }; + motion(cx.editor); + cx.editor.last_motion = Some(Motion(Box::new(motion))); +} + +fn select_prev_sibling(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_prev_sibling(syntax, text, current_selection); + doc.set_selection(view.id, selection); + } + }; + motion(cx.editor); + cx.editor.last_motion = Some(Motion(Box::new(motion))); +} + fn match_brackets(cx: &mut Context) { let (view, doc) = current!(cx.editor); From 7f5610439b9de14e99fa7726d4516397359d48de Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 13 Jan 2022 10:32:25 -0600 Subject: [PATCH 2/9] refactor objects to use higher order functions --- helix-core/src/object.rs | 121 +++++++++++---------------------------- 1 file changed, 35 insertions(+), 86 deletions(-) diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index 09ea8d958cfc..e0c6502e3021 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -2,115 +2,69 @@ use crate::{Range, RopeSlice, Selection, Syntax}; use tree_sitter::Node; pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { - let tree = syntax.tree(); - - selection.clone().transform(|range| { - let from = text.char_to_byte(range.from()); - let to = text.char_to_byte(range.to()); - - // find parent of a descendant that matches the range - let parent = match tree - .root_node() - .descendant_for_byte_range(from, to) - .and_then(|node| { - if node.start_byte() == from && node.end_byte() == to { - node.parent() - } else { - Some(node) - } - }) { - Some(parent) => parent, - None => return range, - }; - - let from = text.byte_to_char(parent.start_byte()); - let to = text.byte_to_char(parent.end_byte()); - - if range.head < range.anchor { - Range::new(to, from) + select_node_impl(syntax, text, selection, |descendant, from, to| { + if descendant.start_byte() == from && descendant.end_byte() == to { + descendant.parent() } else { - Range::new(from, to) + Some(descendant) } }) } pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { - let tree = syntax.tree(); - - selection.clone().transform(|range| { - let from = text.char_to_byte(range.from()); - let to = text.char_to_byte(range.to()); - - let descendant = match tree.root_node().descendant_for_byte_range(from, to) { - // find first child, if not possible, fallback to the node that contains selection - Some(descendant) => match descendant.child(0) { - Some(child) => child, - None => descendant, - }, - None => return range, - }; - - let from = text.byte_to_char(descendant.start_byte()); - let to = text.byte_to_char(descendant.end_byte()); - - if range.head < range.anchor { - Range::new(to, from) - } else { - Range::new(from, to) - } + select_node_impl(syntax, text, selection, |descendant, _from, _to| { + descendant.child(0).or_else(|| Some(descendant)) }) } pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { - let tree = syntax.tree(); - - selection.clone().transform(|range| { - let from = text.char_to_byte(range.from()); - let to = text.char_to_byte(range.to()); - - let sibling = match tree - .root_node() - .descendant_for_byte_range(from, to) - .and_then(find_next_sibling) - { - Some(sibling) => sibling, - None => return range, - }; - - let from = text.byte_to_char(sibling.start_byte()); - let to = text.byte_to_char(sibling.end_byte()); + select_node_impl(syntax, text, selection, |descendant, _from, _to| { + find_sibling_recursive(descendant, |node| node.next_sibling()) + }) +} - if range.head < range.anchor { - Range::new(to, from) - } else { - Range::new(from, to) - } +pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { + select_node_impl(syntax, text, selection, |descendant, _from, _to| { + find_sibling_recursive(descendant, |node| node.prev_sibling()) }) } -fn find_next_sibling(node: Node) -> Option { - node.next_sibling() - .or_else(|| node.parent().and_then(find_next_sibling)) +fn find_sibling_recursive(node: Node, sibling_fn: F) -> Option +where + F: Fn(Node) -> Option, +{ + sibling_fn(node).or_else(|| { + node.parent() + .and_then(|node| find_sibling_recursive(node, sibling_fn)) + }) } -pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { +fn select_node_impl( + syntax: &Syntax, + text: RopeSlice, + selection: &Selection, + select_fn: F, +) -> Selection +where + F: Fn(Node, usize, usize) -> Option, +{ let tree = syntax.tree(); selection.clone().transform(|range| { let from = text.char_to_byte(range.from()); let to = text.char_to_byte(range.to()); - let sibling = match tree + let node = match tree .root_node() .descendant_for_byte_range(from, to) - .and_then(find_prev_sibling) + .and_then(|node| select_fn(node, from, to)) { - Some(sibling) => sibling, + Some(node) => node, None => return range, }; - let from = text.byte_to_char(sibling.start_byte()); - let to = text.byte_to_char(sibling.end_byte()); + let from = text.byte_to_char(node.start_byte()); + let to = text.byte_to_char(node.end_byte()); if range.head < range.anchor { Range::new(to, from) @@ -119,8 +73,3 @@ pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selecti } }) } - -fn find_prev_sibling(node: Node) -> Option { - node.prev_sibling() - .or_else(|| node.parent().and_then(find_prev_sibling)) -} From 807b64f01e6f99dbc090645dd045e394f9fc115c Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 13 Jan 2022 10:37:47 -0600 Subject: [PATCH 3/9] address clippy feedback --- helix-core/src/object.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index e0c6502e3021..99cc97646365 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -13,7 +13,7 @@ pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { select_node_impl(syntax, text, selection, |descendant, _from, _to| { - descendant.child(0).or_else(|| Some(descendant)) + descendant.child(0).or(Some(descendant)) }) } From 0c74d4efcd636a10f26809d2a4c7b3120b0b68f4 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 14 Jan 2022 09:39:07 -0600 Subject: [PATCH 4/9] move selection cloning into commands --- helix-core/src/object.rs | 12 ++++++------ helix-term/src/commands.rs | 12 ++++-------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index 99cc97646365..f2f3475e4607 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -1,7 +1,7 @@ use crate::{Range, RopeSlice, Selection, Syntax}; use tree_sitter::Node; -pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { +pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection { select_node_impl(syntax, text, selection, |descendant, from, to| { if descendant.start_byte() == from && descendant.end_byte() == to { descendant.parent() @@ -11,19 +11,19 @@ pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) }) } -pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { +pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection { select_node_impl(syntax, text, selection, |descendant, _from, _to| { descendant.child(0).or(Some(descendant)) }) } -pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { +pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection { select_node_impl(syntax, text, selection, |descendant, _from, _to| { find_sibling_recursive(descendant, |node| node.next_sibling()) }) } -pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { +pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection { select_node_impl(syntax, text, selection, |descendant, _from, _to| { find_sibling_recursive(descendant, |node| node.prev_sibling()) }) @@ -42,7 +42,7 @@ where fn select_node_impl( syntax: &Syntax, text: RopeSlice, - selection: &Selection, + selection: Selection, select_fn: F, ) -> Selection where @@ -50,7 +50,7 @@ where { let tree = syntax.tree(); - selection.clone().transform(|range| { + selection.transform(|range| { let from = text.char_to_byte(range.from()); let to = text.char_to_byte(range.to()); diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 95f21d99b944..0e77151c02bd 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5492,7 +5492,7 @@ fn expand_selection(cx: &mut Context) { // 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); + let selection = object::expand_selection(syntax, text, current_selection.clone()); doc.set_selection(view.id, selection); } }; @@ -5518,7 +5518,7 @@ fn shrink_selection(cx: &mut Context) { // 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); + let selection = object::shrink_selection(syntax, text, current_selection.clone()); doc.set_selection(view.id, selection); } }; @@ -5532,10 +5532,8 @@ fn select_next_sibling(cx: &mut Context) { if let Some(syntax) = doc.syntax() { let text = doc.text().slice(..); - let current_selection = doc.selection(view.id); - - let selection = object::select_next_sibling(syntax, text, current_selection); + let selection = object::select_next_sibling(syntax, text, current_selection.clone()); doc.set_selection(view.id, selection); } }; @@ -5549,10 +5547,8 @@ fn select_prev_sibling(cx: &mut Context) { if let Some(syntax) = doc.syntax() { let text = doc.text().slice(..); - let current_selection = doc.selection(view.id); - - let selection = object::select_prev_sibling(syntax, text, current_selection); + let selection = object::select_prev_sibling(syntax, text, current_selection.clone()); doc.set_selection(view.id, selection); } }; From d1df47ff3cba7316ba849879ea14d5cc88546d7f Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 14 Jan 2022 09:42:12 -0600 Subject: [PATCH 5/9] add default keybindings under left/right brackets --- helix-term/src/keymap.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 49f8469a1f7d..79b92b54be01 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -570,12 +570,14 @@ impl Default for Keymaps { "D" => goto_first_diag, "space" => add_newline_above, "o" => shrink_selection, + "s" => select_prev_sibling, }, "]" => { "Right bracket" "d" => goto_next_diag, "D" => goto_last_diag, "space" => add_newline_below, "o" => expand_selection, + "s" => select_next_sibling, }, "/" => search, From 5549acdc7220f2d9341e6f0f958b9ea6226d7982 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 14 Jan 2022 10:03:39 -0600 Subject: [PATCH 6/9] use [+t,]+t for selecting sibling syntax nodes --- helix-term/src/keymap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 79b92b54be01..e5167e91e756 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -570,14 +570,14 @@ impl Default for Keymaps { "D" => goto_first_diag, "space" => add_newline_above, "o" => shrink_selection, - "s" => select_prev_sibling, + "t" => select_prev_sibling, }, "]" => { "Right bracket" "d" => goto_next_diag, "D" => goto_last_diag, "space" => add_newline_below, "o" => expand_selection, - "s" => select_next_sibling, + "t" => select_next_sibling, }, "/" => search, From 198600cd79806cb487e3a34da51ee2f5a659cdb5 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sat, 15 Jan 2022 20:14:01 -0600 Subject: [PATCH 7/9] setup Alt-{j,k,h,l} default keymaps for syntax selection commands --- book/src/keymap.md | 6 ++++-- helix-term/src/keymap.rs | 9 +++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 70ec13b32c2e..1d8eb55ba1b5 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -118,6 +118,10 @@ | `Alt-K` | Remove selections matching the regex | `remove_selections` | | `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` | | `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | +| `Alt-k` | Expand selection to parent syntax node | `expand_selection` | +| `Alt-j` | Shrink syntax tree object selection | `shrink_selection` | +| `Alt-h` | Select previous sibling node in syntax tree | `select_prev_sibling` | +| `Alt-l` | Select next sibling node in syntax tree | `select_next_sibling` | ### Search @@ -261,8 +265,6 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire | `]D` | Go to last diagnostic in document (**LSP**) | `goto_last_diag` | | `[space` | Add newline above | `add_newline_above` | | `]space` | Add newline below | `add_newline_below` | -| `]o` | Expand syntax tree object selection. | `expand_selection` | -| `[o` | Shrink syntax tree object selection. | `shrink_selection` | ## Insert Mode diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index e5167e91e756..6f1d8af5d32d 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -552,6 +552,11 @@ impl Default for Keymaps { "S" => split_selection, ";" => collapse_selection, "A-;" => flip_selections, + "A-k" => expand_selection, + "A-j" => shrink_selection, + "A-h" => select_prev_sibling, + "A-l" => select_next_sibling, + "%" => select_all, "x" => extend_line, "X" => extend_to_line_bounds, @@ -569,15 +574,11 @@ impl Default for Keymaps { "d" => goto_prev_diag, "D" => goto_first_diag, "space" => add_newline_above, - "o" => shrink_selection, - "t" => select_prev_sibling, }, "]" => { "Right bracket" "d" => goto_next_diag, "D" => goto_last_diag, "space" => add_newline_below, - "o" => expand_selection, - "t" => select_next_sibling, }, "/" => search, From b337a5bca41e5720f5730568211407b98e14cb00 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sat, 15 Jan 2022 20:41:39 -0600 Subject: [PATCH 8/9] reduce boilerplate of select_next/prev_sibling in commands --- helix-core/src/object.rs | 18 ++++++++++-------- helix-term/src/commands.rs | 29 +++++++++++++++-------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index f2f3475e4607..b06f4144459b 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -17,15 +17,17 @@ pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) }) } -pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection { - select_node_impl(syntax, text, selection, |descendant, _from, _to| { - find_sibling_recursive(descendant, |node| node.next_sibling()) - }) -} - -pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection { +pub fn select_sibling( + syntax: &Syntax, + text: RopeSlice, + selection: Selection, + sibling_fn: &F, +) -> Selection +where + F: Fn(Node) -> Option, +{ select_node_impl(syntax, text, selection, |descendant, _from, _to| { - find_sibling_recursive(descendant, |node| node.prev_sibling()) + find_sibling_recursive(descendant, sibling_fn) }) } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 0e77151c02bd..b6077832326f 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5526,14 +5526,18 @@ fn shrink_selection(cx: &mut Context) { cx.editor.last_motion = Some(Motion(Box::new(motion))); } -fn select_next_sibling(cx: &mut Context) { +fn select_sibling_impl(cx: &mut Context, sibling_fn: &'static F) +where + F: Fn(helix_core::tree_sitter::Node) -> Option, +{ 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_next_sibling(syntax, text, current_selection.clone()); + let selection = + object::select_sibling(syntax, text, current_selection.clone(), sibling_fn); doc.set_selection(view.id, selection); } }; @@ -5541,19 +5545,16 @@ fn select_next_sibling(cx: &mut Context) { cx.editor.last_motion = Some(Motion(Box::new(motion))); } -fn select_prev_sibling(cx: &mut Context) { - let motion = |editor: &mut Editor| { - let (view, doc) = current!(editor); +fn select_next_sibling(cx: &mut Context) { + select_sibling_impl(cx, &|node| { + helix_core::tree_sitter::Node::next_sibling(&node) + }) +} - if let Some(syntax) = doc.syntax() { - let text = doc.text().slice(..); - let current_selection = doc.selection(view.id); - let selection = object::select_prev_sibling(syntax, text, current_selection.clone()); - doc.set_selection(view.id, selection); - } - }; - motion(cx.editor); - cx.editor.last_motion = Some(Motion(Box::new(motion))); +fn select_prev_sibling(cx: &mut Context) { + select_sibling_impl(cx, &|node| { + helix_core::tree_sitter::Node::prev_sibling(&node) + }) } fn match_brackets(cx: &mut Context) { From 1ce524b369264105802d0b0fdc4582288216db98 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sat, 15 Jan 2022 20:43:37 -0600 Subject: [PATCH 9/9] import tree-sitter Node type in commands --- helix-term/src/commands.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index b6077832326f..e23f562178d1 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -11,6 +11,7 @@ use helix_core::{ object, pos_at_coords, regex::{self, Regex, RegexBuilder}, search, selection, shellwords, surround, textobject, + tree_sitter::Node, unicode::width::UnicodeWidthChar, LineEnding, Position, Range, Rope, RopeGraphemes, RopeSlice, Selection, SmallVec, Tendril, Transaction, @@ -5528,7 +5529,7 @@ fn shrink_selection(cx: &mut Context) { fn select_sibling_impl(cx: &mut Context, sibling_fn: &'static F) where - F: Fn(helix_core::tree_sitter::Node) -> Option, + F: Fn(Node) -> Option, { let motion = |editor: &mut Editor| { let (view, doc) = current!(editor); @@ -5546,15 +5547,11 @@ where } fn select_next_sibling(cx: &mut Context) { - select_sibling_impl(cx, &|node| { - helix_core::tree_sitter::Node::next_sibling(&node) - }) + select_sibling_impl(cx, &|node| Node::next_sibling(&node)) } fn select_prev_sibling(cx: &mut Context) { - select_sibling_impl(cx, &|node| { - helix_core::tree_sitter::Node::prev_sibling(&node) - }) + select_sibling_impl(cx, &|node| Node::prev_sibling(&node)) } fn match_brackets(cx: &mut Context) {