%YAML 1.2 --- # http://www.sublimetext.com/docs/3/syntax.html name: Rust scope: source.rust file_extensions: - rs first_line_match: |- (?xi: ^ \s* // .*? -\*- .*? \brust\b .*? -\*- # editorconfig ) variables: non_raw_ident: '[[:alpha:]][_[:alnum:]]*|_[_[:alnum:]]+' # include a word boundary at the end to ensure all possible characters are # consumed, to prevent catastrophic backtracking identifier: '(?:(?:(?:r\#)?{{non_raw_ident}})\b)' camel_ident: '\b_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b' lifetime: '''(?:_|{{non_raw_ident}})(?!\'')\b' escaped_byte: '\\([nrt0\"''\\]|x\h{2})' escaped_char: '\\([nrt0\"''\\]|x[0-7]\h|u\{(?:\h_*){1,6}\})' int_suffixes: '[iu](?:8|16|32|64|128|size)' float_suffixes: 'f(32|64)' dec_literal: '[0-9](?:[0-9_])*' float_exponent: '[eE][+-]?[0-9_]*[0-9][0-9_]*' contexts: main: - include: statements prototype: # Macro metavariables. Ideally we would do this as a with_prototype, # however then we run into infinite recursion. It needs to be a prototype # since macro_rules! allows constructing new code, thus the metavariables # can be inserted in just about any position in the syntax. - match: '\${{identifier}}' scope: variable.other.rust statements: # This isn't really just "statements", it also includes all types, # expressions, items, etc. - include: visibility - match: ';' scope: punctuation.terminator.rust - match: '(''(?:{{non_raw_ident}}))\s*(:)' captures: 1: entity.name.label.rust 2: punctuation.separator.rust - include: lifetime - match: '\b(mod)\s+({{identifier}})\b' captures: 1: storage.type.module.rust 2: entity.name.module.rust push: - meta_scope: meta.module.rust - match: ';' scope: punctuation.terminator.rust pop: true - include: statements-block - match: '\b({{identifier}})\s*(=)\s*(?=\|)' captures: 1: entity.name.function.rust 2: keyword.operator.assignment.rust push: closure - match: '\b(fn)\s+(?={{identifier}})' captures: 1: storage.type.function.rust push: fn-definition - match: '\bstruct\b' scope: storage.type.struct.rust push: struct-identifier - match: '\bunion\b' scope: storage.type.union.rust push: union-identifier - match: '\b(type)\s+({{identifier}})\b' captures: 1: storage.type.type.rust 2: entity.name.type.rust push: - match: '=(?!=)' scope: keyword.operator.assignment.rust push: after-operator - match: '(?=\S)' pop: true - match: '\b(trait)\s+({{identifier}})\b' captures: 1: storage.type.trait.rust 2: entity.name.trait.rust push: - meta_scope: meta.trait.rust - match: '(?=:)' push: impl-where - match: '(?=\bwhere\b)' push: impl-where - match: '(?=<)' push: generic-angles - include: statements-block - match: '\bimpl\b' scope: storage.type.impl.rust push: impl-definition - match: '\benum\b' scope: storage.type.enum.rust push: enum-identifier - include: raw-pointer # `const` in a function header has a different scope from `const` values. - match: '\b(const)\s+(?=unsafe|extern|fn)' captures: 1: storage.modifier.rust - match: '\b(const)\s+({{identifier}})' captures: 1: storage.type.rust 2: entity.name.constant.rust - match: '\b(static)\s+(?:(mut)\s+)?({{identifier}})' captures: 1: storage.type.rust 2: storage.modifier.rust 3: entity.name.constant.rust - match: '\b(break|continue)\b(?:\s+(''{{non_raw_ident}}))?' captures: 1: keyword.control.rust 2: entity.name.label.rust - include: support-type - include: type - match: '\b(macro_rules!)\s+({{identifier}})\b' captures: 1: support.function.rust 2: entity.name.macro.rust push: macro-block - include: comments - include: attribute - include: strings - include: chars # macros which take format specs as the only parameter - match: '\b((?:format(?:_args)?|e?print(?:ln)?|panic|unreachable|unimplemented)!)\s*(\()' captures: 1: support.macro.rust 2: meta.group.rust punctuation.section.group.begin.rust push: - meta_content_scope: meta.group.rust - include: comments - include: format-string - include: format-raw-string - match: '(?=\S)' set: group-tail # macros which take format specs as the second parameter - match: '\b((?:write(?:ln)?|(?:debug_)?assert)!)\s*(\()' captures: 1: support.macro.rust 2: meta.group.rust punctuation.section.group.begin.rust push: - meta_scope: meta.group.rust - include: comments - match: ',' set: - meta_content_scope: meta.group.rust - include: format-string - include: format-raw-string - match: '(?=\S)' set: group-tail - include: group-tail # macros which take format specs as the third parameter # - match: '\b((?:assert_eq|assert_ne|debug_assert_eq|debug_assert_ne)!)\s*(\()' # is more performant as the below # - match: '\b((?:debug_)?assert_(?:eq|ne)!)\s*(\()' - match: '\b{{identifier}}!(?=\s*(\(|\{|\[))' scope: support.macro.rust - include: support-type - include: basic-identifiers - include: numbers - match: '(?=\{)' push: block - match: '(?=\()' push: group - match: '\[' scope: punctuation.section.group.begin.rust push: - meta_scope: meta.group.rust - match: '\]' scope: punctuation.section.group.end.rust pop: true - match: ';' scope: punctuation.separator.rust - include: statements - include: return-type - include: symbols - include: keywords - match: ',' scope: punctuation.separator.rust push: after-operator - match: '\b[[:lower:]_][[:lower:][:digit:]_]*(?=\()' scope: variable.function.rust - match: '{{identifier}}' - match: '\.' scope: punctuation.accessor.dot.rust visibility: - match: '\b(pub)\s*(\()' captures: 1: storage.modifier.rust 2: punctuation.section.group.begin.rust push: - include: comments - match: '\)' scope: punctuation.section.group.end.rust pop: true - match: '(crate|in|self|super)' scope: keyword.other.rust - match: '::' scope: meta.path.rust - match: '{{identifier}}' scope: meta.path.rust - match: '\bpub\b' scope: storage.modifier.rust attribute: - match: '(#)\s*(!?)\s*(\[)' captures: 1: punctuation.definition.annotation.rust 2: punctuation.definition.annotation.rust 3: punctuation.section.group.begin.rust push: # https://github.com/sublimehq/Packages/issues/709#issuecomment-266835130 - meta_scope: meta.annotation.rust - match: '(?:{{identifier}}\s*::\s*)*({{identifier}})' scope: meta.path.rust captures: 1: variable.annotation.rust - match: '\(' scope: meta.annotation.parameters.rust meta.group.rust punctuation.section.group.begin.rust push: - meta_content_scope: meta.annotation.parameters.rust meta.group.rust - match: \) scope: meta.annotation.parameters.rust meta.group.rust punctuation.section.group.end.rust pop: true - include: attribute-call - match: '=' scope: keyword.operator.assignment.rust set: - meta_content_scope: meta.annotation.rust - include: strings - include: chars - include: numbers - include: comments - match: '\]' scope: meta.annotation.rust punctuation.section.group.end.rust pop: true - match: '\]' scope: punctuation.section.group.end.rust pop: true - include: comments attribute-call: - match: \) scope: meta.function-call.rust meta.group.rust punctuation.section.group.end.rust pop: true - match: '({{identifier}})\s*(\()' scope: meta.function-call.rust captures: 1: variable.function.rust 2: meta.group.rust punctuation.section.group.begin.rust push: - meta_content_scope: meta.function-call.rust - include: attribute-call - match: ',' scope: punctuation.separator.rust - match: '=' scope: keyword.operator.assignment.rust - include: strings - include: chars - include: numbers - include: comments - include: lifetime - include: keywords - include: symbols block: - match: '\}' scope: meta.block.rust punctuation.section.block.end.rust pop: true - match: '\{' scope: punctuation.section.block.begin.rust push: [block-body, try-closure] block-body: - meta_scope: meta.block.rust - match: '(?=\})' pop: true - include: statements - include: attribute group: - match: '\)' scope: meta.group.rust punctuation.section.group.end.rust pop: true - match: '\(' scope: punctuation.section.group.begin.rust push: [group-body, try-closure] group-body: - meta_scope: meta.group.rust - match: '(?=\))' pop: true - include: statements group-tail: - meta_scope: meta.group.rust - match: '\)' scope: punctuation.section.group.end.rust pop: true - include: statements after-operator: # after-operator tries to handle ambiguous < and | symbols which can be # either binary operators, or the start of a generic or closure. - match: '(?=<)' set: generic-angles - include: try-closure try-closure: - match: '\s*(?=\|)' set: closure # Exit the context if we didn't find a closure - match: '(?=\S)' pop: true support-type: - match: '(Vec|Option|Result|BTreeMap|HashMap|Box|Rc|Arc|AsRef|AsMut|Into|From)\s*(?=<)' scope: support.type.rust push: generic-angles - match: '[?]?(?=\bSized\b)' scope: keyword.operator.rust - match: '[!]?(?=\bSync|Send\b)' scope: keyword.operator.rust - match: \b(Copy|Send|Sized|Sync|Drop|Fn|FnMut|FnOnce|Box|ToOwned|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator|Option|Some|None|Result|Ok|Err|SliceConcatExt|String|ToString|Vec)\b scope: support.type.rust return-type: - match: '\bimpl\b' scope: storage.type.impl.rust push: - include: comments - include: impl-generic - match: '(?=\S)' pop: true - match: '->' scope: punctuation.separator.rust push: - meta_scope: meta.function.return-type.rust - match: '(?=\s*\{|\bwhere\b)' pop: true - match: '(?=<)' push: generic-angles - include: type-any-identifier - match: '{{identifier}}' # Escape for incomplete expression - match: '(?=\S)' pop: true pattern-param: # A pattern used in a function or closure parameter. - include: comments - match: '&' scope: keyword.operator.rust - match: \b(mut|ref)\b scope: storage.modifier.rust - match: '@' scope: keyword.operator.rust - include: lifetime - match: '\b{{identifier}}\b(?!\s*(?:::|\{|\[|\())' scope: variable.parameter.rust - match: '\{' # Struct pattern. scope: punctuation.section.block.begin.rust push: - meta_scope: meta.block.rust - match: '\}' scope: punctuation.section.block.end.rust pop: true - match: '(\d+)\s*(:)' # Tuple struct field specifier. captures: 1: constant.numeric.integer.decimal.rust 2: punctuation.separator.rust - match: '{{identifier}}\s*(:)' # Struct field specifier. captures: 1: punctuation.separator.rust - match: '\.\.' scope: keyword.operator.rust - include: pattern-param - match: '\(' # Tuple or tuple struct pattern. scope: punctuation.section.group.begin.rust push: - meta_scope: meta.group.rust - match: '\)' scope: punctuation.section.group.end.rust pop: true - match: '\.\.' scope: keyword.operator.rust - include: pattern-param - match: '\[' # Slice pattern. scope: punctuation.section.brackets.begin.rust push: - meta_scope: meta.brackets.rust - match: '\]' scope: punctuation.section.brackets.end.rust pop: true - include: pattern-param # Path for struct patterns. - match: '\bself\b|\bsuper\b' scope: keyword.other.rust - match: '\b{{identifier}}\b' - match: '::' - match: ':(?!:)' # Type scope: punctuation.separator.rust push: - match: '(?=,|\)|\]|\}|\|)' pop: true - include: type-any-identifier - match: ',' scope: punctuation.separator.rust closure: - meta_content_scope: meta.function.closure.rust - match: '\|' scope: punctuation.section.parameters.begin.rust set: [closure-return, closure-parameters] closure-parameters: - meta_scope: meta.function.parameters.rust - match: '\|' scope: punctuation.section.parameters.end.rust pop: true - include: pattern-param # If the user has just typed a |, exit the params # scope as soon as we hit something that it not a # valid part so the whole rest of the document isn't # highlighted using the params scope - match: '(?=[=};)\]])' pop: true closure-return: - meta_content_scope: meta.function.closure.rust - include: return-type - match: (?=\S) set: closure-body closure-body: - match: '(?=\{)' set: closure-explicit-body - match: (?=\S) set: - meta_scope: meta.function.closure.rust - match: '(?=[};)\]\n])' pop: true - include: statements closure-explicit-body: - meta_scope: meta.function.closure.rust - include: block type: # A low-level type. Typically you want type-any-identifier for the full # type grammar. - match: '{{identifier}}(?=<)' push: generic-angles - match: \b(Self|{{int_suffixes}}|{{float_suffixes}}|bool|char|str)\b scope: storage.type.rust # stdsimd types - match: |- (?x) \b(?: [ium]8x(?:2|4|8|16|32) | [iu]8x64 | [ium]16x(?:2|4|8|16) | [iu]16x32 | # f16xN types might come later [iumf]32x(?:2|4|8) | [iuf]32x16 | [iumf]64x(?:2|4) | [iuf]64x8 | m1x(?:64|32|16|8) | # 512-bit masks __m(?:64|128|256)[di]? # __m512 should come later )\b scope: storage.type.rust - match: '\bdyn\b(?!\s*::)(?=\s*(?:\(|{{lifetime}}|{{identifier}}))' scope: storage.type.trait.rust generic-angles: - meta_scope: meta.generic.rust - match: '>' scope: punctuation.definition.generic.end.rust pop: true - match: '<' scope: punctuation.definition.generic.begin.rust push: generic-angles-contents - match: '(?=\S)' pop: true generic-angles-contents: - include: comments - include: attribute - match: '(?=>)' pop: true - match: '<' scope: punctuation.definition.generic.begin.rust push: - match: '>' scope: punctuation.definition.generic.end.rust pop: true - include: generic-angles-contents - include: bool # byte must be before type-any-identifier since it doesn't know about byte tokens - include: byte - include: type-any-identifier # char must be after type-any-identifier to deal with conflict with lifetimes - include: char # Handle negative integers (technically unary negative expression with a literal expression) - match: '-' scope: keyword.operator.arithmetic.rust - include: integers - include: block - match: '{{identifier}}' - match: ':|,' scope: punctuation.separator.rust - match: '\+|=' scope: keyword.operator.rust - match: '(?=\S)' pop: true constant-integer-expression: - include: integers - match: \( scope: punctuation.section.group.begin.rust push: - meta_scope: meta.group.rust - match: \) scope: punctuation.section.group.end.rust pop: true - include: constant-integer-expression - match: '{{identifier}}' scope: variable.other.constant.rust - match: '::' scope: punctuation.accessor.double-colon.rust - match: '[-+%/*]' scope: keyword.operator.arithmetic.rust type-any-identifier: - include: comments - include: support-type - include: return-type - match: '&' scope: keyword.operator.rust - include: raw-pointer - match: \b(mut|ref|const|unsafe)\b scope: storage.modifier.rust - match: '\bas\b' # This is for qualified type paths scope: keyword.operator.rust - match: \b(fn)\b\s*(\() captures: 1: storage.type.function.rust 2: meta.group.rust punctuation.section.group.begin.rust push: - meta_content_scope: meta.group.rust - match: \) scope: meta.group.rust punctuation.section.group.end.rust set: - include: return-type - match: '(?=\S)' pop: true - include: type-any-identifier - include: lifetime - match: '\b([[:upper:]]|_*[[:upper:]][[:alnum:]_]*[[:lower:]][[:alnum:]_]*)\b(::)' scope: meta.path.rust storage.type.rust captures: 1: storage.type.rust 2: punctuation.accessor.rust - match: '{{identifier}}(::)' scope: meta.path.rust captures: 1: punctuation.accessor.rust - match: '(::)(?={{identifier}})' scope: meta.path.rust punctuation.accessor.rust - match: '(?=<)' push: generic-angles - match: '\(' scope: punctuation.section.group.begin.rust push: - meta_scope: meta.group.rust - match: '\)' scope: punctuation.section.group.end.rust pop: true - match: ',' scope: punctuation.separator.rust - include: type-any-identifier - match: '\+' scope: keyword.operator.rust - match: \bextern\b scope: keyword.other.rust push: - include: strings - match: '(?=\S)' pop: true - include: hrtb - include: type - include: type-slice-or-array - match: '\b_\b' scope: keyword.operator.rust - match: '!' scope: keyword.operator.rust - match: '{{identifier}}' raw-pointer: - match: '\*\s*(?:const|mut)\b' scope: storage.modifier.rust hrtb: - match: \bfor\b scope: keyword.other.rust push: - match: '(?=<)' push: generic-angles - include: type-any-identifier - match: '&' scope: keyword.operator.rust - include: lifetime - match: '(?=\S)' pop: true type-slice-or-array: - match: '\[' scope: punctuation.section.group.begin.rust push: - match: '\]' scope: punctuation.section.group.end.rust pop: true - match: ';' scope: punctuation.separator.rust set: - match: '\]' scope: punctuation.section.group.end.rust pop: true - include: constant-integer-expression - include: type-any-identifier struct-identifier: - meta_scope: meta.struct.rust - include: comments - match: '{{identifier}}(?=<)' scope: entity.name.struct.rust set: - meta_scope: meta.struct.rust meta.generic.rust - match: '(?=<)' push: generic-angles - match: '' set: struct-body - match: '{{identifier}}' scope: entity.name.struct.rust set: struct-body - match: '(?=\S)' # Abort on invalid character. pop: true struct-body: - meta_scope: meta.struct.rust - include: comments - match: '(?=\bwhere\b)' push: impl-where - match: '(?=\()' push: struct-tuple - match: '(?=\{)' set: struct-classic - match: '(?=\S)' # Semicolon is valid here, others should just abort. pop: true struct-tuple: - meta_scope: meta.struct.rust - match: '\)' scope: punctuation.section.group.end.rust pop: true - match: '\(' scope: punctuation.section.group.begin.rust push: - match: '(?=\))' pop: true - meta_scope: meta.group.rust - include: comments - include: visibility - include: type-any-identifier - match: ',' scope: punctuation.separator.rust struct-classic: - meta_scope: meta.struct.rust - match: '\}' scope: meta.block.rust punctuation.section.block.end.rust pop: true - match: '\{' scope: punctuation.section.block.begin.rust push: struct-classic-body - match: '(?=\S)' # Abort for an invalid match. pop: true struct-classic-body: - meta_scope: meta.block.rust - match: '(?=\})' pop: true - include: comments - include: attribute - include: visibility - match: '{{identifier}}(?=\s*:)' scope: variable.other.member.rust push: - match: ',' scope: punctuation.separator.rust pop: true - match: '(?=\})' pop: true - include: comments - match: ':' scope: punctuation.separator.rust - include: type-any-identifier - match: '(?=\S)' # Abort for an invalid match. pop: true union-identifier: - meta_scope: meta.union.rust - include: comments - match: '{{identifier}}(?=<)' scope: entity.name.union.rust set: - meta_scope: meta.union.rust meta.generic.rust - match: '(?=<)' push: generic-angles - match: '' set: union-body - match: '{{identifier}}' scope: entity.name.union.rust set: union-body union-body: - meta_scope: meta.union.rust - include: comments - match: '(?=\bwhere\b)' push: impl-where - match: '\{' scope: punctuation.section.block.begin.rust push: struct-classic-body - match: '\}' scope: meta.block.rust punctuation.section.block.end.rust pop: true - match: '(?=;)' pop: true enum-identifier: - meta_scope: meta.enum.rust - include: comments - match: '{{identifier}}(?=<)' scope: entity.name.enum.rust set: - meta_scope: meta.enum.rust meta.generic.rust - match: '(?=<)' push: generic-angles - match: '' set: enum-maybe-where - match: '{{identifier}}' scope: entity.name.enum.rust set: enum-maybe-where - match: '(?=\S)' # Abort on invalid character. pop: true enum-maybe-where: - meta_scope: meta.enum.rust - include: comments - match: '(?=\bwhere\b)' push: impl-where - match: '\{' scope: punctuation.section.block.begin.rust set: enum-body - match: '(?=\S)' # Abort on invalid character. pop: true enum-body: - meta_scope: meta.block.rust meta.enum.rust - include: comments - include: attribute - match: '\}' scope: punctuation.section.block.end.rust pop: true - match: '\b[[:upper:]_][[:upper:][:digit:]_]*\b' scope: entity.name.constant.rust push: enum-variant-type - match: '{{camel_ident}}' scope: storage.type.source.rust push: enum-variant-type - match: '{{identifier}}' push: enum-variant-type enum-variant-type: - include: comments - match: '(?=\})' pop: true - match: ',' scope: punctuation.separator.rust pop: true - match: '=' set: enum-discriminant - match: '(?=\()' push: struct-tuple - match: '(?=\{)' push: struct-classic enum-discriminant: - match: ',' pop: true - match: '(?=\})' pop: true # This is just constant-expression, but we don't have that defined. - include: statements macro-block: - meta_scope: meta.macro.rust - include: comments - match: '\{' scope: punctuation.section.block.begin.rust set: - meta_scope: meta.macro.rust - match: '\}' scope: punctuation.section.block.end.rust pop: true - include: macro-block-contents # Note: ) and ] require a trailing semicolon, but this # does not check for that. - match: '\(' scope: punctuation.section.block.begin.rust set: - meta_scope: meta.macro.rust - match: '\)' scope: punctuation.section.block.end.rust pop: true - include: macro-block-contents - match: '\[' scope: punctuation.section.block.begin.rust set: - meta_scope: meta.macro.rust - match: '\]' scope: punctuation.section.block.end.rust pop: true - include: macro-block-contents macro-block-contents: # Macro block consists of a series of rules separated by semicolon # (trailing semicolon is optional). # # A rule is: BRACKET matchers BRACKET => BRACKET transcribers BRACKET # where BRACKET needs to be matched () or [] or {} - include: comments - match: '\{' scope: punctuation.section.block.begin.rust push: - meta_include_prototype: false - meta_scope: meta.macro.matchers.rust - match: '\}' scope: punctuation.section.block.end.rust set: macro-rule-sep - include: macro-matchers - match: '\(' scope: punctuation.section.block.begin.rust push: - meta_include_prototype: false - meta_scope: meta.macro.matchers.rust - match: '\)' scope: punctuation.section.block.end.rust set: macro-rule-sep - include: macro-matchers - match: '\[' scope: punctuation.section.block.begin.rust push: - meta_include_prototype: false - meta_scope: meta.macro.matchers.rust - match: '\]' scope: punctuation.section.block.end.rust set: macro-rule-sep - include: macro-matchers macro-matchers: - include: comments - match: '\(' scope: punctuation.section.block.begin.rust push: - meta_include_prototype: false - match: '\)' scope: punctuation.section.block.end.rust pop: true - include: macro-matchers - match: '\[' scope: punctuation.section.block.begin.rust push: - meta_include_prototype: false - match: '\]' scope: punctuation.section.block.end.rust pop: true - include: macro-matchers - match: '\{' scope: punctuation.section.block.begin.rust push: - meta_include_prototype: false - match: '\}' scope: punctuation.section.block.end.rust pop: true - include: macro-matchers - match: '(\$\s*{{identifier}})\s*(:)\s*(ident|path|expr|ty|pat_param|pat|stmt|block|item|meta|tt|lifetime|vis|literal)' captures: 1: variable.parameter.rust 2: punctuation.separator.rust 3: storage.type.rust - match: '(\$)\s*(\()' # Kleene operator. captures: 1: keyword.operator.rust 2: punctuation.section.group.begin.rust push: - meta_include_prototype: false - match: '(\))\s*[^?*+]*\s*([?*+])' captures: 1: punctuation.section.group.end.rust 2: keyword.operator.rust pop: true - include: macro-matchers # All other tokens except $ and delimiters are allowed here. - include: numbers - include: strings - include: keywords - include: lifetime - include: chars - include: symbols macro-rule-sep: - include: comments - match: '=>' scope: keyword.operator.rust set: macro-transcriber-block - match: '(?=\S)' # Abort on unexpected character. pop: true macro-transcriber-block: - include: comments - match: '\{' scope: punctuation.section.block.begin.rust set: - meta_scope: meta.macro.transcribers.rust - match: '\}' scope: punctuation.section.block.end.rust set: macro-semi-sep - include: statements - match: '\(' scope: punctuation.section.block.begin.rust set: - meta_scope: meta.macro.transcribers.rust - match: '\)' scope: punctuation.section.block.end.rust set: macro-semi-sep - include: statements - match: '\[' scope: punctuation.section.block.begin.rust set: - meta_scope: meta.macro.transcribers.rust - match: '\]' scope: punctuation.section.block.end.rust set: macro-semi-sep - include: statements - match: '(?=\S)' # Abort on unexpected character. pop: true macro-semi-sep: - include: comments - match: ';' scope: punctuation.terminator.rust pop: true - match: '(?=[})\]])' pop: true - match: '\S' # This is intended to help make it evident when you forget a semicolon. scope: invalid.illegal.rust impl-definition: - meta_scope: meta.impl.rust - include: comments - match: '(?=<)' set: [impl-for, impl-generic] - match: (?=\S) set: impl-for impl-generic: - meta_scope: meta.impl.rust - match: '(?=<)' push: generic-angles - match: '' pop: true impl-for: # `!?` here matches opt-out trait impls - match: '(?=\s*(?:::|!?{{identifier}}|\$|<)+(<.*?>)?\s+for\s+)' set: - meta_scope: meta.impl.rust - include: comments - match: '!?(?=\s*{{identifier}})' scope: keyword.operator.rust meta.impl.opt-out.rust - match: \bfor\b scope: keyword.other.rust set: impl-identifier - include: type-any-identifier - match: '' set: impl-identifier impl-identifier: - meta_content_scope: meta.impl.rust - include: comments - match: '(?=\{)' set: impl-body - match: '(?=\bwhere\b)' push: impl-where - match: \b(mut|ref)\b scope: storage.modifier.rust - match: '{{identifier}}(?=<)' scope: entity.name.impl.rust push: generic-angles - match: '{{identifier}}' scope: entity.name.impl.rust - match: '&' scope: keyword.operator.rust - include: lifetime - match: '(?=\S)' # Abort on unexpected character. pop: true impl-where: - meta_scope: meta.where.rust - include: comments - match: '(?=(\{|;))' pop: true - match: \bwhere\b scope: keyword.other.rust - include: type-any-identifier - match: ':' scope: punctuation.separator.rust impl-body: - meta_scope: meta.impl.rust - include: statements-block fn-definition: - meta_scope: meta.function.rust - include: comments - match: '{{identifier}}' scope: entity.name.function.rust set: fn-generic fn-generic: - include: comments - match: '(?=<)' push: generic-angles - match: '(?=\()' set: fn-parameters - match: \bwhere\b set: fn-where # Escape for incomplete expression - match: '(?=;)' pop: true fn-parameters: - meta_scope: meta.function.rust - match: '\)' scope: meta.function.parameters.rust punctuation.section.parameters.end.rust set: fn-return - match: '\(' scope: punctuation.section.parameters.begin.rust push: - meta_scope: meta.function.parameters.rust - include: comments - match: '(?=\))' pop: true - include: pattern-param fn-return: - meta_scope: meta.function.rust - include: comments - match: '(?=\{)' set: fn-body - match: '(?=\bwhere\b)' set: fn-where - include: return-type # Escape for incomplete expression, or ';' - match: '(?=\S)' pop: true fn-where: - meta_scope: meta.function.rust meta.where.rust - include: comments - match: '(?=\{)' set: fn-body - match: \bwhere\b scope: keyword.other.rust - include: type-any-identifier - match: '[:,]' scope: punctuation.separator.rust # Escape for incomplete expression, or ';' - match: '(?=\S)' pop: true fn-body: - meta_scope: meta.function.rust - match: '\}' scope: meta.block.rust punctuation.section.block.end.rust pop: true - match: '\{' scope: punctuation.section.block.begin.rust push: - meta_scope: meta.block.rust - match: '(?=\})' pop: true - include: statements statements-block: - include: comments - match: '\}' scope: meta.block.rust punctuation.section.block.end.rust pop: true - match: '\{' scope: punctuation.section.block.begin.rust push: [block-body, try-closure] comments: - include: block-comments - match: "//[!/]" scope: punctuation.definition.comment.rust push: - meta_scope: comment.line.documentation.rust - match: $\n? pop: true - match: // scope: punctuation.definition.comment.rust push: - meta_scope: comment.line.double-slash.rust - match: $\n? pop: true block-comments: - match: '/\*[!\*][^\*/]' scope: punctuation.definition.comment.rust push: - meta_scope: comment.block.documentation.rust - match: \*/ scope: punctuation.definition.comment.rust pop: true # Javadoc style comment with leading * on each line. Helps with word-wrapping. - match: ^\s*(\*)(?!/) captures: 1: punctuation.definition.comment.rust - include: block-comments - match: /\* scope: punctuation.definition.comment.rust push: - meta_scope: comment.block.rust - match: \*/ scope: punctuation.definition.comment.rust pop: true - include: block-comments strings: - include: byte-string - include: raw-byte-string - include: string - include: raw-string chars: - include: char - include: byte byte: - match: "(b)(')" captures: 1: storage.type.string.rust 2: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.single.rust # ASCII except ', \, \n, \r or \t - match: '[\x00-\x08\x0b-\x0c\x0e-\x26\x28-\x5b\x5d-\x7f]' set: byte-tail # Don't mark entire file invalid while writing, even though this is # not valid syntax. - match: '\n' pop: true - match: '{{escaped_byte}}' scope: constant.character.escape.rust set: byte-tail - match: '' set: byte-tail byte-tail: - match: "'" scope: string.quoted.single.rust punctuation.definition.string.end.rust pop: true - match: '\n' pop: true - match: '.' scope: invalid.illegal.byte.rust byte-string: - match: '(b)(")' captures: 1: storage.type.string.rust 2: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.double.rust - match: '"' scope: punctuation.definition.string.end.rust pop: true - match: '{{escaped_byte}}' scope: constant.character.escape.rust - match: '(\\)$' scope: punctuation.separator.continuation.line.rust - match: '\\.' scope: invalid.illegal.character.escape.rust raw-byte-string: - match: (br)(#*)" captures: 1: storage.type.string.rust 2: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.double.raw.rust - match: '"\2' scope: punctuation.definition.string.end.rust pop: true escaped-char: - match: '{{escaped_char}}' scope: constant.character.escape.rust - match: '\\u\{[^}]*\}' scope: invalid.illegal.character.escape.rust - match: '\\.' scope: invalid.illegal.character.escape.rust char: - match: "'" scope: punctuation.definition.string.begin.rust push: - meta_scope: string.quoted.single.rust - match: "[^'\\\\\n\r\t]" set: char-tail # Don't mark entire file invalid while writing, even though this is # not valid syntax. - match: '\n' pop: true - match: '{{escaped_char}}' scope: constant.character.escape.rust set: char-tail - match: '' set: char-tail char-tail: - match: "'" scope: string.quoted.single.rust punctuation.definition.string.end.rust pop: true - match: '\n' pop: true - match: '.' scope: invalid.illegal.char.rust string: - match: '"' scope: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.double.rust - match: '"' scope: punctuation.definition.string.end.rust pop: true - include: escaped-char - match: '(\\)$' scope: punctuation.separator.continuation.line.rust raw-string: - match: (r)((#*)") captures: 1: storage.type.string.rust 2: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.double.raw.rust - match: '"\3' scope: punctuation.definition.string.end.rust pop: true format-string: - match: '"' scope: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.double.rust - match: '"' scope: punctuation.definition.string.end.rust pop: true - include: escaped-char - include: format-escapes - match: '(\\)$' scope: punctuation.separator.continuation.line.rust format-raw-string: - match: (r)(#*)" captures: 1: storage.type.string.rust 2: punctuation.definition.string.begin.rust push: - meta_include_prototype: false - meta_scope: string.quoted.double.raw.rust - match: '"\2' scope: punctuation.definition.string.end.rust pop: true - include: format-escapes format-escapes: - match: '\{\{|\}\}' scope: constant.character.escape.rust - match: |- (?x) # Spec from http://doc.rust-lang.org/std/fmt/ \{ (\d+|{{identifier}})? ( : # format_spec delimiter (.?[<>^])? # [[fill]align] [+-]? # [sign] \#? # ['#'] 0? # [0] (\d+\$?)? # [width] (\.(\d+\$?|\*)?)? # ['.' precision] (\?|{{identifier}})? # [type] )? \} scope: constant.other.placeholder.rust numbers: - include: floats - include: integers floats: - match: '\b({{dec_literal}}(?:\.{{dec_literal}})?(?:{{float_exponent}})?)({{float_suffixes}})' captures: 1: constant.numeric.float.rust 2: storage.type.numeric.rust - match: '\b{{dec_literal}}\.{{dec_literal}}(?:{{float_exponent}})?' scope: constant.numeric.float.rust - match: '\b{{dec_literal}}{{float_exponent}}' scope: constant.numeric.float.rust - match: '\b{{dec_literal}}\.(?![A-Za-z._''])' scope: constant.numeric.float.rust integers: - match: '\b({{dec_literal}})({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.decimal.rust 2: storage.type.numeric.rust - match: '\b(0x[\h_]+)({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.hexadecimal.rust 2: storage.type.numeric.rust - match: '\b(0o[0-7_]+)({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.octal.rust 2: storage.type.numeric.rust - match: '\b(0b[0-1_]+)({{int_suffixes}})?\b' captures: 1: constant.numeric.integer.binary.rust 2: storage.type.numeric.rust lifetime: - match: '{{lifetime}}' scope: storage.modifier.lifetime.rust basic-identifiers: - match: '\b(?:(?:r#)?[[:upper:]_][[:upper:][:digit:]_]+)\b' scope: constant.other.rust - match: '\b(c_[[:lower:][:digit:]_]+|[[:lower:]_][[:lower:][:digit:]_]*_t)\b' scope: storage.type.rust - match: '\b(?:r#)?_*[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\b' scope: storage.type.source.rust - match: '(?={{identifier}}::)' push: - meta_scope: meta.path.rust - include: no-path-identifiers - match: '::' scope: punctuation.accessor.rust set: no-type-names - match: '(::)(?={{identifier}})' scope: meta.path.rust captures: 1: punctuation.accessor.rust push: no-type-names - include: no-path-identifiers no-path-identifiers: - match: \b(self)\b scope: variable.language.rust - match: \b(super)\b scope: keyword.other.rust no-type-names: # This push state prevents highlighting basic types like # i32, etc when following :: - include: comments - include: basic-identifiers - match: '{{identifier}}' - match: '(?=<)' push: generic-angles - match: '' pop: true symbols: - match: '=>' # Making this an operator helps visually break up large # match blocks containing just enums scope: keyword.operator.rust - match: '<-|->' scope: keyword.operator.rust - match: '\.\.\.|\.\.=|\.\.' scope: keyword.operator.range.rust - match: '[!<>=]=' scope: keyword.operator.comparison.rust - match: '(?:[-+%/*^&|]|<<|>>)?=' scope: keyword.operator.assignment.rust - match: '&&|\|\||!' scope: keyword.operator.logical.rust - match: '[&|^]|<<|>>' scope: keyword.operator.bitwise.rust - match: '[<>]' scope: keyword.operator.comparison.rust - match: '[-+%/*]' scope: keyword.operator.arithmetic.rust - match: '[@~?$#'']' scope: keyword.operator.rust - match: '[:;,]' scope: punctuation.separator.rust bool: - match: \b(true|false)\b scope: constant.language.rust keywords: # All keywords. Note in `statements` some of these are superseded by more # specific rules. - include: bool - match: \b(let|const|static)\b scope: storage.type.rust - match: \bfn\b scope: storage.type.function.rust - match: \bmod\b scope: storage.type.module.rust - match: \bstruct\b scope: storage.type.struct.rust - match: \bimpl\b scope: storage.type.impl.rust - match: \benum\b scope: storage.type.enum.rust - match: \btype\b scope: storage.type.type.rust - match: \btrait\b scope: storage.type.trait.rust - match: \b(mut|pub|unsafe|move|ref)\b scope: storage.modifier.rust - match: \b(crate|extern|use|where)\b scope: keyword.other.rust - match: \b(async|await|else|for|if|loop|match|try|while|yield)\b scope: keyword.control.rust - match: \b(break|continue)\b scope: keyword.control.rust - match: \breturn\b scope: keyword.control.rust - match: \b(as|in|box)\b scope: keyword.operator.rust - match: \b(virtual|become|priv|typeof|unsized|do|abstract|final|override|macro)\b scope: invalid.illegal.rust - match: \b(super|self|Self)\b scope: keyword.other.rust