|
|
@ -234,6 +234,7 @@ pub struct TextObjectQuery {
|
|
|
|
pub query: Query,
|
|
|
|
pub query: Query,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum CapturedNode<'a> {
|
|
|
|
pub enum CapturedNode<'a> {
|
|
|
|
Single(Node<'a>),
|
|
|
|
Single(Node<'a>),
|
|
|
|
/// Guaranteed to be not empty
|
|
|
|
/// Guaranteed to be not empty
|
|
|
@ -268,12 +269,12 @@ impl TextObjectQuery {
|
|
|
|
/// and support for this is partial and could use improvement.
|
|
|
|
/// and support for this is partial and could use improvement.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// ```query
|
|
|
|
/// ```query
|
|
|
|
/// ;; supported:
|
|
|
|
|
|
|
|
/// (comment)+ @capture
|
|
|
|
/// (comment)+ @capture
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// ;; unsupported:
|
|
|
|
/// ; OR
|
|
|
|
/// (
|
|
|
|
/// (
|
|
|
|
/// (comment)+
|
|
|
|
/// (comment)*
|
|
|
|
|
|
|
|
/// .
|
|
|
|
/// (function)
|
|
|
|
/// (function)
|
|
|
|
/// ) @capture
|
|
|
|
/// ) @capture
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
@ -299,28 +300,29 @@ impl TextObjectQuery {
|
|
|
|
let capture_idx = capture_names
|
|
|
|
let capture_idx = capture_names
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.find_map(|cap| self.query.capture_index_for_name(cap))?;
|
|
|
|
.find_map(|cap| self.query.capture_index_for_name(cap))?;
|
|
|
|
let captures = cursor.matches(&self.query, node, RopeProvider(slice));
|
|
|
|
|
|
|
|
|
|
|
|
let nodes = cursor
|
|
|
|
let nodes = captures.flat_map(move |mat| {
|
|
|
|
.captures(&self.query, node, RopeProvider(slice))
|
|
|
|
let captures = mat.captures.iter().filter(move |c| c.index == capture_idx);
|
|
|
|
.filter_map(move |(mat, _)| {
|
|
|
|
let nodes = captures.map(|c| c.node);
|
|
|
|
let nodes: Vec<_> = mat
|
|
|
|
let pattern_idx = mat.pattern_index;
|
|
|
|
.captures
|
|
|
|
let quantifier = self.query.capture_quantifiers(pattern_idx)[capture_idx as usize];
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.filter_map(|x| {
|
|
|
|
let iter: Box<dyn Iterator<Item = CapturedNode>> = match quantifier {
|
|
|
|
if x.index == capture_idx {
|
|
|
|
CaptureQuantifier::OneOrMore | CaptureQuantifier::ZeroOrMore => {
|
|
|
|
Some(x.node)
|
|
|
|
let nodes: Vec<Node> = nodes.collect();
|
|
|
|
} else {
|
|
|
|
if nodes.is_empty() {
|
|
|
|
None
|
|
|
|
Box::new(std::iter::empty())
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
})
|
|
|
|
Box::new(std::iter::once(CapturedNode::Grouped(nodes)))
|
|
|
|
.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)
|
|
|
|
Some(nodes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1122,8 +1124,8 @@ pub(crate) fn generate_edits(
|
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
use std::{iter, mem, ops, str, usize};
|
|
|
|
use std::{iter, mem, ops, str, usize};
|
|
|
|
use tree_sitter::{
|
|
|
|
use tree_sitter::{
|
|
|
|
CaptureQuantifier, Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor,
|
|
|
|
Language as Grammar, Node, Parser, Point, Query, QueryCaptures, QueryCursor, QueryError,
|
|
|
|
QueryError, QueryMatch, Range, TextProvider, Tree,
|
|
|
|
QueryMatch, Range, TextProvider, Tree,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const CANCELLATION_CHECK_INTERVAL: usize = 100;
|
|
|
|
const CANCELLATION_CHECK_INTERVAL: usize = 100;
|
|
|
|