@@ -2,11 +2,12 @@ use crate::{Change, Rope, RopeSlice, Transaction};
22pub use helix_syntax::Lang;
33pub use helix_syntax::{get_language, get_language_name};
44
5+use std::cell::RefCell;
56use std::collections::HashMap;
67use std::path::{Path, PathBuf};
78use std::sync::Arc;
89
9−use once_cell::sync::OnceCell;
10+use once_cell::sync::{Lazy, OnceCell};
1011
1112// largely based on tree-sitter/cli/src/loader.rs
1213pub struct LanguageConfiguration {
@@ -65,8 +66,6 @@ impl LanguageConfiguration {
6566 }
6667}
6768
68−use once_cell::sync::Lazy;
69−
7069pub static LOADER: Lazy<Loader> = Lazy::new(Loader::init);
7170
7271pub struct Loader {
@@ -145,13 +144,20 @@ impl Loader {
145144 }
146145}
147146
148−//
149−
150−pub struct Syntax {
151− // grammar: Grammar,
152− parser: Parser,
147+pub struct TSParser {
148+ parser: tree_sitter::Parser,
153149 cursors: Vec<QueryCursor>,
150+}
154151
152+// could also just use a pool, or a single instance?
153+thread_local! {
154+ pub static PARSER: RefCell<TSParser> = RefCell::new(TSParser {
155+ parser: Parser::new(),
156+ cursors: Vec::new(),
157+ })
158+}
159+
160+pub struct Syntax {
155161 config: Arc<HighlightConfiguration>,
156162
157163 pub(crate) root_layer: LanguageLayer,
@@ -163,10 +169,6 @@ impl Syntax {
163169 /*language: Lang,*/ source: &Rope,
164170 config: Arc<HighlightConfiguration>,
165171 ) -> Self {
166− // fetch grammar for parser based on language string
167− // let grammar = get_language(&language);
168− let parser = Parser::new();
169−
170172 let root_layer = LanguageLayer { tree: None };
171173
172174 // track markers of injections
@@ -174,25 +176,25 @@ impl Syntax {
174176
175177 let mut syntax = Self {
176178 // grammar,
177− parser,
178− cursors: Vec::new(),
179179 config,
180180 root_layer,
181181 };
182182
183183 // update root layer
184− syntax.root_layer.parse(
185− &mut syntax.parser,
186− &syntax.config,
187− source,
188− 0,
189− vec![Range {
190− start_byte: 0,
191− end_byte: usize::MAX,
192− start_point: Point::new(0, 0),
193− end_point: Point::new(usize::MAX, usize::MAX),
194− }],
195− );
184+ PARSER.with(|ts_parser| {
185+ syntax.root_layer.parse(
186+ &mut ts_parser.borrow_mut(),
187+ &syntax.config,
188+ source,
189+ 0,
190+ vec![Range {
191+ start_byte: 0,
192+ end_byte: usize::MAX,
193+ start_point: Point::new(0, 0),
194+ end_point: Point::new(usize::MAX, usize::MAX),
195+ }],
196+ );
197+ });
196198 syntax
197199 }
198200
@@ -202,13 +204,15 @@ impl Syntax {
202204 source: &Rope,
203205 changeset: &ChangeSet,
204206 ) -> Result<(), Error> {
205− self.root_layer.update(
206− &mut self.parser,
207− &self.config,
208− old_source,
209− source,
210− changeset,
211− )
207+ PARSER.with(|ts_parser| {
208+ self.root_layer.update(
209+ &mut ts_parser.borrow_mut(),
210+ &self.config,
211+ old_source,
212+ source,
213+ changeset,
214+ )
215+ })
212216
213217 // TODO: deal with injections and update them too
214218 }
@@ -229,7 +233,8 @@ impl Syntax {
229233
230234 /// Iterate over the highlighted regions for a given slice of source code.
231235 pub fn highlight_iter<'a>(
232− &'a mut self,
236+ &self,
237+ ts_parser: &'a mut TSParser,
233238 source: &'a [u8],
234239 range: Option<std::ops::Range<usize>>,
235240 cancellation_flag: Option<&'a AtomicUsize>,
@@ -283,7 +288,7 @@ impl Syntax {
283288 byte_offset: range.map(|r| r.start).unwrap_or(0), // TODO: simplify
284289 injection_callback,
285290 cancellation_flag,
286− highlighter: self,
291+ highlighter: ts_parser,
287292 iter_count: 0,
288293 layers: vec![layer],
289294 next_event: None,
@@ -336,19 +341,21 @@ impl LanguageLayer {
336341
337342 fn parse(
338343 &mut self,
339− parser: &mut Parser,
344+ ts_parser: &mut TSParser,
340345 config: &HighlightConfiguration,
341346 source: &Rope,
342347 mut depth: usize,
343348 mut ranges: Vec<Range>,
344349 ) -> Result<(), Error> {
345− if parser.set_included_ranges(&ranges).is_ok() {
346− parser
350+ if ts_parser.parser.set_included_ranges(&ranges).is_ok() {
351+ ts_parser
352+ .parser
347353 .set_language(config.language)
348354 .map_err(|_| Error::InvalidLanguage)?;
349355
350356 // unsafe { syntax.parser.set_cancellation_flag(cancellation_flag) };
351− let tree = parser
357+ let tree = ts_parser
358+ .parser
352359 .parse_with(
353360 &mut |byte, _| {
354361 if byte <= source.len_bytes() {
@@ -517,7 +524,7 @@ impl LanguageLayer {
517524
518525 fn update(
519526 &mut self,
520− parser: &mut Parser,
527+ ts_parser: &mut TSParser,
521528 config: &HighlightConfiguration,
522529 old_source: &Rope,
523530 source: &Rope,
@@ -535,7 +542,7 @@ impl LanguageLayer {
535542 }
536543
537544 self.parse(
538− parser,
545+ ts_parser,
539546 config,
540547 source,
541548 0,
@@ -652,7 +659,7 @@ where
652659{
653660 source: &'a [u8],
654661 byte_offset: usize,
655− highlighter: &'a mut Syntax,
662+ highlighter: &'a mut TSParser,
656663 injection_callback: F,
657664 cancellation_flag: Option<&'a AtomicUsize>,
658665 layers: Vec<HighlightIterLayer<'a>>,
@@ -839,7 +846,7 @@ impl<'a> HighlightIterLayer<'a> {
839846 /// added to the returned vector.
840847 fn new<F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a>(
841848 source: &'a [u8],
842− highlighter: &mut Syntax,
849+ highlighter: &mut TSParser,
843850 cancellation_flag: Option<&'a AtomicUsize>,
844851 injection_callback: &mut F,
845852 mut config: &'a HighlightConfiguration,