summaryrefslogtreecommitdiffstats
path: root/syntax/rust.vim
diff options
context:
space:
mode:
Diffstat (limited to 'syntax/rust.vim')
-rw-r--r--syntax/rust.vim59
1 files changed, 52 insertions, 7 deletions
diff --git a/syntax/rust.vim b/syntax/rust.vim
index 81abf942..90e5b6b6 100644
--- a/syntax/rust.vim
+++ b/syntax/rust.vim
@@ -9,9 +9,9 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
if version < 600
- syntax clear
+ syntax clear
elseif exists("b:current_syntax")
- finish
+ finish
endif
" Syntax definitions {{{1
@@ -29,6 +29,7 @@ syn match rustPanic "\<panic\(\w\)*!" contained
syn keyword rustKeyword break
syn keyword rustKeyword box nextgroup=rustBoxPlacement skipwhite skipempty
syn keyword rustKeyword continue
+syn keyword rustKeyword crate
syn keyword rustKeyword extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite skipempty
syn keyword rustKeyword fn nextgroup=rustFuncName skipwhite skipempty
syn keyword rustKeyword in impl let
@@ -45,8 +46,6 @@ syn keyword rustKeyword mod trait nextgroup=rustIdentifier skipwhite skipe
syn keyword rustStorage move mut ref static const
syn match rustDefault /\<default\ze\_s\+\(impl\|fn\|type\|const\)\>/
-syn keyword rustInvalidBareKeyword crate
-
syn keyword rustPubScopeCrate crate contained
syn match rustPubScopeDelim /[()]/ contained
syn match rustPubScope /([^()]*)/ contained contains=rustPubScopeDelim,rustPubScopeCrate,rustSuper,rustModPath,rustModPathSep,rustSelf transparent
@@ -155,6 +154,16 @@ syn region rustDerive start="derive(" end=")" contained contains=rustDer
" Some are deprecated (Encodable, Decodable) or to be removed after a new snapshot (Show).
syn keyword rustDeriveTrait contained Clone Hash RustcEncodable RustcDecodable Encodable Decodable PartialEq Eq PartialOrd Ord Rand Show Debug Default FromPrimitive Send Sync Copy
+" dyn keyword: It's only a keyword when used inside a type expression, so
+" we make effort here to highlight it only when Rust identifiers follow it
+" (not minding the case of pre-2018 Rust where a path starting with :: can
+" follow).
+"
+" This is so that uses of dyn variable names such as in 'let &dyn = &2'
+" and 'let dyn = 2' will not get highlighted as a keyword.
+syn match rustKeyword "\<dyn\ze\_s\+\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)" contains=rustDynKeyword
+syn keyword rustDynKeyword dyn contained
+
" Number literals
syn match rustDecNumber display "\<[0-9][0-9_]*\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
syn match rustHexNumber display "\<0x[a-fA-F0-9_]\+\%([iu]\%(size\|8\|16\|32\|64\|128\)\)\="
@@ -174,7 +183,7 @@ syn match rustFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE
" For the benefit of delimitMate
syn region rustLifetimeCandidate display start=/&'\%(\([^'\\]\|\\\(['nrt0\\\"]\|x\x\{2}\|u{\%(\x_*\)\{1,6}}\)\)'\)\@!/ end=/[[:cntrl:][:space:][:punct:]]\@=\|$/ contains=rustSigil,rustLifetime
-syn region rustGenericRegion display start=/<\%('\|[^[cntrl:][:space:][:punct:]]\)\@=')\S\@=/ end=/>/ contains=rustGenericLifetimeCandidate
+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
@@ -191,11 +200,17 @@ syn region rustCommentLine star
syn region rustCommentLineDoc start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell
syn region rustCommentLineDocError start="//\%(//\@!\|!\)" end="$" contains=rustTodo,@Spell contained
syn region rustCommentBlock matchgroup=rustCommentBlock start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell
-syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell
+syn region rustCommentBlockDoc matchgroup=rustCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNest,rustCommentBlockDocRustCode,@Spell
syn region rustCommentBlockDocError matchgroup=rustCommentBlockDocError start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained
syn region rustCommentBlockNest matchgroup=rustCommentBlock start="/\*" end="\*/" contains=rustTodo,rustCommentBlockNest,@Spell contained transparent
syn region rustCommentBlockDocNest matchgroup=rustCommentBlockDoc start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNest,@Spell contained transparent
syn region rustCommentBlockDocNestError matchgroup=rustCommentBlockDocError start="/\*" end="\*/" contains=rustTodo,rustCommentBlockDocNestError,@Spell contained transparent
+
+if exists("b:current_syntax_embed")
+syn match rustCommentLine "^//"
+syn match rustCommentLineDoc "^//\%(//\@!\|!\)"
+endif
+
" FIXME: this is a really ugly and not fully correct implementation. Most
" importantly, a case like ``/* */*`` should have the final ``*`` not being in
" a comment, but in practice at present it leaves comments open two levels
@@ -215,6 +230,32 @@ syn keyword rustTodo contained TODO FIXME XXX NB NOTE
" FIXME: use the AST to make really good folding
syn region rustFoldBraces start="{" end="}" transparent fold
+if !exists("b:current_syntax_embed")
+ let b:current_syntax_embed = 1
+ syntax include @RustCodeInComment <sfile>:p:h/rust.vim
+ unlet b:current_syntax_embed
+
+ " We borrow the rules from rust’s src/librustdoc/html/markdown.rs, so that
+ " we only highlight as Rust what it would perceive as Rust (almost; it’s
+ " possible to trick it if you try hard, and indented code blocks aren’t
+ " supported because Markdown is a menace to parse and only mad dogs and
+ " Englishmen would try to handle that case correctly in this syntax file).
+ 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}\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment
+ 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}\)\%([^A-Za-z0-9_-]\+\|$\)\)*$' end='^\z1$' keepend contains=@RustCodeInComment,rustCommentBlockDocStar
+ " Strictly, this may or may not be correct; this code, for example, would
+ " mishighlight:
+ "
+ " /**
+ " ```rust
+ " println!("{}", 1
+ " * 1);
+ " ```
+ " */
+ "
+ " … but I don’t care. Balance of probability, and all that.
+ syn match rustCommentBlockDocStar /^\s*\*\s\?/ contained
+endif
+
" Default highlighting {{{1
hi def link rustDecNumber rustNumber
hi def link rustHexNumber rustNumber
@@ -246,6 +287,7 @@ hi def link rustFloat Float
hi def link rustArrowCharacter rustOperator
hi def link rustOperator Operator
hi def link rustKeyword Keyword
+hi def link rustDynKeyword rustKeyword
hi def link rustTypedef Keyword " More precise is Typedef, but it doesn't feel right for Rust
hi def link rustStructure Keyword " More precise is Structure
hi def link rustUnion rustStructure
@@ -269,7 +311,9 @@ hi def link rustCommentLineDoc SpecialComment
hi def link rustCommentLineDocError Error
hi def link rustCommentBlock rustCommentLine
hi def link rustCommentBlockDoc rustCommentLineDoc
+hi def link rustCommentBlockDocStar rustCommentBlockDoc
hi def link rustCommentBlockDocError Error
+hi def link rustCommentDocCodeFence rustCommentLineDoc
hi def link rustAssert PreCondit
hi def link rustPanic PreCondit
hi def link rustMacro Macro
@@ -282,7 +326,6 @@ hi def link rustStorage StorageClass
hi def link rustObsoleteStorage Error
hi def link rustLifetime Special
hi def link rustLabel Label
-hi def link rustInvalidBareKeyword Error
hi def link rustExternCrate rustKeyword
hi def link rustObsoleteExternMod Error
hi def link rustBoxPlacementParens Delimiter
@@ -300,4 +343,6 @@ syn sync maxlines=500
let b:current_syntax = "rust"
+" vim: set et sw=4 sts=4 ts=8:
+
endif