Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 1 | " Vim syntax file |
| 2 | " Language: Rust |
| 3 | " Maintainer: Patrick Walton <pcwalton@mozilla.com> |
| 4 | " Maintainer: Ben Blum <bblum@cs.cmu.edu> |
| 5 | " Maintainer: Chris Morgan <me@chrismorgan.info> |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 6 | " Last Change: 2023-09-11 |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 7 | " For bugs, patches and license go to https://github.com/rust-lang/rust.vim |
| 8 | |
| 9 | if version < 600 |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 10 | syntax clear |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 11 | elseif exists("b:current_syntax") |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 12 | finish |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 13 | endif |
| 14 | |
| 15 | " Syntax definitions {{{1 |
| 16 | " Basic keywords {{{2 |
| 17 | syn keyword rustConditional match if else |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 18 | syn keyword rustRepeat loop while |
| 19 | " `:syn match` must be used to prioritize highlighting `for` keyword. |
| 20 | syn match rustRepeat /\<for\>/ |
| 21 | " Highlight `for` keyword in `impl ... for ... {}` statement. This line must |
| 22 | " be put after previous `syn match` line to overwrite it. |
| 23 | syn match rustKeyword /\%(\<impl\>.\+\)\@<=\<for\>/ |
| 24 | syn keyword rustRepeat in |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 25 | syn keyword rustTypedef type nextgroup=rustIdentifier skipwhite skipempty |
| 26 | syn keyword rustStructure struct enum nextgroup=rustIdentifier skipwhite skipempty |
| 27 | syn keyword rustUnion union nextgroup=rustIdentifier skipwhite skipempty contained |
| 28 | syn match rustUnionContextual /\<union\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*/ transparent contains=rustUnion |
| 29 | syn keyword rustOperator as |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 30 | syn keyword rustExistential existential nextgroup=rustTypedef skipwhite skipempty contained |
| 31 | syn match rustExistentialContextual /\<existential\_s\+type/ transparent contains=rustExistential,rustTypedef |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 32 | |
| 33 | syn match rustAssert "\<assert\(\w\)*!" contained |
| 34 | syn match rustPanic "\<panic\(\w\)*!" contained |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 35 | syn match rustAsync "\<async\%(\s\|\n\)\@=" |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 36 | syn keyword rustKeyword break |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 37 | syn keyword rustKeyword box |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 38 | syn keyword rustKeyword continue |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 39 | syn keyword rustKeyword crate |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 40 | syn keyword rustKeyword extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty |
| 41 | syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite skipempty |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 42 | syn keyword rustKeyword impl let |
| 43 | syn keyword rustKeyword macro |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 44 | syn keyword rustKeyword pub nextgroup=rustPubScope skipwhite skipempty |
| 45 | syn keyword rustKeyword return |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 46 | syn keyword rustKeyword yield |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 47 | syn keyword rustSuper super |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 48 | syn keyword rustKeyword where |
| 49 | syn keyword rustUnsafeKeyword unsafe |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 50 | syn keyword rustKeyword use nextgroup=rustModPath skipwhite skipempty |
| 51 | " FIXME: Scoped impl's name is also fallen in this category |
| 52 | syn keyword rustKeyword mod trait nextgroup=rustIdentifier skipwhite skipempty |
| 53 | syn keyword rustStorage move mut ref static const |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 54 | syn match rustDefault /\<default\ze\_s\+\(impl\|fn\|type\|const\)\>/ |
| 55 | syn keyword rustAwait await |
| 56 | syn match rustKeyword /\<try\>!\@!/ display |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 57 | |
| 58 | syn keyword rustPubScopeCrate crate contained |
| 59 | syn match rustPubScopeDelim /[()]/ contained |
| 60 | syn match rustPubScope /([^()]*)/ contained contains=rustPubScopeDelim,rustPubScopeCrate,rustSuper,rustModPath,rustModPathSep,rustSelf transparent |
| 61 | |
| 62 | syn keyword rustExternCrate crate contained nextgroup=rustIdentifier,rustExternCrateString skipwhite skipempty |
| 63 | " This is to get the `bar` part of `extern crate "foo" as bar;` highlighting. |
| 64 | syn match rustExternCrateString /".*"\_s*as/ contained nextgroup=rustIdentifier skipwhite transparent skipempty contains=rustString,rustOperator |
| 65 | syn keyword rustObsoleteExternMod mod contained nextgroup=rustIdentifier skipwhite skipempty |
| 66 | |
| 67 | syn match rustIdentifier contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 68 | syn match rustFuncName "\%(r#\)\=\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 69 | |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 70 | syn region rustMacroRepeat matchgroup=rustMacroRepeatDelimiters start="$(" end="),\=[*+]" contains=TOP |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 71 | syn match rustMacroVariable "$\w\+" |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 72 | syn match rustRawIdent "\<r#\h\w*" contains=NONE |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 73 | |
| 74 | " Reserved (but not yet used) keywords {{{2 |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 75 | syn keyword rustReservedKeyword become do priv typeof unsized abstract virtual final override |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 76 | |
| 77 | " Built-in types {{{2 |
| 78 | syn keyword rustType isize usize char bool u8 u16 u32 u64 u128 f32 |
| 79 | syn keyword rustType f64 i8 i16 i32 i64 i128 str Self |
| 80 | |
| 81 | " Things from the libstd v1 prelude (src/libstd/prelude/v1.rs) {{{2 |
| 82 | " This section is just straight transformation of the contents of the prelude, |
| 83 | " to make it easy to update. |
| 84 | |
| 85 | " Reexported core operators {{{3 |
| 86 | syn keyword rustTrait Copy Send Sized Sync |
| 87 | syn keyword rustTrait Drop Fn FnMut FnOnce |
| 88 | |
| 89 | " Reexported functions {{{3 |
| 90 | " There’s no point in highlighting these; when one writes drop( or drop::< it |
| 91 | " gets the same highlighting anyway, and if someone writes `let drop = …;` we |
| 92 | " don’t really want *that* drop to be highlighted. |
| 93 | "syn keyword rustFunction drop |
| 94 | |
| 95 | " Reexported types and traits {{{3 |
| 96 | syn keyword rustTrait Box |
| 97 | syn keyword rustTrait ToOwned |
| 98 | syn keyword rustTrait Clone |
| 99 | syn keyword rustTrait PartialEq PartialOrd Eq Ord |
| 100 | syn keyword rustTrait AsRef AsMut Into From |
| 101 | syn keyword rustTrait Default |
| 102 | syn keyword rustTrait Iterator Extend IntoIterator |
| 103 | syn keyword rustTrait DoubleEndedIterator ExactSizeIterator |
| 104 | syn keyword rustEnum Option |
| 105 | syn keyword rustEnumVariant Some None |
| 106 | syn keyword rustEnum Result |
| 107 | syn keyword rustEnumVariant Ok Err |
| 108 | syn keyword rustTrait SliceConcatExt |
| 109 | syn keyword rustTrait String ToString |
| 110 | syn keyword rustTrait Vec |
| 111 | |
| 112 | " Other syntax {{{2 |
| 113 | syn keyword rustSelf self |
| 114 | syn keyword rustBoolean true false |
| 115 | |
| 116 | " If foo::bar changes to foo.bar, change this ("::" to "\."). |
| 117 | " If foo::bar changes to Foo::bar, change this (first "\w" to "\u"). |
| 118 | syn match rustModPath "\w\(\w\)*::[^<]"he=e-3,me=e-3 |
| 119 | syn match rustModPathSep "::" |
| 120 | |
| 121 | syn match rustFuncCall "\w\(\w\)*("he=e-1,me=e-1 |
| 122 | syn match rustFuncCall "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>(); |
| 123 | |
| 124 | " This is merely a convention; note also the use of [A-Z], restricting it to |
| 125 | " latin identifiers rather than the full Unicode uppercase. I have not used |
| 126 | " [:upper:] as it depends upon 'noignorecase' |
| 127 | "syn match rustCapsIdent display "[A-Z]\w\(\w\)*" |
| 128 | |
| 129 | syn match rustOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?" |
| 130 | " This one isn't *quite* right, as we could have binary-& with a reference |
| 131 | syn match rustSigil display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1 |
| 132 | syn match rustSigil display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1 |
| 133 | " This isn't actually correct; a closure with no arguments can be `|| { }`. |
| 134 | " Last, because the & in && isn't a sigil |
| 135 | syn match rustOperator display "&&\|||" |
| 136 | " This is rustArrowCharacter rather than rustArrow for the sake of matchparen, |
| 137 | " so it skips the ->; see http://stackoverflow.com/a/30309949 for details. |
| 138 | syn match rustArrowCharacter display "->" |
| 139 | syn match rustQuestionMark display "?\([a-zA-Z]\+\)\@!" |
| 140 | |
| 141 | syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustPanic |
| 142 | syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustPanic |
| 143 | |
| 144 | syn match rustEscapeError display contained /\\./ |
| 145 | syn match rustEscape display contained /\\\([nrt0\\'"]\|x\x\{2}\)/ |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 146 | syn match rustEscapeUnicode display contained /\\u{\%(\x_*\)\{1,6}}/ |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 147 | syn match rustStringContinuation display contained /\\\n\s*/ |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 148 | syn region rustString matchgroup=rustStringDelimiter start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation |
| 149 | syn region rustString matchgroup=rustStringDelimiter start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell |
| 150 | syn region rustString matchgroup=rustStringDelimiter start='b\?r\z(#*\)"' end='"\z1' contains=@Spell |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 151 | |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 152 | " Match attributes with either arbitrary syntax or special highlighting for |
| 153 | " derives. We still highlight strings and comments inside of the attribute. |
| 154 | syn region rustAttribute start="#!\?\[" end="\]" contains=@rustAttributeContents,rustAttributeParenthesizedParens,rustAttributeParenthesizedCurly,rustAttributeParenthesizedBrackets,rustDerive |
| 155 | syn region rustAttributeParenthesizedParens matchgroup=rustAttribute start="\w\%(\w\)*("rs=e end=")"re=s transparent contained contains=rustAttributeBalancedParens,@rustAttributeContents |
| 156 | syn region rustAttributeParenthesizedCurly matchgroup=rustAttribute start="\w\%(\w\)*{"rs=e end="}"re=s transparent contained contains=rustAttributeBalancedCurly,@rustAttributeContents |
| 157 | syn region rustAttributeParenthesizedBrackets matchgroup=rustAttribute start="\w\%(\w\)*\["rs=e end="\]"re=s transparent contained contains=rustAttributeBalancedBrackets,@rustAttributeContents |
| 158 | syn region rustAttributeBalancedParens matchgroup=rustAttribute start="("rs=e end=")"re=s transparent contained contains=rustAttributeBalancedParens,@rustAttributeContents |
| 159 | syn region rustAttributeBalancedCurly matchgroup=rustAttribute start="{"rs=e end="}"re=s transparent contained contains=rustAttributeBalancedCurly,@rustAttributeContents |
| 160 | syn region rustAttributeBalancedBrackets matchgroup=rustAttribute start="\["rs=e end="\]"re=s transparent contained contains=rustAttributeBalancedBrackets,@rustAttributeContents |
| 161 | syn cluster rustAttributeContents contains=rustString,rustCommentLine,rustCommentBlock,rustCommentLineDocError,rustCommentBlockDocError |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 162 | syn region rustDerive start="derive(" end=")" contained contains=rustDeriveTrait |
| 163 | " This list comes from src/libsyntax/ext/deriving/mod.rs |
| 164 | " Some are deprecated (Encodable, Decodable) or to be removed after a new snapshot (Show). |
| 165 | syn keyword rustDeriveTrait contained Clone Hash RustcEncodable RustcDecodable Encodable Decodable PartialEq Eq PartialOrd Ord Rand Show Debug Default FromPrimitive Send Sync Copy |
| 166 | |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 167 | " dyn keyword: It's only a keyword when used inside a type expression, so |
| 168 | " we make effort here to highlight it only when Rust identifiers follow it |
| 169 | " (not minding the case of pre-2018 Rust where a path starting with :: can |
| 170 | " follow). |
| 171 | " |
| 172 | " This is so that uses of dyn variable names such as in 'let &dyn = &2' |
| 173 | " and 'let dyn = 2' will not get highlighted as a keyword. |
| 174 | syn match rustKeyword "\<dyn\ze\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)" contains=rustDynKeyword |
| 175 | syn keyword rustDynKeyword dyn contained |
| 176 | |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 177 | " Number literals |
| 178 | syn match rustDecNumber display "\<[0-9][0-9_]*\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\=" |
| 179 | syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\=" |
| 180 | syn match rustOctNumber display "\<0o[0-7_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\=" |
| 181 | syn match rustBinNumber display "\<0b[01_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\=" |
| 182 | |
| 183 | " Special case for numbers of the form "1." which are float literals, unless followed by |
| 184 | " an identifier, which makes them integer literals with a method call or field access, |
| 185 | " or by another ".", which makes them integer literals followed by the ".." token. |
| 186 | " (This must go first so the others take precedence.) |
| 187 | syn match rustFloat display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!" |
| 188 | " To mark a number as a normal float, it must have at least one of the three things integral values don't have: |
| 189 | " a decimal point and more numbers; an exponent; and a type suffix. |
| 190 | syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\=" |
| 191 | syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\=" |
| 192 | syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)" |
| 193 | |
| 194 | " For the benefit of delimitMate |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 195 | syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u{\%(\x_*\)\{1,6}}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime |
| 196 | syn region rustGenericRegion display start=/<\%('\|[^[:cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 197 | syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime |
| 198 | |
| 199 | "rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting |
| 200 | syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" |
| 201 | syn match rustLabel display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*:" |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 202 | syn match rustLabel display "\%(\<\%(break\|continue\)\s*\)\@<=\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 203 | syn match rustCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/ |
| 204 | " The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII). |
| 205 | syn match rustCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/ |
| 206 | syn match rustCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 207 | syn match rustCharacter /'\([^\\]\|\\\(.\|x\x\{2}\|u{\%(\x_*\)\{1,6}}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 208 | |
| 209 | syn match rustShebang /\%^#![^[].*/ |
| 210 | syn region rustCommentLine start="//" end="$" contains=rustTodo,@Spell |
| 211 | syn region rustCommentLineDoc start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell |
| 212 | syn region rustCommentLineDocError start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell contained |
| 213 | syn region rustCommentBlock matchgroup=rustCommentBlock start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 214 | syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNest,rustCommentBlockDocRustCode,@Spell |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 215 | syn region rustCommentBlockDocError matchgroup=rustCommentBlockDocError start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained |
| 216 | syn region rustCommentBlockNest matchgroup=rustCommentBlock start="/\*" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent |
| 217 | syn region rustCommentBlockDocNest matchgroup=rustCommentBlockDoc start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent |
| 218 | syn region rustCommentBlockDocNestError matchgroup=rustCommentBlockDocError start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained transparent |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 219 | |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 220 | " FIXME: this is a really ugly and not fully correct implementation. Most |
| 221 | " importantly, a case like ``/* */*`` should have the final ``*`` not being in |
| 222 | " a comment, but in practice at present it leaves comments open two levels |
| 223 | " deep. But as long as you stay away from that particular case, I *believe* |
| 224 | " the highlighting is correct. Due to the way Vim's syntax engine works |
| 225 | " (greedy for start matches, unlike Rust's tokeniser which is searching for |
| 226 | " the earliest-starting match, start or end), I believe this cannot be solved. |
| 227 | " Oh you who would fix it, don't bother with things like duplicating the Block |
| 228 | " rules and putting ``\*\@<!`` at the start of them; it makes it worse, as |
| 229 | " then you must deal with cases like ``/*/**/*/``. And don't try making it |
| 230 | " worse with ``\%(/\@<!\*\)\@<!``, either... |
| 231 | |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 232 | syn keyword rustTodo contained TODO FIXME XXX NB NOTE SAFETY |
| 233 | |
| 234 | " asm! macro {{{2 |
| 235 | syn region rustAsmMacro matchgroup=rustMacro start="\<asm!\s*(" end=")" contains=rustAsmDirSpec,rustAsmSym,rustAsmConst,rustAsmOptionsGroup,rustComment.*,rustString.* |
| 236 | |
| 237 | " Clobbered registers |
| 238 | syn keyword rustAsmDirSpec in out lateout inout inlateout contained nextgroup=rustAsmReg skipwhite skipempty |
| 239 | syn region rustAsmReg start="(" end=")" contained contains=rustString |
| 240 | |
| 241 | " Symbol operands |
| 242 | syn keyword rustAsmSym sym contained nextgroup=rustAsmSymPath skipwhite skipempty |
| 243 | syn region rustAsmSymPath start="\S" end=",\|)"me=s-1 contained contains=rustComment.*,rustIdentifier |
| 244 | |
| 245 | " Const |
| 246 | syn region rustAsmConstBalancedParens start="("ms=s+1 end=")" contained contains=@rustAsmConstExpr |
| 247 | syn cluster rustAsmConstExpr contains=rustComment.*,rust.*Number,rustString,rustAsmConstBalancedParens |
| 248 | syn region rustAsmConst start="const" end=",\|)"me=s-1 contained contains=rustStorage,@rustAsmConstExpr |
| 249 | |
| 250 | " Options |
| 251 | syn region rustAsmOptionsGroup start="options\s*(" end=")" contained contains=rustAsmOptions,rustAsmOptionsKey |
| 252 | syn keyword rustAsmOptionsKey options contained |
| 253 | syn keyword rustAsmOptions pure nomem readonly preserves_flags noreturn nostack att_syntax contained |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 254 | |
| 255 | " Folding rules {{{2 |
| 256 | " Trivial folding rules to begin with. |
| 257 | " FIXME: use the AST to make really good folding |
| 258 | syn region rustFoldBraces start="{" end="}" transparent fold |
| 259 | |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 260 | if !exists("b:current_syntax_embed") |
| 261 | let b:current_syntax_embed = 1 |
| 262 | syntax include @RustCodeInComment <sfile>:p:h/rust.vim |
| 263 | unlet b:current_syntax_embed |
| 264 | |
| 265 | " Currently regions marked as ```<some-other-syntax> will not get |
| 266 | " highlighted at all. In the future, we can do as vim-markdown does and |
| 267 | " highlight with the other syntax. But for now, let's make sure we find |
| 268 | " the closing block marker, because the rules below won't catch it. |
| 269 | syn region rustCommentLinesDocNonRustCode matchgroup=rustCommentDocCodeFence start='^\z(\s*//[!/]\s*```\).\+$' end='^\z1$' keepend contains=rustCommentLineDoc |
| 270 | |
| 271 | " We borrow the rules from rust’s src/librustdoc/html/markdown.rs, so that |
| 272 | " we only highlight as Rust what it would perceive as Rust (almost; it’s |
| 273 | " possible to trick it if you try hard, and indented code blocks aren’t |
| 274 | " supported because Markdown is a menace to parse and only mad dogs and |
| 275 | " Englishmen would try to handle that case correctly in this syntax file). |
| 276 | syn region rustCommentLinesDocRustCode matchgroup=rustCommentDocCodeFence start='^\z(\s*//[!/]\s*```\)[^A-Za-z0-9_-]*\%(\%(should_panic\|no_run\|ignore\|allow_fail\|rust\|test_harness\|compile_fail\|E\d\{4}\|edition201[58]\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment,rustCommentLineDocLeader |
| 277 | syn region rustCommentBlockDocRustCode matchgroup=rustCommentDocCodeFence start='^\z(\%(\s*\*\)\?\s*```\)[^A-Za-z0-9_-]*\%(\%(should_panic\|no_run\|ignore\|allow_fail\|rust\|test_harness\|compile_fail\|E\d\{4}\|edition201[58]\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment,rustCommentBlockDocStar |
| 278 | " Strictly, this may or may not be correct; this code, for example, would |
| 279 | " mishighlight: |
| 280 | " |
| 281 | " /** |
| 282 | " ```rust |
| 283 | " println!("{}", 1 |
| 284 | " * 1); |
| 285 | " ``` |
| 286 | " */ |
| 287 | " |
| 288 | " … but I don’t care. Balance of probability, and all that. |
| 289 | syn match rustCommentBlockDocStar /^\s*\*\s\?/ contained |
| 290 | syn match rustCommentLineDocLeader "^\s*//\%(//\@!\|!\)" contained |
| 291 | endif |
| 292 | |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 293 | " Default highlighting {{{1 |
| 294 | hi def link rustDecNumber rustNumber |
| 295 | hi def link rustHexNumber rustNumber |
| 296 | hi def link rustOctNumber rustNumber |
| 297 | hi def link rustBinNumber rustNumber |
| 298 | hi def link rustIdentifierPrime rustIdentifier |
| 299 | hi def link rustTrait rustType |
| 300 | hi def link rustDeriveTrait rustTrait |
| 301 | |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 302 | hi def link rustMacroRepeatDelimiters Macro |
| 303 | hi def link rustMacroVariable Define |
| 304 | hi def link rustSigil StorageClass |
| 305 | hi def link rustEscape Special |
| 306 | hi def link rustEscapeUnicode rustEscape |
| 307 | hi def link rustEscapeError Error |
| 308 | hi def link rustStringContinuation Special |
| 309 | hi def link rustString String |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 310 | hi def link rustStringDelimiter String |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 311 | hi def link rustCharacterInvalid Error |
| 312 | hi def link rustCharacterInvalidUnicode rustCharacterInvalid |
| 313 | hi def link rustCharacter Character |
| 314 | hi def link rustNumber Number |
| 315 | hi def link rustBoolean Boolean |
| 316 | hi def link rustEnum rustType |
| 317 | hi def link rustEnumVariant rustConstant |
| 318 | hi def link rustConstant Constant |
| 319 | hi def link rustSelf Constant |
| 320 | hi def link rustFloat Float |
| 321 | hi def link rustArrowCharacter rustOperator |
| 322 | hi def link rustOperator Operator |
| 323 | hi def link rustKeyword Keyword |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 324 | hi def link rustDynKeyword rustKeyword |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 325 | hi def link rustTypedef Keyword " More precise is Typedef, but it doesn't feel right for Rust |
| 326 | hi def link rustStructure Keyword " More precise is Structure |
| 327 | hi def link rustUnion rustStructure |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 328 | hi def link rustExistential rustKeyword |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 329 | hi def link rustPubScopeDelim Delimiter |
| 330 | hi def link rustPubScopeCrate rustKeyword |
| 331 | hi def link rustSuper rustKeyword |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 332 | hi def link rustUnsafeKeyword Exception |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 333 | hi def link rustReservedKeyword Error |
| 334 | hi def link rustRepeat Conditional |
| 335 | hi def link rustConditional Conditional |
| 336 | hi def link rustIdentifier Identifier |
| 337 | hi def link rustCapsIdent rustIdentifier |
| 338 | hi def link rustModPath Include |
| 339 | hi def link rustModPathSep Delimiter |
| 340 | hi def link rustFunction Function |
| 341 | hi def link rustFuncName Function |
| 342 | hi def link rustFuncCall Function |
| 343 | hi def link rustShebang Comment |
| 344 | hi def link rustCommentLine Comment |
| 345 | hi def link rustCommentLineDoc SpecialComment |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 346 | hi def link rustCommentLineDocLeader rustCommentLineDoc |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 347 | hi def link rustCommentLineDocError Error |
| 348 | hi def link rustCommentBlock rustCommentLine |
| 349 | hi def link rustCommentBlockDoc rustCommentLineDoc |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 350 | hi def link rustCommentBlockDocStar rustCommentBlockDoc |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 351 | hi def link rustCommentBlockDocError Error |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 352 | hi def link rustCommentDocCodeFence rustCommentLineDoc |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 353 | hi def link rustAssert PreCondit |
| 354 | hi def link rustPanic PreCondit |
| 355 | hi def link rustMacro Macro |
| 356 | hi def link rustType Type |
| 357 | hi def link rustTodo Todo |
| 358 | hi def link rustAttribute PreProc |
| 359 | hi def link rustDerive PreProc |
| 360 | hi def link rustDefault StorageClass |
| 361 | hi def link rustStorage StorageClass |
| 362 | hi def link rustObsoleteStorage Error |
| 363 | hi def link rustLifetime Special |
| 364 | hi def link rustLabel Label |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 365 | hi def link rustExternCrate rustKeyword |
| 366 | hi def link rustObsoleteExternMod Error |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 367 | hi def link rustQuestionMark Special |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 368 | hi def link rustAsync rustKeyword |
| 369 | hi def link rustAwait rustKeyword |
| 370 | hi def link rustAsmDirSpec rustKeyword |
| 371 | hi def link rustAsmSym rustKeyword |
| 372 | hi def link rustAsmOptions rustKeyword |
| 373 | hi def link rustAsmOptionsKey rustAttribute |
Bram Moolenaar | 3c2881d | 2017-03-21 19:18:29 +0100 | [diff] [blame] | 374 | |
| 375 | " Other Suggestions: |
| 376 | " hi rustAttribute ctermfg=cyan |
| 377 | " hi rustDerive ctermfg=cyan |
| 378 | " hi rustAssert ctermfg=yellow |
| 379 | " hi rustPanic ctermfg=red |
| 380 | " hi rustMacro ctermfg=magenta |
| 381 | |
| 382 | syn sync minlines=200 |
| 383 | syn sync maxlines=500 |
| 384 | |
| 385 | let b:current_syntax = "rust" |
Gregory Anders | fc93594 | 2023-09-12 13:23:38 -0500 | [diff] [blame] | 386 | |
| 387 | " vim: set et sw=4 sts=4 ts=8: |