Fix nondeterministic highlighting (#3275)

* 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
This commit is contained in:
A-Walrus 2022-08-05 03:12:14 +03:00 committed by GitHub
parent f32c05db85
commit cfa882557e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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.
@ -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 {