From 1a54b1794d1c6c619cecda296e36170a4a1278fd Mon Sep 17 00:00:00 2001 From: Quentin Boyer Date: Thu, 22 Jan 2026 01:15:51 +0100 Subject: [PATCH] Refactor to be able to pass a query --- crates/highlight/src/c_lib.rs | 2 +- crates/highlight/src/highlight.rs | 53 +++++++++++++++++-------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/crates/highlight/src/c_lib.rs b/crates/highlight/src/c_lib.rs index f21337bf..dd596ee2 100644 --- a/crates/highlight/src/c_lib.rs +++ b/crates/highlight/src/c_lib.rs @@ -297,7 +297,7 @@ impl TSHighlighter { }) }) }, - &|_| true, + &|_, _| true, ); if let Ok(highlights) = highlights { diff --git a/crates/highlight/src/highlight.rs b/crates/highlight/src/highlight.rs index eef83a8e..892370d6 100644 --- a/crates/highlight/src/highlight.rs +++ b/crates/highlight/src/highlight.rs @@ -165,7 +165,7 @@ struct LocalScope<'a> { struct HighlightIter<'a, F, G> where F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, - G: Fn(&(tree_sitter::QueryMatch<'a, 'a>, usize)) -> bool, + G: Fn(&QueryMatch, &Query) -> bool + 'a, { source: &'a [u8], language_name: &'a str, @@ -174,19 +174,16 @@ where injection_callback: F, capture_filter: &'a G, cancellation_flag: Option<&'a AtomicUsize>, - layers: Vec>, + layers: Vec>, iter_count: usize, next_event: Option, last_highlight_range: Option<(usize, usize, usize)>, } -struct HighlightIterLayer<'a, G> -where - G: Fn(&(tree_sitter::QueryMatch<'a, 'a>, usize)) -> bool, -{ +struct HighlightIterLayer<'a> { _tree: Tree, cursor: QueryCursor, - captures: iter::Peekable, &'a G>>, + captures: iter::Peekable, usize)> + 'a>>, config: &'a HighlightConfiguration, highlight_end_stack: Vec, scope_stack: Vec>, @@ -294,7 +291,7 @@ impl Highlighter { source: &'a [u8], cancellation_flag: Option<&'a AtomicUsize>, mut injection_callback: impl FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, - query_filter: &'a impl Fn(&(QueryMatch, usize)) -> bool, + query_filter: &'a impl Fn(&QueryMatch, &Query) -> bool, ) -> Result> + 'a, Error> { let layers = HighlightIterLayer::new( source, @@ -512,17 +509,17 @@ impl HighlightConfiguration { } } -impl<'a, G> HighlightIterLayer<'a, G> -where - G: Fn(&(tree_sitter::QueryMatch<'a, 'a>, usize)) -> bool, -{ +impl<'a> HighlightIterLayer<'a> { /// Create a new 'layer' of highlighting for this document. /// /// In the event that the new layer contains "combined injections" (injections where multiple /// disjoint ranges are parsed as one syntax tree), these will be eagerly processed and /// added to the returned vector. #[allow(clippy::too_many_arguments)] - fn new Option<&'a HighlightConfiguration> + 'a>( + fn new< + F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, + G: Fn(&QueryMatch, &Query) -> bool, + >( source: &'a [u8], parent_name: Option<&str>, highlighter: &mut Highlighter, @@ -615,13 +612,21 @@ where let cursor_ref = unsafe { mem::transmute::<&mut QueryCursor, &'static mut QueryCursor>(&mut cursor) }; + let captures = unsafe { - std::mem::transmute::, _QueryCaptures<_, _>>( - cursor_ref.captures(&config.query, tree_ref.root_node(), source), - ) - } - .filter(query_filter) - .peekable(); + std::mem::transmute::< + QueryCaptures<_, _>, + _QueryCaptures<'a, 'a, &'a [u8], &'a [u8]>, + >(cursor_ref.captures( + &config.query, + tree_ref.root_node(), + source, + )) + }; + + let captures: Box> = Box::new( + captures.filter(|(result, _): &(_, _)| query_filter(result, &config.query)), + ); result.push(HighlightIterLayer { highlight_end_stack: Vec::new(), @@ -633,7 +638,7 @@ where cursor, depth, _tree: tree, - captures, + captures: captures.peekable(), config, ranges, }); @@ -774,7 +779,7 @@ where impl<'a, F, G> HighlightIter<'a, F, G> where F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, - G: Fn(&(tree_sitter::QueryMatch<'a, 'a>, usize)) -> bool, + G: Fn(&QueryMatch, &Query) -> bool, { fn emit_event( &mut self, @@ -819,7 +824,7 @@ where } } - fn insert_layer(&mut self, mut layer: HighlightIterLayer<'a, G>) { + fn insert_layer(&mut self, mut layer: HighlightIterLayer<'a>) { if let Some(sort_key) = layer.sort_key() { let mut i = 1; while i < self.layers.len() { @@ -841,7 +846,7 @@ where impl<'a, F, G> Iterator for HighlightIter<'a, F, G> where F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, - G: Fn(&(tree_sitter::QueryMatch<'a, 'a>, usize)) -> bool, + G: Fn(&QueryMatch, &Query) -> bool, { type Item = Result; @@ -926,7 +931,7 @@ where // to the highlighted document. if let (Some(language_name), Some(content_node)) = (language_name, content_node) { if let Some(config) = (self.injection_callback)(language_name) { - let ranges = HighlightIterLayer::::intersect_ranges( + let ranges = HighlightIterLayer::intersect_ranges( &self.layers[0].ranges, &[content_node], include_children,