Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-syntax/src/tree_sitter/query/predicate.rs')
-rw-r--r--helix-syntax/src/tree_sitter/query/predicate.rs57
1 files changed, 48 insertions, 9 deletions
diff --git a/helix-syntax/src/tree_sitter/query/predicate.rs b/helix-syntax/src/tree_sitter/query/predicate.rs
index 7a2f858e..91f3dabe 100644
--- a/helix-syntax/src/tree_sitter/query/predicate.rs
+++ b/helix-syntax/src/tree_sitter/query/predicate.rs
@@ -5,7 +5,9 @@ use std::ptr::NonNull;
use std::{fmt, slice};
use crate::tree_sitter::query::property::QueryProperty;
-use crate::tree_sitter::query::{Capture, Pattern, PatternData, Query, QueryData, QueryStr};
+use crate::tree_sitter::query::{
+ Capture, Pattern, PatternData, Query, QueryData, QueryStr, UserPredicate,
+};
use crate::tree_sitter::query_cursor::MatchedNode;
use crate::tree_sitter::TsInput;
@@ -34,6 +36,7 @@ pub(super) enum TextPredicateKind {
AnyString(Box<[QueryStr]>),
}
+#[derive(Debug)]
pub(crate) struct TextPredicate {
capture: Capture,
kind: TextPredicateKind,
@@ -161,10 +164,9 @@ impl Query {
pub(super) fn parse_pattern_predicates(
&mut self,
pattern: Pattern,
- mut custom_predicate: impl FnMut(Pattern, Predicate) -> Result<(), InvalidPredicateError>,
+ mut custom_predicate: impl FnMut(Pattern, UserPredicate) -> Result<(), InvalidPredicateError>,
) -> Result<PatternData, InvalidPredicateError> {
let text_predicate_start = self.text_predicates.len() as u32;
- let property_start = self.properties.len() as u32;
let predicate_steps = unsafe {
let mut len = 0u32;
@@ -203,7 +205,7 @@ impl Query {
"match?" | "not-match?" | "any-match?" | "any-not-match?" => {
predicate.check_arg_count(2)?;
let capture_idx = predicate.capture_arg(0)?;
- let regex = predicate.str_arg(1)?.get(self);
+ let regex = predicate.query_str_arg(1)?.get(self);
let negated = matches!(predicate.name(), "not-match?" | "any-not-match?");
let match_all = matches!(predicate.name(), "match?" | "not-match?");
@@ -219,14 +221,34 @@ impl Query {
});
}
- "set!" => self.properties.push(QueryProperty::parse(&predicate)?),
+ "set!" => {
+ let property = QueryProperty::parse(&predicate)?;
+ custom_predicate(
+ pattern,
+ UserPredicate::SetProperty {
+ key: property.key.get(&self),
+ val: property.val.map(|val| val.get(&self)),
+ },
+ )?
+ }
+ "is-not?" | "is?" => {
+ let property = QueryProperty::parse(&predicate)?;
+ custom_predicate(
+ pattern,
+ UserPredicate::IsPropertySet {
+ negate: predicate.name() == "is-not?",
+ key: property.key.get(&self),
+ val: property.val.map(|val| val.get(&self)),
+ },
+ )?
+ }
"any-of?" | "not-any-of?" => {
predicate.check_min_arg_count(1)?;
let capture = predicate.capture_arg(0)?;
let negated = predicate.name() == "not-any-of?";
let values: Result<_, InvalidPredicateError> = (1..predicate.num_args())
- .map(|i| predicate.str_arg(i))
+ .map(|i| predicate.query_str_arg(i))
.collect();
self.text_predicates.push(TextPredicate {
capture,
@@ -239,12 +261,11 @@ impl Query {
// is and is-not are better handeled as custom predicates since interpreting is context dependent
// "is?" => property_predicates.push((QueryProperty::parse(&predicate), false)),
// "is-not?" => property_predicates.push((QueryProperty::parse(&predicate), true)),
- _ => custom_predicate(pattern, predicate)?,
+ _ => custom_predicate(pattern, UserPredicate::Other(predicate))?,
}
}
Ok(PatternData {
text_predicates: text_predicate_start..self.text_predicates.len() as u32,
- properties: property_start..self.properties.len() as u32,
})
}
}
@@ -312,7 +333,7 @@ impl<'a> Predicate<'a> {
Ok(())
}
- pub fn str_arg(&self, i: usize) -> Result<QueryStr, InvalidPredicateError> {
+ pub fn query_str_arg(&self, i: usize) -> Result<QueryStr, InvalidPredicateError> {
match self.arg(i) {
PredicateArg::String(str) => Ok(str),
PredicateArg::Capture(capture) => bail!(
@@ -323,6 +344,10 @@ impl<'a> Predicate<'a> {
}
}
+ pub fn str_arg(&self, i: usize) -> Result<&str, InvalidPredicateError> {
+ Ok(self.query_str_arg(i)?.get(self.query))
+ }
+
pub fn num_args(&self) -> usize {
self.args.len()
}
@@ -352,6 +377,20 @@ pub struct InvalidPredicateError {
pub(super) msg: Box<str>,
}
+impl From<String> for InvalidPredicateError {
+ fn from(value: String) -> Self {
+ InvalidPredicateError {
+ msg: value.into_boxed_str(),
+ }
+ }
+}
+
+impl<'a> From<&'a str> for InvalidPredicateError {
+ fn from(value: &'a str) -> Self {
+ InvalidPredicateError { msg: value.into() }
+ }
+}
+
impl fmt::Display for InvalidPredicateError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.msg)