-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(command): select all siblings and children #7445
feat(command): select all siblings and children #7445
Conversation
after trying this out for a bit I think |
Hmm, but in this case, the command would basically never do anything when the selection is just a cursor, or really any time you don't happen to have an entire node contained in the selection. But on the other hand, I could see this being useful for if you only want a subset of the children. I'll add a third command that does this. |
Just added |
e52d4c5
to
9bc49a0
Compare
9bc49a0
to
4086b3b
Compare
4086b3b
to
9104939
Compare
9104939
to
98a9e9b
Compare
98a9e9b
to
afd5c49
Compare
afd5c49
to
bd6214e
Compare
bd6214e
to
1302f26
Compare
1302f26
to
b0ad2cd
Compare
fef4927
to
24aeefe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Adapted to cross tree sitter injection layer like the othrr motions now do, the rest lgtm
helix-core/src/object.rs
Outdated
@@ -40,6 +41,85 @@ pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selectio | |||
}) | |||
} | |||
|
|||
fn find_parent_with_more_children(mut node: Node) -> Option<Node> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think thus also needs to be able to cross injection layer so I would use the new tree cursor here
Sounds good, will do |
24aeefe
to
82d4c78
Compare
Ok I've rebased and changed all the motions to use the new in-crate |
helix-core/src/syntax/tree_cursor.rs
Outdated
let found = match self.named { | ||
true => self.cursor.goto_first_named_child(), | ||
false => self.cursor.goto_first_child(), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let found = match self.named { | |
true => self.cursor.goto_first_named_child(), | |
false => self.cursor.goto_first_child(), | |
}; | |
let found = self.cursor.goto_first_child_impl(self.named); |
helix-core/src/syntax/tree_cursor.rs
Outdated
if !found { | ||
return None; | ||
} | ||
|
||
return Some(self.cursor.node()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
``
if !found { | |
return None; | |
} | |
return Some(self.cursor.node()); | |
return found.then_some(self.cursor.node()); |
helix-core/src/syntax/tree_cursor.rs
Outdated
let found = match self.named { | ||
true => self.cursor.goto_next_named_sibling(), | ||
false => self.cursor.goto_next_sibling(), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let found = match self.named { | |
true => self.cursor.goto_next_named_sibling(), | |
false => self.cursor.goto_next_sibling(), | |
}; | |
let found = if self.named { | |
self.cursor.goto_next_named_sibling() | |
} else | |
self.cursor.goto_next_sibling(), | |
}; |
I don't love matching on bools. Nothing really wrong with it but this is one of the "multiple ways to do the same things so always doing it the same way make code more consistent".
may be worth making named
a parameter (with an _impl` function) so you don't need the if else at all.
helix-core/src/syntax/tree_cursor.rs
Outdated
// subsequent iterations, keep visiting siblings until we run out | ||
if found { | ||
return Some(self.cursor.node()); | ||
} | ||
|
||
None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// subsequent iterations, keep visiting siblings until we run out | |
if found { | |
return Some(self.cursor.node()); | |
} | |
None | |
// subsequent iterations, keep visiting siblings until we run out | |
found.then_some(self.cursor.node()) |
helix-term/src/commands.rs
Outdated
if selection.contains(&all_children) { | ||
all_children | ||
} else { | ||
selection | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I am not sure this is quite what I had in mind here. If I can tell this right this would just not do anything as soon as any child is not in the selection. Instead I would like to see this be sort of like anl intersection. We should select the children covered by a selection.
In pseudo code all_chidren.retain(|range| selection.contains(range)
(just better implemented so its not O(n^2)
.
If this is too complex just omit this and I think I can implement this when solving #3007
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe I'll just leave it out for now
helix-core/src/object.rs
Outdated
if !children.is_empty() { | ||
Some(children.into_iter()) | ||
} else { | ||
None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every callsite has a fallback so lets just inline that code here to avoid duplication
if !children.is_empty() { | |
Some(children.into_iter()) | |
} else { | |
None | |
} | |
if children.is_empty() { | |
vec![fallback] | |
} else { | |
chidren | |
} |
helix-core/src/object.rs
Outdated
cursor: &'n mut TreeCursor<'n>, | ||
text: RopeSlice, | ||
direction: Direction, | ||
) -> Option<<Vec<Range> as std::iter::IntoIterator>::IntoIter> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just return a Vec and let the callsite call into_iter
or if you really want to return an iterator use an anonymous impl Iterator
instead this is a bit hard to read
7cdf1d4
to
77b7d94
Compare
Good suggestions, I took care of them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Sorry for throwing a wrench into this with the TreeCursor changes - thanks for rebasing and improving the TreeCursor while you were at it
I can finally stop splitting by commas inside a function call to select the arguments :) But it seems the docs weren't updated with the new |
This adds two new related commands:
select_all_siblings
Selects all siblings of the node under the cursor.
select_all_children
Selects all children of the node under the cursor.
select_all_children_in_selection
Selects all children of the node under the cursor, but only if the children are contained inside the starting selection.Edit: saving this one for a future PR