aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA-Walrus2022-08-05 00:12:14 +0000
committerGitHub2022-08-05 00:12:14 +0000
commitcfa882557eb24cf0bed0485d0811d3f35832ba4b (patch)
tree5470412f52a7c79e37e1f827e3b8e36ebd88864b
parentf32c05db857c61fddb45b66d2ca1de2bd70b7db2 (diff)
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
-rw-r--r--helix-core/src/syntax.rs16
1 files changed, 9 insertions, 7 deletions
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 4188d148..99922d37 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -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 {