on master help sign in
Include macro attributes to impls, structs, enums, functions etc. textobjects (#2494)
62fd1f6Andrey Tkachenko
helix-core/src/syntax.rs+27−25
@@ -234,6 +234,7 @@ pub struct TextObjectQuery {
234 pub query: Query,
234 pub query: Query,
235}
235}
236
236
237+#[derive(Debug)]
237pub enum CapturedNode<'a> {
238pub enum CapturedNode<'a> {
238 Single(Node<'a>),
239 Single(Node<'a>),
239 /// Guaranteed to be not empty
240 /// Guaranteed to be not empty
@@ -268,12 +269,12 @@ impl TextObjectQuery {
268 /// and support for this is partial and could use improvement.
269 /// and support for this is partial and could use improvement.
269 ///
270 ///
270 /// ```query
271 /// ```query
271− /// ;; supported:
272 /// (comment)+ @capture
272 /// (comment)+ @capture
273 ///
273 ///
274− /// ;; unsupported:
274+ /// ; OR
275 /// (
275 /// (
276− /// (comment)+
276+ /// (comment)*
277+ /// .
277 /// (function)
278 /// (function)
278 /// ) @capture
279 /// ) @capture
279 /// ```
280 /// ```
@@ -299,28 +300,29 @@ impl TextObjectQuery {
299 let capture_idx = capture_names
300 let capture_idx = capture_names
300 .iter()
301 .iter()
301 .find_map(|cap| self.query.capture_index_for_name(cap))?;
302 .find_map(|cap| self.query.capture_index_for_name(cap))?;
303+
304+ let nodes = cursor
302− let captures = cursor.matches(&self.query, node, RopeProvider(slice));
305+ .captures(&self.query, node, RopeProvider(slice))
303−
306+ .filter_map(move |(mat, _)| {
304− let nodes = captures.flat_map(move |mat| {
307+ let nodes: Vec<_> = mat
308+ .captures
309+ .iter()
310+ .filter_map(|x| {
305− let captures = mat.captures.iter().filter(move |c| c.index == capture_idx);
311+ if x.index == capture_idx {
306− let nodes = captures.map(|c| c.node);
312+ Some(x.node)
307− let pattern_idx = mat.pattern_index;
313+ } else {
308− let quantifier = self.query.capture_quantifiers(pattern_idx)[capture_idx as usize];
314+ None
309−
315+ }
310− let iter: Box<dyn Iterator<Item = CapturedNode>> = match quantifier {
316+ })
311− CaptureQuantifier::OneOrMore | CaptureQuantifier::ZeroOrMore => {
312− let nodes: Vec<Node> = nodes.collect();
317+ .collect();
318+
313− if nodes.is_empty() {
319+ if nodes.len() > 1 {
314− Box::new(std::iter::empty())
315− } else {
316− Box::new(std::iter::once(CapturedNode::Grouped(nodes)))
320+ Some(CapturedNode::Grouped(nodes))
317− }
321+ } else {
322+ nodes.into_iter().map(CapturedNode::Single).next()
318 }
323 }
319− _ => Box::new(nodes.map(CapturedNode::Single)),
320− };
324+ });
321
325
322− iter
323− });
324 Some(nodes)
326 Some(nodes)
325 }
327 }
326}
328}
@@ -1122,8 +1124,8 @@ pub(crate) fn generate_edits(
1122use std::sync::atomic::{AtomicUsize, Ordering};
1124use std::sync::atomic::{AtomicUsize, Ordering};
1123use std::{iter, mem, ops, str, usize};
1125use std::{iter, mem, ops, str, usize};
1124use tree_sitter::{
1126use tree_sitter::{
1125− CaptureQuantifier, Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor,
1127+ Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor, QueryError,
1126− QueryError, QueryMatch, Range, TextProvider, Tree,
1128+ QueryMatch, Range, TextProvider, Tree,
1127};
1129};
1128
1130
1129const CANCELLATION_CHECK_INTERVAL: usize = 100;
1131const CANCELLATION_CHECK_INTERVAL: usize = 100;
runtime/queries/rust/textobjects.scm+51−12
@@ -1,23 +1,62 @@
1+(
2+ [
3+ (attribute_item)+
4+ (line_comment)+
5+ ]*
6+ .
1−(function_item
7+ (function_item
2− body: (_) @function.inside) @function.around
8+ body: (_) @function.inside)) @function.around
3
9
10+(
11+ [
12+ (attribute_item)+
13+ (line_comment)+
14+ ]*
15+ .
4−(struct_item
16+ (struct_item
5− body: (_) @class.inside) @class.around
17+ body: (_) @class.inside)) @class.around
6
18
19+(
20+ [
21+ (attribute_item)+
22+ (line_comment)+
23+ ]*
24+ .
7−(enum_item
25+ (enum_item
8− body: (_) @class.inside) @class.around
26+ body: (_) @class.inside)) @class.around
9
27
28+(
29+ [
30+ (attribute_item)+
31+ (line_comment)+
32+ ]*
33+ .
10−(union_item
34+ (union_item
11− body: (_) @class.inside) @class.around
35+ body: (_) @class.inside)) @class.around
12
36
37+(
38+ [
39+ (attribute_item)+
40+ (line_comment)+
41+ ]*
42+ .
13−(trait_item
43+ (trait_item
14− body: (_) @class.inside) @class.around
44+ body: (_) @class.inside)) @class.around
15
45
46+(
47+ [
48+ (attribute_item)+
49+ (line_comment)+
50+ ]*
51+ .
16−(impl_item
52+ (impl_item
17− body: (_) @class.inside) @class.around
53+ body: (_) @class.inside)) @class.around
18
54
19(parameters
55(parameters
20 (_) @parameter.inside)
56 (_) @parameter.inside)
57+
58+(type_parameters
59+ (_) @parameter.inside)
21
60
22(closure_parameters
61(closure_parameters
23 (_) @parameter.inside)
62 (_) @parameter.inside)