summaryrefslogtreecommitdiffstats
path: root/indent
diff options
context:
space:
mode:
Diffstat (limited to 'indent')
-rw-r--r--indent/clojure.vim19
-rw-r--r--indent/go.vim20
-rw-r--r--indent/rust.vim56
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