mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Wrap selection in siblings if reached boundary sibling
This commit is contained in:
parent
079f544260
commit
8ea52b33db
@ -42,11 +42,8 @@ pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selectio
|
|||||||
text,
|
text,
|
||||||
selection,
|
selection,
|
||||||
|cursor| {
|
|cursor| {
|
||||||
while !cursor.goto_next_sibling() {
|
cursor.goto_parent_until_has_siblings();
|
||||||
if !cursor.goto_parent() {
|
cursor.goto_next_sibling_or_wrap();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Some(Direction::Forward),
|
Some(Direction::Forward),
|
||||||
)
|
)
|
||||||
@ -98,11 +95,8 @@ pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: Selectio
|
|||||||
text,
|
text,
|
||||||
selection,
|
selection,
|
||||||
|cursor| {
|
|cursor| {
|
||||||
while !cursor.goto_prev_sibling() {
|
cursor.goto_parent_until_has_siblings();
|
||||||
if !cursor.goto_parent() {
|
cursor.goto_prev_sibling_or_wrap();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Some(Direction::Backward),
|
Some(Direction::Backward),
|
||||||
)
|
)
|
||||||
|
@ -103,6 +103,17 @@ pub fn goto_parent_with<P>(&mut self, predicate: P) -> bool
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn goto_parent_until_has_siblings(&mut self) {
|
||||||
|
while self.is_only_child() {
|
||||||
|
self.goto_parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if a cursor points to the node that is a child and has no siblings
|
||||||
|
pub fn is_only_child(&self) -> bool {
|
||||||
|
self.node().parent().is_some_and(|p| p.child_count() == 1)
|
||||||
|
}
|
||||||
|
|
||||||
/// Finds the injection layer that has exactly the same range as the given `range`.
|
/// 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> {
|
fn layer_id_of_byte_range(&self, search_range: Range<usize>) -> Option<LayerId> {
|
||||||
let start_idx = self
|
let start_idx = self
|
||||||
@ -146,6 +157,29 @@ pub fn goto_first_child(&mut self) -> bool {
|
|||||||
self.goto_first_child_impl(false)
|
self.goto_first_child_impl(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn goto_last_child(&mut self) -> bool {
|
||||||
|
// Check if the current node's range is an exact injection layer range.
|
||||||
|
if let Some(layer_id) = self
|
||||||
|
.layer_id_of_byte_range(self.node().byte_range())
|
||||||
|
.filter(|&layer_id| layer_id != self.current)
|
||||||
|
{
|
||||||
|
// Switch to the child layer.
|
||||||
|
self.current = layer_id;
|
||||||
|
self.cursor = self.layers[self.current].tree().root_node();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let child = self.cursor.children(&mut self.cursor.walk()).last();
|
||||||
|
|
||||||
|
if let Some(child) = child {
|
||||||
|
// Otherwise descend in the current tree.
|
||||||
|
self.cursor = child;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn goto_first_named_child(&mut self) -> bool {
|
pub fn goto_first_named_child(&mut self) -> bool {
|
||||||
self.goto_first_child_impl(true)
|
self.goto_first_child_impl(true)
|
||||||
}
|
}
|
||||||
@ -238,6 +272,30 @@ pub fn named_children(&'a mut self) -> ChildIter {
|
|||||||
named: true,
|
named: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn goto_first_sibling(&mut self) {
|
||||||
|
self.goto_parent();
|
||||||
|
self.goto_first_child();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn goto_last_sibling(&mut self) {
|
||||||
|
self.goto_parent();
|
||||||
|
self.goto_last_child();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn goto_next_sibling_or_wrap(&mut self) {
|
||||||
|
let went_to_next = self.goto_next_sibling();
|
||||||
|
if !went_to_next {
|
||||||
|
self.goto_first_sibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn goto_prev_sibling_or_wrap(&mut self) {
|
||||||
|
let went_to_prev = self.goto_prev_sibling();
|
||||||
|
if !went_to_prev {
|
||||||
|
self.goto_last_sibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChildIter<'n> {
|
pub struct ChildIter<'n> {
|
||||||
|
Loading…
Reference in New Issue
Block a user