diff options
Diffstat (limited to 'runtime/indent')
-rw-r--r-- | runtime/indent/clojure.vim | 206 | ||||
-rw-r--r-- | runtime/indent/fortran.vim | 30 | ||||
-rw-r--r-- | runtime/indent/html.vim | 12 | ||||
-rw-r--r-- | runtime/indent/javascript.vim | 194 | ||||
-rw-r--r-- | runtime/indent/lua.vim | 4 | ||||
-rw-r--r-- | runtime/indent/php.vim | 60 | ||||
-rw-r--r-- | runtime/indent/r.vim | 24 | ||||
-rw-r--r-- | runtime/indent/rhelp.vim | 3 | ||||
-rw-r--r-- | runtime/indent/rmd.vim | 3 | ||||
-rw-r--r-- | runtime/indent/rnoweb.vim | 3 | ||||
-rw-r--r-- | runtime/indent/rrst.vim | 3 | ||||
-rw-r--r-- | runtime/indent/sh.vim | 30 | ||||
-rw-r--r-- | runtime/indent/tex.vim | 249 | ||||
-rw-r--r-- | runtime/indent/vhdl.vim | 21 | ||||
-rw-r--r-- | runtime/indent/vim.vim | 18 | ||||
-rw-r--r-- | runtime/indent/zimbu.vim | 12 |
16 files changed, 642 insertions, 230 deletions
diff --git a/runtime/indent/clojure.vim b/runtime/indent/clojure.vim index 476ac1de1c..7592b10d7d 100644 --- a/runtime/indent/clojure.vim +++ b/runtime/indent/clojure.vim @@ -1,17 +1,12 @@ " Vim indent file -" Language: Clojure -" Author: Meikel Brandmeyer <mb@kotka.de> -" URL: http://kotka.de/projects/clojure/vimclojure.html +" Language: Clojure +" Author: Meikel Brandmeyer <mb@kotka.de> +" URL: http://kotka.de/projects/clojure/vimclojure.html " -" Maintainer: Sung Pae <self@sungpae.com> -" URL: https://github.com/guns/vim-clojure-static -" License: Same as Vim -" Last Change: 27 March 2014 - -" TODO: Indenting after multibyte characters is broken: -" (let [Δ (if foo -" bar ; Indent error -" baz)]) +" Maintainer: Sung Pae <self@sungpae.com> +" URL: https://github.com/guns/vim-clojure-static +" License: Same as Vim +" Last Change: 18 July 2016 if exists("b:did_indent") finish @@ -57,36 +52,39 @@ if exists("*searchpairpos") let g:clojure_align_subforms = 0 endif - function! s:SynIdName() + function! s:syn_id_name() return synIDattr(synID(line("."), col("."), 0), "name") endfunction - function! s:CurrentChar() + function! s:ignored_region() + return s:syn_id_name() =~? '\vstring|regex|comment|character' + endfunction + + function! s:current_char() return getline('.')[col('.')-1] endfunction - function! s:CurrentWord() + function! s:current_word() return getline('.')[col('.')-1 : searchpos('\v>', 'n', line('.'))[1]-2] endfunction - function! s:IsParen() - return s:CurrentChar() =~# '\v[\(\)\[\]\{\}]' && - \ s:SynIdName() !~? '\vstring|regex|comment|character' + function! s:is_paren() + return s:current_char() =~# '\v[\(\)\[\]\{\}]' && !s:ignored_region() endfunction " Returns 1 if string matches a pattern in 'patterns', which may be a " list of patterns, or a comma-delimited string of implicitly anchored " patterns. - function! s:MatchesOne(patterns, string) + function! s:match_one(patterns, string) let list = type(a:patterns) == type([]) - \ ? a:patterns - \ : map(split(a:patterns, ','), '"^" . v:val . "$"') + \ ? a:patterns + \ : map(split(a:patterns, ','), '"^" . v:val . "$"') for pat in list if a:string =~# pat | return 1 | endif endfor endfunction - function! s:MatchPairs(open, close, stopat) + function! s:match_pairs(open, close, stopat) " Stop only on vector and map [ resp. {. Ignore the ones in strings and " comments. if a:stopat == 0 @@ -95,11 +93,11 @@ if exists("*searchpairpos") let stopat = a:stopat endif - let pos = searchpairpos(a:open, '', a:close, 'bWn', "!s:IsParen()", stopat) - return [pos[0], virtcol(pos)] + let pos = searchpairpos(a:open, '', a:close, 'bWn', "!s:is_paren()", stopat) + return [pos[0], col(pos)] endfunction - function! s:ClojureCheckForStringWorker() + function! s:clojure_check_for_string_worker() " Check whether there is the last character of the previous line is " highlighted as a string. If so, we check whether it's a ". In this " case we have to check also the previous character. The " might be the @@ -113,17 +111,17 @@ if exists("*searchpairpos") call cursor(nb, 0) call cursor(0, col("$") - 1) - if s:SynIdName() !~? "string" + if s:syn_id_name() !~? "string" return -1 endif " This will not work for a " in the first column... - if s:CurrentChar() == '"' + if s:current_char() == '"' call cursor(0, col("$") - 2) - if s:SynIdName() !~? "string" + if s:syn_id_name() !~? "string" return -1 endif - if s:CurrentChar() != '\\' + if s:current_char() != '\\' return -1 endif call cursor(0, col("$") - 1) @@ -138,40 +136,40 @@ if exists("*searchpairpos") return indent(".") endfunction - function! s:CheckForString() + function! s:check_for_string() let pos = getpos('.') try - let val = s:ClojureCheckForStringWorker() + let val = s:clojure_check_for_string_worker() finally call setpos('.', pos) endtry return val endfunction - function! s:StripNamespaceAndMacroChars(word) + function! s:strip_namespace_and_macro_chars(word) return substitute(a:word, "\\v%(.*/|[#'`~@^,]*)(.*)", '\1', '') endfunction - function! s:ClojureIsMethodSpecialCaseWorker(position) + function! s:clojure_is_method_special_case_worker(position) " Find the next enclosing form. call search('\S', 'Wb') " Special case: we are at a '(('. - if s:CurrentChar() == '(' + if s:current_char() == '(' return 0 endif call cursor(a:position) - let nextParen = s:MatchPairs('(', ')', 0) + let next_paren = s:match_pairs('(', ')', 0) " Special case: we are now at toplevel. - if nextParen == [0, 0] + if next_paren == [0, 0] return 0 endif - call cursor(nextParen) + call cursor(next_paren) call search('\S', 'W') - let w = s:StripNamespaceAndMacroChars(s:CurrentWord()) + let w = s:strip_namespace_and_macro_chars(s:current_word()) if g:clojure_special_indent_words =~# '\V\<' . w . '\>' return 1 endif @@ -179,27 +177,43 @@ if exists("*searchpairpos") return 0 endfunction - function! s:IsMethodSpecialCase(position) + function! s:is_method_special_case(position) let pos = getpos('.') try - let val = s:ClojureIsMethodSpecialCaseWorker(a:position) + let val = s:clojure_is_method_special_case_worker(a:position) finally call setpos('.', pos) endtry return val endfunction - function! GetClojureIndent() + " Check if form is a reader conditional, that is, it is prefixed by #? + " or @#? + function! s:is_reader_conditional_special_case(position) + if getline(a:position[0])[a:position[1] - 3 : a:position[1] - 2] == "#?" + return 1 + endif + + return 0 + endfunction + + " Returns 1 for opening brackets, -1 for _anything else_. + function! s:bracket_type(char) + return stridx('([{', a:char) > -1 ? 1 : -1 + endfunction + + " Returns: [opening-bracket-lnum, indent] + function! s:clojure_indent_pos() " Get rid of special case. if line(".") == 1 - return 0 + return [0, 0] endif " We have to apply some heuristics here to figure out, whether to use " normal lisp indenting or not. - let i = s:CheckForString() + let i = s:check_for_string() if i > -1 - return i + !!g:clojure_align_multiline_strings + return [0, i + !!g:clojure_align_multiline_strings] endif call cursor(0, 1) @@ -207,28 +221,28 @@ if exists("*searchpairpos") " Find the next enclosing [ or {. We can limit the second search " to the line, where the [ was found. If no [ was there this is " zero and we search for an enclosing {. - let paren = s:MatchPairs('(', ')', 0) - let bracket = s:MatchPairs('\[', '\]', paren[0]) - let curly = s:MatchPairs('{', '}', bracket[0]) + let paren = s:match_pairs('(', ')', 0) + let bracket = s:match_pairs('\[', '\]', paren[0]) + let curly = s:match_pairs('{', '}', bracket[0]) " In case the curly brace is on a line later then the [ or - in " case they are on the same line - in a higher column, we take the " curly indent. if curly[0] > bracket[0] || curly[1] > bracket[1] if curly[0] > paren[0] || curly[1] > paren[1] - return curly[1] + return curly endif endif " If the curly was not chosen, we take the bracket indent - if " there was one. if bracket[0] > paren[0] || bracket[1] > paren[1] - return bracket[1] + return bracket endif " There are neither { nor [ nor (, ie. we are at the toplevel. if paren == [0, 0] - return 0 + return paren endif " Now we have to reimplement lispindent. This is surprisingly easy, as @@ -246,58 +260,120 @@ if exists("*searchpairpos") " - In any other case we use the column of the end of the word + 2. call cursor(paren) - if s:IsMethodSpecialCase(paren) - return paren[1] + &shiftwidth - 1 + if s:is_method_special_case(paren) + return [paren[0], paren[1] + &shiftwidth - 1] + endif + + if s:is_reader_conditional_special_case(paren) + return paren endif " In case we are at the last character, we use the paren position. if col("$") - 1 == paren[1] - return paren[1] + return paren endif " In case after the paren is a whitespace, we search for the next word. call cursor(0, col('.') + 1) - if s:CurrentChar() == ' ' + if s:current_char() == ' ' call search('\v\S', 'W') endif " If we moved to another line, there is no word after the (. We " use the ( position for indent. if line(".") > paren[0] - return paren[1] + return paren endif " We still have to check, whether the keyword starts with a (, [ or {. " In that case we use the ( position for indent. - let w = s:CurrentWord() - if stridx('([{', w[0]) > -1 - return paren[1] + let w = s:current_word() + if s:bracket_type(w[0]) == 1 + return paren endif " Test words without namespace qualifiers and leading reader macro " metacharacters. " " e.g. clojure.core/defn and #'defn should both indent like defn. - let ww = s:StripNamespaceAndMacroChars(w) + let ww = s:strip_namespace_and_macro_chars(w) if &lispwords =~# '\V\<' . ww . '\>' - return paren[1] + &shiftwidth - 1 + return [paren[0], paren[1] + &shiftwidth - 1] endif if g:clojure_fuzzy_indent - \ && !s:MatchesOne(g:clojure_fuzzy_indent_blacklist, ww) - \ && s:MatchesOne(g:clojure_fuzzy_indent_patterns, ww) - return paren[1] + &shiftwidth - 1 + \ && !s:match_one(g:clojure_fuzzy_indent_blacklist, ww) + \ && s:match_one(g:clojure_fuzzy_indent_patterns, ww) + return [paren[0], paren[1] + &shiftwidth - 1] endif call search('\v\_s', 'cW') call search('\v\S', 'W') if paren[0] < line(".") - return paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1) + return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)] endif call search('\v\S', 'bW') - return 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 + + let bracket_count = 0 + + " Take the indent of the first previous non-white line that is + " at the same sexp level. cf. src/misc1.c:get_lisp_indent() + while 1 + let lnum = prevnonblank(lnum - 1) + let col = 1 + + if lnum <= opening_lnum + break + endif + + call cursor(lnum, col) + + " Handle bracket counting edge case + if s:is_paren() + let bracket_count += s:bracket_type(s:current_char()) + endif + + while 1 + if search('\v[(\[{}\])]', '', lnum) < 1 + break + elseif !s:ignored_region() + let bracket_count += s:bracket_type(s:current_char()) + endif + endwhile + + if bracket_count == 0 + " 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 setlocal indentexpr=GetClojureIndent() diff --git a/runtime/indent/fortran.vim b/runtime/indent/fortran.vim index d492889fc7..e19a19fb1f 100644 --- a/runtime/indent/fortran.vim +++ b/runtime/indent/fortran.vim @@ -1,11 +1,11 @@ " Vim indent file " Language: Fortran 2008 (and older: Fortran 2003, 95, 90, and 77) -" Version: 0.42 -" Last Change: 2015 Nov. 30 +" Version: 0.44 +" Last Change: 2016 Jan. 26 " Maintainer: Ajit J. Thakkar <ajit@unb.ca>; <http://www2.unb.ca/~ajit/> " Usage: For instructions, do :help fortran-indent from Vim " Credits: -" Useful suggestions were made by: Albert Oliver Serra. +" Useful suggestions were made by: Albert Oliver Serra and Takuya Fujiwara. " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -92,10 +92,10 @@ function FortranGetIndent(lnum) "Indent do loops only if they are all guaranteed to be of do/end do type if exists("b:fortran_do_enddo") || exists("g:fortran_do_enddo") if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*do\>' - let ind = ind + &sw + let ind = ind + shiftwidth() endif if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*end\s*do\>' - let ind = ind - &sw + let ind = ind - shiftwidth() endif endif @@ -105,14 +105,14 @@ function FortranGetIndent(lnum) \ ||prevstat=~? '^\s*\(type\|interface\|associate\|enum\)\>' \ ||prevstat=~?'^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*\(forall\|where\|block\)\>' \ ||prevstat=~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*if\>' - let ind = ind + &sw + let ind = ind + shiftwidth() " Remove unwanted indent after logical and arithmetic ifs if prevstat =~? '\<if\>' && prevstat !~? '\<then\>' - let ind = ind - &sw + let ind = ind - shiftwidth() endif " Remove unwanted indent after type( statements if prevstat =~? '^\s*type\s*(' - let ind = ind - &sw + let ind = ind - shiftwidth() endif endif @@ -125,12 +125,12 @@ function FortranGetIndent(lnum) \ ||prevstat =~? '^\s*'.prefix.'subroutine\>' \ ||prevstat =~? '^\s*'.prefix.type.'function\>' \ ||prevstat =~? '^\s*'.type.prefix.'function\>' - let ind = ind + &sw + let ind = ind + shiftwidth() endif if getline(v:lnum) =~? '^\s*contains\>' \ ||getline(v:lnum)=~? '^\s*end\s*' \ .'\(function\|subroutine\|module\|program\)\>' - let ind = ind - &sw + let ind = ind - shiftwidth() endif endif @@ -141,23 +141,23 @@ function FortranGetIndent(lnum) \. '\(else\|else\s*if\|else\s*where\|case\|' \. 'end\s*\(if\|where\|select\|interface\|' \. 'type\|forall\|associate\|enum\|block\)\)\>' - let ind = ind - &sw + let ind = ind - shiftwidth() " Fix indent for case statement immediately after select if prevstat =~? '\<select\s\+\(case\|type\)\>' - let ind = ind + &sw + let ind = ind + shiftwidth() endif endif "First continuation line if prevstat =~ '&\s*$' && prev2stat !~ '&\s*$' - let ind = ind + &sw + let ind = ind + shiftwidth() endif if prevstat =~ '&\s*$' && prevstat =~ '\<else\s*if\>' - let ind = ind - &sw + let ind = ind - shiftwidth() endif "Line after last continuation line if prevstat !~ '&\s*$' && prev2stat =~ '&\s*$' && prevstat !~? '\<then\>' - let ind = ind - &sw + let ind = ind - shiftwidth() endif return ind diff --git a/runtime/indent/html.vim b/runtime/indent/html.vim index 8aaf82e21f..828bc3120b 100644 --- a/runtime/indent/html.vim +++ b/runtime/indent/html.vim @@ -2,7 +2,7 @@ " Header: "{{{ " Maintainer: Bram Moolenaar " Original Author: Andy Wokula <anwoku@yahoo.de> -" Last Change: 2015 Sep 25 +" Last Change: 2016 Mar 30 " Version: 1.0 " Description: HTML indent script with cached state for faster indenting on a " range of lines. @@ -240,13 +240,13 @@ call s:AddITags(s:indent_tags, [ \ 'sup', 'table', 'textarea', 'title', 'tt', 'u', 'ul', 'var', 'th', 'td', \ 'tr', 'tbody', 'tfoot', 'thead']) -" Tags added 2011 Sep 09 (especially HTML5 tags): +" New HTML5 elements: call s:AddITags(s:indent_tags, [ \ 'area', 'article', 'aside', 'audio', 'bdi', 'canvas', - \ 'command', 'datalist', 'details', 'embed', 'figure', 'footer', - \ 'header', 'group', 'keygen', 'mark', 'math', 'meter', 'nav', 'output', - \ 'progress', 'ruby', 'section', 'svg', 'texture', 'time', 'video', - \ 'wbr', 'text']) + \ 'command', 'data', 'datalist', 'details', 'embed', 'figcaption', + \ 'figure', 'footer', 'header', 'keygen', 'mark', 'meter', 'nav', 'output', + \ 'progress', 'rp', 'rt', 'ruby', 'section', 'source', 'summary', 'svg', + \ 'time', 'track', 'video', 'wbr']) " Tags added for web components: call s:AddITags(s:indent_tags, [ diff --git a/runtime/indent/javascript.vim b/runtime/indent/javascript.vim index 21c8fff86c..3507e305ed 100644 --- a/runtime/indent/javascript.vim +++ b/runtime/indent/javascript.vim @@ -1,18 +1,192 @@ " Vim indent file -" Language: Javascript -" Maintainer: Going to be Darrick Wiebe -" Last Change: 2015 Jun 09 +" Language: Javascript +" Maintainer: vim-javascript community +" URL: https://github.com/pangloss/vim-javascript +" Last Change: August 12, 2016 " Only load this indent file when no other was loaded. -if exists("b:did_indent") - finish +if exists('b:did_indent') + finish endif let b:did_indent = 1 -" C indenting is not too bad. -setlocal cindent +" Now, set up our indentation expression and keys that trigger it. +setlocal indentexpr=GetJavascriptIndent() +setlocal nolisp +setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e setlocal cinoptions+=j1,J1 -setlocal cinkeys-=0# -setlocal cinkeys+=0] -let b:undo_indent = "setl cin<" +let b:undo_indent = 'setlocal indentexpr< indentkeys< cinoptions<' + +" Only define the function once. +if exists('*GetJavascriptIndent') + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" Get shiftwidth value +if exists('*shiftwidth') + function s:sw() + return shiftwidth() + endfunction +else + function s:sw() + return &sw + endfunction +endif + +let s:line_pre = '^\s*\%(\/\*.\{-}\*\/\s*\)*' +let s:expr_case = s:line_pre . '\%(\%(case\>.\+\)\|default\)\s*:' +" Regex of syntax group names that are or delimit string or are comments. +let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)' + +" Regex of syntax group names that are strings or documentation. +let s:syng_comment = '\%(comment\|doc\)' + +" Expression used to check whether we should skip a match with searchpair(). +let s:skip_expr = "line('.') < (prevnonblank(v:lnum) - 2000) ? dummy : synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" + +function s:lookForParens(start,end,flags,time) + if has('reltime') + return searchpair(a:start,'',a:end,a:flags,s:skip_expr,0,a:time) + else + return searchpair(a:start,'',a:end,a:flags,0,0) + endif +endfunction + +let s:line_term = '\%(\s*\%(\/\*.\{-}\*\/\s*\)\=\)\@>$' + +" configurable regexes that define continuation lines, not including (, {, or [. +if !exists('g:javascript_opfirst') + let g:javascript_opfirst = '\%([<>,:?^%]\|\([-/.+]\)\%(\1\|\*\|\/\)\@!\|\*\/\@!\|=>\@!\||\|&\|in\%(stanceof\)\=\>\)' +endif +let g:javascript_opfirst = s:line_pre . g:javascript_opfirst + +if !exists('g:javascript_continuation') + let g:javascript_continuation = '\%([<*,.?:^%]\|+\@<!+\|-\@<!-\|=\@<!>\|\*\@<!\/\|=\||\|&\|\<in\%(stanceof\)\=\)' +endif +let g:javascript_continuation .= s:line_term + +function s:Onescope(lnum,text,add) + return a:text =~# '\%(\<else\|\<do\|=>' . (a:add ? '\|\<try\|\<finally' : '' ) . '\)' . s:line_term || + \ ((a:add && a:text =~ s:line_pre . '$' && search('\%' . s:PrevCodeLine(a:lnum - 1) . 'l.)' . s:line_term)) || + \ cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1) && + \ s:lookForParens('(', ')', 'cbW', 100) > 0 && search((a:add ? + \ '\%(function\*\|[[:lower:][:upper:]_$][[:digit:][:lower:][:upper:]_$]*\)' : + \ '\<\%(for\%(\s\+each\)\=\|if\|let\|w\%(hile\|ith\)\)') . '\_s*\%#\C','bW') && + \ (a:add || (expand('<cword>') ==# 'while' ? !s:lookForParens('\<do\>\C', '\<while\>\C','bW',100) : 1)) +endfunction + +" Auxiliary Functions {{{2 + +" strip line of comment +function s:StripLine(c) + return a:c !~# s:expr_case ? substitute(a:c, '\%(:\@<!\/\/.*\)$', '','') : a:c +endfunction + +" Find line above 'lnum' that isn't empty, in a comment, or in a string. +function s:PrevCodeLine(lnum) + let l:lnum = prevnonblank(a:lnum) + while l:lnum > 0 + if synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"]'),0),'name') !~? s:syng_strcom + break + endif + let l:lnum = prevnonblank(l:lnum - 1) + endwhile + return l:lnum +endfunction + +" Check if line 'lnum' has a balanced amount of parentheses. +function s:Balanced(lnum) + let open_0 = 0 + let open_2 = 0 + let open_4 = 0 + let l:line = getline(a:lnum) + let pos = match(l:line, '[][(){}]', 0) + while pos != -1 + if synIDattr(synID(a:lnum,pos + 1,0),'name') !~? s:syng_strcom + let idx = stridx('(){}[]', l:line[pos]) + if idx % 2 == 0 + let open_{idx} = open_{idx} + 1 + else + let open_{idx - 1} = open_{idx - 1} - 1 + endif + endif + let pos = match(l:line, '[][(){}]', pos + 1) + endwhile + return (!open_4 + !open_2 + !open_0) - 2 +endfunction +" }}} + +function GetJavascriptIndent() + if !exists('b:js_cache') + let b:js_cache = [0,0,0] + endif + " Get the current line. + let l:line = getline(v:lnum) + let syns = synIDattr(synID(v:lnum, 1, 0), 'name') + + " start with strings,comments,etc.{{{2 + if (l:line !~ '^[''"`]' && syns =~? 'string\|template') || + \ (l:line !~ '^\s*[/*]' && syns =~? s:syng_comment) + return -1 + endif + if l:line !~ '^\%(\/\*\|\s*\/\/\)' && syns =~? s:syng_comment + return cindent(v:lnum) + endif + let l:lnum = s:PrevCodeLine(v:lnum - 1) + if l:lnum == 0 + return 0 + endif + + if (l:line =~# s:expr_case) + let cpo_switch = &cpo + set cpo+=% + let ind = cindent(v:lnum) + let &cpo = cpo_switch + return ind + endif + "}}} + + " the containing paren, bracket, curly. Memoize, last lineNr either has the + " same scope or starts a new one, unless if it closed a scope. + call cursor(v:lnum,1) + if b:js_cache[0] >= l:lnum && b:js_cache[0] <= v:lnum && b:js_cache[0] && + \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum) > 0) + let num = b:js_cache[1] + elseif syns != '' && l:line[0] =~ '\s' + let pattern = syns =~? 'block' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] : + \ syns =~? 'jsbracket'? ['\[','\]'] : ['[({[]','[])}]'] + let num = s:lookForParens(pattern[0],pattern[1],'bW',2000) + else + let num = s:lookForParens('[({[]','[])}]','bW',2000) + endif + let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')] + + if l:line =~ s:line_pre . '[])}]' + return indent(num) + endif + + let pline = s:StripLine(getline(l:lnum)) + let inb = num == 0 ? 1 : (s:Onescope(num, s:StripLine(strpart(getline(num),0,b:js_cache[2] - 1)),1) || + \ (l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term)) && num < l:lnum + let switch_offset = (!inb || num == 0) || expand("<cword>") !=# 'switch' ? 0 : &cino !~ ':' || !has('float') ? s:sw() : + \ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '.*:[^,]*s' ? s:sw() : 1)) + + " most significant, find the indent amount + if (inb && (l:line =~# g:javascript_opfirst || + \ (pline =~# g:javascript_continuation && pline !~# s:expr_case && (pline !~ ':' . s:line_term || l:line !~# + \ s:line_pre . '\%(d\%(o\|ebugger\)\|else\|f\%(or\|inally\)\|if\|let\|switch\|t\%(hrow\|ry\)\|w\%(hile\|ith\)\)\>')))) || + \ (num < l:lnum && s:Onescope(l:lnum,pline,0) && l:line !~ s:line_pre . '{') + return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset + elseif num > 0 + return indent(num) + s:sw() + switch_offset + endif + +endfunction + + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/indent/lua.vim b/runtime/indent/lua.vim index 393994c590..d1d2c0d600 100644 --- a/runtime/indent/lua.vim +++ b/runtime/indent/lua.vim @@ -2,7 +2,7 @@ " Language: Lua script " Maintainer: Marcus Aurelius Farias <marcus.cf 'at' bol.com.br> " First Author: Max Ischenko <mfi 'at' ukr.net> -" Last Change: 2014 Nov 12 +" Last Change: 2016 Jan 10 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -52,7 +52,7 @@ function! GetLuaIndent() endif endif - " Subtract a 'shiftwidth' on end, else (and elseif), until and '}' + " Subtract a 'shiftwidth' on end, else, elseif, until and '}' " This is the part that requires 'indentkeys'. let midx = match(getline(v:lnum), '^\s*\%(end\>\|else\>\|elseif\>\|until\>\|}\)') if midx != -1 && synIDattr(synID(v:lnum, midx + 1, 1), "name") != "luaComment" diff --git a/runtime/indent/php.vim b/runtime/indent/php.vim index 1bffa7f195..07ecd8f141 100644 --- a/runtime/indent/php.vim +++ b/runtime/indent/php.vim @@ -3,8 +3,8 @@ " Author: John Wellesz <John.wellesz (AT) teaser (DOT) fr> " URL: http://www.2072productions.com/vim/indent/php.vim " Home: https://github.com/2072/PHP-Indenting-for-VIm -" Last Change: 2014 November 26th -" Version: 1.57 +" Last Change: 2015 September 8th +" Version: 1.60 " " " Type :help php-indent for available options @@ -50,16 +50,25 @@ let b:did_indent = 1 let g:php_sync_method = 0 +if exists('*shiftwidth') + function! s:sw() + return shiftwidth() + endfunction +else + function! s:sw() + return &shiftwidth + endfunction +endif if exists("PHP_default_indenting") - let b:PHP_default_indenting = PHP_default_indenting * &sw + let b:PHP_default_indenting = PHP_default_indenting * s:sw() else let b:PHP_default_indenting = 0 endif if exists("PHP_outdentSLComments") - let b:PHP_outdentSLComments = PHP_outdentSLComments * &sw + let b:PHP_outdentSLComments = PHP_outdentSLComments * s:sw() else let b:PHP_outdentSLComments = 0 endif @@ -124,7 +133,7 @@ endif if exists("*GetPhpIndent") call ResetPhpOptions() - finish " XXX -- comment this line for easy dev + finish endif @@ -135,7 +144,7 @@ let s:functionDecl = '\<function\>\%(\s\+'.s:PHP_validVariable.'\)\=\s*(.*' let s:endline= '\s*\%(//.*\|#.*\|/\*.*\*/\s*\)\=$' -let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<''\=\a\w*''\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)\|^[^''"`]*[''"`]$' +let s:terminated = '\%(\%(;\%(\s*\%(?>\|}\)\)\=\|<<<\s*[''"]\=\a\w*[''"]\=$\|^\s*}\|^\s*'.s:PHP_validVariable.':\)'.s:endline.'\)\|^[^''"`]*[''"`]$' let s:PHP_startindenttag = '<?\%(.*?>\)\@!\|<script[^>]*>\%(.*<\/script>\)\@!' @@ -200,7 +209,7 @@ function! GetLastRealCodeLNum(startline) " {{{ elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc - let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<''\\=\1''\\=$', '') + let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '') while getline(lnum) !~? tofind && lnum > 1 let lnum = lnum - 1 endwhile @@ -314,7 +323,7 @@ function! FindTheSwitchIndent (lnum) " {{{ let test = GetLastRealCodeLNum(a:lnum - 1) if test <= 1 - return indent(1) - &sw * b:PHP_vintage_case_default_indent + return indent(1) - s:sw() * b:PHP_vintage_case_default_indent end while getline(test) =~ '^\s*}' && test > 1 @@ -328,7 +337,7 @@ function! FindTheSwitchIndent (lnum) " {{{ if getline(test) =~# '^\s*switch\>' return indent(test) elseif getline(test) =~# s:defaultORcase - return indent(test) - &sw * b:PHP_vintage_case_default_indent + return indent(test) - s:sw() * b:PHP_vintage_case_default_indent else return FindTheSwitchIndent(test) endif @@ -401,7 +410,7 @@ function! GetPhpIndent() endif if b:PHP_default_indenting - let b:PHP_default_indenting = g:PHP_default_indenting * &sw + let b:PHP_default_indenting = g:PHP_default_indenting * s:sw() endif let cline = getline(v:lnum) @@ -439,6 +448,7 @@ function! GetPhpIndent() if !b:InPHPcode_checked " {{{ One time check let b:InPHPcode_checked = 1 + let b:UserIsTypingComment = 0 let synname = "" if cline !~ '<?.*?>' @@ -447,8 +457,7 @@ function! GetPhpIndent() if synname!="" if synname == "SpecStringEntrails" - let b:InPHPcode = -1 " thumb down - let b:UserIsTypingComment = 0 + let b:InPHPcode = -1 let b:InPHPcode_tofind = "" elseif synname != "phpHereDoc" && synname != "phpHereDocDelimiter" let b:InPHPcode = 1 @@ -456,8 +465,7 @@ function! GetPhpIndent() if synname =~# '^php\%(Doc\)\?Comment' let b:UserIsTypingComment = 1 - else - let b:UserIsTypingComment = 0 + let b:InPHPcode_checked = 0 endif if synname =~? '^javaScript' @@ -466,18 +474,16 @@ function! GetPhpIndent() else let b:InPHPcode = 0 - let b:UserIsTypingComment = 0 let lnum = v:lnum - 1 - while getline(lnum) !~? '<<<''\=\a\w*''\=$' && lnum > 1 + while getline(lnum) !~? '<<<\s*[''"]\=\a\w*[''"]\=$' && lnum > 1 let lnum = lnum - 1 endwhile - let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '') + let b:InPHPcode_tofind = substitute( getline(lnum), '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '') endif else let b:InPHPcode = 0 - let b:UserIsTypingComment = 0 let b:InPHPcode_tofind = s:PHP_startindenttag endif endif "!b:InPHPcode_checked }}} @@ -537,9 +543,9 @@ function! GetPhpIndent() elseif last_line =~ '^[^''"`]\+[''"`]$' let b:InPHPcode = -1 let b:InPHPcode_tofind = substitute( last_line, '^.*\([''"`]\).*$', '^[^\1]*\1[;,]$', '') - elseif last_line =~? '<<<''\=\a\w*''\=$' + elseif last_line =~? '<<<\s*[''"]\=\a\w*[''"]\=$' let b:InPHPcode = 0 - let b:InPHPcode_tofind = substitute( last_line, '^.*<<<''\=\(\a\w*\)''\=$', '^\\s*\1;\\=$', '') + let b:InPHPcode_tofind = substitute( last_line, '^.*<<<\s*[''"]\=\(\a\w*\)[''"]\=$', '^\\s*\1;\\=$', '') elseif !UserIsEditing && cline =~ '^\s*/\*\%(.*\*/\)\@!' && getline(v:lnum + 1) !~ '^\s*\*' let b:InPHPcode = 0 @@ -660,7 +666,7 @@ function! GetPhpIndent() let b:PHP_CurrentIndentLevel = b:PHP_default_indenting return indent(FindTheIfOfAnElse(v:lnum, 1)) elseif cline =~# s:defaultORcase - return FindTheSwitchIndent(v:lnum) + &sw * b:PHP_vintage_case_default_indent + return FindTheSwitchIndent(v:lnum) + s:sw() * b:PHP_vintage_case_default_indent elseif cline =~ '^\s*)\=\s*{' let previous_line = last_line let last_line_num = lnum @@ -672,7 +678,7 @@ function! GetPhpIndent() let ind = indent(last_line_num) if b:PHP_BracesAtCodeLevel - let ind = ind + &sw + let ind = ind + s:sw() endif return ind @@ -683,7 +689,7 @@ function! GetPhpIndent() endwhile elseif last_line =~# unstated && cline !~ '^\s*);\='.endline - let ind = ind + &sw + let ind = ind + s:sw() return ind + addSpecial elseif (ind != b:PHP_default_indenting || last_line =~ '^[)\]]' ) && last_line =~ terminated @@ -782,7 +788,7 @@ function! GetPhpIndent() endif if !dontIndent && (!b:PHP_BracesAtCodeLevel || last_line !~# '^\s*{') - let ind = ind + &sw + let ind = ind + s:sw() endif if b:PHP_BracesAtCodeLevel || b:PHP_vintage_case_default_indent == 1 @@ -800,17 +806,17 @@ function! GetPhpIndent() endif elseif last_line =~ '^\s*'.s:blockstart - let ind = ind + &sw + let ind = ind + s:sw() elseif AntepenultimateLine =~ '{'.endline || AntepenultimateLine =~ terminated || AntepenultimateLine =~# s:defaultORcase - let ind = ind + &sw + let ind = ind + s:sw() endif endif if cline =~ '^\s*[)\]];\=' - let ind = ind - &sw + let ind = ind - s:sw() endif let b:PHP_CurrentIndentLevel = ind diff --git a/runtime/indent/r.vim b/runtime/indent/r.vim index 105f0cd7ad..01f3812ed2 100644 --- a/runtime/indent/r.vim +++ b/runtime/indent/r.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: R " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> -" Last Change: Thu Mar 26, 2015 05:36PM +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Thu Feb 18, 2016 06:32AM " Only load this indent file when no other was loaded. @@ -32,7 +33,7 @@ if ! exists("g:r_indent_ess_compatible") let g:r_indent_ess_compatible = 0 endif if ! exists("g:r_indent_op_pattern") - let g:r_indent_op_pattern = '\(+\|-\|\*\|/\|=\|\~\|%\)$' + let g:r_indent_op_pattern = '\(&\||\|+\|-\|\*\|/\|=\|\~\|%\|->\)\s*$' endif function s:RDelete_quotes(line) @@ -265,7 +266,7 @@ function GetRIndent() return 0 endif - if cline =~ '^\s*{' + if cline =~ '^\s*{' && s:Get_paren_balance(cline, '{', '}') > 0 if g:r_indent_ess_compatible && line =~ ')$' let nlnum = lnum let nline = line @@ -283,7 +284,7 @@ function GetRIndent() endif " line is an incomplete command: - if line =~ '\<\(if\|while\|for\|function\)\s*()$' || line =~ '\<else$' || line =~ '<-$' + if line =~ '\<\(if\|while\|for\|function\)\s*()$' || line =~ '\<else$' || line =~ '<-$' || line =~ '->$' return indent(lnum) + &sw endif @@ -344,7 +345,7 @@ function GetRIndent() endif let post_block = 0 - if line =~ '}$' + if line =~ '}$' && s:Get_paren_balance(line, '{', '}') < 0 let lnum = s:Get_matching_brace(lnum, '{', '}', 0) let line = SanitizeRLine(getline(lnum)) if lnum > 0 && line =~ '^\s*{' @@ -359,14 +360,14 @@ function GetRIndent() let olnum = s:Get_prev_line(lnum) let oline = getline(olnum) if olnum > 0 - if line =~ g:r_indent_op_pattern - if oline =~ g:r_indent_op_pattern + if line =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0 + if oline =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0 return indent(lnum) else return indent(lnum) + &sw endif else - if oline =~ g:r_indent_op_pattern + if oline =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0 return indent(lnum) - &sw endif endif @@ -471,7 +472,6 @@ function GetRIndent() endif let ind = indent(lnum) - let pind = indent(plnum) if g:r_indent_align_args == 0 && pb != 0 let ind += pb * &sw @@ -483,6 +483,12 @@ function GetRIndent() return ind endif + if plnum > 0 + let pind = indent(plnum) + else + let pind = 0 + endif + if ind == pind || (ind == (pind + &sw) && pline =~ '{$' && ppost_else == 0) return ind endif diff --git a/runtime/indent/rhelp.vim b/runtime/indent/rhelp.vim index 3b37128b2c..9dc2031cb6 100644 --- a/runtime/indent/rhelp.vim +++ b/runtime/indent/rhelp.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: R Documentation (Help), *.Rd " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> -" Last Change: Thu Oct 16, 2014 07:07AM +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Tue Apr 07, 2015 04:38PM " Only load this indent file when no other was loaded. diff --git a/runtime/indent/rmd.vim b/runtime/indent/rmd.vim index 9a8a3cb719..88904405e8 100644 --- a/runtime/indent/rmd.vim +++ b/runtime/indent/rmd.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: Rmd " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> -" Last Change: Thu Jul 10, 2014 07:11PM +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Tue Apr 07, 2015 04:38PM " Only load this indent file when no other was loaded. diff --git a/runtime/indent/rnoweb.vim b/runtime/indent/rnoweb.vim index d0cad3d8d9..29fa5bc78f 100644 --- a/runtime/indent/rnoweb.vim +++ b/runtime/indent/rnoweb.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: Rnoweb " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> -" Last Change: Sun Mar 22, 2015 09:28AM +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Tue Apr 07, 2015 04:38PM " Only load this indent file when no other was loaded. diff --git a/runtime/indent/rrst.vim b/runtime/indent/rrst.vim index 8bfa8344ce..f3ee53e7fb 100644 --- a/runtime/indent/rrst.vim +++ b/runtime/indent/rrst.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: Rrst " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> -" Last Change: Wed Jul 09, 2014 07:33PM +" Homepage: https://github.com/jalvesaq/R-Vim-runtime +" Last Change: Tue Apr 07, 2015 04:38PM " Only load this indent file when no other was loaded. diff --git a/runtime/indent/sh.vim b/runtime/indent/sh.vim index 5bd8c77fab..aca110f504 100644 --- a/runtime/indent/sh.vim +++ b/runtime/indent/sh.vim @@ -3,23 +3,29 @@ " Maintainer: Christian Brabandt <cb@256bit.org> " Previous Maintainer: Peter Aronoff <telemachus@arpinum.org> " Original Author: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2015-12-15 +" Latest Revision: 2016-06-27 " License: Vim (see :h license) " Repository: https://github.com/chrisbra/vim-sh-indent +" Changelog: +" 20160627: - detect heredocs correctly +" 20160213: - detect function definition correctly +" 20160202: - use shiftwidth() function +" 20151215: - set b:undo_indent variable +" 20150728: - add foreach detection for zsh if exists("b:did_indent") finish endif let b:did_indent = 1 -let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<' - setlocal indentexpr=GetShIndent() setlocal indentkeys+=0=then,0=do,0=else,0=elif,0=fi,0=esac,0=done,0=end,),0=;;,0=;& setlocal indentkeys+=0=fin,0=fil,0=fip,0=fir,0=fix setlocal indentkeys-=:,0# setlocal nosmartindent +let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<' + if exists("*GetShIndent") finish endif @@ -28,7 +34,7 @@ let s:cpo_save = &cpo set cpo&vim function s:buffer_shiftwidth() - return &shiftwidth + return shiftwidth() endfunction let s:sh_indent_defaults = { @@ -67,7 +73,7 @@ function! GetShIndent() if !s:is_case_ended(line) let ind += s:indent_value('case-statements') endif - elseif line =~ '^\s*\<\k\+\>\s*()\s*{' || line =~ '^\s*{' + elseif line =~ '^\s*\<\k\+\>\s*()\s*{' || line =~ '^\s*{' || line =~ '^\s*function\s*\w\S\+\s*\%(()\)\?\s*{' if line !~ '}\s*\%(#.*\)\=$' let ind += s:indent_value('default') endif @@ -102,6 +108,8 @@ function! GetShIndent() endif elseif s:is_case_break(line) let ind -= s:indent_value('case-breaks') + elseif s:is_here_doc(line) + let ind = 0 endif return ind @@ -160,6 +168,14 @@ function! s:is_case_break(line) return a:line =~ '^\s*;[;&]' endfunction +function! s:is_here_doc(line) + if a:line =~ '^\w\+$' + let here_pat = '<<-\?'. s:escape(a:line). '\$' + return search(here_pat, 'bnW') > 0 + endif + return 0 +endfunction + function! s:is_case_ended(line) return s:is_case_break(a:line) || a:line =~ ';[;&]\s*\%(#.*\)\=$' endfunction @@ -172,5 +188,9 @@ function! s:is_case_empty(line) endif endfunction +function! s:escape(pattern) + return '\V'. escape(a:pattern, '\\') +endfunction + let &cpo = s:cpo_save unlet s:cpo_save diff --git a/runtime/indent/tex.vim b/runtime/indent/tex.vim index 7e3a351083..0150bb9623 100644 --- a/runtime/indent/tex.vim +++ b/runtime/indent/tex.vim @@ -2,10 +2,9 @@ " Language: LaTeX " Maintainer: YiChao Zhou <broken.zhou AT gmail.com> " Created: Sat, 16 Feb 2002 16:50:19 +0100 -" Last Change: 2012 Mar 18 19:19:50 -" Version: 0.7 -" Please email me if you found something we can do. Bug report and -" feature request is welcome. +" Version: 0.9.2 +" Please email me if you found something I can do. Comments, bug report and +" feature request are welcome. " Last Update: {{{ " 25th Sep 2002, by LH : @@ -41,7 +40,7 @@ " (*) Trust user when in "verbatim" and "lstlisting" " 2012/03/11 by Zhou Yichao <broken.zhou AT gmail.com> " (*) Modify "&" so that only indent when current line start with -" "&". +" "&". " 2012/03/12 by Zhou Yichao <broken.zhou AT gmail.com> " (*) Modify indentkeys. " 2012/03/18 by Zhou Yichao <broken.zhou AT gmail.com> @@ -49,6 +48,17 @@ " 2013/05/02 by Zhou Yichao <broken.zhou AT gmail.com> " (*) Fix problem about GetTeXIndent checker. Thank Albert Netymk " for reporting this. +" 2014/06/23 by Zhou Yichao <broken.zhou AT gmail.com> +" (*) Remove the feature g:tex_indent_and because it is buggy. +" (*) If there is not any obvious indentation hints, we do not +" alert our user's current indentation. +" (*) g:tex_indent_brace now only works if the open brace is the +" last character of that line. +" 2014/08/03 by Zhou Yichao <broken.zhou AT gmail.com> +" (*) Indent current line if last line has larger indentation +" 2014/08/09 by Zhou Yichao <broken.zhou AT gmail.com> +" (*) Add missing return value for s:GetEndIndentation(...) +" " }}} " Document: {{{ @@ -60,7 +70,17 @@ " * g:tex_indent_brace " " If this variable is unset or non-zero, it will use smartindent-like style -" for "{}" and "[]" +" for "{}" and "[]". Now this only works if the open brace is the last +" character of that line. +" +" % Example 1 +" \usetikzlibrary{ +" external +" } +" +" % Example 2 +" \tikzexternalize[ +" prefix=tikz] " " * g:tex_indent_items " @@ -98,14 +118,6 @@ " " A list of environment names. separated with '\|', where no indentation is " required. The default is 'document\|verbatim'. -" -" * g:tex_indent_and -" -" If this variable is unset or zero, vim will try to align the line with first -" "&". This is pretty useful when you use environment like table or align. -" Note that this feature need to search back some line, so vim may become -" a little slow. -" " }}} " Only define the function once @@ -126,8 +138,8 @@ endif if !exists("g:tex_indent_brace") let g:tex_indent_brace = 1 endif -if !exists("g:tex_indent_and") - let g:tex_indent_and = 1 +if !exists("g:tex_max_scan_line") + let g:tex_max_scan_line = 60 endif if g:tex_indent_items if !exists("g:tex_itemize_env") @@ -140,10 +152,6 @@ else let g:tex_items = '' endif -if !exists("g:tex_indent_paretheses") - let g:tex_indent_paretheses = 1 -endif - if !exists("g:tex_noindent_env") let g:tex_noindent_env = 'document\|verbatim\|lstlisting' endif "}}} @@ -160,6 +168,7 @@ let g:tex_items = '^\s*' . substitute(g:tex_items, '^\(\^\\s\*\)*', '', '') function! GetTeXIndent() " {{{ " Find a non-blank line above the current line. let lnum = prevnonblank(v:lnum - 1) + let cnum = v:lnum " Comment line is not what we need. while lnum != 0 && getline(lnum) =~ '^\s*%' @@ -171,8 +180,8 @@ function! GetTeXIndent() " {{{ return 0 endif - let line = substitute(getline(lnum), '%.*', ' ','g') " last line - let cline = substitute(getline(v:lnum), '%.*', ' ', 'g') " current line + let line = substitute(getline(lnum), '\s*%.*', '','g') " last line + let cline = substitute(getline(v:lnum), '\s*%.*', '', 'g') " current line " We are in verbatim, so do what our user what. if synIDattr(synID(v:lnum, indent(v:lnum), 1), "name") == "texZone" @@ -183,26 +192,12 @@ function! GetTeXIndent() " {{{ end endif - " You want to align with "&" - if g:tex_indent_and - " Align only when current line start with "&" - if line =~ '&.*\\\\' && cline =~ '^\s*&' - return indent(v:lnum) + stridx(line, "&") - stridx(cline, "&") - endif - - " set line & lnum to the line which doesn't contain "&" - while lnum != 0 && (stridx(line, "&") != -1 || line =~ '^\s*%') - let lnum = prevnonblank(lnum - 1) - let line = getline(lnum) - endwhile - endif - - if lnum == 0 return 0 endif let ind = indent(lnum) + let stay = 1 " New code for comment: retain the indent of current line if cline =~ '^\s*%' @@ -216,77 +211,197 @@ function! GetTeXIndent() " {{{ " ZYC modification : \end after \begin won't cause wrong indent anymore if line =~ '\\begin{.*}' && line !~ g:tex_noindent_env let ind = ind + &sw + let stay = 0 if g:tex_indent_items " Add another sw for item-environments if line =~ g:tex_itemize_env let ind = ind + &sw + let stay = 0 endif endif endif + if cline =~ '\\end{.*}' + let retn = s:GetEndIndentation(v:lnum) + if retn != -1 + return retn + endif + end " Subtract a 'shiftwidth' when an environment ends - if cline =~ '\\end{.*}' && cline !~ g:tex_noindent_env - + if cline =~ '\\end{.*}' + \ && cline !~ g:tex_noindent_env + \ && cline !~ '\\begin{.*}.*\\end{.*}' if g:tex_indent_items " Remove another sw for item-environments if cline =~ g:tex_itemize_env let ind = ind - &sw + let stay = 0 endif endif let ind = ind - &sw + let stay = 0 endif if g:tex_indent_brace - let sum1 = 0 - for i in range(0, strlen(line)-1) - if line[i] == "}" || line[i] == "]" || - \ strpart(line, i, 7) == '\right)' - let sum1 = max([0, sum1-1]) - endif - if line[i] == "{" || line[i] == "[" || - \ strpart(line, i, 6) == '\left(' - let sum1 += 1 - endif - endfor + let char = line[strlen(line)-1] + if char == '[' || char == '{' + let ind += &sw + let stay = 0 + endif - let sum2 = 0 - for i in reverse(range(0, strlen(cline)-1)) - if cline[i] == "{" || cline[i] == "[" || - \ strpart(cline, i, 6) == '\left(' - let sum2 = max([0, sum2-1]) - endif - if cline[i] == "}" || cline[i] == "]" || - \ strpart(cline, i, 7) == '\right)' - let sum2 += 1 + let cind = indent(v:lnum) + let char = cline[cind] + if (char == ']' || char == '}') && + \ s:CheckPairedIsLastCharacter(v:lnum, cind) + let ind -= &sw + let stay = 0 + endif + + for i in range(indent(lnum)+1, strlen(line)-1) + let char = line[i] + if char == ']' || char == '}' + if s:CheckPairedIsLastCharacter(lnum, i) + let ind -= &sw + let stay = 0 + endif endif endfor - - let ind += (sum1 - sum2) * &sw - endif - - if g:tex_indent_paretheses endif " Special treatment for 'item' " ---------------------------- if g:tex_indent_items - " '\item' or '\bibitem' itself: if cline =~ g:tex_items let ind = ind - &sw + let stay = 0 endif - " lines following to '\item' are intented once again: if line =~ g:tex_items let ind = ind + &sw + let stay = 0 + endif + endif + + if stay + " If there is no obvious indentation hint, we trust our user. + if empty(cline) + return ind + else + return max([indent(v:lnum), s:GetLastBeginIndentation(v:lnum)]) + endif + else + return ind + endif +endfunction "}}} + +function! s:GetLastBeginIndentation(lnum) " {{{ + let matchend = 1 + for lnum in range(a:lnum-1, max([a:lnum - g:tex_max_scan_line, 1]), -1) + let line = getline(lnum) + if line =~ '\\end{.*}' + let matchend += 1 + endif + if line =~ '\\begin{.*}' + let matchend -= 1 endif + if matchend == 0 + if line =~ g:tex_itemize_env + return indent(lnum) + 2 * &sw + endif + if line =~ g:tex_noindent_env + return indent(lnum) + endif + return indent(lnum) + &sw + endif + endfor + return -1 +endfunction + +function! s:GetEndIndentation(lnum) " {{{ + if getline(a:lnum) =~ '\\begin{.*}.*\\end{.*}' + return -1 + endif + + let min_indent = 100 + let matchend = 1 + for lnum in range(a:lnum-1, max([a:lnum-g:tex_max_scan_line, 1]), -1) + let line = getline(lnum) + if line =~ '\\end{.*}' + let matchend += 1 + endif + if line =~ '\\begin{.*}' + let matchend -= 1 + endif + if matchend == 0 + return indent(lnum) + endif + if !empty(line) + let min_indent = min([min_indent, indent(lnum)]) + endif + endfor + return min_indent - &sw +endfunction + +" Most of the code is from matchparen.vim +function! s:CheckPairedIsLastCharacter(lnum, col) "{{{ + " Get the character under the cursor and check if it's in 'matchpairs'. + let c_lnum = a:lnum + let c_col = a:col+1 + + + let c = getline(c_lnum)[c_col-1] + let plist = split(&matchpairs, '.\zs[:,]') + let i = index(plist, c) + if i < 0 + return 0 + endif + + " Figure out the arguments for searchpairpos(). + if i % 2 == 0 + let s_flags = 'nW' + let c2 = plist[i + 1] + else + let s_flags = 'nbW' + let c2 = c + let c = plist[i - 1] + endif + if c == '[' + let c = '\[' + let c2 = '\]' + endif + + " Find the match. When it was just before the cursor move it there for a + " moment. + let save_cursor = winsaveview() + call cursor(c_lnum, c_col) + + " When not in a string or comment ignore matches inside them. + " We match "escape" for special items, such as lispEscapeSpecial. + let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' . + \ '=~? "string\\|character\\|singlequote\\|escape\\|comment"' + execute 'if' s_skip '| let s_skip = 0 | endif' + + let stopline = max([0, c_lnum - g:tex_max_scan_line]) + + " Limit the search time to 300 msec to avoid a hang on very long lines. + " This fails when a timeout is not supported. + try + let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, 100) + catch /E118/ + endtry + + call winrestview(save_cursor) + if m_lnum > 0 + let line = getline(m_lnum) + return strlen(line) == m_col endif - return ind + return 0 endfunction "}}} let &cpo = s:cpo_save diff --git a/runtime/indent/vhdl.vim b/runtime/indent/vhdl.vim index 3e847b9575..6982859670 100644 --- a/runtime/indent/vhdl.vim +++ b/runtime/indent/vhdl.vim @@ -1,8 +1,8 @@ " VHDL indent ('93 syntax) " Language: VHDL " Maintainer: Gerald Lai <laigera+vim?gmail.com> -" Version: 1.58 -" Last Change: 2011 Sep 27 +" Version: 1.60 +" Last Change: 2016 Feb 26 " URL: http://www.vim.org/scripts/script.php?script_id=1450 " only load this indent file when no other was loaded @@ -104,7 +104,7 @@ function GetVHDLindent() let pn = prevnonblank(pn - 1) let ps = getline(pn) endwhile - if (curs =~ '^\s*)' || curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*\%(=>\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)\)') && (prevs =~? s:NC.'\<\%(procedure\s\+\S\+\|generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(procedure\|generic\|map\|port\)'.s:ES && prevs =~ '^\s*(')) + if (curs =~ '^\s*)' || curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*\((.*)\)*\s*\%(=>\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\s\+\)\)') && (prevs =~? s:NC.'\<\%(procedure\s\+\S\+\|generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(procedure\|generic\|map\|port\)'.s:ES && prevs =~ '^\s*(')) " align closing ")" with opening "(" if curs =~ '^\s*)' return ind2 + stridx(prevs_noi, '(') @@ -412,11 +412,22 @@ function GetVHDLindent() " **************************************************************************************** " indent: maintain indent of previous opening statement - " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=" + "in", "out", "inout", "buffer", "linkage", variable & ":=" + " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=" + eventually ;$ " where: start of current line - if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)' + if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=].*;.*$' return ind2 endif + " **************************************************************************************** + " indent: maintain indent of previous opening statement, corner case which + " does not end in ;, but is part of a mapping + " keywords: without "procedure", "generic", "map", "port" + ":" but not ":=", never + ;$ and + " prevline without "procedure", "generic", "map", "port" + ":" but not ":=" + eventually ;$ + " where: start of current line + if curs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=].*[^;].*$' + if prevs =~? '^\s*\%(\<\%(procedure\|generic\|map\|port\)\>.*\)\@<!\w\+\s*\w*\s*:[^=].*;.*$' + return ind2 + endif + endif " return leftover filtered indent return ind diff --git a/runtime/indent/vim.vim b/runtime/indent/vim.vim index 7511325af4..8ebfa12caf 100644 --- a/runtime/indent/vim.vim +++ b/runtime/indent/vim.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Vim script " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2014 Dec 12 +" Last Change: 2016 Jun 27 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -58,19 +58,19 @@ function GetVimIndentIntern() if exists("g:vim_indent_cont") let ind = ind + g:vim_indent_cont else - let ind = ind + &sw * 3 + let ind = ind + shiftwidth() * 3 endif - elseif prev_text =~ '^\s*aug\%[roup]' && prev_text !~ '^\s*aug\%[roup]\s*!\=\s\+END' - let ind = ind + &sw + elseif prev_text =~ '^\s*aug\%[roup]\s\+' && prev_text !~ '^\s*aug\%[roup]\s\+[eE][nN][dD]\>' + let ind = ind + shiftwidth() else " A line starting with :au does not increment/decrement indent. if prev_text !~ '^\s*au\%[tocmd]' let i = match(prev_text, '\(^\||\)\s*\(if\|wh\%[ile]\|for\|try\|cat\%[ch]\|fina\%[lly]\|fu\%[nction]\|el\%[seif]\)\>') if i >= 0 - let ind += &sw + let ind += shiftwidth() if strpart(prev_text, i, 1) == '|' && has('syntax_items') \ && synIDattr(synID(lnum, i, 1), "name") =~ '\(Comment\|String\)$' - let ind -= &sw + let ind -= shiftwidth() endif endif endif @@ -82,15 +82,15 @@ function GetVimIndentIntern() let i = match(prev_text, '[^\\]|\s*\(ene\@!\)') if i > 0 && prev_text !~ '^\s*au\%[tocmd]' if !has('syntax_items') || synIDattr(synID(lnum, i + 2, 1), "name") !~ '\(Comment\|String\)$' - let ind = ind - &sw + let ind = ind - shiftwidth() endif endif " Subtract a 'shiftwidth' on a :endif, :endwhile, :catch, :finally, :endtry, " :endfun, :else and :augroup END. - if cur_text =~ '^\s*\(ene\@!\|cat\|fina\|el\|aug\%[roup]\s*!\=\s\+[eE][nN][dD]\)' - let ind = ind - &sw + if cur_text =~ '^\s*\(ene\@!\|cat\|fina\|el\|aug\%[roup]\s\+[eE][nN][dD]\)' + let ind = ind - shiftwidth() endif return ind diff --git a/runtime/indent/zimbu.vim b/runtime/indent/zimbu.vim index 9565b10843..5451877ea7 100644 --- a/runtime/indent/zimbu.vim +++ b/runtime/indent/zimbu.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Zimbu " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2012 Sep 08 +" Last Change: 2016 Jan 25 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -74,9 +74,9 @@ func GetZimbuIndent(lnum) \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" \ . " =~ '\\(Comment\\|String\\|Char\\)$'") if pp > 0 - return indent(prevLnum) + &sw + return indent(prevLnum) + shiftwidth() endif - return indent(prevLnum) + &sw * 2 + return indent(prevLnum) + shiftwidth() * 2 endif if plnumstart == p return indent(prevLnum) @@ -102,13 +102,13 @@ func GetZimbuIndent(lnum) endif if prevline =~ '^\s*\(IF\|\|ELSEIF\|ELSE\|GENERATE_IF\|\|GENERATE_ELSEIF\|GENERATE_ELSE\|WHILE\|REPEAT\|TRY\|CATCH\|FINALLY\|FOR\|DO\|SWITCH\|CASE\|DEFAULT\|FUNC\|VIRTUAL\|ABSTRACT\|DEFINE\|REPLACE\|FINAL\|PROC\|MAIN\|NEW\|ENUM\|CLASS\|INTERFACE\|BITS\|MODULE\|SHARED\)\>' - let plindent += &sw + let plindent += shiftwidth() endif if thisline =~ '^\s*\(}\|ELSEIF\>\|ELSE\>\|CATCH\|FINALLY\|GENERATE_ELSEIF\>\|GENERATE_ELSE\>\|UNTIL\>\)' - let plindent -= &sw + let plindent -= shiftwidth() endif if thisline =~ '^\s*\(CASE\>\|DEFAULT\>\)' && prevline !~ '^\s*SWITCH\>' - let plindent -= &sw + let plindent -= shiftwidth() endif " line up continued comment that started after some code |