Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Include macro attributes to impls, structs, enums, functions etc. texobjects #2494

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ pub struct TextObjectQuery {
pub query: Query,
}

#[derive(Debug)]
pub enum CapturedNode<'a> {
Single(Node<'a>),
/// Guaranteed to be not empty
Expand Down Expand Up @@ -268,12 +269,12 @@ impl TextObjectQuery {
/// and support for this is partial and could use improvement.
///
/// ```query
/// ;; supported:
/// (comment)+ @capture
///
/// ;; unsupported:
/// ; OR
/// (
/// (comment)+
/// (comment)*
/// .
/// (function)
/// ) @capture
/// ```
Expand All @@ -299,28 +300,29 @@ impl TextObjectQuery {
let capture_idx = capture_names
.iter()
.find_map(|cap| self.query.capture_index_for_name(cap))?;
let captures = cursor.matches(&self.query, node, RopeProvider(slice));

let nodes = captures.flat_map(move |mat| {
let captures = mat.captures.iter().filter(move |c| c.index == capture_idx);
let nodes = captures.map(|c| c.node);
let pattern_idx = mat.pattern_index;
let quantifier = self.query.capture_quantifiers(pattern_idx)[capture_idx as usize];

let iter: Box<dyn Iterator<Item = CapturedNode>> = match quantifier {
CaptureQuantifier::OneOrMore | CaptureQuantifier::ZeroOrMore => {
let nodes: Vec<Node> = nodes.collect();
if nodes.is_empty() {
Box::new(std::iter::empty())
} else {
Box::new(std::iter::once(CapturedNode::Grouped(nodes)))
}

let nodes = cursor
.captures(&self.query, node, RopeProvider(slice))
.filter_map(move |(mat, _)| {
let nodes: Vec<_> = mat
.captures
.iter()
.filter_map(|x| {
if x.index == capture_idx {
Some(x.node)
} else {
None
}
})
.collect();

if nodes.len() > 1 {
Some(CapturedNode::Grouped(nodes))
} else {
nodes.into_iter().map(CapturedNode::Single).next()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First time I came across this pattern, looks interesting but I have to take a second look on this to know what it does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think CaptureNode should be refactored from enum to struct with SmallVec as nodes

}
_ => Box::new(nodes.map(CapturedNode::Single)),
};
});

iter
});
Some(nodes)
}
}
Expand Down Expand Up @@ -1122,8 +1124,8 @@ pub(crate) fn generate_edits(
use std::sync::atomic::{AtomicUsize, Ordering};
use std::{iter, mem, ops, str, usize};
use tree_sitter::{
CaptureQuantifier, Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor,
QueryError, QueryMatch, Range, TextProvider, Tree,
Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor, QueryError,
QueryMatch, Range, TextProvider, Tree,
};

const CANCELLATION_CHECK_INTERVAL: usize = 100;
Expand Down
63 changes: 51 additions & 12 deletions runtime/queries/rust/textobjects.scm
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
(function_item
body: (_) @function.inside) @function.around
(
[
(attribute_item)+
(line_comment)+
]*
.
(function_item
body: (_) @function.inside)) @function.around

(struct_item
body: (_) @class.inside) @class.around
(
[
(attribute_item)+
(line_comment)+
]*
.
(struct_item
body: (_) @class.inside)) @class.around

(enum_item
body: (_) @class.inside) @class.around
(
[
(attribute_item)+
(line_comment)+
]*
.
(enum_item
body: (_) @class.inside)) @class.around

(union_item
body: (_) @class.inside) @class.around
(
[
(attribute_item)+
(line_comment)+
]*
.
(union_item
body: (_) @class.inside)) @class.around

(trait_item
body: (_) @class.inside) @class.around
(
[
(attribute_item)+
(line_comment)+
]*
.
(trait_item
body: (_) @class.inside)) @class.around

(impl_item
body: (_) @class.inside) @class.around
(
[
(attribute_item)+
(line_comment)+
]*
.
(impl_item
body: (_) @class.inside)) @class.around

(parameters
(_) @parameter.inside)

(type_parameters
(_) @parameter.inside)

(closure_parameters
(_) @parameter.inside)
Expand Down