summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Stankiewicz <sheerun@sher.pl>2013-09-26 12:44:31 +0200
committerAdam Stankiewicz <sheerun@sher.pl>2013-09-26 12:44:31 +0200
commit90d87abd3051c5acf15bc352c9f51f18e23b7095 (patch)
treebf13d90559fdbfeeb7cf79cb0c2e04edfeed7443
parentd6710f1b578ee233e92d1810fdb3e5c9fba651f7 (diff)
downloadvim-polyglot-90d87abd3051c5acf15bc352c9f51f18e23b7095.tar.gz
vim-polyglot-90d87abd3051c5acf15bc352c9f51f18e23b7095.zip
Add Rust lang support
-rw-r--r--after/syntax/rust.vim33
-rwxr-xr-xbuild1
-rw-r--r--compiler/rustc.vim33
-rw-r--r--ftdetect/polyglot.vim1
-rw-r--r--ftplugin/rust.vim45
-rw-r--r--indent/rust.vim147
-rw-r--r--syntax/rust.vim251
7 files changed, 511 insertions, 0 deletions
diff --git a/after/syntax/rust.vim b/after/syntax/rust.vim
new file mode 100644
index 00000000..1ab8394e
--- /dev/null
+++ b/after/syntax/rust.vim
@@ -0,0 +1,33 @@
+if !exists('g:rust_conceal') || !has('conceal') || &enc != 'utf-8'
+ finish
+endif
+
+" For those who don't want to see `::`...
+if exists('g:rust_conceal_mod_path')
+ syn match rustNiceOperator "::" conceal cchar=ㆍ
+endif
+
+syn match rustRightArrowHead contained ">" conceal cchar= 
+syn match rustRightArrowTail contained "-" conceal cchar=⟶
+syn match rustNiceOperator "->" contains=rustRightArrowHead,rustRightArrowTail
+
+syn match rustFatRightArrowHead contained ">" conceal cchar= 
+syn match rustFatRightArrowTail contained "=" conceal cchar=⟹
+syn match rustNiceOperator "=>" contains=rustFatRightArrowHead,rustFatRightArrowTail
+
+syn match rustNiceOperator /\<\@!_\(_*\>\)\@=/ conceal cchar=′
+
+" For those who don't want to see `pub`...
+if exists('g:rust_conceal_pub')
+ syn match rustPublicSigil contained "pu" conceal cchar=*
+ syn match rustPublicRest contained "b" conceal cchar= 
+ syn match rustNiceOperator "pub " contains=rustPublicSigil,rustPublicRest
+endif
+
+hi link rustNiceOperator Operator
+
+if !exists('g:rust_conceal_mod_path')
+ hi! link Conceal Operator
+endif
+
+setlocal conceallevel=2
diff --git a/build b/build
index b39c94ec..2eff07a1 100755
--- a/build
+++ b/build
@@ -98,6 +98,7 @@ PACKS="
python:vim-scripts/python.vim--Vasiliev
rspec:sheerun/rspec.vim
ruby:vim-ruby/vim-ruby
+ rust:wting/rust.vim
sbt:derekwyatt/vim-sbt
scala:derekwyatt/vim-scala
slim:slim-template/vim-slim
diff --git a/compiler/rustc.vim b/compiler/rustc.vim
new file mode 100644
index 00000000..f9b854ed
--- /dev/null
+++ b/compiler/rustc.vim
@@ -0,0 +1,33 @@
+" Vim compiler file
+" Compiler: Rust Compiler
+" Maintainer: Chris Morgan <me@chrismorgan.info>
+" Latest Revision: 2013 Jul 12
+
+if exists("current_compiler")
+ finish
+endif
+let current_compiler = "rustc"
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+if exists(":CompilerSet") != 2
+ command -nargs=* CompilerSet setlocal <args>
+endif
+
+if exists("g:rustc_makeprg_no_percent") && g:rustc_makeprg_no_percent == 1
+ CompilerSet makeprg=rustc
+else
+ CompilerSet makeprg=rustc\ \%
+endif
+
+CompilerSet errorformat=
+ \%f:%l:%c:\ %t%*[^:]:\ %m,
+ \%f:%l:%c:\ %*\\d:%*\\d\ %t%*[^:]:\ %m,
+ \%-G%f:%l\ %s,
+ \%-G%*[\ ]^,
+ \%-G%*[\ ]^%*[~],
+ \%-G%*[\ ]...
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim
index 2ed87038..3c2604c0 100644
--- a/ftdetect/polyglot.vim
+++ b/ftdetect/polyglot.vim
@@ -104,6 +104,7 @@ au BufNewFile,BufRead *.jbuilder set filetype=ruby
au BufNewFile,BufRead Puppetfile set filetype=ruby
au BufNewFile,BufRead [Bb]uildfile set filetype=ruby
au BufNewFile,BufRead Appraisals set filetype=ruby
+au BufRead,BufNewFile *.rs,*.rc set filetype=rust
au BufRead,BufNewFile *.sbt set filetype=sbt
fun! s:DetectScala()
if getline(1) == '#!/usr/bin/env scala'
diff --git a/ftplugin/rust.vim b/ftplugin/rust.vim
new file mode 100644
index 00000000..281a63ef
--- /dev/null
+++ b/ftplugin/rust.vim
@@ -0,0 +1,45 @@
+" Vim syntax file
+" Language: Rust
+" Maintainer: Chris Morgan <me@chrismorgan.info>
+" Last Change: 2013 Jul 10
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+" The rust source code at present seems to typically omit a leader on /*!
+" comments, so we'll use that as our default, but make it easy to switch.
+" This does not affect indentation at all (I tested it with and without
+" leader), merely whether a leader is inserted by default or not.
+if exists("g:rust_bang_comment_leader") && g:rust_bang_comment_leader == 1
+ " Why is the `,s0:/*,mb:\ ,ex:*/` there, you ask? I don't understand why,
+ " but without it, */ gets indented one space even if there were no
+ " leaders. I'm fairly sure that's a Vim bug.
+ setlocal comments=s1:/*,mb:*,ex:*/,s0:/*,mb:\ ,ex:*/,:///,://!,://
+else
+ setlocal comments=s0:/*!,m:\ ,ex:*/,s1:/*,mb:*,ex:*/,:///,://!,://
+endif
+setlocal commentstring=//%s
+setlocal formatoptions-=t formatoptions+=croqnl
+" j was only added in 7.3.541, so stop complaints about its nonexistence
+silent! setlocal formatoptions+=j
+
+" This includeexpr isn't perfect, but it's a good start
+setlocal includeexpr=substitute(v:fname,'::','/','g')
+
+" NOT adding .rc as it's being phased out (0.7)
+setlocal suffixesadd=.rs
+
+if exists("g:ftplugin_rust_source_path")
+ let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
+endif
+
+if exists("g:loaded_delimitMate")
+ if exists("b:delimitMate_excluded_regions")
+ let b:rust_original_delimitMate_excluded_regions = b:delimitMate_excluded_regions
+ endif
+ let b:delimitMate_excluded_regions = delimitMate#Get("excluded_regions") . ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
+endif
+
+let b:undo_ftplugin = "setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd< | if exists('b:rust_original_delimitMate_excluded_regions') | let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions | unlet b:rust_original_delimitMate_excluded_regions | elseif exists('b:delimitMate_excluded_regions') | unlet b:delimitMate_excluded_regions | endif"
diff --git a/indent/rust.vim b/indent/rust.vim
new file mode 100644
index 00000000..ae3ca403
--- /dev/null
+++ b/indent/rust.vim
@@ -0,0 +1,147 @@
+" Vim indent file
+" Language: Rust
+" Author: Chris Morgan <me@chrismorgan.info>
+" Last Change: 2013 Jul 10
+
+" Only load this indent file when no other was loaded.
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+setlocal cindent
+setlocal cinoptions=L0,(0,Ws,JN,j1
+setlocal cinkeys=0{,0},!^F,o,O,0[,0]
+" Don't think cinwords will actually do anything at all... never mind
+setlocal cinwords=do,for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern
+
+" Some preliminary settings
+setlocal nolisp " Make sure lisp indenting doesn't supersede us
+setlocal autoindent " indentexpr isn't much help otherwise
+" Also do indentkeys, otherwise # gets shoved to column 0 :-/
+setlocal indentkeys=0{,0},!^F,o,O,0[,0]
+
+setlocal indentexpr=GetRustIndent(v:lnum)
+
+" Only define the function once.
+if exists("*GetRustIndent")
+ finish
+endif
+
+" Come here when loading the script the first time.
+
+function s:get_line_trimmed(lnum)
+ " Get the line and remove a trailing comment.
+ " Use syntax highlighting attributes when possible.
+ " NOTE: this is not accurate; /* */ or a line continuation could trick it
+ let line = getline(a:lnum)
+ let line_len = strlen(line)
+ if has('syntax_items')
+ " If the last character in the line is a comment, do a binary search for
+ " the start of the comment. synID() is slow, a linear search would take
+ " too long on a long line.
+ if synIDattr(synID(a:lnum, line_len, 1), "name") =~ "Comment\|Todo"
+ let min = 1
+ let max = line_len
+ while min < max
+ let col = (min + max) / 2
+ if synIDattr(synID(a:lnum, col, 1), "name") =~ "Comment\|Todo"
+ let max = col
+ else
+ let min = col + 1
+ endif
+ endwhile
+ let line = strpart(line, 0, min - 1)
+ endif
+ return substitute(line, "\s*$", "", "")
+ else
+ " Sorry, this is not complete, nor fully correct (e.g. string "//").
+ " Such is life.
+ return substitute(line, "\s*//.*$", "", "")
+ endif
+endfunction
+
+function GetRustIndent(lnum)
+
+ " Starting assumption: cindent (called at the end) will do it right
+ " normally. We just want to fix up a few cases.
+
+ let line = getline(a:lnum)
+
+ if has('syntax_items')
+ let synname = synIDattr(synID(a:lnum, 1, 1), "name")
+ if synname == "rustString"
+ " If the start of the line is in a string, don't change the indent
+ return -1
+ elseif synname =~ "\\(Comment\\|Todo\\)"
+ \ && line !~ "^\\s*/\\*" " not /* opening line
+ if synname =~ "CommentML" " multi-line
+ if line !~ "^\\s*\\*" && getline(a:lnum - 1) =~ "^\\s*/\\*"
+ " This is (hopefully) the line after a /*, and it has no
+ " leader, so the correct indentation is that of the
+ " previous line.
+ return GetRustIndent(a:lnum - 1)
+ endif
+ endif
+ " If it's in a comment, let cindent take care of it now. This is
+ " for cases like "/*" where the next line should start " * ", not
+ " "* " as the code below would otherwise cause for module scope
+ " Fun fact: " /*\n*\n*/" takes two calls to get right!
+ return cindent(a:lnum)
+ endif
+ endif
+
+ " cindent gets second and subsequent match patterns/struct members wrong,
+ " as it treats the comma as indicating an unfinished statement::
+ "
+ " match a {
+ " b => c,
+ " d => e,
+ " f => g,
+ " };
+
+ " Search backwards for the previous non-empty line.
+ let prevline = s:get_line_trimmed(prevnonblank(a:lnum - 1))
+ if prevline[len(prevline) - 1] == ","
+ \ && s:get_line_trimmed(a:lnum) !~ "^\\s*[\\[\\]{}]"
+ " Oh ho! The previous line ended in a comma! I bet cindent will try to
+ " take this too far... For now, let's use the previous line's indent
+ return GetRustIndent(a:lnum - 1)
+ endif
+
+ " cindent doesn't do the module scope well at all; e.g.::
+ "
+ " static FOO : &'static [bool] = [
+ " true,
+ " false,
+ " false,
+ " true,
+ " ];
+ "
+ " uh oh, next statement is indented further!
+
+ " Note that this does *not* apply the line continuation pattern properly;
+ " that's too hard to do correctly for my liking at present, so I'll just
+ " start with these two main cases (square brackets and not returning to
+ " column zero)
+
+ call cursor(a:lnum, 1)
+ if searchpair('{\|(', '', '}\|)', 'nbW') == 0
+ if searchpair('\[', '', '\]', 'nbW') == 0
+ " Global scope, should be zero
+ return 0
+ else
+ " At the module scope, inside square brackets only
+ "if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum
+ if line =~ "^\\s*]"
+ " It's the closing line, dedent it
+ return 0
+ else
+ return &shiftwidth
+ endif
+ endif
+ endif
+
+ " Fall back on cindent, which does it mostly right
+ return cindent(a:lnum)
+endfunction
diff --git a/syntax/rust.vim b/syntax/rust.vim
new file mode 100644
index 00000000..689af99b
--- /dev/null
+++ b/syntax/rust.vim
@@ -0,0 +1,251 @@
+" Vim syntax file
+" Language: Rust
+" Maintainer: Patrick Walton <pcwalton@mozilla.com>
+" Maintainer: Ben Blum <bblum@cs.cmu.edu>
+" Maintainer: Chris Morgan <me@chrismorgan.info>
+" Last Change: 2013 Sep 4
+
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+" Syntax definitions {{{1
+" Basic keywords {{{2
+syn keyword rustConditional match if else
+syn keyword rustOperator as
+
+syn match rustAssert "\<assert\(\w\)*!" contained
+syn match rustFail "\<fail\(\w\)*!" contained
+syn keyword rustKeyword break do extern
+syn keyword rustKeyword in if impl let log
+syn keyword rustKeyword for impl let log
+syn keyword rustKeyword loop mod once priv pub
+syn keyword rustKeyword return
+syn keyword rustKeyword unsafe while
+syn keyword rustKeyword use nextgroup=rustModPath skipwhite
+" FIXME: Scoped impl's name is also fallen in this category
+syn keyword rustKeyword mod trait struct enum type nextgroup=rustIdentifier skipwhite
+syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite
+syn keyword rustStorage const mut ref static
+
+syn match rustIdentifier contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
+syn match rustFuncName "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
+
+" Reserved (but not yet used) keywords {{{2
+syn keyword rustKeyword alignof be offsetof pure sizeof typeof yield
+
+" Built-in types {{{2
+syn keyword rustType int uint float char bool u8 u16 u32 u64 f32
+syn keyword rustType f64 i8 i16 i32 i64 str Self
+
+" Things from the prelude (src/libstd/prelude.rs) {{{2
+" This section is just straight transformation of the contents of the prelude,
+" to make it easy to update.
+
+" Core operators {{{3
+syn keyword rustEnum Either
+syn keyword rustEnumVariant Left Right
+syn keyword rustTrait Sized
+syn keyword rustTrait Freeze Send
+syn keyword rustTrait Add Sub Mul Div Rem Neg Not
+syn keyword rustTrait BitAnd BitOr BitXor
+syn keyword rustTrait Drop
+syn keyword rustTrait Shl Shr Index
+syn keyword rustEnum Option
+syn keyword rustEnumVariant Some None
+syn keyword rustEnum Result
+syn keyword rustEnumVariant Ok Err
+
+" Functions {{{3
+"syn keyword rustFunction print println
+"syn keyword rustFunction range
+
+" Types and traits {{{3
+syn keyword rustTrait ToCStr
+syn keyword rustTrait Clone DeepClone
+syn keyword rustTrait Eq ApproxEq Ord TotalEq TotalOrd Ordering Equiv
+syn keyword rustEnumVariant Less Equal Greater
+syn keyword rustTrait Char
+syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
+syn keyword rustTrait Hash
+syn keyword rustTrait Times
+syn keyword rustTrait FromIterator Extendable
+syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator ClonableIterator
+syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
+syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul
+syn keyword rustTrait Orderable Signed Unsigned Round
+syn keyword rustTrait Algebraic Trigonometric Exponential Hyperbolic
+syn keyword rustTrait Integer Fractional Real RealExt
+syn keyword rustTrait Bitwise BitCount Bounded
+syn keyword rustTrait Primitive Int Float ToStrRadix
+syn keyword rustTrait GenericPath
+syn keyword rustTrait Path
+syn keyword rustTrait PosixPath
+syn keyword rustTrait WindowsPath
+syn keyword rustTrait RawPtr
+syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr ToBytesConsume
+syn keyword rustTrait Str StrVector StrSlice OwnedStr
+syn keyword rustTrait FromStr
+syn keyword rustTrait IterBytes
+syn keyword rustTrait ToStr ToStrConsume
+syn keyword rustTrait CopyableTuple ImmutableTuple
+syn keyword rustTrait CloneableTuple1 ImmutableTuple1
+syn keyword rustTrait CloneableTuple2 CloneableTuple3 CloneableTuple4 CloneableTuple5
+syn keyword rustTrait CloneableTuple6 CloneableTuple7 CloneableTuple8 CloneableTuple9
+syn keyword rustTrait CloneableTuple10 CloneableTuple11 CloneableTuple12
+syn keyword rustTrait ImmutableTuple2 ImmutableTuple3 ImmutableTuple4 ImmutableTuple5
+syn keyword rustTrait ImmutableTuple6 ImmutableTuple7 ImmutableTuple8 ImmutableTuple9
+syn keyword rustTrait ImmutableTuple10 ImmutableTuple11 ImmutableTuple12
+syn keyword rustTrait Vector VectorVector CopyableVector ImmutableVector
+syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCopyableVector
+syn keyword rustTrait OwnedVector OwnedCopyableVector OwnedEqVector MutableVector
+syn keyword rustTrait Reader ReaderUtil Writer WriterUtil
+syn keyword rustTrait Default
+
+"syn keyword rustFunction stream
+syn keyword rustTrait Port Chan GenericChan GenericSmartChan GenericPort Peekable
+"syn keyword rustFunction spawn
+
+syn keyword rustSelf self
+syn keyword rustBoolean true false
+
+syn keyword rustConstant Some None " option
+syn keyword rustConstant Left Right " either
+syn keyword rustConstant Ok Err " result
+syn keyword rustConstant Less Equal Greater " Ordering
+
+" Other syntax {{{2
+
+" If foo::bar changes to foo.bar, change this ("::" to "\.").
+" If foo::bar changes to Foo::bar, change this (first "\w" to "\u").
+syn match rustModPath "\w\(\w\)*::[^<]"he=e-3,me=e-3
+syn match rustModPath "\w\(\w\)*" contained " only for 'use path;'
+syn match rustModPathSep "::"
+
+syn match rustFuncCall "\w\(\w\)*("he=e-1,me=e-1
+syn match rustFuncCall "\w\(\w\)*::<"he=e-3,me=e-3 " foo::<T>();
+
+" This is merely a convention; note also the use of [A-Z], restricting it to
+" latin identifiers rather than the full Unicode uppercase. I have not used
+" [:upper:] as it depends upon 'noignorecase'
+"syn match rustCapsIdent display "[A-Z]\w\(\w\)*"
+
+syn match rustOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?"
+" This one isn't *quite* right, as we could have binary-& with a reference
+syn match rustSigil display /&\s\+[&~@*][^)= \t\r\n]/he=e-1,me=e-1
+syn match rustSigil display /[&~@*][^)= \t\r\n]/he=e-1,me=e-1
+" This isn't actually correct; a closure with no arguments can be `|| { }`.
+" Last, because the & in && isn't a sigil
+syn match rustOperator display "&&\|||"
+
+syn match rustMacro '\w\(\w\)*!' contains=rustAssert,rustFail
+syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustFail
+
+syn match rustFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn?]\|\[\^\=.[^]]*\]\)" contained
+syn match rustFormat display "%%" contained
+syn match rustSpecial display contained /\\\([nrt\\'"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)/
+syn match rustStringContinuation display contained /\\\n\s*/
+syn region rustString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustTodo,rustFormat,rustSpecial,rustStringContinuation
+
+syn region rustAttribute start="#\[" end="\]" contains=rustString,rustDeriving
+syn region rustDeriving start="deriving(" end=")" contained contains=rustTrait
+
+" Number literals
+syn match rustNumber display "\<[0-9][0-9_]*\>"
+syn match rustNumber display "\<[0-9][0-9_]*\(u\|u8\|u16\|u32\|u64\)\>"
+syn match rustNumber display "\<[0-9][0-9_]*\(i\|i8\|i16\|i32\|i64\)\>"
+
+syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\>"
+syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\(u\|u8\|u16\|u32\|u64\)\>"
+syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\(i8\|i16\|i32\|i64\)\>"
+syn match rustBinNumber display "\<0b[01_]\+\>"
+syn match rustBinNumber display "\<0b[01_]\+\(u\|u8\|u16\|u32\|u64\)\>"
+syn match rustBinNumber display "\<0b[01_]\+\(i8\|i16\|i32\|i64\)\>"
+
+syn match rustFloat display "\<[0-9][0-9_]*\(f\|f32\|f64\)\>"
+syn match rustFloat display "\<[0-9][0-9_]*\([eE][+-]\=[0-9_]\+\)\>"
+syn match rustFloat display "\<[0-9][0-9_]*\([eE][+-]\=[0-9_]\+\)\(f\|f32\|f64\)\>"
+syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\>"
+syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\(f\|f32\|f64\)\>"
+syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\%([eE][+-]\=[0-9_]\+\)\>"
+syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\%([eE][+-]\=[0-9_]\+\)\(f\|f32\|f64\)\>"
+
+" For the benefit of delimitMate
+syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt\\\"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
+syn region rustGenericRegion display start=/<\%('\|[^[cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate
+syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
+
+"rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting
+syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
+syn match rustCharacter /'\([^'\\]\|\\\([nrt\\'"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'/ contains=rustSpecial
+
+syn region rustCommentML start="/\*" end="\*/" contains=rustTodo
+syn region rustComment start="//" end="$" contains=rustTodo keepend
+syn region rustCommentMLDoc start="/\*\%(!\|\*/\@!\)" end="\*/" contains=rustTodo
+syn region rustCommentDoc start="//[/!]" end="$" contains=rustTodo keepend
+
+syn keyword rustTodo contained TODO FIXME XXX NB NOTE
+
+" Folding rules {{{2
+" Trivial folding rules to begin with.
+" TODO: use the AST to make really good folding
+syn region rustFoldBraces start="{" end="}" transparent fold
+" If you wish to enable this, setlocal foldmethod=syntax
+" It's not enabled by default as it would drive some people mad.
+
+" Default highlighting {{{1
+hi def link rustHexNumber rustNumber
+hi def link rustBinNumber rustNumber
+hi def link rustIdentifierPrime rustIdentifier
+hi def link rustTrait rustType
+
+hi def link rustSigil StorageClass
+hi def link rustFormat Special
+hi def link rustSpecial Special
+hi def link rustStringContinuation Special
+hi def link rustString String
+hi def link rustCharacter Character
+hi def link rustNumber Number
+hi def link rustBoolean Boolean
+hi def link rustEnum rustType
+hi def link rustEnumVariant rustConstant
+hi def link rustConstant Constant
+hi def link rustSelf Constant
+hi def link rustFloat Float
+hi def link rustOperator Operator
+hi def link rustKeyword Keyword
+hi def link rustConditional Conditional
+hi def link rustIdentifier Identifier
+hi def link rustCapsIdent rustIdentifier
+hi def link rustModPath Include
+hi def link rustModPathSep Delimiter
+hi def link rustFunction Function
+hi def link rustFuncName Function
+hi def link rustFuncCall Function
+hi def link rustCommentMLDoc rustCommentDoc
+hi def link rustCommentDoc SpecialComment
+hi def link rustCommentML rustComment
+hi def link rustComment Comment
+hi def link rustAssert PreCondit
+hi def link rustFail PreCondit
+hi def link rustMacro Macro
+hi def link rustType Type
+hi def link rustTodo Todo
+hi def link rustAttribute PreProc
+hi def link rustDeriving PreProc
+hi def link rustStorage StorageClass
+hi def link rustLifetime Special
+
+" Other Suggestions:
+" hi rustAttribute ctermfg=cyan
+" hi rustDeriving ctermfg=cyan
+" hi rustAssert ctermfg=yellow
+" hi rustFail ctermfg=red
+" hi rustMacro ctermfg=magenta
+
+syn sync minlines=200
+syn sync maxlines=500
+
+let b:current_syntax = "rust"