diff --git a/book/src/themes.md b/book/src/themes.md index 4d80f99a3..f17195aaa 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -51,6 +51,7 @@ Possible keys: | `attribute` | | | `keyword` | | | `keyword.directive` | Preprocessor directives (\#if in C) | +| `keyword.control` | Control flow | | `namespace` | | | `punctuation` | | | `punctuation.delimiter` | | diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 5b45a88f9..833ccfb96 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -161,7 +161,7 @@ impl LanguageConfiguration { let injections_query = read_query(&language, "injections.scm"); - let locals_query = ""; + let locals_query = read_query(&language, "locals.scm"); if highlights_query.is_empty() { None @@ -171,7 +171,7 @@ impl LanguageConfiguration { language, &highlights_query, &injections_query, - locals_query, + &locals_query, ) .unwrap(); // TODO: no unwrap config.configure(scopes); diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm index bb15074b2..5e469e67d 100644 --- a/runtime/queries/rust/highlights.scm +++ b/runtime/queries/rust/highlights.scm @@ -1,214 +1,336 @@ -; Identifier conventions +; ------- +; Tree-Sitter doesn't allow overrides in regards to captures, +; though it is possible to affect the child node of a captured +; node. Thus, the approach here is to flip the order so that +; overrides are unnecessary. +; ------- -; Assume all-caps names are constants -((identifier) @constant - (#match? @constant "^[A-Z][A-Z\\d_]+$")) -; Assume other uppercase names are enum constructors -(enum_variant) @type.enum.variant -((identifier) @constructor - (#match? @constructor "^[A-Z]")) +; ------- +; Types +; ------- -; Assume that uppercase names in paths are types -(mod_item - name: (identifier) @namespace) -(scoped_identifier - path: (identifier) @namespace) -(scoped_identifier - (scoped_identifier - name: (identifier) @namespace)) -(scoped_type_identifier - path: (identifier) @namespace) -(scoped_type_identifier - (scoped_identifier - name: (identifier) @namespace)) +; --- +; Primitives +; --- -((scoped_identifier - path: (identifier) @type) - (#match? @type "^[A-Z]")) -((scoped_identifier - path: (scoped_identifier - name: (identifier) @type)) - (#match? @type "^[A-Z]")) +(escape_sequence) @escape +(primitive_type) @type.builtin +(boolean_literal) @constant.builtin +[ + (integer_literal) + (float_literal) +] @number +[ + (char_literal) + (string_literal) + (raw_string_literal) +] @string +[ + (line_comment) + (block_comment) +] @comment -; Namespaces +; --- +; Extraneous +; --- -(crate) @namespace -(extern_crate_declaration - (crate) - name: (identifier) @namespace) -(scoped_use_list - path: (identifier) @namespace) -(scoped_use_list - path: (scoped_identifier - (identifier) @namespace)) -(use_list (scoped_identifier (identifier) @namespace . (_))) +(self) @variable.builtin +(enum_variant (identifier) @type.enum.variant) -; Function calls +(field_initializer + (field_identifier) @property) +(shorthand_field_initializer) @variable +(shorthand_field_identifier) @variable -(call_expression - function: (identifier) @function) -(call_expression - function: (field_expression - field: (field_identifier) @function.method)) -(call_expression - function: (scoped_identifier - "::" - name: (identifier) @function)) +(lifetime + "'" @label + (identifier) @label) +(loop_label + (identifier) @type) -(generic_function - function: (identifier) @function) -(generic_function - function: (scoped_identifier - name: (identifier) @function)) -(generic_function - function: (field_expression - field: (field_identifier) @function.method)) +; --- +; Punctuation +; --- -(macro_invocation - macro: (identifier) @function.macro - "!" @function.macro) -(macro_invocation - macro: (scoped_identifier - (identifier) @function.macro .)) +[ + "::" + "." + ";" +] @punctuation.delimiter -; (metavariable) @variable -(metavariable) @function.macro +[ + "(" + ")" + "[" + "]" +] @punctuation.bracket +(type_arguments + [ + "<" + ">" + ] @punctuation.bracket) +(type_parameters + [ + "<" + ">" + ] @punctuation.bracket) -"$" @function.macro +; --- +; Parameters +; --- -; Function definitions +(parameter + pattern: (identifier) @variable.parameter) +(closure_parameters + (identifier) @variable.parameter) -(function_item (identifier) @function) -(function_signature_item (identifier) @function) -; Other identifiers -(type_identifier) @type -(primitive_type) @type.builtin -(field_identifier) @property +; ------- +; Keywords +; ------- -(line_comment) @comment -(block_comment) @comment +(for_expression + "for" @keyword.control) +((identifier) @keyword.control + (#match? @keyword.control "^yield$")) +[ + "while" + "loop" + "in" + "break" + "continue" -"(" @punctuation.bracket -")" @punctuation.bracket -"[" @punctuation.bracket -"]" @punctuation.bracket + "match" + "if" + "else" + "return" + + "await" +] @keyword.control + +[ + (crate) + (super) + "as" + "use" + "pub" + "mod" + "extern" + + "fn" + "struct" + "enum" + "impl" + "where" + "trait" + "for" + + "type" + "union" + "unsafe" + "default" + "macro_rules!" + + "let" + "ref" + "move" + + "dyn" + "static" + "const" + "async" +] @keyword -(type_arguments - "<" @punctuation.bracket - ">" @punctuation.bracket) -(type_parameters - "<" @punctuation.bracket - ">" @punctuation.bracket) - -"::" @punctuation.delimiter -"." @punctuation.delimiter -";" @punctuation.delimiter - -(parameter (identifier) @variable.parameter) -(closure_parameters (_) @variable.parameter) - -(lifetime (identifier) @label) - -"async" @keyword -"break" @keyword -"const" @keyword -"continue" @keyword -(crate) @keyword -"default" @keyword -"dyn" @keyword -"else" @keyword -"enum" @keyword -"extern" @keyword -"fn" @keyword -"for" @keyword -"if" @keyword -"impl" @keyword -"in" @keyword -"let" @keyword -"let" @keyword -"loop" @keyword -"macro_rules!" @keyword -"match" @keyword -"mod" @keyword -"move" @keyword -"pub" @keyword -"ref" @keyword -"return" @keyword -"static" @keyword -"struct" @keyword -"trait" @keyword -"type" @keyword -"union" @keyword -"unsafe" @keyword -"use" @keyword -"where" @keyword -"while" @keyword (mutable_specifier) @keyword.mut -(use_list (self) @keyword) -(scoped_use_list (self) @keyword) -(scoped_identifier (self) @keyword) -(super) @keyword -"as" @keyword -(self) @variable.builtin -[ -(char_literal) -(string_literal) -(raw_string_literal) -] @string -(boolean_literal) @constant.builtin -(integer_literal) @number -(float_literal) @number +; ------- +; Guess Other Types +; ------- -(escape_sequence) @escape +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]+$")) + +; --- +; PascalCase identifiers in call_expressions (e.g. `Ok()`) +; are assumed to be enum constructors. +; --- + +(call_expression + function: [ + ((identifier) @type.variant + (#match? @type.variant "^[A-Z]")) + (scoped_identifier + name: ((identifier) @type.variant + (#match? @type.variant "^[A-Z]"))) + ]) + +; --- +; Assume that types in match arms are enums and not +; tuple structs. Same for `if let` expressions. +; --- + +(match_pattern + (scoped_identifier + name: (identifier) @constructor)) +(tuple_struct_pattern + type: [ + ((identifier) @constructor) + (scoped_identifier + name: (identifier) @constructor) + ]) +(struct_pattern + type: [ + ((type_identifier) @constructor) + (scoped_type_identifier + name: (type_identifier) @constructor) + ]) +; --- +; Other PascalCase identifiers are assumed to be structs. +; --- + +((identifier) @type + (#match? @type "^[A-Z]")) + + + +; ------- +; Functions +; ------- + +(call_expression + function: [ + ((identifier) @function) + (scoped_identifier + name: (identifier) @function) + (field_expression + field: (field_identifier) @function) + ]) +(generic_function + function: [ + ((identifier) @function) + (scoped_identifier + name: (identifier) @function) + (field_expression + field: (field_identifier) @function.method) + ]) + +(function_item + name: (identifier) @function) + +; --- +; Macros +; --- + +(meta_item + (identifier) @attribute) (attribute_item) @attribute (inner_attribute_item) @attribute +(macro_definition + name: (identifier) @function.macro) +(macro_invocation + macro: [ + ((identifier) @function.macro) + (scoped_identifier + name: (identifier) @function.macro) + ] + "!" @function.macro) + +(metavariable) @variable.parameter +(fragment_specifier) @variable.parameter + + + +; ------- +; Operators +; ------- + [ -"*" -"'" -"->" -"=>" -"<=" -"=" -"==" -"!" -"!=" -"%" -"%=" -"&" -"&=" -"&&" -"|" -"|=" -"||" -"^" -"^=" -"*" -"*=" -"-" -"-=" -"+" -"+=" -"/" -"/=" -">" -"<" -">=" -">>" -"<<" -">>=" -"@" -".." -"..=" -"'" + "*" + "'" + "->" + "=>" + "<=" + "=" + "==" + "!" + "!=" + "%" + "%=" + "&" + "&=" + "&&" + "|" + "|=" + "||" + "^" + "^=" + "*" + "*=" + "-" + "-=" + "+" + "+=" + "/" + "/=" + ">" + "<" + ">=" + ">>" + "<<" + ">>=" + "@" + ".." + "..=" + "'" ] @operator + + +; ------- +; Paths +; ------- + +(use_declaration + argument: (identifier) @namespace) +(use_wildcard + (identifier) @namespace) +(extern_crate_declaration + name: (identifier) @namespace) +(mod_item + name: (identifier) @namespace) +(scoped_use_list + path: (identifier)? @namespace) +(use_list + (identifier) @namespace) +(use_as_clause + path: (identifier)? @namespace + alias: (identifier) @namespace) + +; --- +; Remaining Paths +; --- + +(scoped_identifier + path: (identifier)? @namespace + name: (identifier) @namespace) +(scoped_type_identifier + path: (identifier) @namespace) + + + +; ------- +; Remaining Identifiers +; ------- + "?" @special + +(type_identifier) @type +(identifier) @variable +(field_identifier) @variable