on master help sign in
automatically disable TS when parsing takes longer than 500ms
commitb0705337bec836604bdb97689d0a44940c6bddae authorPascal Kuthe <pascal.kuthe@semimod.de> dateFri 12 May 2023, 16:49 (3 years ago) parent2f23064
5 files changed+23−18
helix-core/src/syntax.rs+15−8 helix-core/tests/indent.rs+1−1 helix-term/src/ui/markdown.rs+1−1 helix-term/src/ui/picker.rs−3 helix-view/src/document.rs+6−5
helix-core/src/syntax.rs+15−8
@@ -768,7 +768,11 @@ fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<st
768768}
769769
770770impl Syntax {
771− pub fn new(source: &Rope, config: Arc<HighlightConfiguration>, loader: Arc<Loader>) -> Self {
771+ pub fn new(
772+ source: &Rope,
773+ config: Arc<HighlightConfiguration>,
774+ loader: Arc<Loader>,
775+ ) -> Option<Self> {
772776 let root_layer = LanguageLayer {
773777 tree: None,
774778 config,
@@ -793,11 +797,13 @@ impl Syntax {
793797 loader,
794798 };
795799
796− syntax
797− .update(source, source, &ChangeSet::new(source))
798− .unwrap();
800+ let res = syntax.update(source, source, &ChangeSet::new(source));
799801
800− syntax
802+ if res.is_err() {
803+ log::error!("TS parser failed, disabeling TS for the current buffer: {res:?}");
804+ return None;
805+ }
806+ Some(syntax)
801807 }
802808
803809 pub fn update(
@@ -925,6 +931,7 @@ impl Syntax {
925931
926932 PARSER.with(|ts_parser| {
927933 let ts_parser = &mut ts_parser.borrow_mut();
934+ ts_parser.parser.set_timeout_micros(1000 * 500); // half a second is pretty generours
928935 let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new);
929936 // TODO: might need to set cursor range
930937 cursor.set_byte_range(0..usize::MAX);
@@ -2371,7 +2378,7 @@ mod test {
23712378 let mut cursor = QueryCursor::new();
23722379
23732380 let config = HighlightConfiguration::new(language, "", "", "").unwrap();
2374− let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader));
2381+ let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
23752382
23762383 let root = syntax.tree().root_node();
23772384 let mut test = |capture, range| {
@@ -2442,7 +2449,7 @@ mod test {
24422449 fn main() {}
24432450 ",
24442451 );
2445− let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader));
2452+ let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
24462453 let tree = syntax.tree();
24472454 let root = tree.root_node();
24482455 assert_eq!(root.kind(), "source_file");
@@ -2529,7 +2536,7 @@ mod test {
25292536 let language = get_language(language_name).unwrap();
25302537
25312538 let config = HighlightConfiguration::new(language, "", "", "").unwrap();
2532− let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader));
2539+ let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
25332540
25342541 let root = syntax
25352542 .tree()
helix-core/tests/indent.rs+1−1
@@ -72,7 +72,7 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
7272
7373 let language_config = loader.language_config_for_scope(lang_scope).unwrap();
7474 let highlight_config = language_config.highlight_config(&[]).unwrap();
75− let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader));
75+ let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader)).unwrap();
7676 let indent_query = language_config.indent_query().unwrap();
7777 let text = doc.slice(..);
7878
helix-term/src/ui/markdown.rs+1−1
@@ -51,7 +51,7 @@ pub fn highlighted_code_block<'a>(
5151 language.into(),
5252 ))
5353 .and_then(|config| config.highlight_config(theme.scopes()))
54− .map(|config| Syntax::new(&rope, config, Arc::clone(&config_loader)));
54+ .and_then(|config| Syntax::new(&rope, config, Arc::clone(&config_loader)));
5555
5656 let syntax = match syntax {
5757 Some(s) => s,
helix-term/src/ui/picker.rs−3
@@ -240,12 +240,10 @@ impl<T: Item + 'static> FilePicker<T> {
240240 log::info!("highlighting picker item failed");
241241 return
242242 };
243− log::info!("hmm1");
244243 let Some(Overlay { content: picker, .. }) = compositor.find::<Overlay<Self>>() else {
245244 log::info!("picker closed before syntax highlighting finished");
246245 return
247246 };
248− log::info!("hmm2");
249247 // Try to find a document in the cache
250248 let doc = match current_file {
251249 PathOrId::Id(doc_id) => doc_mut!(editor, &doc_id),
@@ -254,7 +252,6 @@ impl<T: Item + 'static> FilePicker<T> {
254252 _ => return,
255253 },
256254 };
257− log::info!("yay");
258255 doc.syntax = Some(syntax);
259256 };
260257 Callback::EditorCompositor(Box::new(callback))
helix-view/src/document.rs+6−5
@@ -972,8 +972,7 @@ impl Document {
972972 ) {
973973 if let (Some(language_config), Some(loader)) = (language_config, loader) {
974974 if let Some(highlight_config) = language_config.highlight_config(&loader.scopes()) {
975− let syntax = Syntax::new(&self.text, highlight_config, loader);
976− self.syntax = Some(syntax);
975+ self.syntax = Syntax::new(&self.text, highlight_config, loader);
977976 }
978977
979978 self.language = Some(language_config);
@@ -1113,9 +1112,11 @@ impl Document {
11131112 // update tree-sitter syntax tree
11141113 if let Some(syntax) = &mut self.syntax {
11151114 // TODO: no unwrap
1116− syntax
1117− .update(&old_doc, &self.text, transaction.changes())
1118− .unwrap();
1115+ let res = syntax.update(&old_doc, &self.text, transaction.changes());
1116+ if res.is_err() {
1117+ log::error!("TS parser failed, disabeling TS for the current buffer: {res:?}");
1118+ self.syntax = None;
1119+ }
11191120 }
11201121
11211122 let changes = transaction.changes();