Skip to content

Commit

Permalink
Fix nondeterministic highlighting (#3275)
Browse files Browse the repository at this point in the history
* Fix nondeterministic highlighting

This is done by prefering matches in the begining, ie for
`keyword.function`, `keyword` is a better match than `function`.

* Use all positions and not just leftmost

Fixes possible edgecase with something like `function.method.builtin`
and the queries `function.builtin` and `function.method`

* Switch to bitmask for slightly better performance

* Make matches from the start of string

Also change comments to match new behaviour
  • Loading branch information
A-Walrus authored Aug 5, 2022
1 parent f32c05d commit cfa8825
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions helix-core/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1356,8 +1356,8 @@ impl HighlightConfiguration {
/// Tree-sitter syntax-highlighting queries specify highlights in the form of dot-separated
/// highlight names like `punctuation.bracket` and `function.method.builtin`. Consumers of
/// these queries can choose to recognize highlights with different levels of specificity.
/// For example, the string `function.builtin` will match against `function.method.builtin`
/// and `function.builtin.constructor`, but will not match `function.method`.
/// For example, the string `function.builtin` will match against `function.builtin.constructor`
/// but will not match `function.method.builtin` and `function.method`.
///
/// When highlighting, results are returned as `Highlight` values, which contain the index
/// of the matched highlight this list of highlight names.
Expand All @@ -1377,11 +1377,13 @@ impl HighlightConfiguration {
let recognized_name = recognized_name;
let mut len = 0;
let mut matches = true;
for part in recognized_name.split('.') {
len += 1;
if !capture_parts.contains(&part) {
matches = false;
break;
for (i, part) in recognized_name.split('.').enumerate() {
match capture_parts.get(i) {
Some(capture_part) if *capture_part == part => len += 1,
_ => {
matches = false;
break;
}
}
}
if matches && len > best_match_len {
Expand Down

0 comments on commit cfa8825

Please sign in to comment.