Skip to content

Commit 0a1fc45

Browse files
committed
auto merge of rust-lang#7665 : chris-morgan/rust/better-vim-support, r=cmr
General tweaks for Vim support, especially proper indenting.
2 parents 62bb843 + 121ae82 commit 0a1fc45

File tree

3 files changed

+173
-14
lines changed

3 files changed

+173
-14
lines changed

src/etc/vim/ftplugin/rust.vim

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
" Vim syntax file
2+
" Language: Rust
3+
" Maintainer: Chris Morgan <[email protected]>
4+
" Last Change: 2013 Jul 6
5+
6+
if exists("b:did_ftplugin")
7+
finish
8+
endif
9+
let b:did_ftplugin = 1
10+
11+
setlocal comments=s1:/*,mb:*,ex:*/,:///,://!,://
12+
setlocal commentstring=//%s
13+
setlocal formatoptions-=t formatoptions+=croqnlj
14+
15+
" This includeexpr isn't perfect, but it's a good start
16+
setlocal includeexpr=substitute(v:fname,'::','/','g')
17+
18+
" NOT adding .rc as it's being phased out (0.7)
19+
setlocal suffixesadd=.rs
20+
21+
if exists("g:ftplugin_rust_source_path")
22+
let &l:path=g:ftplugin_rust_source_path . ',' . &l:path
23+
endif
24+
25+
let b:undo_ftplugin = "setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd<"

src/etc/vim/indent/rust.vim

Lines changed: 129 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,137 @@
11
" Vim indent file
2+
" Language: Rust
3+
" Author: Chris Morgan <[email protected]>
4+
" Last Change: 2013 Jul 10
25

6+
" Only load this indent file when no other was loaded.
37
if exists("b:did_indent")
4-
finish
8+
finish
59
endif
6-
710
let b:did_indent = 1
811

912
setlocal cindent
1013
setlocal cinoptions=L0,(0,Ws,JN
11-
setlocal cinkeys=0{,0},!^F,o,O
14+
setlocal cinkeys=0{,0},!^F,o,O,0[,0]
15+
" Don't think cinwords will actually do anything at all... never mind
16+
setlocal cinwords=do,for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern
17+
18+
" Some preliminary settings
19+
setlocal nolisp " Make sure lisp indenting doesn't supersede us
20+
setlocal autoindent " indentexpr isn't much help otherwise
21+
" Also do indentkeys, otherwise # gets shoved to column 0 :-/
22+
setlocal indentkeys=0{,0},!^F,o,O,0[,0]
23+
24+
setlocal indentexpr=GetRustIndent(v:lnum)
25+
26+
" Only define the function once.
27+
if exists("*GetRustIndent")
28+
finish
29+
endif
30+
31+
" Come here when loading the script the first time.
32+
33+
function s:get_line_trimmed(lnum)
34+
" Get the line and remove a trailing comment.
35+
" Use syntax highlighting attributes when possible.
36+
" NOTE: this is not accurate; /* */ or a line continuation could trick it
37+
let line = getline(a:lnum)
38+
let line_len = strlen(line)
39+
if has('syntax_items')
40+
" If the last character in the line is a comment, do a binary search for
41+
" the start of the comment. synID() is slow, a linear search would take
42+
" too long on a long line.
43+
if synIDattr(synID(a:lnum, line_len, 1), "name") =~ "Comment\|Todo"
44+
let min = 1
45+
let max = line_len
46+
while min < max
47+
let col = (min + max) / 2
48+
if synIDattr(synID(a:lnum, col, 1), "name") =~ "Comment\|Todo"
49+
let max = col
50+
else
51+
let min = col + 1
52+
endif
53+
endwhile
54+
let line = strpart(line, 0, min - 1)
55+
endif
56+
return substitute(line, "\s*$", "", "")
57+
else
58+
" Sorry, this is not complete, nor fully correct (e.g. string "//").
59+
" Such is life.
60+
return substitute(line, "\s*//.*$", "", "")
61+
endif
62+
endfunction
63+
64+
function GetRustIndent(lnum)
65+
66+
" Starting assumption: cindent (called at the end) will do it right
67+
" normally. We just want to fix up a few cases.
68+
69+
if has('syntax_items')
70+
if synIDattr(synID(a:lnum, 1, 1), "name") == "rustString"
71+
" If the start of the line is in a string, don't change the indent
72+
return -1
73+
elseif synIDattr(synID(a:lnum, 1, 1), "name") =~ "\\(Comment\\|Todo\\)"
74+
\ && getline(a:lnum) !~ "^\\s*/\\*"
75+
" If it's in a comment, let cindent take care of it now. This is
76+
" for cases like "/*" where the next line should start " * ", not
77+
" "* " as the code below would otherwise cause for module scope
78+
" Fun fact: " /*\n*\n*/" takes two calls to get right!
79+
return cindent(a:lnum)
80+
endif
81+
endif
82+
83+
" cindent gets second and subsequent match patterns/struct members wrong,
84+
" as it treats the comma as indicating an unfinished statement::
85+
"
86+
" match a {
87+
" b => c,
88+
" d => e,
89+
" f => g,
90+
" };
91+
92+
" Search backwards for the previous non-empty line.
93+
let prevline = s:get_line_trimmed(prevnonblank(a:lnum - 1))
94+
if prevline[len(prevline) - 1] == ","
95+
\ && s:get_line_trimmed(a:lnum) !~ "^\\s*[\\[\\]{}]"
96+
" Oh ho! The previous line ended in a comma! I bet cindent will try to
97+
" take this too far... For now, let's use the previous line's indent
98+
return GetRustIndent(a:lnum - 1)
99+
endif
100+
101+
" cindent doesn't do the module scope well at all; e.g.::
102+
"
103+
" static FOO : &'static [bool] = [
104+
" true,
105+
" false,
106+
" false,
107+
" true,
108+
" ];
109+
"
110+
" uh oh, next statement is indented further!
111+
112+
" Note that this does *not* apply the line continuation pattern properly;
113+
" that's too hard to do correctly for my liking at present, so I'll just
114+
" start with these two main cases (square brackets and not returning to
115+
" column zero)
116+
117+
let line = getline(a:lnum)
118+
call cursor(a:lnum, 1)
119+
if searchpair('{\|(', '', '}\|)', 'nbW') == 0
120+
if searchpair('\[', '', '\]', 'nbW') == 0
121+
" Global scope, should be zero
122+
return 0
123+
else
124+
" At the module scope, inside square brackets only
125+
"if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum
126+
if line =~ "^\\s*]"
127+
" It's the closing line, dedent it
128+
return 0
129+
else
130+
return &shiftwidth
131+
endif
132+
endif
133+
endif
134+
135+
" Fall back on cindent, which does it mostly right
136+
return cindent(a:lnum)
137+
endfunction

src/etc/vim/syntax/rust.vim

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
" Language: Rust
33
" Maintainer: Patrick Walton <[email protected]>
44
" Maintainer: Ben Blum <[email protected]>
5-
" Last Change: 2013 Jun 14
5+
" Maintainer: Chris Morgan <[email protected]>
6+
" Last Change: 2013 Jul 10
67

78
if version < 600
89
syntax clear
@@ -13,8 +14,8 @@ endif
1314
syn keyword rustConditional match if else
1415
syn keyword rustOperator as
1516

16-
syn match rustAssert "\<assert\(\w\)*!"
17-
syn match rustFail "\<fail\(\w\)*!"
17+
syn match rustAssert "\<assert\(\w\)*!" contained
18+
syn match rustFail "\<fail\(\w\)*!" contained
1819
syn keyword rustKeyword break copy do extern
1920
syn keyword rustKeyword for if impl let log
2021
syn keyword rustKeyword copy do extern
@@ -90,7 +91,7 @@ syn match rustFormat display "%%" contained
9091
syn region rustString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=rustTodo,rustFormat
9192

9293
syn region rustAttribute start="#\[" end="\]" contains=rustString,rustDeriving
93-
syn region rustDeriving start="deriving(" end=")" contains=rustTrait
94+
syn region rustDeriving start="deriving(" end=")" contained contains=rustTrait
9495

9596
" Number literals
9697
syn match rustNumber display "\<[0-9][0-9_]*\>"
@@ -116,13 +117,18 @@ syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\%([eE][+-]\=[0-9
116117
syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*"
117118
syn match rustCharacter "'\([^'\\]\|\\\(['nrt\\\"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'"
118119

119-
syn region rustCommentDoc start="/\*[\*!]" end="\*/"
120-
syn region rustCommentDoc start="//[/!]" skip="\\$" end="$" keepend
121-
syn match rustComment "/\*\*/"
122-
syn region rustComment start="/\*\([^\*!]\|$\)" end="\*/" contains=rustTodo
123-
syn region rustComment start="//\([^/!]\|$\)" skip="\\$" end="$" contains=rustTodo keepend
120+
syn region rustComment start="/\*" end="\*/" contains=rustTodo
121+
syn region rustComment start="//" skip="\\$" end="$" contains=rustTodo keepend
122+
syn region rustCommentDoc start="/\*\%(!\|\*/\@!\)" end="\*/" contains=rustTodo
123+
syn region rustCommentDoc start="//[/!]" skip="\\$" end="$" contains=rustTodo keepend
124124

125-
syn keyword rustTodo contained TODO FIXME XXX NB
125+
syn keyword rustTodo contained TODO FIXME XXX NB NOTE
126+
127+
" Trivial folding rules to begin with.
128+
" TODO: use the AST to make really good folding
129+
syn region rustFoldBraces start="{" end="}" transparent fold
130+
" If you wish to enable this, setlocal foldmethod=syntax
131+
" It's not enabled by default as it would drive some people mad.
126132

127133
hi def link rustHexNumber rustNumber
128134
hi def link rustBinNumber rustNumber
@@ -142,10 +148,13 @@ hi def link rustKeyword Keyword
142148
hi def link rustConditional Conditional
143149
hi def link rustIdentifier Identifier
144150
hi def link rustModPath Include
151+
hi def link rustModPathSep Delimiter
145152
hi def link rustFuncName Function
146153
hi def link rustFuncCall Function
147154
hi def link rustCommentDoc SpecialComment
148155
hi def link rustComment Comment
156+
hi def link rustAssert PreCondit
157+
hi def link rustFail PreCondit
149158
hi def link rustMacro Macro
150159
hi def link rustType Type
151160
hi def link rustTodo Todo
@@ -160,7 +169,6 @@ hi def link rustLifetime Special
160169
" hi rustAssert ctermfg=yellow
161170
" hi rustFail ctermfg=red
162171
" hi rustMacro ctermfg=magenta
163-
" hi rustModPathSep ctermfg=grey
164172

165173
syn sync minlines=200
166174
syn sync maxlines=500

0 commit comments

Comments
 (0)