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