From 820e9c5dbf83ef2402142f89342351dd44b612c8 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Wed, 10 Jul 2013 09:56:08 +1000 Subject: [PATCH 1/2] Fix comment indenting properly for Vim files. Indentation now works correctly on subsequent lines of a multi-line comment, whether there are leaders (` * `) or not. (Formerly it was incorrectly doing a two-space indent if there was no leader.) By default, this no longer puts a ` * ` leader on `/*!` comments, as that appears to be the current convention in the Rust source code, but that can easily be re-enabled if desired: let g:rust_bang_comment_leader = 1 --- src/etc/vim/ftplugin/rust.vim | 15 +++++++++++++-- src/etc/vim/indent/rust.vim | 18 ++++++++++++++---- src/etc/vim/syntax/rust.vim | 6 ++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/etc/vim/ftplugin/rust.vim b/src/etc/vim/ftplugin/rust.vim index f329dd6ce02ac..063b1152cb2c6 100644 --- a/src/etc/vim/ftplugin/rust.vim +++ b/src/etc/vim/ftplugin/rust.vim @@ -1,14 +1,25 @@ " Vim syntax file " Language: Rust " Maintainer: Chris Morgan -" Last Change: 2013 Jul 6 +" Last Change: 2013 Jul 10 if exists("b:did_ftplugin") finish endif let b:did_ftplugin = 1 -setlocal comments=s1:/*,mb:*,ex:*/,:///,://!,:// +" 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+=croqnlj diff --git a/src/etc/vim/indent/rust.vim b/src/etc/vim/indent/rust.vim index 55fceb96af3fb..806f8519f0a2c 100644 --- a/src/etc/vim/indent/rust.vim +++ b/src/etc/vim/indent/rust.vim @@ -66,12 +66,23 @@ 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') - if synIDattr(synID(a:lnum, 1, 1), "name") == "rustString" + 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 synIDattr(synID(a:lnum, 1, 1), "name") =~ "\\(Comment\\|Todo\\)" - \ && getline(a:lnum) !~ "^\\s*/\\*" + 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 @@ -114,7 +125,6 @@ function GetRustIndent(lnum) " start with these two main cases (square brackets and not returning to " column zero) - let line = getline(a:lnum) call cursor(a:lnum, 1) if searchpair('{\|(', '', '}\|)', 'nbW') == 0 if searchpair('\[', '', '\]', 'nbW') == 0 diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index dfcdb11e7682a..3f654ea903063 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -117,9 +117,9 @@ syn match rustFloat display "\<[0-9][0-9_]*\.[0-9_]\+\%([eE][+-]\=[0-9 syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" syn match rustCharacter "'\([^'\\]\|\\\(['nrt\\\"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'" -syn region rustComment start="/\*" end="\*/" contains=rustTodo +syn region rustCommentML start="/\*" end="\*/" contains=rustTodo syn region rustComment start="//" skip="\\$" end="$" contains=rustTodo keepend -syn region rustCommentDoc start="/\*\%(!\|\*/\@!\)" end="\*/" contains=rustTodo +syn region rustCommentMLDoc start="/\*\%(!\|\*/\@!\)" end="\*/" contains=rustTodo syn region rustCommentDoc start="//[/!]" skip="\\$" end="$" contains=rustTodo keepend syn keyword rustTodo contained TODO FIXME XXX NB NOTE @@ -151,7 +151,9 @@ hi def link rustModPath Include hi def link rustModPathSep Delimiter 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 From 8f24833f30eea6597f3c63a9b8a4998eb5f413fa Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Wed, 10 Jul 2013 15:58:32 +1000 Subject: [PATCH 2/2] Fix Vim indentation for inline closures. --- src/etc/vim/indent/rust.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/vim/indent/rust.vim b/src/etc/vim/indent/rust.vim index 806f8519f0a2c..ae3ca403aedd8 100644 --- a/src/etc/vim/indent/rust.vim +++ b/src/etc/vim/indent/rust.vim @@ -10,7 +10,7 @@ endif let b:did_indent = 1 setlocal cindent -setlocal cinoptions=L0,(0,Ws,JN +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