diff --git a/helix-syntax/src/injections_tree.rs b/helix-syntax/src/injections_tree.rs index fdc53e491..793039a38 100644 --- a/helix-syntax/src/injections_tree.rs +++ b/helix-syntax/src/injections_tree.rs @@ -4,9 +4,9 @@ use std::sync::Arc; use hashbrown::HashMap; use slotmap::{new_key_type, SlotMap}; -use tree_sitter::Tree; use crate::parse::LayerUpdateFlags; +use crate::tree_sitter::SyntaxTree; use crate::{HighlightConfiguration, RopeProvider}; // TODO(perf): replace std::ops::Range with helix_core::Range once added @@ -20,7 +20,7 @@ new_key_type! { #[derive(Debug)] pub struct LanguageLayer { pub config: Arc, - pub(crate) parse_tree: Option, + pub(crate) parse_tree: Option, /// internal flags used during parsing to track incremental invalidation pub(crate) flags: LayerUpdateFlags, pub(crate) parent: Option, diff --git a/helix-syntax/src/tree_sitter.rs b/helix-syntax/src/tree_sitter.rs index d75c5b245..c2aa6fad9 100644 --- a/helix-syntax/src/tree_sitter.rs +++ b/helix-syntax/src/tree_sitter.rs @@ -1,6 +1,7 @@ mod grammar; mod parser; mod query; +mod query_captures; mod ropey; mod syntax_tree; mod syntax_tree_node; diff --git a/helix-syntax/src/tree_sitter/query.rs b/helix-syntax/src/tree_sitter/query.rs index 26ae045e4..514b89908 100644 --- a/helix-syntax/src/tree_sitter/query.rs +++ b/helix-syntax/src/tree_sitter/query.rs @@ -4,6 +4,8 @@ use std::path::{Path, PathBuf}; use std::ptr::NonNull; use std::{slice, str}; +use regex_cursor::Cursor; + use crate::tree_sitter::query::predicate::{InvalidPredicateError, Predicate, TextPredicate}; use crate::tree_sitter::query::property::QueryProperty; use crate::tree_sitter::Grammar; @@ -155,6 +157,24 @@ impl Query { Ok(query) } + pub fn satsifies_text_predicate( + &self, + cursor: &mut regex_cursor::Input, + pattern: u32, + ) { + let text_predicates = self.patterns[pattern as usize].text_predicates; + let text_predicates = + &self.text_predicates[text_predicates.start as usize..text_predicates.end as usize]; + for predicate in text_predicates { + match predicate.kind { + predicate::TextPredicateKind::EqString(_) => todo!(), + predicate::TextPredicateKind::EqCapture(_) => todo!(), + predicate::TextPredicateKind::MatchString(_) => todo!(), + predicate::TextPredicateKind::AnyString(_) => todo!(), + } + } + } + // fn parse_predicates(&mut self) { // let pattern_count = unsafe { ts_query_pattern_count(self.raw) }; diff --git a/helix-syntax/src/tree_sitter/query_captures.rs b/helix-syntax/src/tree_sitter/query_captures.rs new file mode 100644 index 000000000..41a2c0938 --- /dev/null +++ b/helix-syntax/src/tree_sitter/query_captures.rs @@ -0,0 +1,66 @@ +use std::ptr::{self, NonNull}; + +use regex_cursor::Cursor; + +use crate::tree_sitter::query::Query; +use crate::tree_sitter::syntax_tree_node::SyntaxTreeNodeRaw; + +enum QueryCursorData {} + +pub struct QueryCaptures<'a> { + query: &'a Query, + query_cursor: &'a mut QueryCursorData, + text_cursor: regex_cursor::RopeyCursor<'a>, +} + +impl QueryCaptures<'_, C> { + fn next(&mut self) { + let mut query_match = TSQueryMatch { + id: 0, + pattern_index: 0, + capture_count: 0, + captures: ptr::null(), + }; + let mut capture_idx = 0; + loop { + let success = unsafe { + ts_query_cursor_next_capture( + &mut self.query_cursor, + &mut query_match, + &mut capture_idx, + ) + }; + if !success { + break; + } + } + let mut input = regex_cursor::Input::new(self.text_cursor.clone()); + } +} + +#[repr(C)] +#[derive(Debug)] +struct TSQueryCapture { + node: SyntaxTreeNodeRaw, + index: u32, +} + +#[repr(C)] +#[derive(Debug)] +struct TSQueryMatch { + id: u32, + pattern_index: u16, + capture_count: u16, + captures: *const TSQueryCapture, +} + +extern "C" { + /// Advance to the next capture of the currently running query. + /// If there is a capture, write its match to `*match` and its index within + /// the matche's capture list to `*capture_index`. Otherwise, return `false`. + fn ts_query_cursor_next_capture( + self_: &mut QueryCursorData, + match_: &mut TSQueryMatch, + capture_index: &mut u32, + ) -> bool; +}