Skip to content

Commit

Permalink
Use new in-crate TreeCursor
Browse files Browse the repository at this point in the history
  • Loading branch information
dead10ck committed Apr 7, 2024
1 parent fcfcb50 commit 82d4c78
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 56 deletions.
67 changes: 17 additions & 50 deletions helix-core/src/object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{movement::Direction, syntax::TreeCursor, Range, RopeSlice, Selection, Syntax};
use tree_sitter::{Node, Tree};
use tree_sitter::Node;

pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
let cursor = &mut syntax.walk();
Expand Down Expand Up @@ -41,43 +41,29 @@ pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selectio
})
}

fn find_parent_with_more_children(mut node: Node) -> Option<Node> {
while let Some(parent) = node.parent() {
if parent.child_count() > 1 {
return Some(parent);
}

node = parent;
}

None
}

pub fn select_all_siblings(tree: &Tree, text: RopeSlice, selection: Selection) -> Selection {
let root_node = &tree.root_node();
pub fn select_all_siblings(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
let mut cursor = syntax.walk();

selection.transform_iter(|range| {
let from = text.char_to_byte(range.from());
let to = text.char_to_byte(range.to());
let fallback = || vec![range].into_iter();
let (from, to) = range.into_byte_range(text);
cursor.reset_to_byte_range(from, to);

root_node
.descendant_for_byte_range(from, to)
.and_then(find_parent_with_more_children)
.and_then(|parent| select_children(parent, text, range.direction()))
.unwrap_or_else(|| vec![range].into_iter())
if !cursor.goto_parent_with(|parent| parent.child_count() > 1) {
return fallback();
}

select_children(cursor.node(), text, range.direction()).unwrap_or_else(fallback)
})
}

pub fn select_all_children(tree: &Tree, text: RopeSlice, selection: Selection) -> Selection {
let root_node = &tree.root_node();
pub fn select_all_children(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
let mut cursor = syntax.walk();

selection.transform_iter(|range| {
let from = text.char_to_byte(range.from());
let to = text.char_to_byte(range.to());

root_node
.descendant_for_byte_range(from, to)
.and_then(|parent| select_children(parent, text, range.direction()))
let (from, to) = range.into_byte_range(text);
cursor.reset_to_byte_range(from, to);
select_children(cursor.node(), text, range.direction())
.unwrap_or_else(|| vec![range].into_iter())
})
}
Expand All @@ -91,16 +77,7 @@ fn select_children(

let children = node
.named_children(&mut cursor)
.map(|child| {
let from = text.byte_to_char(child.start_byte());
let to = text.byte_to_char(child.end_byte());

if direction == Direction::Backward {
Range::new(to, from)
} else {
Range::new(from, to)
}
})
.map(|child| Range::from_node(child, text, direction))
.collect::<Vec<_>>();

if !children.is_empty() {
Expand All @@ -110,16 +87,6 @@ fn select_children(
}
}

fn find_sibling_recursive<F>(node: Node, sibling_fn: F) -> Option<Node>
where
F: Fn(Node) -> Option<Node>,
{
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 {
select_node_impl(syntax, text, selection, |cursor| {
while !cursor.goto_prev_sibling() {
Expand Down
13 changes: 13 additions & 0 deletions helix-core/src/syntax/tree_cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ impl<'a> TreeCursor<'a> {
true
}

pub fn goto_parent_with<P>(&mut self, predicate: P) -> bool
where
P: Fn(&Node) -> bool,
{
while self.goto_parent() {
if predicate(&self.node()) {
return true;
}
}

false
}

/// Finds the injection layer that has exactly the same range as the given `range`.
fn layer_id_of_byte_range(&self, search_range: Range<usize>) -> Option<LayerId> {
let start_idx = self
Expand Down
11 changes: 5 additions & 6 deletions helix-term/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ use helix_core::{
syntax::{BlockCommentToken, LanguageServerFeature},
text_annotations::{Overlay, TextAnnotations},
textobject,
tree_sitter::Tree,
unicode::width::UnicodeWidthChar,
visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeGraphemes,
RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction,
RopeReader, RopeSlice, Selection, SmallVec, Syntax, Tendril, Transaction,
};
use helix_view::{
document::{FormatterError, Mode, SCRATCH_BUFFER_NAME},
Expand Down Expand Up @@ -4980,14 +4979,14 @@ pub fn extend_parent_node_start(cx: &mut Context) {

fn select_all_impl<F>(editor: &mut Editor, select_fn: F)
where
F: Fn(&Tree, RopeSlice, Selection) -> Selection,
F: Fn(&Syntax, 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());
let selection = select_fn(syntax, text, current_selection.clone());
doc.set_selection(view.id, selection);
}
}
Expand All @@ -5002,8 +5001,8 @@ fn select_all_siblings(cx: &mut Context) {

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());
select_all_impl(editor, |syntax, text, selection| {
let all_children = object::select_all_children(syntax, text, selection.clone());

if selection.contains(&all_children) {
all_children
Expand Down

0 comments on commit 82d4c78

Please sign in to comment.