|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
use crate::{syntax::TreeCursor, Range, RopeSlice, Selection, Syntax};
|
|
|
|
|
use crate::{movement::Direction, syntax::TreeCursor, Range, RopeSlice, Selection, Syntax};
|
|
|
|
|
use tree_sitter::{Node, Tree};
|
|
|
|
|
|
|
|
|
|
pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
|
|
|
|
|
let cursor = &mut syntax.walk();
|
|
|
|
@ -40,6 +41,65 @@ 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();
|
|
|
|
|
|
|
|
|
|
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(find_parent_with_more_children)
|
|
|
|
|
.map(|parent| select_children(parent, text, range.direction()))
|
|
|
|
|
.unwrap_or_else(|| vec![range].into_iter())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn select_children(
|
|
|
|
|
node: Node,
|
|
|
|
|
text: RopeSlice,
|
|
|
|
|
direction: Direction,
|
|
|
|
|
) -> <Vec<Range> as std::iter::IntoIterator>::IntoIter {
|
|
|
|
|
let mut cursor = node.walk();
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
|
.into_iter()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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() {
|
|
|
|
|