automatically disable TS when parsing takes longer than 500ms

pull/6446/merge
Pascal Kuthe 2 years ago committed by Blaž Hrastnik
parent 2f2306475c
commit b0705337be

@ -768,7 +768,11 @@ fn byte_range_to_str(range: std::ops::Range<usize>, source: RopeSlice) -> Cow<st
} }
impl Syntax { impl Syntax {
pub fn new(source: &Rope, config: Arc<HighlightConfiguration>, loader: Arc<Loader>) -> Self { pub fn new(
source: &Rope,
config: Arc<HighlightConfiguration>,
loader: Arc<Loader>,
) -> Option<Self> {
let root_layer = LanguageLayer { let root_layer = LanguageLayer {
tree: None, tree: None,
config, config,
@ -793,11 +797,13 @@ impl Syntax {
loader, loader,
}; };
syntax let res = syntax.update(source, source, &ChangeSet::new(source));
.update(source, source, &ChangeSet::new(source))
.unwrap();
syntax if res.is_err() {
log::error!("TS parser failed, disabeling TS for the current buffer: {res:?}");
return None;
}
Some(syntax)
} }
pub fn update( pub fn update(
@ -925,6 +931,7 @@ impl Syntax {
PARSER.with(|ts_parser| { PARSER.with(|ts_parser| {
let ts_parser = &mut ts_parser.borrow_mut(); let ts_parser = &mut ts_parser.borrow_mut();
ts_parser.parser.set_timeout_micros(1000 * 500); // half a second is pretty generours
let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new); let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new);
// TODO: might need to set cursor range // TODO: might need to set cursor range
cursor.set_byte_range(0..usize::MAX); cursor.set_byte_range(0..usize::MAX);
@ -2371,7 +2378,7 @@ mod test {
let mut cursor = QueryCursor::new(); let mut cursor = QueryCursor::new();
let config = HighlightConfiguration::new(language, "", "", "").unwrap(); let config = HighlightConfiguration::new(language, "", "", "").unwrap();
let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)); let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
let root = syntax.tree().root_node(); let root = syntax.tree().root_node();
let mut test = |capture, range| { let mut test = |capture, range| {
@ -2442,7 +2449,7 @@ mod test {
fn main() {} fn main() {}
", ",
); );
let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)); let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
let tree = syntax.tree(); let tree = syntax.tree();
let root = tree.root_node(); let root = tree.root_node();
assert_eq!(root.kind(), "source_file"); assert_eq!(root.kind(), "source_file");
@ -2529,7 +2536,7 @@ mod test {
let language = get_language(language_name).unwrap(); let language = get_language(language_name).unwrap();
let config = HighlightConfiguration::new(language, "", "", "").unwrap(); let config = HighlightConfiguration::new(language, "", "", "").unwrap();
let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)); let syntax = Syntax::new(&source, Arc::new(config), Arc::new(loader)).unwrap();
let root = syntax let root = syntax
.tree() .tree()

@ -72,7 +72,7 @@ fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
let language_config = loader.language_config_for_scope(lang_scope).unwrap(); let language_config = loader.language_config_for_scope(lang_scope).unwrap();
let highlight_config = language_config.highlight_config(&[]).unwrap(); let highlight_config = language_config.highlight_config(&[]).unwrap();
let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader)); let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader)).unwrap();
let indent_query = language_config.indent_query().unwrap(); let indent_query = language_config.indent_query().unwrap();
let text = doc.slice(..); let text = doc.slice(..);

@ -51,7 +51,7 @@ pub fn highlighted_code_block<'a>(
language.into(), language.into(),
)) ))
.and_then(|config| config.highlight_config(theme.scopes())) .and_then(|config| config.highlight_config(theme.scopes()))
.map(|config| Syntax::new(&rope, config, Arc::clone(&config_loader))); .and_then(|config| Syntax::new(&rope, config, Arc::clone(&config_loader)));
let syntax = match syntax { let syntax = match syntax {
Some(s) => s, Some(s) => s,

@ -240,12 +240,10 @@ impl<T: Item + 'static> FilePicker<T> {
log::info!("highlighting picker item failed"); log::info!("highlighting picker item failed");
return return
}; };
log::info!("hmm1");
let Some(Overlay { content: picker, .. }) = compositor.find::<Overlay<Self>>() else { let Some(Overlay { content: picker, .. }) = compositor.find::<Overlay<Self>>() else {
log::info!("picker closed before syntax highlighting finished"); log::info!("picker closed before syntax highlighting finished");
return return
}; };
log::info!("hmm2");
// Try to find a document in the cache // Try to find a document in the cache
let doc = match current_file { let doc = match current_file {
PathOrId::Id(doc_id) => doc_mut!(editor, &doc_id), PathOrId::Id(doc_id) => doc_mut!(editor, &doc_id),
@ -254,7 +252,6 @@ impl<T: Item + 'static> FilePicker<T> {
_ => return, _ => return,
}, },
}; };
log::info!("yay");
doc.syntax = Some(syntax); doc.syntax = Some(syntax);
}; };
Callback::EditorCompositor(Box::new(callback)) Callback::EditorCompositor(Box::new(callback))

@ -972,8 +972,7 @@ impl Document {
) { ) {
if let (Some(language_config), Some(loader)) = (language_config, loader) { if let (Some(language_config), Some(loader)) = (language_config, loader) {
if let Some(highlight_config) = language_config.highlight_config(&loader.scopes()) { if let Some(highlight_config) = language_config.highlight_config(&loader.scopes()) {
let syntax = Syntax::new(&self.text, highlight_config, loader); self.syntax = Syntax::new(&self.text, highlight_config, loader);
self.syntax = Some(syntax);
} }
self.language = Some(language_config); self.language = Some(language_config);
@ -1113,9 +1112,11 @@ impl Document {
// update tree-sitter syntax tree // update tree-sitter syntax tree
if let Some(syntax) = &mut self.syntax { if let Some(syntax) = &mut self.syntax {
// TODO: no unwrap // TODO: no unwrap
syntax let res = syntax.update(&old_doc, &self.text, transaction.changes());
.update(&old_doc, &self.text, transaction.changes()) if res.is_err() {
.unwrap(); log::error!("TS parser failed, disabeling TS for the current buffer: {res:?}");
self.syntax = None;
}
} }
let changes = transaction.changes(); let changes = transaction.changes();

Loading…
Cancel
Save