diff options
Diffstat (limited to 'indent')
-rw-r--r-- | indent/eruby.vim | 16 | ||||
-rw-r--r-- | indent/nix.vim | 23 | ||||
-rw-r--r-- | indent/purescript.vim | 2 | ||||
-rw-r--r-- | indent/rust.vim | 340 |
4 files changed, 203 insertions, 178 deletions
diff --git a/indent/eruby.vim b/indent/eruby.vim index 6fd76600..cdc5fedf 100644 --- a/indent/eruby.vim +++ b/indent/eruby.vim @@ -6,7 +6,7 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ruby') == -1 " URL: https://github.com/vim-ruby/vim-ruby " Release Coordinator: Doug Kearns <dougkearns@gmail.com> -if exists("b:did_indent") +if get(b:, 'did_indent') =~# '\<eruby\>' finish endif @@ -14,12 +14,14 @@ runtime! indent/ruby.vim unlet! b:did_indent setlocal indentexpr= -if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=# 'eruby' - exe "runtime! indent/".b:eruby_subtype.".vim" -else - runtime! indent/html.vim +if &filetype =~# '^eruby\>' + if exists("b:eruby_subtype") && b:eruby_subtype != '' && b:eruby_subtype !=# 'eruby' + exe "runtime! indent/".b:eruby_subtype.".vim" + else + runtime! indent/html.vim + endif endif -unlet! b:did_indent +let b:did_indent = get(b:, 'did_indent', 1) . '.eruby' " Force HTML indent to not keep state. let b:html_indent_usestate = 0 @@ -33,8 +35,6 @@ if &l:indentexpr == '' endif let b:eruby_subtype_indentexpr = &l:indentexpr -let b:did_indent = 1 - setlocal indentexpr=GetErubyIndent() setlocal indentkeys=o,O,*<Return>,<>>,{,},0),0],o,O,!^F,=end,=else,=elsif,=rescue,=ensure,=when diff --git a/indent/nix.vim b/indent/nix.vim index fd277dcc..2910cbd6 100644 --- a/indent/nix.vim +++ b/indent/nix.vim @@ -21,6 +21,8 @@ let s:cpo_save = &cpo set cpo&vim let s:skip_syntax = '\%(Comment\|String\)$' +let s:binding_open = '\%(\<let\>\|{\)' +let s:binding_close = '\%(\<in\>\|}\)' let s:block_open = '\%({\|[\)' let s:block_close = '\%(}\|]\)' @@ -43,6 +45,23 @@ function! GetNixIndent() let current_line = getline(v:lnum) let last_line = getline(lnum) + if current_line =~ '^\s*in\>' + let save_cursor = getcurpos() + normal ^ + let bslnum = searchpair(s:binding_open, '', s:binding_close, 'bnW', + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "StringSpecial$"') + call setpos('.', save_cursor) + return indent(bslnum) + endif + + if last_line =~ ';$' + let bslnum = searchpair(s:binding_open, '', s:binding_close, 'bnW', + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "StringSpecial$"') + if bslnum != 0 + let ind = indent(bslnum) + &sw + endif + endif + if last_line =~ s:block_open . '\s*$' let ind += &sw endif @@ -51,6 +70,10 @@ function! GetNixIndent() let ind -= &sw endif + if last_line =~ '[(=]$' + let ind += &sw + endif + if last_line =~ '\<let\s*$' let ind += &sw endif diff --git a/indent/purescript.vim b/indent/purescript.vim index c22da095..515f88e2 100644 --- a/indent/purescript.vim +++ b/indent/purescript.vim @@ -103,7 +103,7 @@ function! GetPurescriptIndent() return s endif - if prevline =~ '^\S.*::' && line !~ '^\s*\(\.\|->\|→\|=>\|⇒\)' && !~ '^instance' + if prevline =~ '^\S.*::' && line !~ '^\s*\(\.\|->\|→\|=>\|⇒\)' && prevline !~ '^instance' " f :: String " -> String return 0 diff --git a/indent/rust.vim b/indent/rust.vim index 042e2ab5..fa4dfb54 100644 --- a/indent/rust.vim +++ b/indent/rust.vim @@ -3,17 +3,17 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 " Vim indent file " Language: Rust " Author: Chris Morgan <me@chrismorgan.info> -" Last Change: 2017 Mar 21 +" Last Change: 2018 Jan 10 " For bugs, patches and license go to https://github.com/rust-lang/rust.vim " Only load this indent file when no other was loaded. if exists("b:did_indent") - finish + finish endif let b:did_indent = 1 setlocal cindent -setlocal cinoptions=L0,(0,Ws,J1,j1 +setlocal cinoptions=L0,(0,Ws,J1,j1,m1 setlocal cinkeys=0{,0},!^F,o,O,0[,0] " Don't think cinwords will actually do anything at all... never mind setlocal cinwords=for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fn,extern,macro @@ -28,7 +28,7 @@ setlocal indentexpr=GetRustIndent(v:lnum) " Only define the function once. if exists("*GetRustIndent") - finish + finish endif let s:save_cpo = &cpo @@ -37,181 +37,183 @@ set cpo&vim " 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 + " 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! s:is_string_comment(lnum, col) - if has('syntax_items') - for id in synstack(a:lnum, a:col) - let synname = synIDattr(id, "name") - if synname == "rustString" || synname =~ "^rustComment" - return 1 - endif - endfor - else - " without syntax, let's not even try - return 0 - endif + if has('syntax_items') + for id in synstack(a:lnum, a:col) + let synname = synIDattr(id, "name") + if synname == "rustString" || synname =~ "^rustComment" + return 1 + endif + endfor + else + " without syntax, let's not even try + return 0 + 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 prevlinenum = prevnonblank(a:lnum - 1) - let prevline = s:get_line_trimmed(prevlinenum) - while prevlinenum > 1 && prevline !~ '[^[:blank:]]' - let prevlinenum = prevnonblank(prevlinenum - 1) - let prevline = s:get_line_trimmed(prevlinenum) - endwhile - - " Handle where clauses nicely: subsequent values should line up nicely. - if prevline[len(prevline) - 1] == "," - \ && prevline =~# '^\s*where\s' - return indent(prevlinenum) + 6 - endif - - if prevline[len(prevline) - 1] == "," - \ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]' - \ && prevline !~ '^\s*fn\s' - \ && prevline !~ '([^()]\+,$' - \ && s:get_line_trimmed(a:lnum) !~ '^\s*\S\+\s*=>' - " Oh ho! The previous line ended in a comma! I bet cindent will try to - " take this too far... For now, let's normally use the previous line's - " indent. - - " One case where this doesn't work out is where *this* line contains - " square or curly brackets; then we normally *do* want to be indenting - " further. - " - " Another case where we don't want to is one like a function - " definition with arguments spread over multiple lines: - " - " fn foo(baz: Baz, - " baz: Baz) // <-- cindent gets this right by itself - " - " Another case is similar to the previous, except calling a function - " instead of defining it, or any conditional expression that leaves - " an open paren: - " - " foo(baz, - " baz); - " - " if baz && (foo || - " bar) { - " - " Another case is when the current line is a new match arm. - " - " There are probably other cases where we don't want to do this as - " well. Add them as needed. - return indent(prevlinenum) - endif - - if !has("patch-7.4.355") - " cindent before 7.4.355 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', - \ 's:is_string_comment(line("."), col("."))') == 0 - if searchpair('\[', '', '\]', 'nbW', - \ 's:is_string_comment(line("."), col("."))') == 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 - endif - - " Fall back on cindent, which does it mostly right - return cindent(a: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 prevlinenum = prevnonblank(a:lnum - 1) + let prevline = s:get_line_trimmed(prevlinenum) + while prevlinenum > 1 && prevline !~ '[^[:blank:]]' + let prevlinenum = prevnonblank(prevlinenum - 1) + let prevline = s:get_line_trimmed(prevlinenum) + endwhile + + " Handle where clauses nicely: subsequent values should line up nicely. + if prevline[len(prevline) - 1] == "," + \ && prevline =~# '^\s*where\s' + return indent(prevlinenum) + 6 + endif + + if prevline[len(prevline) - 1] == "," + \ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]' + \ && prevline !~ '^\s*fn\s' + \ && prevline !~ '([^()]\+,$' + \ && s:get_line_trimmed(a:lnum) !~ '^\s*\S\+\s*=>' + " Oh ho! The previous line ended in a comma! I bet cindent will try to + " take this too far... For now, let's normally use the previous line's + " indent. + + " One case where this doesn't work out is where *this* line contains + " square or curly brackets; then we normally *do* want to be indenting + " further. + " + " Another case where we don't want to is one like a function + " definition with arguments spread over multiple lines: + " + " fn foo(baz: Baz, + " baz: Baz) // <-- cindent gets this right by itself + " + " Another case is similar to the previous, except calling a function + " instead of defining it, or any conditional expression that leaves + " an open paren: + " + " foo(baz, + " baz); + " + " if baz && (foo || + " bar) { + " + " Another case is when the current line is a new match arm. + " + " There are probably other cases where we don't want to do this as + " well. Add them as needed. + return indent(prevlinenum) + endif + + if !has("patch-7.4.355") + " cindent before 7.4.355 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', + \ 's:is_string_comment(line("."), col("."))') == 0 + if searchpair('\[', '', '\]', 'nbW', + \ 's:is_string_comment(line("."), col("."))') == 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 + endif + + " Fall back on cindent, which does it mostly right + return cindent(a:lnum) endfunction let &cpo = s:save_cpo unlet s:save_cpo +" vim: set et sw=4 sts=4 ts=8: + endif |