diff options
Diffstat (limited to 'indent')
-rw-r--r-- | indent/clojure.vim | 19 | ||||
-rw-r--r-- | indent/go.vim | 20 | ||||
-rw-r--r-- | indent/rust.vim | 56 |
3 files changed, 72 insertions, 23 deletions
diff --git a/indent/clojure.vim b/indent/clojure.vim index 66d5e0f2..3f0fd823 100644 --- a/indent/clojure.vim +++ b/indent/clojure.vim @@ -8,11 +8,6 @@ " License: Same as Vim " Last Change: %%RELEASE_DATE%% -" TODO: Indenting after multibyte characters is broken: -" (let [Δ (if foo -" bar ; Indent error -" baz)]) - if exists("b:did_indent") finish endif @@ -99,7 +94,7 @@ if exists("*searchpairpos") endif let pos = searchpairpos(a:open, '', a:close, 'bWn', "!s:is_paren()", stopat) - return [pos[0], virtcol(pos)] + return [pos[0], col(pos)] endfunction function! s:clojure_check_for_string_worker() @@ -306,15 +301,23 @@ if exists("*searchpairpos") endif call search('\v\S', 'bW') - return [line('.'), virtcol('.') + 1] + return [line('.'), col('.') + 1] endfunction function! GetClojureIndent() let lnum = line('.') + let orig_lnum = lnum + let orig_col = col('.') let [opening_lnum, indent] = s:clojure_indent_pos() + " Account for multibyte characters + if opening_lnum > 0 + let indent -= indent - virtcol([opening_lnum, indent]) + endif + " Return if there are no previous lines to inherit from if opening_lnum < 1 || opening_lnum >= lnum - 1 + call cursor(orig_lnum, orig_col) return indent endif @@ -349,11 +352,13 @@ if exists("*searchpairpos") " Check if this is part of a multiline string call cursor(lnum, 1) if s:syn_id_name() !~? '\vstring|regex' + call cursor(orig_lnum, orig_col) return indent(lnum) endif endif endwhile + call cursor(orig_lnum, orig_col) return indent endfunction diff --git a/indent/go.vim b/indent/go.vim index faf4d79e..e3d6e841 100644 --- a/indent/go.vim +++ b/indent/go.vim @@ -24,6 +24,18 @@ if exists("*GoIndent") finish endif +" The shiftwidth() function is relatively new. +" Don't require it to exist. +if exists('*shiftwidth') + func s:sw() + return shiftwidth() + endfunc +else + func s:sw() + return &shiftwidth + endfunc +endif + function! GoIndent(lnum) let prevlnum = prevnonblank(a:lnum-1) if prevlnum == 0 @@ -40,17 +52,17 @@ function! GoIndent(lnum) if prevl =~ '[({]\s*$' " previous line opened a block - let ind += &sw + let ind += s:sw() endif if prevl =~# '^\s*\(case .*\|default\):$' " previous line is part of a switch statement - let ind += &sw + let ind += s:sw() endif " TODO: handle if the previous line is a label. if thisl =~ '^\s*[)}]' " this line closed a block - let ind -= &sw + let ind -= s:sw() endif " Colons are tricky. @@ -58,7 +70,7 @@ function! GoIndent(lnum) " We ignore trying to deal with jump labels because (a) they're rare, and " (b) they're hard to disambiguate from a composite literal key. if thisl =~# '^\s*\(case .*\|default\):$' - let ind -= &sw + let ind -= s:sw() endif return ind diff --git a/indent/rust.vim b/indent/rust.vim index 1f08c519..b9d6330c 100644 --- a/indent/rust.vim +++ b/indent/rust.vim @@ -13,7 +13,7 @@ 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 +setlocal cinwords=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 @@ -30,7 +30,7 @@ endif " Come here when loading the script the first time. -function s:get_line_trimmed(lnum) +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 @@ -40,12 +40,12 @@ function s:get_line_trimmed(lnum) " 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" + 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" + if synIDattr(synID(a:lnum, col, 1), "name") =~ 'Comment\|Todo' let max = col else let min = col + 1 @@ -61,6 +61,20 @@ function s:get_line_trimmed(lnum) 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 +endfunction + function GetRustIndent(lnum) " Starting assumption: cindent (called at the end) will do it right @@ -73,10 +87,10 @@ function GetRustIndent(lnum) 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 + elseif synname =~ '\(Comment\|Todo\)' + \ && line !~ '^\s*/\*' " not /* opening line if synname =~ "CommentML" " multi-line - if line !~ "^\\s*\\*" && getline(a:lnum - 1) =~ "^\\s*/\\*" + 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. @@ -101,10 +115,16 @@ function GetRustIndent(lnum) " }; " Search backwards for the previous non-empty line. - let prevline = s:get_line_trimmed(prevnonblank(a:lnum - 1)) + 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 if prevline[len(prevline) - 1] == "," - \ && s:get_line_trimmed(a:lnum) !~ "^\\s*[\\[\\]{}]" - \ && prevline !~ "^\\s*fn\\s" + \ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]' + \ && prevline !~ '^\s*fn\s' + \ && prevline !~ '([^()]\+,$' " 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. @@ -119,6 +139,16 @@ function GetRustIndent(lnum) " 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) { + " " There are probably other cases where we don't want to do this as " well. Add them as needed. return GetRustIndent(a:lnum - 1) @@ -141,8 +171,10 @@ function GetRustIndent(lnum) " column zero) call cursor(a:lnum, 1) - if searchpair('{\|(', '', '}\|)', 'nbW') == 0 - if searchpair('\[', '', '\]', 'nbW') == 0 + 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 |