@@ -234,7 +234,6 @@ impl Syntax {
234234 /// Iterate over the highlighted regions for a given slice of source code.
235235 pub fn highlight_iter<'a>(
236236 &self,
237− ts_parser: &'a mut TSParser,
238237 source: &'a [u8],
239238 range: Option<std::ops::Range<usize>>,
240239 cancellation_flag: Option<&'a AtomicUsize>,
@@ -288,7 +287,6 @@ impl Syntax {
288287 byte_offset: range.map(|r| r.start).unwrap_or(0), // TODO: simplify
289288 injection_callback,
290289 cancellation_flag,
291− highlighter: ts_parser,
292290 iter_count: 0,
293291 layers: vec![layer],
294292 next_event: None,
@@ -659,7 +657,6 @@ where
659657{
660658 source: &'a [u8],
661659 byte_offset: usize,
662− highlighter: &'a mut TSParser,
663660 injection_callback: F,
664661 cancellation_flag: Option<&'a AtomicUsize>,
665662 layers: Vec<HighlightIterLayer<'a>>,
@@ -846,7 +843,6 @@ impl<'a> HighlightIterLayer<'a> {
846843 /// added to the returned vector.
847844 fn new<F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a>(
848845 source: &'a [u8],
849− highlighter: &mut TSParser,
850846 cancellation_flag: Option<&'a AtomicUsize>,
851847 injection_callback: &mut F,
852848 mut config: &'a HighlightConfiguration,
@@ -858,86 +854,103 @@ impl<'a> HighlightIterLayer<'a> {
858854 loop {
859855 // --> Tree parsing part
860856
861− if highlighter.parser.set_included_ranges(&ranges).is_ok() {
862− highlighter
863− .parser
864− .set_language(config.language)
865− .map_err(|_| Error::InvalidLanguage)?;
866−
867− unsafe { highlighter.parser.set_cancellation_flag(cancellation_flag) };
868− let tree = highlighter
869− .parser
870− .parse(source, None)
871− .ok_or(Error::Cancelled)?;
872− unsafe { highlighter.parser.set_cancellation_flag(None) };
873− let mut cursor = highlighter.cursors.pop().unwrap_or_else(QueryCursor::new);
874−
875− // Process combined injections.
876− if let Some(combined_injections_query) = &config.combined_injections_query {
877− let mut injections_by_pattern_index =
878− vec![(None, Vec::new(), false); combined_injections_query.pattern_count()];
879− let matches =
880− cursor.matches(combined_injections_query, tree.root_node(), |n: Node| {
881− &source[n.byte_range()]
882− });
883− for mat in matches {
884− let entry = &mut injections_by_pattern_index[mat.pattern_index];
885− let (language_name, content_node, include_children) =
886− injection_for_match(config, combined_injections_query, &mat, source);
887− if language_name.is_some() {
888− entry.0 = language_name;
889− }
890− if let Some(content_node) = content_node {
891− entry.1.push(content_node);
892− }
893− entry.2 = include_children;
894− }
895− for (lang_name, content_nodes, includes_children) in injections_by_pattern_index
896− {
897− if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty()) {
898− if let Some(next_config) = (injection_callback)(lang_name) {
899− let ranges = Self::intersect_ranges(
900− &ranges,
901− &content_nodes,
902− includes_children,
857+ PARSER.with(|ts_parser| {
858+ let highlighter = &mut ts_parser.borrow_mut();
859+
860+ if highlighter.parser.set_included_ranges(&ranges).is_ok() {
861+ highlighter
862+ .parser
863+ .set_language(config.language)
864+ .map_err(|_| Error::InvalidLanguage)?;
865+
866+ unsafe { highlighter.parser.set_cancellation_flag(cancellation_flag) };
867+ let tree = highlighter
868+ .parser
869+ .parse(source, None)
870+ .ok_or(Error::Cancelled)?;
871+ unsafe { highlighter.parser.set_cancellation_flag(None) };
872+ let mut cursor = highlighter.cursors.pop().unwrap_or_else(QueryCursor::new);
873+
874+ // Process combined injections.
875+ if let Some(combined_injections_query) = &config.combined_injections_query {
876+ let mut injections_by_pattern_index = vec![
877+ (None, Vec::new(), false);
878+ combined_injections_query
879+ .pattern_count()
880+ ];
881+ let matches = cursor.matches(
882+ combined_injections_query,
883+ tree.root_node(),
884+ |n: Node| &source[n.byte_range()],
885+ );
886+ for mat in matches {
887+ let entry = &mut injections_by_pattern_index[mat.pattern_index];
888+ let (language_name, content_node, include_children) =
889+ injection_for_match(
890+ config,
891+ combined_injections_query,
892+ &mat,
893+ source,
903894 );
904− if !ranges.is_empty() {
905− queue.push((next_config, depth + 1, ranges));
895+ if language_name.is_some() {
896+ entry.0 = language_name;
897+ }
898+ if let Some(content_node) = content_node {
899+ entry.1.push(content_node);
900+ }
901+ entry.2 = include_children;
902+ }
903+ for (lang_name, content_nodes, includes_children) in
904+ injections_by_pattern_index
905+ {
906+ if let (Some(lang_name), false) = (lang_name, content_nodes.is_empty())
907+ {
908+ if let Some(next_config) = (injection_callback)(lang_name) {
909+ let ranges = Self::intersect_ranges(
910+ &ranges,
911+ &content_nodes,
912+ includes_children,
913+ );
914+ if !ranges.is_empty() {
915+ queue.push((next_config, depth + 1, ranges));
916+ }
906917 }
907918 }
908919 }
909920 }
921+
922+ // --> Highlighting query part
923+
924+ // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which
925+ // prevents them from being moved. But both of these values are really just
926+ // pointers, so it's actually ok to move them.
927+ let tree_ref = unsafe { mem::transmute::<_, &'static Tree>(&tree) };
928+ let cursor_ref =
929+ unsafe { mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) };
930+ let captures = cursor_ref
931+ .captures(&config.query, tree_ref.root_node(), move |n: Node| {
932+ &source[n.byte_range()]
933+ })
934+ .peekable();
935+
936+ result.push(HighlightIterLayer {
937+ highlight_end_stack: Vec::new(),
938+ scope_stack: vec![LocalScope {
939+ inherits: false,
940+ range: 0..usize::MAX,
941+ local_defs: Vec::new(),
942+ }],
943+ cursor,
944+ depth,
945+ _tree: Some(tree),
946+ captures,
947+ config,
948+ ranges,
949+ });
910950 }
911951
912− // --> Highlighting query part
913−
914− // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which
915− // prevents them from being moved. But both of these values are really just
916− // pointers, so it's actually ok to move them.
917− let tree_ref = unsafe { mem::transmute::<_, &'static Tree>(&tree) };
918− let cursor_ref =
919− unsafe { mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) };
920− let captures = cursor_ref
921− .captures(&config.query, tree_ref.root_node(), move |n: Node| {
922− &source[n.byte_range()]
923− })
924− .peekable();
925−
926− result.push(HighlightIterLayer {
927− highlight_end_stack: Vec::new(),
928− scope_stack: vec![LocalScope {
929− inherits: false,
930− range: 0..usize::MAX,
931− local_defs: Vec::new(),
932− }],
933− cursor,
934− depth,
935− _tree: Some(tree),
936− captures,
937− config,
938− ranges,
939− });
940− }
952+ Ok(()) // so we can use the try operator
953+ })?;
941954
942955 if queue.is_empty() {
943956 break;
@@ -1114,7 +1127,10 @@ where
11141127 break;
11151128 } else {
11161129 let layer = self.layers.remove(0);
1117− self.highlighter.cursors.push(layer.cursor);
1130+ PARSER.with(|ts_parser| {
1131+ let highlighter = &mut ts_parser.borrow_mut();
1132+ highlighter.cursors.push(layer.cursor);
1133+ });
11181134 }
11191135 }
11201136 }
@@ -1228,7 +1244,6 @@ where
12281244 if !ranges.is_empty() {
12291245 match HighlightIterLayer::new(
12301246 self.source,
1231− self.highlighter,
12321247 self.cancellation_flag,
12331248 &mut self.injection_callback,
12341249 config,