]> git.lizzy.rs Git - rust.git/blob - src/etc/vim/syntax/rust.vim
Merge pull request #20510 from tshepang/patch-6
[rust.git] / src / etc / vim / syntax / rust.vim
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>
6 " Last Change:  July 18, 2014
7
8 if version < 600
9   syntax clear
10 elseif exists("b:current_syntax")
11   finish
12 endif
13
14 " Syntax definitions {{{1
15 " Basic keywords {{{2
16 syn keyword   rustConditional match if else
17 syn keyword   rustOperator    as
18
19 syn match     rustAssert      "\<assert\(\w\)*!" contained
20 syn match     rustPanic       "\<panic\(\w\)*!" contained
21 syn keyword   rustKeyword     break
22 syn keyword   rustKeyword     box nextgroup=rustBoxPlacement skipwhite skipempty
23 syn keyword   rustKeyword     continue
24 syn keyword   rustKeyword     extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty
25 syn keyword   rustKeyword     fn nextgroup=rustFuncName skipwhite skipempty
26 syn keyword   rustKeyword     for in if impl let
27 syn keyword   rustKeyword     loop once pub
28 syn keyword   rustKeyword     return super
29 syn keyword   rustKeyword     unsafe virtual where while
30 syn keyword   rustKeyword     use nextgroup=rustModPath skipwhite skipempty
31 " FIXME: Scoped impl's name is also fallen in this category
32 syn keyword   rustKeyword     mod trait struct enum type nextgroup=rustIdentifier skipwhite skipempty
33 syn keyword   rustStorage     move mut ref static const
34
35 syn keyword   rustInvalidBareKeyword crate
36
37 syn keyword   rustExternCrate crate contained nextgroup=rustIdentifier,rustExternCrateString skipwhite skipempty
38 " This is to get the `bar` part of `extern crate "foo" as bar;` highlighting.
39 syn match   rustExternCrateString /".*"\_s*as/ contained nextgroup=rustIdentifier skipwhite transparent skipempty contains=rustString,rustOperator
40 syn keyword   rustObsoleteExternMod mod contained nextgroup=rustIdentifier skipwhite skipempty
41
42 syn match     rustIdentifier  contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
43 syn match     rustFuncName    "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
44
45 syn region    rustBoxPlacement matchgroup=rustBoxPlacementParens start="(" end=")" contains=TOP contained
46 syn keyword   rustBoxPlacementExpr GC containedin=rustBoxPlacement
47 " Ideally we'd have syntax rules set up to match arbitrary expressions. Since
48 " we don't, we'll just define temporary contained rules to handle balancing
49 " delimiters.
50 syn region    rustBoxPlacementBalance start="(" end=")" containedin=rustBoxPlacement transparent
51 syn region    rustBoxPlacementBalance start="\[" end="\]" containedin=rustBoxPlacement transparent
52 " {} are handled by rustFoldBraces
53
54 syn region rustMacroRepeat matchgroup=rustMacroRepeatDelimiters start="$(" end=")" contains=TOP nextgroup=rustMacroRepeatCount
55 syn match rustMacroRepeatCount ".\?[*+]" contained
56 syn match rustMacroVariable "$\w\+"
57
58 " Reserved (but not yet used) keywords {{{2
59 syn keyword   rustReservedKeyword alignof be do offsetof priv pure sizeof typeof unsized yield abstract final override
60
61 " Built-in types {{{2
62 syn keyword   rustType        int uint float char bool u8 u16 u32 u64 f32
63 syn keyword   rustType        f64 i8 i16 i32 i64 str Self
64
65 " Things from the prelude (src/libstd/prelude.rs) {{{2
66 " This section is just straight transformation of the contents of the prelude,
67 " to make it easy to update.
68
69 " Reexported core operators {{{3
70 syn keyword   rustTrait       Copy Send Sized Sync
71 syn keyword   rustTrait       Add Sub Mul Div Rem Neg Not
72 syn keyword   rustTrait       BitAnd BitOr BitXor
73 syn keyword   rustTrait       Drop Deref DerefMut
74 syn keyword   rustTrait       Shl Shr
75 syn keyword   rustTrait       Index IndexMut
76 syn keyword   rustTrait       Slice SliceMut
77 syn keyword   rustTrait       Fn FnMut FnOnce
78
79 " Reexported functions {{{3
80 "syn keyword rustFunction range repeat
81 "syn keyword rustFunction drop
82 "syn keyword rustFunction from_str
83
84 " Reexported types and traits {{{3
85 syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr
86 syn keyword rustTrait IntoBytes
87 syn keyword rustTrait ToCStr
88 syn keyword rustTrait Char UnicodeChar
89 syn keyword rustTrait Clone
90 syn keyword rustTrait PartialEq PartialOrd Eq Ord
91 syn keyword rustEnum Ordering Equiv
92 syn keyword rustEnumVariant Less Equal Greater
93 syn keyword rustTrait FromIterator Extend ExactSizeIterator
94 syn keyword rustTrait Iterator DoubleEndedIterator
95 syn keyword rustTrait RandomAccessIterator CloneableIterator
96 syn keyword rustTrait OrdIterator MutableDoubleEndedIterator
97 syn keyword rustTrait ToPrimitive FromPrimitive
98 syn keyword rustTrait Box
99 syn keyword rustEnum Option
100 syn keyword rustEnumVariant Some None
101 syn keyword rustTrait GenericPath Path PosixPath WindowsPath
102 syn keyword rustTrait RawPtr RawMutPtr
103 syn keyword rustEnum Result
104 syn keyword rustEnumVariant Ok Err
105 syn keyword rustTrait Buffer Writer Reader Seek BufferPrelude
106 syn keyword rustTrait Str StrVector StrPrelude
107 syn keyword rustTrait IntoMaybeOwned StrAllocating UnicodeStrPrelude
108 syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
109 syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
110 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
111 syn keyword rustTrait SlicePrelude AsSlice CloneSlicePrelude
112 syn keyword rustTrait VectorVector PartialEqSlicePrelude OrdSlicePrelude
113 syn keyword rustTrait CloneSliceAllocPrelude OrdSliceAllocPrelude SliceAllocPrelude
114 syn keyword rustTrait IntoString String ToString
115 syn keyword rustTrait Vec
116
117 " Reexported runtime types {{{3
118 "syn keyword rustFunction sync_channel channel
119 syn keyword rustTrait SyncSender Sender Receiver
120 "syn keyword rustFunction spawn
121
122 " Other syntax {{{2
123
124 syn keyword   rustSelf        self
125 syn keyword   rustBoolean     true false
126
127 " If foo::bar changes to foo.bar, change this ("::" to "\.").
128 " If foo::bar changes to Foo::bar, change this (first "\w" to "\u").
129 syn match     rustModPath     "\w\(\w\)*::[^<]"he=e-3,me=e-3
130 syn match     rustModPathSep  "::"
131
132 syn match     rustFuncCall    "\w\(\w\)*("he=e-1,me=e-1
133 syn match     rustFuncCall    "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>();
134
135 " This is merely a convention; note also the use of [A-Z], restricting it to
136 " latin identifiers rather than the full Unicode uppercase. I have not used
137 " [:upper:] as it depends upon 'noignorecase'
138 "syn match     rustCapsIdent    display "[A-Z]\w\(\w\)*"
139
140 syn match     rustOperator     display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?"
141 " This one isn't *quite* right, as we could have binary-& with a reference
142 syn match     rustSigil        display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1
143 syn match     rustSigil        display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1
144 " This isn't actually correct; a closure with no arguments can be `|| { }`.
145 " Last, because the & in && isn't a sigil
146 syn match     rustOperator     display "&&\|||"
147
148 syn match     rustMacro       '\w\(\w\)*!' contains=rustAssert,rustPanic
149 syn match     rustMacro       '#\w\(\w\)*' contains=rustAssert,rustPanic
150
151 syn match     rustEscapeError   display contained /\\./
152 syn match     rustEscape        display contained /\\\([nrt0\\'"]\|x\x\{2}\)/
153 syn match     rustEscapeUnicode display contained /\\\(u\x\{4}\|U\x\{8}\)/
154 syn match     rustEscapeUnicode display contained /\\u{\x\{1,6}}/
155 syn match     rustStringContinuation display contained /\\\n\s*/
156 syn region    rustString      start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeError,rustStringContinuation
157 syn region    rustString      start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustStringContinuation,@Spell
158 syn region    rustString      start='b\?r\z(#*\)"' end='"\z1' contains=@Spell
159
160 syn region    rustAttribute   start="#!\?\[" end="\]" contains=rustString,rustDerive
161 syn region    rustDerive      start="derive(" end=")" contained contains=rustTrait
162
163 " Number literals
164 syn match     rustDecNumber   display "\<[0-9][0-9_]*\%([iu]\%(8\|16\|32\|64\)\=\)\="
165 syn match     rustHexNumber   display "\<0x[a-fA-F0-9_]\+\%([iu]\%(8\|16\|32\|64\)\=\)\="
166 syn match     rustOctNumber   display "\<0o[0-7_]\+\%([iu]\%(8\|16\|32\|64\)\=\)\="
167 syn match     rustBinNumber   display "\<0b[01_]\+\%([iu]\%(8\|16\|32\|64\)\=\)\="
168
169 " Special case for numbers of the form "1." which are float literals, unless followed by
170 " an identifier, which makes them integer literals with a method call or field access,
171 " or by another ".", which makes them integer literals followed by the ".." token.
172 " (This must go first so the others take precedence.)
173 syn match     rustFloat       display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!"
174 " To mark a number as a normal float, it must have at least one of the three things integral values don't have:
175 " a decimal point and more numbers; an exponent; and a type suffix.
176 syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\="
177 syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\="
178 syn match     rustFloat       display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)"
179
180 " For the benefit of delimitMate
181 syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
182 syn region rustGenericRegion display start=/<\%('\|[^[cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate
183 syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
184
185 "rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting
186 syn match     rustLifetime    display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
187 syn match   rustCharacterInvalid   display contained /b\?'\zs[\n\r\t']\ze'/
188 " The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII).
189 syn match   rustCharacterInvalidUnicode   display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/
190 syn match   rustCharacter   /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=rustEscape,rustEscapeError,rustCharacterInvalid,rustCharacterInvalidUnicode
191 syn match   rustCharacter   /'\([^\\]\|\\\(.\|x\x\{2}\|u\x\{4}\|U\x\{8}\|u{\x\{1,6}}\)\)'/ contains=rustEscape,rustEscapeUnicode,rustEscapeError,rustCharacterInvalid
192
193 syn region rustCommentLine                                        start="//"                      end="$"   contains=rustTodo,@Spell
194 syn region rustCommentLineDoc                                     start="//\%(//\@!\|!\)"         end="$"   contains=rustTodo,@Spell
195 syn region rustCommentBlock    matchgroup=rustCommentBlock        start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell
196 syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc     start="/\*\%(!\|\*[*/]\@!\)"    end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell
197 syn region rustCommentBlockNest matchgroup=rustCommentBlock       start="/\*"                     end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent
198 syn region rustCommentBlockDocNest matchgroup=rustCommentBlockDoc start="/\*"                     end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent
199 " FIXME: this is a really ugly and not fully correct implementation. Most
200 " importantly, a case like ``/* */*`` should have the final ``*`` not being in
201 " a comment, but in practice at present it leaves comments open two levels
202 " deep. But as long as you stay away from that particular case, I *believe*
203 " the highlighting is correct. Due to the way Vim's syntax engine works
204 " (greedy for start matches, unlike Rust's tokeniser which is searching for
205 " the earliest-starting match, start or end), I believe this cannot be solved.
206 " Oh you who would fix it, don't bother with things like duplicating the Block
207 " rules and putting ``\*\@<!`` at the start of them; it makes it worse, as
208 " then you must deal with cases like ``/*/**/*/``. And don't try making it
209 " worse with ``\%(/\@<!\*\)\@<!``, either...
210
211 syn keyword rustTodo contained TODO FIXME XXX NB NOTE
212
213 " Folding rules {{{2
214 " Trivial folding rules to begin with.
215 " FIXME: use the AST to make really good folding
216 syn region rustFoldBraces start="{" end="}" transparent fold
217
218 " Default highlighting {{{1
219 hi def link rustDecNumber       rustNumber
220 hi def link rustHexNumber       rustNumber
221 hi def link rustOctNumber       rustNumber
222 hi def link rustBinNumber       rustNumber
223 hi def link rustIdentifierPrime rustIdentifier
224 hi def link rustTrait           rustType
225
226 hi def link rustMacroRepeatCount   rustMacroRepeatDelimiters
227 hi def link rustMacroRepeatDelimiters   Macro
228 hi def link rustMacroVariable Define
229 hi def link rustSigil         StorageClass
230 hi def link rustEscape        Special
231 hi def link rustEscapeUnicode rustEscape
232 hi def link rustEscapeError   Error
233 hi def link rustStringContinuation Special
234 hi def link rustString        String
235 hi def link rustCharacterInvalid Error
236 hi def link rustCharacterInvalidUnicode rustCharacterInvalid
237 hi def link rustCharacter     Character
238 hi def link rustNumber        Number
239 hi def link rustBoolean       Boolean
240 hi def link rustEnum          rustType
241 hi def link rustEnumVariant   rustConstant
242 hi def link rustConstant      Constant
243 hi def link rustSelf          Constant
244 hi def link rustFloat         Float
245 hi def link rustOperator      Operator
246 hi def link rustKeyword       Keyword
247 hi def link rustReservedKeyword Error
248 hi def link rustConditional   Conditional
249 hi def link rustIdentifier    Identifier
250 hi def link rustCapsIdent     rustIdentifier
251 hi def link rustModPath       Include
252 hi def link rustModPathSep    Delimiter
253 hi def link rustFunction      Function
254 hi def link rustFuncName      Function
255 hi def link rustFuncCall      Function
256 hi def link rustCommentLine   Comment
257 hi def link rustCommentLineDoc SpecialComment
258 hi def link rustCommentBlock  rustCommentLine
259 hi def link rustCommentBlockDoc rustCommentLineDoc
260 hi def link rustAssert        PreCondit
261 hi def link rustPanic         PreCondit
262 hi def link rustMacro         Macro
263 hi def link rustType          Type
264 hi def link rustTodo          Todo
265 hi def link rustAttribute     PreProc
266 hi def link rustDerive        PreProc
267 hi def link rustStorage       StorageClass
268 hi def link rustObsoleteStorage Error
269 hi def link rustLifetime      Special
270 hi def link rustInvalidBareKeyword Error
271 hi def link rustExternCrate   rustKeyword
272 hi def link rustObsoleteExternMod Error
273 hi def link rustBoxPlacementParens Delimiter
274 hi def link rustBoxPlacementExpr rustKeyword
275
276 " Other Suggestions:
277 " hi rustAttribute ctermfg=cyan
278 " hi rustDerive ctermfg=cyan
279 " hi rustAssert ctermfg=yellow
280 " hi rustPanic ctermfg=red
281 " hi rustMacro ctermfg=magenta
282
283 syn sync minlines=200
284 syn sync maxlines=500
285
286 let b:current_syntax = "rust"