Skip to content

Commit

Permalink
Include macro attributes to impls, structs, enums, functions etc. tex…
Browse files Browse the repository at this point in the history
…tobjects (helix-editor#2494)
  • Loading branch information
andreytkachenko authored and mtoohey31 committed Jun 15, 2022
1 parent 39cde45 commit aeec393
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 37 deletions.
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()
}
_ => 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

0 comments on commit aeec393

Please sign in to comment.