Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a knob to configure tree sitter timeout #13217

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions book/src/languages.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ There are three possible locations for a `languages.toml` file:
`.helix` folder. Its settings will be merged with the language configuration
in the configuration directory and the built-in configuration.

## Top level configuration

These top level configuration keys are available:

| Key | Description |
| --- | ----------- |
| `syntax-timeout` | How long to allow tree-sitter to parse a file. Default is 500 milliseconds |

## Language configuration

Each language is configured by adding a `[[language]]` section to a
Expand Down
18 changes: 17 additions & 1 deletion helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use std::{
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
time::Duration,
};

use once_cell::sync::{Lazy, OnceCell};
Expand Down Expand Up @@ -86,6 +87,13 @@ pub struct Configuration {
pub language: Vec<LanguageConfiguration>,
#[serde(default)]
pub language_server: HashMap<String, LanguageServerConfiguration>,
#[serde(default = "default_syntax_timeout")]
/// Tree sitter syntax timeout in milliseconds
pub syntax_timeout: u64,
}

fn default_syntax_timeout() -> u64 {
500
}

// largely based on tree-sitter/cli/src/loader.rs
Expand Down Expand Up @@ -915,6 +923,8 @@ pub struct Loader {
language_server_configs: HashMap<String, LanguageServerConfiguration>,

scopes: ArcSwap<Vec<String>>,

timeout: Duration,
}

pub type LoaderError = globset::Error;
Expand Down Expand Up @@ -955,6 +965,7 @@ impl Loader {
language_config_ids_by_shebang,
language_server_configs: config.language_server,
scopes: ArcSwap::from_pointee(Vec::new()),
timeout: Duration::from_millis(config.syntax_timeout),
})
}

Expand Down Expand Up @@ -1270,7 +1281,9 @@ impl Syntax {

PARSER.with(|ts_parser| {
let ts_parser = &mut ts_parser.borrow_mut();
ts_parser.parser.set_timeout_micros(1000 * 500); // half a second is pretty generours
ts_parser
.parser
.set_timeout_micros(loader.timeout.as_micros().try_into().unwrap_or(u64::MAX));
let mut cursor = ts_parser.cursors.pop().unwrap_or_default();
// TODO: might need to set cursor range
cursor.set_byte_range(0..usize::MAX);
Expand Down Expand Up @@ -2789,6 +2802,7 @@ mod test {
let loader = Loader::new(Configuration {
language: vec![],
language_server: HashMap::new(),
syntax_timeout: 500,
})
.unwrap();
let language = get_language("rust").unwrap();
Expand Down Expand Up @@ -2857,6 +2871,7 @@ mod test {
let loader = Loader::new(Configuration {
language: vec![],
language_server: HashMap::new(),
syntax_timeout: 500,
})
.unwrap();

Expand Down Expand Up @@ -2969,6 +2984,7 @@ mod test {
let loader = Loader::new(Configuration {
language: vec![],
language_server: HashMap::new(),
syntax_timeout: 500,
})
.unwrap();
let language = get_language(language_name).unwrap();
Expand Down