diff options
Diffstat (limited to '')
| -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 | 
