diff options
Diffstat (limited to 'runtime/indent')
43 files changed, 1154 insertions, 226 deletions
diff --git a/runtime/indent/Makefile b/runtime/indent/Makefile index d192605527..f6c44736d2 100644 --- a/runtime/indent/Makefile +++ b/runtime/indent/Makefile @@ -10,5 +10,5 @@ test: VIMRUNTIME=$(VIMRUNTIME) $(VIM) --clean --not-a-term -u testdir/runtest.vim -clean: +clean testclean: rm -f testdir/*.fail testdir/*.out diff --git a/runtime/indent/bash.vim b/runtime/indent/bash.vim new file mode 100644 index 0000000000..b91640687c --- /dev/null +++ b/runtime/indent/bash.vim @@ -0,0 +1,18 @@ +" Vim indent file +" Language: bash +" Maintainer: Bram +" Last Change: 2019 Sep 27 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif + +" The actual indenting is in sh.vim and controlled by buffer-local variables. +unlet! b:is_sh +unlet! b:is_kornshell +let b:is_bash = 1 + +runtime! indent/sh.vim + +" vim: ts=8 diff --git a/runtime/indent/cdl.vim b/runtime/indent/cdl.vim index 5fae7b9046..4f9b7a8967 100644 --- a/runtime/indent/cdl.vim +++ b/runtime/indent/cdl.vim @@ -62,10 +62,14 @@ fun! CdlGetIndent(lnum) " PREVIOUS LINE let ind = indent(lnum) let line = getline(lnum) - let f = -1 " wether a '=' is a conditional or a asignment, -1 means we don't know yet - " one 'closing' element at the beginning of the line has already reduced the - " indent, but 'else', 'elseif' & 'then' increment it for the next line - " '=' at the beginning has already de right indent (increased for asignments) + + " Whether a '=' is a conditional or an assignment. -1 means we don't know + " yet. + " One 'closing' element at the beginning of the line has already reduced the + " indent, but 'else', 'elseif' & 'then' increment it for the next line. + " '=' at the beginning already has the right indent (increased for + " asignments). + let f = -1 let inicio = matchend(line, '^\c\s*\(else\a*\|then\|endif\|/[*/]\|[);={]\)') if inicio > 0 let c = line[inicio-1] diff --git a/runtime/indent/clojure.vim b/runtime/indent/clojure.vim index 7c4186e29b..30a0b478e2 100644 --- a/runtime/indent/clojure.vim +++ b/runtime/indent/clojure.vim @@ -1,12 +1,11 @@ " Vim indent file -" 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: 18 July 2016 +" Language: Clojure +" Maintainer: Alex Vear <av@axvr.io> +" Former Maintainers: Sung Pae <self@sungpae.com> +" Meikel Brandmeyer <mb@kotka.de> +" URL: https://github.com/clojure-vim/clojure.vim +" License: Vim (see :h license) +" Last Change: 2021-02-13 if exists("b:did_indent") finish @@ -87,7 +86,7 @@ if exists("*searchpairpos") 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 + if a:stopat == 0 && g:clojure_maxlines > 0 let stopat = max([line(".") - g:clojure_maxlines, 0]) else let stopat = a:stopat @@ -121,7 +120,7 @@ if exists("*searchpairpos") if s:syn_id_name() !~? "string" return -1 endif - if s:current_char() != '\\' + if s:current_char() != '\' return -1 endif call cursor(0, col("$") - 1) @@ -170,7 +169,35 @@ if exists("*searchpairpos") call search('\S', 'W') let w = s:strip_namespace_and_macro_chars(s:current_word()) + if g:clojure_special_indent_words =~# '\V\<' . w . '\>' + + " `letfn` is a special-special-case. + if w ==# 'letfn' + " Earlier code left the cursor at: + " (letfn [...] ...) + " ^ + + " Search and get coordinates of first `[` + " (letfn [...] ...) + " ^ + call search('\[', 'W') + let pos = getcurpos() + let letfn_bracket = [pos[1], pos[2]] + + " Move cursor to start of the form this function was + " initially called on. Grab the coordinates of the + " closest outer `[`. + call cursor(a:position) + let outer_bracket = s:match_pairs('\[', '\]', 0) + + " If the located square brackets are not the same, + " don't use special-case formatting. + if outer_bracket != letfn_bracket + return 0 + endif + endif + return 1 endif @@ -190,11 +217,7 @@ if exists("*searchpairpos") " 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 + return getline(a:position[0])[a:position[1] - 3 : a:position[1] - 2] == "#?" endfunction " Returns 1 for opening brackets, -1 for _anything else_. @@ -261,7 +284,7 @@ if exists("*searchpairpos") call cursor(paren) if s:is_method_special_case(paren) - return [paren[0], paren[1] + shiftwidth() - 1] + return [paren[0], paren[1] + &shiftwidth - 1] endif if s:is_reader_conditional_special_case(paren) @@ -292,6 +315,19 @@ if exists("*searchpairpos") return paren endif + " If the keyword begins with #, check if it is an anonymous + " function or set, in which case we indent by the shiftwidth + " (minus one if g:clojure_align_subforms = 1), or if it is + " ignored, in which case we use the ( position for indent. + if w[0] == "#" + " TODO: Handle #=() and other rare reader invocations? + if w[1] == '(' || w[1] == '{' + return [paren[0], paren[1] + (g:clojure_align_subforms ? 0 : &shiftwidth - 1)] + elseif w[1] == '_' + return paren + endif + endif + " Test words without namespace qualifiers and leading reader macro " metacharacters. " @@ -299,19 +335,19 @@ if exists("*searchpairpos") let ww = s:strip_namespace_and_macro_chars(w) if &lispwords =~# '\V\<' . ww . '\>' - return [paren[0], paren[1] + shiftwidth() - 1] + return [paren[0], paren[1] + &shiftwidth - 1] endif if g:clojure_fuzzy_indent \ && !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] + return [paren[0], paren[1] + &shiftwidth - 1] endif call search('\v\_s', 'cW') call search('\v\S', 'W') if paren[0] < line(".") - return [paren[0], 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') diff --git a/runtime/indent/dune.vim b/runtime/indent/dune.vim new file mode 100644 index 0000000000..0590d66d13 --- /dev/null +++ b/runtime/indent/dune.vim @@ -0,0 +1,13 @@ +" Vim indent file +" Language: dune +" Maintainers: Markus Mottl <markus.mottl@gmail.com> +" URL: https://github.com/ocaml/vim-ocaml +" Last Change: 2021 Jan 01 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" dune format-dune-file uses 1 space to indent +setlocal softtabstop=1 shiftwidth=1 expandtab diff --git a/runtime/indent/erlang.vim b/runtime/indent/erlang.vim index 9228f18683..625cfde0c1 100644 --- a/runtime/indent/erlang.vim +++ b/runtime/indent/erlang.vim @@ -4,9 +4,9 @@ " Contributors: Edwin Fine <efine145_nospam01 at usa dot net> " Pawel 'kTT' Salata <rockplayer.pl@gmail.com> " Ricardo Catalinas JimĂ©nez <jimenezrick@gmail.com> -" Last Update: 2013-Jul-21 +" Last Update: 2020-Jun-11 " License: Vim license -" URL: https://github.com/hcs42/vim-erlang +" URL: https://github.com/vim-erlang/vim-erlang-runtime " Note About Usage: " This indentation script works best with the Erlang syntax file created by @@ -56,7 +56,8 @@ endfunction " Line tokenizer library {{{1 " ====================== -" Indtokens are "indentation tokens". +" Indtokens are "indentation tokens". See their exact format in the +" documentaiton of the s:GetTokensFromLine function. " Purpose: " Calculate the new virtual column after the given segment of a line. @@ -119,9 +120,10 @@ endfunction " Returns: " indtokens = [indtoken] " indtoken = [token, vcol, col] -" token = string (examples: 'begin', '<variable>', '}') -" vcol = integer (the virtual column of the first character of the token) -" col = integer +" token = string (examples: 'begin', '<quoted_atom>', '}') +" vcol = integer (the virtual column of the first character of the token; +" counting starts from 0) +" col = integer (counting starts from 0) function! s:GetTokensFromLine(line, string_continuation, atom_continuation, \tabstop) @@ -386,9 +388,12 @@ endfunction " lnum: integer " direction: 'up' | 'down' " Returns: -" result: [] -- the result is an empty list if we hit the beginning or end -" of the file -" | indtoken +" result: [[], 0, 0] +" -- the result is an empty list if we hit the beginning or end of +" the file +" | [indtoken, lnum, i] +" -- the content, lnum and token index of the next (or previous) +" indtoken function! s:FindIndToken(lnum, dir) let lnum = a:lnum while 1 @@ -396,9 +401,12 @@ function! s:FindIndToken(lnum, dir) let [lnum, indtokens] = s:TokenizeLine(lnum, a:dir) if lnum ==# 0 " We hit the beginning or end of the file - return [] + return [[], 0, 0] elseif !empty(indtokens) - return indtokens[a:dir ==# 'up' ? -1 : 0] + " We found a non-empty line. If we were moving up, we return the last + " token of this line. Otherwise we return the first token if this line. + let i = (a:dir ==# 'up' ? len(indtokens) - 1 : 0) + return [indtokens[i], lnum, i] endif endwhile endfunction @@ -417,7 +425,7 @@ function! s:PrevIndToken(lnum, i) " If the current line has a previous token, return that if a:i > 0 - return s:all_tokens[a:lnum][a:i - 1] + return [s:all_tokens[a:lnum][a:i - 1], a:lnum, a:i - 1] else return s:FindIndToken(a:lnum, 'up') endif @@ -437,7 +445,7 @@ function! s:NextIndToken(lnum, i) " If the current line has a next token, return that if len(s:all_tokens[a:lnum]) > a:i + 1 - return s:all_tokens[a:lnum][a:i + 1] + return [s:all_tokens[a:lnum][a:i + 1], a:lnum, a:i + 1] else return s:FindIndToken(a:lnum, 'down') endif @@ -518,7 +526,9 @@ endfunction " ok. % IsLineAtomContinuation = false function! s:IsLineAtomContinuation(lnum) if has('syntax_items') - return synIDattr(synID(a:lnum, 1, 0), 'name') =~# '^erlangQuotedAtom' + let syn_name = synIDattr(synID(a:lnum, 1, 0), 'name') + return syn_name =~# '^erlangQuotedAtom' || + \ syn_name =~# '^erlangQuotedRecord' else return 0 endif @@ -535,7 +545,7 @@ endfunction " is_standalone: bool function! s:IsCatchStandalone(lnum, i) call s:Log(' IsCatchStandalone called: lnum=' . a:lnum . ', i=' . a:i) - let prev_indtoken = s:PrevIndToken(a:lnum, a:i) + let [prev_indtoken, _, _] = s:PrevIndToken(a:lnum, a:i) " If we hit the beginning of the file, it is not a catch in a try block if prev_indtoken == [] @@ -544,7 +554,7 @@ function! s:IsCatchStandalone(lnum, i) let prev_token = prev_indtoken[0] - if prev_token =~# '[A-Z_@0-9]' + if prev_token =~# '^[A-Z_@0-9]' let is_standalone = 0 elseif prev_token =~# '[a-z]' if index(['after', 'and', 'andalso', 'band', 'begin', 'bnot', 'bor', 'bsl', @@ -659,11 +669,14 @@ endfunction " stack: [token] " token: string " stored_vcol: integer +" lnum: the line number of the "end of clause" mark (or 0 if we hit the +" beginning of the file) +" i: the index of the "end of clause" token within its own line " Returns: " result: [should_return, indent] " should_return: bool -- if true, the caller should return `indent` to Vim " indent -- integer -function! s:BeginningOfClauseFound(stack, token, stored_vcol) +function! s:BeginningOfClauseFound(stack, token, stored_vcol, lnum, i) if !empty(a:stack) && a:stack[0] ==# 'when' call s:Log(' BeginningOfClauseFound: "when" found in stack') call s:Pop(a:stack) @@ -681,13 +694,45 @@ function! s:BeginningOfClauseFound(stack, token, stored_vcol) return [1, a:stored_vcol + shiftwidth()] elseif a:stack[0] ==# ';' call s:Pop(a:stack) - if empty(a:stack) - call s:Log(' Stack is ["->", ";"], so LTI is in a function head ' . - \'-> return') - return [0, a:stored_vcol] - else + + if !empty(a:stack) return [1, s:UnexpectedToken(a:token, a:stack)] endif + + if a:lnum ==# 0 + " Set lnum and i to be NextIndToken-friendly + let lnum = 1 + let i = -1 + else + let lnum = a:lnum + let i = a:i + endif + + " Are we after a "-spec func() ...;" clause? + let [next1_indtoken, next1_lnum, next1_i] = s:NextIndToken(lnum, i) + if !empty(next1_indtoken) && next1_indtoken[0] =~# '-' + let [next2_indtoken, next2_lnum, next2_i] = + \s:NextIndToken(next1_lnum, next1_i) + if !empty(next2_indtoken) && next2_indtoken[0] =~# 'spec' + let [next3_indtoken, next3_lnum, next3_i] = + \s:NextIndToken(next2_lnum, next2_i) + if !empty(next3_indtoken) + let [next4_indtoken, next4_lnum, next4_i] = + \s:NextIndToken(next3_lnum, next3_i) + if !empty(next4_indtoken) + " Yes, we are. + call s:Log(' Stack is ["->", ";"], so LTI is in a "-spec" ' . + \'attribute -> return') + return [1, next4_indtoken[1]] + endif + endif + endif + endif + + call s:Log(' Stack is ["->", ";"], so LTI is in a function head ' . + \'-> return') + return [1, a:stored_vcol] + else return [1, s:UnexpectedToken(a:token, a:stack)] endif @@ -714,7 +759,7 @@ function! s:SearchEndPair(lnum, curr_col) return s:SearchPair( \ a:lnum, a:curr_col, \ '\C\<\%(case\|try\|begin\|receive\|if\)\>\|' . - \ '\<fun\>\%(\s\|\n\|%.*$\)*(', + \ '\<fun\>\%(\s\|\n\|%.*$\|[A-Z_@][a-zA-Z_@]*\)*(', \ '', \ '\<end\>') endfunction @@ -756,7 +801,7 @@ function! s:ErlangCalcIndent2(lnum, stack) " Hit the start of the file if lnum ==# 0 let [ret, res] = s:BeginningOfClauseFound(stack, 'beginning_of_file', - \stored_vcol) + \stored_vcol, 0, 0) if ret | return res | endif return 0 @@ -775,7 +820,8 @@ function! s:ErlangCalcIndent2(lnum, stack) endif if token ==# '<end_of_clause>' - let [ret, res] = s:BeginningOfClauseFound(stack, token, stored_vcol) + let [ret, res] = s:BeginningOfClauseFound(stack, token, stored_vcol, + \lnum, i) if ret | return res | endif if stored_vcol ==# -1 @@ -787,7 +833,7 @@ function! s:ErlangCalcIndent2(lnum, stack) endif elseif stack == ['prev_term_plus'] - if token =~# '[a-zA-Z_@]' || + if token =~# '[a-zA-Z_@#]' || \ token ==# '<string>' || token ==# '<string_start>' || \ token ==# '<quoted_atom>' || token ==# '<quoted_atom_start>' call s:Log(' previous token found: curr_vcol + plus = ' . @@ -917,9 +963,18 @@ function! s:ErlangCalcIndent2(lnum, stack) if ret | return res | endif elseif token ==# 'fun' - let next_indtoken = s:NextIndToken(lnum, i) + let [next_indtoken, next_lnum, next_i] = s:NextIndToken(lnum, i) call s:Log(' Next indtoken = ' . string(next_indtoken)) + if !empty(next_indtoken) && next_indtoken[0] =~# '^[A-Z_@]' + " The "fun" is followed by a variable, so we might have a named fun: + " "fun Fun() -> ok end". Thus we take the next token to decide + " whether this is a function definition ("fun()") or just a function + " reference ("fun Mod:Fun"). + let [next_indtoken, _, _] = s:NextIndToken(next_lnum, next_i) + call s:Log(' Next indtoken = ' . string(next_indtoken)) + endif + if !empty(next_indtoken) && next_indtoken[0] ==# '(' " We have an anonymous function definition " (e.g. "fun () -> ok end") @@ -1327,6 +1382,26 @@ function! ErlangIndent() return -1 endif + " If the line starts with the comment, and so is the previous non-blank line + if currline =~# '^\s*%' + let lnum = prevnonblank(v:lnum - 1) + if lnum ==# 0 + call s:Log('First non-empty line of the file -> return 0.') + return 0 + else + let ml = matchlist(getline(lnum), '^\(\s*\)%') + " If the previous line also starts with a comment, then return the same + " indentation that line has. Otherwise exit from this special "if" and + " don't care that the current line is a comment. + if !empty(ml) + let new_col = s:CalcVCol(ml[1], 0, len(ml[1]) - 1, 0, &tabstop) + call s:Log('Comment line after another comment line -> ' . + \'use same indent: ' . new_col) + return new_col + endif + endif + endif + let ml = matchlist(currline, \'^\(\s*\)\(\%(end\|of\|catch\|after\)\>\|[)\]}]\|>>\)') @@ -1381,6 +1456,24 @@ function! ErlangIndent() endfunction +" ErlangShowTokensInLine functions {{{1 +" ================================ + +" These functions are useful during development. + +function! ErlangShowTokensInLine(line) + echo "Line: " . a:line + let indtokens = s:GetTokensFromLine(a:line, 0, 0, &tabstop) + echo "Tokens:" + for it in indtokens + echo it + endfor +endfunction + +function! ErlangShowTokensInCurrentLine() + return ErlangShowTokensInLine(getline('.')) +endfunction + " Cleanup {{{1 " ======= diff --git a/runtime/indent/fortran.vim b/runtime/indent/fortran.vim index 2ba69e86df..26ed33a54d 100644 --- a/runtime/indent/fortran.vim +++ b/runtime/indent/fortran.vim @@ -1,12 +1,13 @@ " Vim indent file " Language: Fortran 2008 (and older: Fortran 2003, 95, 90, and 77) -" Version: 47 -" Last Change: 2016 Oct. 29 +" Version: (v48) 2020 October 07 " 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, in chronological order, by: -" Albert Oliver Serra, Takuya Fujiwara and Philipp Edelmann. +" Version 0.1 was created in September 2000 by Ajit Thakkar. +" Since then, useful suggestions and contributions have been made, in order, by: +" Albert Oliver Serra, Takuya Fujiwara, Philipp Edelmann, Eisuke Kawashima, +" and Louis Cochen. " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -39,10 +40,10 @@ if !exists("b:fortran_fixed_source") elseif exists("fortran_fixed_source") " User guarantees fixed source form let b:fortran_fixed_source = 1 - elseif expand("%:e") ==? "f\<90\|95\|03\|08\>" + elseif expand("%:e") =~? '^f\%(90\|95\|03\|08\)$' " Free-form file extension defaults as in Intel ifort, gcc(gfortran), NAG, Pathscale, and Cray compilers let b:fortran_fixed_source = 0 - elseif expand("%:e") ==? "f\|f77\|for" + elseif expand("%:e") =~? '^\%(f\|f77\|for\)$' " Fixed-form file extension defaults let b:fortran_fixed_source = 1 else @@ -73,11 +74,15 @@ endif if (b:fortran_fixed_source == 1) setlocal indentexpr=FortranGetFixedIndent() if exists("*FortranGetFixedIndent") + let &cpoptions = s:cposet + unlet s:cposet finish endif else setlocal indentexpr=FortranGetFreeIndent() if exists("*FortranGetFreeIndent") + let &cpoptions = s:cposet + unlet s:cposet finish endif endif @@ -145,7 +150,7 @@ function FortranGetIndent(lnum) \. 'type\|forall\|associate\|enum\|block\)\)\>' let ind = ind - shiftwidth() " Fix indent for case statement immediately after select - if prevstat =~? '\<select\s\+\(case\|type\)\>' + if prevstat =~? '\<select\s*\(case\|type\)\>' let ind = ind + shiftwidth() endif endif @@ -212,7 +217,7 @@ function FortranGetFixedIndent() return ind endfunction -let &cpoptions=s:cposet +let &cpoptions = s:cposet unlet s:cposet " vim:sw=2 tw=130 diff --git a/runtime/indent/haml.vim b/runtime/indent/haml.vim index e6416e6f53..baca1d49d9 100644 --- a/runtime/indent/haml.vim +++ b/runtime/indent/haml.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Haml " Maintainer: Tim Pope <vimNOSPAM@tpope.org> -" Last Change: 2017 Jun 13 +" Last Change: 2019 Dec 05 if exists("b:did_indent") finish @@ -10,7 +10,7 @@ runtime! indent/ruby.vim unlet! b:did_indent let b:did_indent = 1 -setlocal autoindent sw=2 et +setlocal autoindent setlocal indentexpr=GetHamlIndent() setlocal indentkeys=o,O,*<Return>,},],0),!^F,=end,=else,=elsif,=rescue,=ensure,=when diff --git a/runtime/indent/html.vim b/runtime/indent/html.vim index 1d2043ae9e..7019bd4a82 100644 --- a/runtime/indent/html.vim +++ b/runtime/indent/html.vim @@ -1,9 +1,8 @@ " Vim indent script for HTML -" Header: "{{{ " Maintainer: Bram Moolenaar " Original Author: Andy Wokula <anwoku@yahoo.de> -" Last Change: 2019 Mar 20 -" Version: 1.0 +" Last Change: 2021 Jan 26 +" Version: 1.0 "{{{ " Description: HTML indent script with cached state for faster indenting on a " range of lines. " Supports template systems through hooks. @@ -223,7 +222,7 @@ endfunc "}}} call s:AddITags(s:indent_tags, [ \ 'a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', \ 'blockquote', 'body', 'button', 'caption', 'center', 'cite', 'code', - \ 'colgroup', 'del', 'dfn', 'dir', 'div', 'dl', 'em', 'fieldset', 'font', + \ 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', \ 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', \ 'i', 'iframe', 'ins', 'kbd', 'label', 'legend', 'li', \ 'map', 'menu', 'noframes', 'noscript', 'object', 'ol', @@ -587,7 +586,7 @@ func! s:Alien3() return eval(b:hi_js1indent) endif if b:hi_indent.scripttype == "javascript" - return GetJavascriptIndent() + return eval(b:hi_js1indent) + GetJavascriptIndent() else return -1 endif @@ -816,7 +815,7 @@ func! s:Alien5() let idx = match(prevtext, '^\s*\zs<!--') if idx >= 0 " just below comment start, add a shiftwidth - return idx + shiftwidth() + return indent(prevlnum) + shiftwidth() endif " Some files add 4 spaces just below a TODO line. It's difficult to detect @@ -942,11 +941,11 @@ func! s:InsideTag(foundHtmlString) let idx = match(text, '<' . s:tagname . '\s\+\zs\w') endif if idx == -1 - " after just "<tag" indent one level more + " after just "<tag" indent two levels more let idx = match(text, '<' . s:tagname . '$') if idx >= 0 - call cursor(lnum, idx) - return virtcol('.') + shiftwidth() + call cursor(lnum, idx + 1) + return virtcol('.') - 1 + shiftwidth() * 2 endif endif if idx > 0 diff --git a/runtime/indent/j.vim b/runtime/indent/j.vim index ea3d50936b..c308512ecc 100644 --- a/runtime/indent/j.vim +++ b/runtime/indent/j.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: J -" Maintainer: David BĂĽrgin <676c7473@gmail.com> -" URL: https://github.com/glts/vim-j +" Maintainer: David BĂĽrgin <dbuergin@gluet.ch> +" URL: https://gitlab.com/glts/vim-j " Last Change: 2015-01-11 if exists('b:did_indent') diff --git a/runtime/indent/json.vim b/runtime/indent/json.vim index b66a03d81b..c649e37013 100644 --- a/runtime/indent/json.vim +++ b/runtime/indent/json.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: JSON " Mantainer: Eli Parra <eli@elzr.com> https://github.com/elzr/vim-json -" Last Change: 2017 Jun 13 +" Last Change: 2020 Aug 30 " https://github.com/jakar/vim-json/commit/20b650e22aa750c4ab6a66aa646bdd95d7cd548a#diff-e81fc111b2052e306d126bd9989f7b7c " Original Author: Rogerz Zhang <rogerz.zhang at gmail.com> http://github.com/rogerz/vim-json " Acknowledgement: Based off of vim-javascript maintained by Darrick Wiebe @@ -19,7 +19,7 @@ let b:did_indent = 1 setlocal nosmartindent " Now, set up our indentation expression and keys that trigger it. -setlocal indentexpr=GetJSONIndent() +setlocal indentexpr=GetJSONIndent(v:lnum) setlocal indentkeys=0{,0},0),0[,0],!^F,o,O,e " Only define the function once. @@ -86,26 +86,28 @@ endfunction " 3. GetJSONIndent Function {{{1 " ========================= -function GetJSONIndent() +function GetJSONIndent(...) " 3.1. Setup {{{2 " ---------- + " For the current line, use the first argument if given, else v:lnum + let clnum = a:0 ? a:1 : v:lnum - " Set up variables for restoring position in file. Could use v:lnum here. + " Set up variables for restoring position in file. Could use clnum here. let vcol = col('.') " 3.2. Work on the current line {{{2 " ----------------------------- " Get the current line. - let line = getline(v:lnum) + let line = getline(clnum) let ind = -1 " If we got a closing bracket on an empty line, find its match and indent " according to it. let col = matchend(line, '^\s*[]}]') - if col > 0 && !s:IsInString(v:lnum, col) - call cursor(v:lnum, col) + if col > 0 && !s:IsInString(clnum, col) + call cursor(clnum, col) let bs = strpart('{}[]', stridx('}]', line[col - 1]) * 2, 2) let pairstart = escape(bs[0], '[') @@ -122,14 +124,14 @@ function GetJSONIndent() endif " If we are in a multi-line string, don't do anything to it. - if s:IsInString(v:lnum, matchend(line, '^\s*') + 1) + if s:IsInString(clnum, matchend(line, '^\s*') + 1) return indent('.') endif " 3.3. Work on the previous line. {{{2 " ------------------------------- - let lnum = prevnonblank(v:lnum - 1) + let lnum = prevnonblank(clnum - 1) if lnum == 0 return 0 @@ -151,7 +153,7 @@ function GetJSONIndent() if counts[0] == '1' || counts[1] == '1' || counts[2] == '1' return ind + shiftwidth() else - call cursor(v:lnum, vcol) + call cursor(clnum, vcol) end endif diff --git a/runtime/indent/make.vim b/runtime/indent/make.vim index 66a8a40173..4483efdbd8 100644 --- a/runtime/indent/make.vim +++ b/runtime/indent/make.vim @@ -20,8 +20,8 @@ let s:comment_rx = '^\s*#' let s:rule_rx = '^[^ \t#:][^#:]*:\{1,2}\%([^=:]\|$\)' let s:continued_rule_rx = '^[^#:]*:\{1,2}\%([^=:]\|$\)' let s:continuation_rx = '\\$' -let s:assignment_rx = '^\s*\h\w*\s*[+?]\==\s*\zs.*\\$' -let s:folded_assignment_rx = '^\s*\h\w*\s*[+?]\==' +let s:assignment_rx = '^\s*\h\w*\s*[+:?]\==\s*\zs.*\\$' +let s:folded_assignment_rx = '^\s*\h\w*\s*[+:?]\==' " TODO: This needs to be a lot more restrictive in what it matches. let s:just_inserted_rule_rx = '^\s*[^#:]\+:\{1,2}$' let s:conditional_directive_rx = '^ *\%(ifn\=\%(eq\|def\)\|else\)\>' diff --git a/runtime/indent/matlab.vim b/runtime/indent/matlab.vim index d2818a18ea..6390445c60 100644 --- a/runtime/indent/matlab.vim +++ b/runtime/indent/matlab.vim @@ -29,7 +29,7 @@ if exists("*GetMatlabIndent") | finish | endif let s:keepcpo = &cpo set cpo&vim -let s:end = '\<end\>\%([^(]*)\)\@!' " Array indexing heuristic +let s:end = '\<end\>\%([^({]*[)}]\)\@!' " Array indexing heuristic let s:open_pat = 'for\|if\|parfor\|spmd\|switch\|try\|while\|classdef\|properties\|methods\|events\|enumeration' let s:dedent_pat = '\C^\s*\zs\<\%(end\|else\|elseif\|catch\|\(case\|otherwise\|function\)\)\>' let s:start_pat = '\C\<\%(function\|' . s:open_pat . '\)\>' @@ -38,7 +38,7 @@ let s:zflag = has('patch-7.4.984') ? 'z' : '' " Returns whether a comment or string envelops the specified column. function! s:IsCommentOrString(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), "name") =~# 'matlabComment\|matlabMultilineComment\|matlabString' + return synIDattr(synID(a:lnum, a:col, 1), "name") =~# 'matlabComment\|matlabMultilineComment\|matlabCellComment\|matlabString' endfunction " Returns whether the specified line continues on the next line. @@ -105,7 +105,7 @@ function! GetMatlabIndent() else " Count how many blocks the previous line opens/closes " Line continuations/brackets indent once per statement - let result = indent(prevlnum) + shiftwidth() * (open - close + let result = (prevlnum > 0) * indent(prevlnum) + shiftwidth() * (open - close \ + (b:MATLAB_bracketlevel ? -!curbracketlevel : !!curbracketlevel) \ + (curbracketlevel <= 0) * (above_lc - b:MATLAB_waslc)) endif diff --git a/runtime/indent/meson.vim b/runtime/indent/meson.vim new file mode 100644 index 0000000000..f116781f74 --- /dev/null +++ b/runtime/indent/meson.vim @@ -0,0 +1,180 @@ +" Vim indent file +" Language: Meson +" License: VIM License +" Maintainer: Nirbheek Chauhan <nirbheek.chauhan@gmail.com> +" Original Authors: David Bustos <bustos@caltech.edu> +" Bram Moolenaar <Bram@vim.org> +" Last Change: 2019 Oct 18 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" Some preliminary settings +setlocal nolisp " Make sure lisp indenting doesn't supersede us +setlocal autoindent " indentexpr isn't much help otherwise + +setlocal indentexpr=GetMesonIndent(v:lnum) +setlocal indentkeys+==elif,=else,=endforeach,=endif,0) + +" Only define the function once. +if exists("*GetMesonIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +" Come here when loading the script the first time. + +let s:maxoff = 50 " maximum number of lines to look backwards for () + +function GetMesonIndent(lnum) + echom getline(line(".")) + + " If this line is explicitly joined: If the previous line was also joined, + " line it up with that one, otherwise add two 'shiftwidth' + if getline(a:lnum - 1) =~ '\\$' + if a:lnum > 1 && getline(a:lnum - 2) =~ '\\$' + return indent(a:lnum - 1) + endif + return indent(a:lnum - 1) + (exists("g:mesonindent_continue") ? eval(g:mesonindent_continue) : (shiftwidth() * 2)) + endif + + " If the start of the line is in a string don't change the indent. + if has('syntax_items') + \ && synIDattr(synID(a:lnum, 1, 1), "name") =~ "String$" + return -1 + endif + + " Search backwards for the previous non-empty line. + let plnum = prevnonblank(v:lnum - 1) + + if plnum == 0 + " This is the first non-empty line, use zero indent. + return 0 + endif + + " If the previous line is inside parenthesis, use the indent of the starting + " line. + " Trick: use the non-existing "dummy" variable to break out of the loop when + " going too far back. + call cursor(plnum, 1) + let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW', + \ "line('.') < " . (plnum - s:maxoff) . " ? dummy :" + \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" + \ . " =~ '\\(Comment\\|Todo\\|String\\)$'") + if parlnum > 0 + let plindent = indent(parlnum) + let plnumstart = parlnum + else + let plindent = indent(plnum) + let plnumstart = plnum + endif + + + " When inside parenthesis: If at the first line below the parenthesis add + " a 'shiftwidth', otherwise same as previous line. + " i = (a + " + b + " + c) + call cursor(a:lnum, 1) + let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW', + \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :" + \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" + \ . " =~ '\\(Comment\\|Todo\\|String\\)$'") + if p > 0 + if p == plnum + " When the start is inside parenthesis, only indent one 'shiftwidth'. + let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW', + \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :" + \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" + \ . " =~ '\\(Comment\\|Todo\\|String\\)$'") + if pp > 0 + return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth()) + endif + return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : shiftwidth()) + endif + if plnumstart == p + return indent(plnum) + endif + return plindent + endif + + + " Get the line and remove a trailing comment. + " Use syntax highlighting attributes when possible. + let pline = getline(plnum) + let pline_len = strlen(pline) + 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(plnum, pline_len, 1), "name") =~ "\\(Comment\\|Todo\\)$" + let min = 1 + let max = pline_len + while min < max + let col = (min + max) / 2 + if synIDattr(synID(plnum, col, 1), "name") =~ "\\(Comment\\|Todo\\)$" + let max = col + else + let min = col + 1 + endif + endwhile + let pline = strpart(pline, 0, min - 1) + endif + else + let col = 0 + while col < pline_len + if pline[col] == '#' + let pline = strpart(pline, 0, col) + break + endif + let col = col + 1 + endwhile + endif + + " If the previous line ended the conditional/loop + if getline(plnum) =~ '^\s*\(endif\|endforeach\)\>\s*' + " Maintain indent + return -1 + endif + + " If the previous line ended with a builtin, indent this line + if pline =~ '^\s*\(foreach\|if\|else\|elif\)\>\s*' + return plindent + shiftwidth() + endif + + " If the current line begins with a header keyword, deindent + if getline(a:lnum) =~ '^\s*\(else\|elif\|endif\|endforeach\)' + + " Unless the previous line was a one-liner + if getline(plnumstart) =~ '^\s*\(foreach\|if\)\>\s*' + return plindent + endif + + " Or the user has already dedented + if indent(a:lnum) <= plindent - shiftwidth() + return -1 + endif + + return plindent - shiftwidth() + endif + + " When after a () construct we probably want to go back to the start line. + " a = (b + " + c) + " here + if parlnum > 0 + return plindent + endif + + return -1 + +endfunction + +let &cpo = s:keepcpo +unlet s:keepcpo + +" vim:sw=2 diff --git a/runtime/indent/ocaml.vim b/runtime/indent/ocaml.vim index 8fe9de3d61..19c81f49c4 100644 --- a/runtime/indent/ocaml.vim +++ b/runtime/indent/ocaml.vim @@ -3,7 +3,7 @@ " Maintainers: Jean-Francois Yuen <jfyuen@happycoders.org> " Mike Leary <leary@nwlink.com> " Markus Mottl <markus.mottl@gmail.com> -" URL: http://www.ocaml.info/vim/indent/ocaml.vim +" URL: https://github.com/ocaml/vim-ocaml " Last Change: 2017 Jun 13 " 2005 Jun 25 - Fixed multiple bugs due to 'else\nreturn ind' working " 2005 May 09 - Added an option to not indent OCaml-indents specially (MM) @@ -30,7 +30,8 @@ setlocal nosmartindent " Comment formatting if !exists("no_ocaml_comments") if (has("comments")) - setlocal comments=sr:(*,mb:*,ex:*) + setlocal comments=sr:(*\ ,mb:\ ,ex:*) + setlocal comments^=sr:(**,mb:\ \ ,ex:*) setlocal fo=cqort endif endif diff --git a/runtime/indent/perl.vim b/runtime/indent/perl.vim index 094d1d37ea..5fc8b7008a 100644 --- a/runtime/indent/perl.vim +++ b/runtime/indent/perl.vim @@ -1,9 +1,9 @@ " Vim indent file " Language: Perl 5 " Maintainer: vim-perl <vim-perl@googlegroups.com> -" Homepage: http://github.com/vim-perl/vim-perl -" Bugs/requests: http://github.com/vim-perl/vim-perl/issues -" Last Change: 2017-01-04 +" Homepage: https://github.com/vim-perl/vim-perl +" Bugs/requests: https://github.com/vim-perl/vim-perl/issues +" Last Change: 2020 Apr 15 " Suggestions and improvements by : " Aaron J. Sherman (use syntax for hints) diff --git a/runtime/indent/php.vim b/runtime/indent/php.vim index 67a1327dc9..0e623689d5 100644 --- a/runtime/indent/php.vim +++ b/runtime/indent/php.vim @@ -3,7 +3,7 @@ " Author: John Wellesz <John.wellesz (AT) gmail (DOT) com> " URL: https://www.2072productions.com/vim/indent/php.vim " Home: https://github.com/2072/PHP-Indenting-for-VIm -" Last Change: 2019 Jully 21st +" Last Change: 2020 Mar 05 " Version: 1.70 " " diff --git a/runtime/indent/ps1.vim b/runtime/indent/ps1.vim new file mode 100644 index 0000000000..0f794db83b --- /dev/null +++ b/runtime/indent/ps1.vim @@ -0,0 +1,17 @@ +" Vim indent file +" Language: Windows PowerShell +" URL: https://github.com/PProvost/vim-ps1 +" Last Change: 2017 Oct 19 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" smartindent is good enough for powershell +setlocal smartindent +" disable the indent removal for # marks +inoremap <buffer> # X# + +let b:undo_indent = "setl si<" diff --git a/runtime/indent/python.vim b/runtime/indent/python.vim index e53987a0de..f9236e63c7 100644 --- a/runtime/indent/python.vim +++ b/runtime/indent/python.vim @@ -28,6 +28,11 @@ set cpo&vim let s:maxoff = 50 " maximum number of lines to look backwards for () +" See if the specified line is already user-dedented from the expected value. +function s:Dedented(lnum, expected) + return indent(a:lnum) <= a:expected - shiftwidth() +endfunction + function GetPythonIndent(lnum) " If this line is explicitly joined: If the previous line was also joined, @@ -158,12 +163,12 @@ function GetPythonIndent(lnum) " If the previous line was a stop-execution statement... if getline(plnum) =~ '^\s*\(break\|continue\|raise\|return\|pass\)\>' " See if the user has already dedented - if indent(a:lnum) > indent(plnum) - shiftwidth() - " If not, recommend one dedent - return indent(plnum) - shiftwidth() + if s:Dedented(a:lnum, indent(plnum)) + " If so, trust the user + return -1 endif - " Otherwise, trust the user - return -1 + " If not, recommend one dedent + return indent(plnum) - shiftwidth() endif " If the current line begins with a keyword that lines up with "try" @@ -191,7 +196,7 @@ function GetPythonIndent(lnum) endif " Or the user has already dedented - if indent(a:lnum) <= plindent - shiftwidth() + if s:Dedented(a:lnum, plindent) return -1 endif @@ -203,7 +208,12 @@ function GetPythonIndent(lnum) " + c) " here if parlnum > 0 - return plindent + " ...unless the user has already dedented + if s:Dedented(a:lnum, plindent) + return -1 + else + return plindent + endif endif return -1 diff --git a/runtime/indent/perl6.vim b/runtime/indent/raku.vim index 8561c8c58c..3f9b49ec77 100644 --- a/runtime/indent/perl6.vim +++ b/runtime/indent/raku.vim @@ -1,9 +1,9 @@ " Vim indent file " Language: Perl 6 " Maintainer: vim-perl <vim-perl@googlegroups.com> -" Homepage: http://github.com/vim-perl/vim-perl -" Bugs/requests: http://github.com/vim-perl/vim-perl/issues -" Last Change: 2017 Jun 13 +" Homepage: https://github.com/vim-perl/vim-perl +" Bugs/requests: https://github.com/vim-perl/vim-perl/issues +" Last Change: 2020 Apr 15 " Contributors: Andy Lester <andy@petdance.com> " Hinrik Ă–rn Sigurðsson <hinrik.sig@gmail.com> " @@ -36,7 +36,7 @@ let b:did_indent = 1 " Is syntax highlighting active ? let b:indent_use_syntax = has("syntax") -setlocal indentexpr=GetPerl6Indent() +setlocal indentexpr=GetRakuIndent() " we reset it first because the Perl 5 indent file might have been loaded due " to a .pl/pm file extension, and indent files don't clean up afterwards @@ -50,7 +50,7 @@ endif let s:cpo_save = &cpo set cpo-=C -function! GetPerl6Indent() +function! GetRakuIndent() " Get the line to be indented let cline = getline(v:lnum) @@ -60,11 +60,6 @@ function! GetPerl6Indent() return 0 endif - " Don't reindent coments on first column - if cline =~ '^#' - return 0 - endif - " Get current syntax item at the line's first char let csynid = '' if b:indent_use_syntax @@ -72,7 +67,7 @@ function! GetPerl6Indent() endif " Don't reindent POD and heredocs - if csynid =~ "^p6Pod" + if csynid =~ "^rakuPod" return indent(v:lnum) endif @@ -92,7 +87,7 @@ function! GetPerl6Indent() let skippin = 2 while skippin let synid = synIDattr(synID(lnum,1,0),"name") - if (synid =~ "^p6Pod" || synid =~ "p6Comment") + if (synid =~ "^rakuPod" || synid =~ "rakuComment") let lnum = prevnonblank(lnum - 1) if lnum == 0 return 0 @@ -107,19 +102,19 @@ function! GetPerl6Indent() endif if line =~ '[<«\[{(]\s*\(#[^)}\]»>]*\)\=$' - let ind = ind + shiftwidth() + let ind = ind + &sw endif if cline =~ '^\s*[)}\]»>]' - let ind = ind - shiftwidth() + let ind = ind - &sw endif " Indent lines that begin with 'or' or 'and' if cline =~ '^\s*\(or\|and\)\>' if line !~ '^\s*\(or\|and\)\>' - let ind = ind + shiftwidth() + let ind = ind + &sw endif elseif line =~ '^\s*\(or\|and\)\>' - let ind = ind - shiftwidth() + let ind = ind - &sw endif return ind diff --git a/runtime/indent/rmd.vim b/runtime/indent/rmd.vim index 83fe4e4fed..8fd57257fa 100644 --- a/runtime/indent/rmd.vim +++ b/runtime/indent/rmd.vim @@ -2,7 +2,7 @@ " Language: Rmd " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> " Homepage: https://github.com/jalvesaq/R-Vim-runtime -" Last Change: Sun Aug 19, 2018 09:14PM +" Last Change: Sun Mar 28, 2021 08:05PM " Only load this indent file when no other was loaded. @@ -13,7 +13,7 @@ runtime indent/r.vim let s:RIndent = function(substitute(&indentexpr, "()", "", "")) let b:did_indent = 1 -setlocal indentkeys=0{,0},:,!^F,o,O,e +setlocal indentkeys=0{,0},<:>,!^F,o,O,e setlocal indentexpr=GetRmdIndent() if exists("*GetRmdIndent") @@ -23,6 +23,21 @@ endif let s:cpo_save = &cpo set cpo&vim +" Simple Python indentation algorithm +function s:GetPyIndent() + let plnum = prevnonblank(v:lnum - 1) + let pline = getline(plnum) + let cline = getline(v:lnum) + if pline =~ '^s```\s*{\s*python ' + return 0 + elseif pline =~ ':$' + return indent(plnum) + &shiftwidth + elseif cline =~ 'else:$' + return indent(plnum) - &shiftwidth + endif + return indent(plnum) +endfunction + function s:GetMdIndent() let pline = getline(v:lnum - 1) let cline = getline(v:lnum) @@ -37,13 +52,14 @@ function s:GetMdIndent() endfunction function s:GetYamlIndent() - let pline = getline(v:lnum - 1) + let plnum = prevnonblank(v:lnum - 1) + let pline = getline(plnum) if pline =~ ':\s*$' - return indent(v:lnum) + shiftwidth() + return indent(plnum) + shiftwidth() elseif pline =~ '^\s*- ' return indent(v:lnum) + 2 endif - return indent(prevnonblank(v:lnum - 1)) + return indent(plnum) endfunction function GetRmdIndent() @@ -52,9 +68,11 @@ function GetRmdIndent() endif if search('^[ \t]*```{r', "bncW") > search('^[ \t]*```$', "bncW") return s:RIndent() - elseif v:lnum > 1 && search('^---$', "bnW") == 1 && - \ (search('^---$', "nW") > v:lnum || search('^...$', "nW") > v:lnum) + elseif v:lnum > 1 && (search('^---$', "bnW") == 1 && + \ (search('^---$', "nW") > v:lnum || search('^\.\.\.$', "nW") > v:lnum)) return s:GetYamlIndent() + elseif search('^[ \t]*```{python', "bncW") > search('^[ \t]*```$', "bncW") + return s:GetPyIndent() else return s:GetMdIndent() endif diff --git a/runtime/indent/rpl.vim b/runtime/indent/rpl.vim index fab258ed2b..8577c4d274 100644 --- a/runtime/indent/rpl.vim +++ b/runtime/indent/rpl.vim @@ -2,7 +2,7 @@ " Language: RPL/2 " Version: 0.2 " Last Change: 2017 Jun 13 -" Maintainer: BERTRAND Joël <rpl2@free.fr> +" Maintainer: BERTRAND JoĂ«l <rpl2@free.fr> " Only load this indent file when no other was loaded. if exists("b:did_indent") diff --git a/runtime/indent/rst.vim b/runtime/indent/rst.vim index c1ef8c9957..a31ad8e080 100644 --- a/runtime/indent/rst.vim +++ b/runtime/indent/rst.vim @@ -1,7 +1,9 @@ " Vim indent file -" Language: reStructuredText Documentation Format -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2011-08-03 +" Vim reST indent file +" Language: reStructuredText Documentation Format +" Maintainer: Marshall Ward <marshall.ward@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Latest Revision: 2020-03-31 if exists("b:did_indent") finish @@ -18,6 +20,12 @@ endif let s:itemization_pattern = '^\s*[-*+]\s' let s:enumeration_pattern = '^\s*\%(\d\+\|#\)\.\s\+' +let s:note_pattern = '^\.\. ' + +function! s:get_paragraph_start() + let paragraph_mark_start = getpos("'{")[1] + return getline(paragraph_mark_start) =~ '\S' ? paragraph_mark_start : paragraph_mark_start + 1 +endfunction function GetRSTIndent() let lnum = prevnonblank(v:lnum - 1) @@ -28,6 +36,13 @@ function GetRSTIndent() let ind = indent(lnum) let line = getline(lnum) + let psnum = s:get_paragraph_start() + if psnum != 0 + if getline(psnum) =~ s:note_pattern + let ind = 3 + endif + endif + if line =~ s:itemization_pattern let ind += 2 elseif line =~ s:enumeration_pattern diff --git a/runtime/indent/ruby.vim b/runtime/indent/ruby.vim index 5c420d7543..657aa763b1 100644 --- a/runtime/indent/ruby.vim +++ b/runtime/indent/ruby.vim @@ -4,7 +4,6 @@ " Previous Maintainer: Nikolai Weibull <now at bitwi.se> " URL: https://github.com/vim-ruby/vim-ruby " Release Coordinator: Doug Kearns <dougkearns@gmail.com> -" Last Change: 2019 Jan 06 " 0. Initialization {{{1 " ================= @@ -27,7 +26,12 @@ endif if !exists('g:ruby_indent_block_style') " Possible values: "expression", "do" - let g:ruby_indent_block_style = 'expression' + let g:ruby_indent_block_style = 'do' +endif + +if !exists('g:ruby_indent_hanging_elements') + " Non-zero means hanging indents are enabled, zero means disabled + let g:ruby_indent_hanging_elements = 1 endif setlocal nosmartindent @@ -51,15 +55,27 @@ set cpo&vim " Syntax group names that are strings. let s:syng_string = - \ ['String', 'Interpolation', 'InterpolationDelimiter', 'NoInterpolation', 'StringEscape'] + \ ['String', 'Interpolation', 'InterpolationDelimiter', 'StringEscape'] " Syntax group names that are strings or documentation. let s:syng_stringdoc = s:syng_string + ['Documentation'] " Syntax group names that are or delimit strings/symbols/regexes or are comments. -let s:syng_strcom = s:syng_stringdoc + - \ ['Regexp', 'RegexpDelimiter', 'RegexpEscape', - \ 'Symbol', 'StringDelimiter', 'ASCIICode', 'Comment'] +let s:syng_strcom = s:syng_stringdoc + [ + \ 'Character', + \ 'Comment', + \ 'HeredocDelimiter', + \ 'PercentRegexpDelimiter', + \ 'PercentStringDelimiter', + \ 'PercentSymbolDelimiter', + \ 'Regexp', + \ 'RegexpCharClass', + \ 'RegexpDelimiter', + \ 'RegexpEscape', + \ 'StringDelimiter', + \ 'Symbol', + \ 'SymbolDelimiter', + \ ] " Expression used to check whether we should skip a match with searchpair(). let s:skip_expr = @@ -69,7 +85,7 @@ let s:skip_expr = let s:ruby_indent_keywords = \ '^\s*\zs\<\%(module\|class\|if\|for' . \ '\|while\|until\|else\|elsif\|case\|when\|unless\|begin\|ensure\|rescue' . - \ '\|\%(\K\k*[!?]\?\)\=\s*def\):\@!\>' . + \ '\|\%(\K\k*[!?]\?\s\+\)\=def\):\@!\>' . \ '\|\%([=,*/%+-]\|<<\|>>\|:\s\)\s*\zs' . \ '\<\%(if\|for\|while\|until\|case\|unless\|begin\):\@!\>' @@ -83,7 +99,7 @@ let s:ruby_deindent_keywords = let s:end_start_regex = \ '\C\%(^\s*\|[=,*/%+\-|;{]\|<<\|>>\|:\s\)\s*\zs' . \ '\<\%(module\|class\|if\|for\|while\|until\|case\|unless\|begin' . - \ '\|\%(\K\k*[!?]\?\)\=\s*def\):\@!\>' . + \ '\|\%(\K\k*[!?]\?\s\+\)\=def\):\@!\>' . \ '\|\%(^\|[^.:@$]\)\@<=\<do:\@!\>' " Regex that defines the middle-match for the 'end' keyword. @@ -146,7 +162,7 @@ let s:block_regex = let s:block_continuation_regex = '^\s*[^])}\t ].*'.s:block_regex " Regex that describes a leading operator (only a method call's dot for now) -let s:leading_operator_regex = '^\s*[.]' +let s:leading_operator_regex = '^\s*\%(&\=\.\)' " 2. GetRubyIndent Function {{{1 " ========================= @@ -310,7 +326,11 @@ function! s:ClosingBracketOnEmptyLine(cline_info) abort if searchpair(escape(bracket_pair[0], '\['), '', bracket_pair[1], 'bW', s:skip_expr) > 0 if closing_bracket == ')' && col('.') != col('$') - 1 - let ind = virtcol('.') - 1 + if g:ruby_indent_hanging_elements + let ind = virtcol('.') - 1 + else + let ind = indent(line('.')) + end elseif g:ruby_indent_block_style == 'do' let ind = indent(line('.')) else " g:ruby_indent_block_style == 'expression' @@ -535,7 +555,9 @@ function! s:AfterUnbalancedBracket(pline_info) abort let [opening, closing] = s:ExtraBrackets(info.plnum) if opening.pos != -1 - if opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 + if !g:ruby_indent_hanging_elements + return indent(info.plnum) + info.sw + elseif opening.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 if col('.') + 1 == col('$') return indent(info.plnum) + info.sw else @@ -620,8 +642,7 @@ function! s:PreviousNotMSL(msl_info) abort " TODO (2016-10-07) Wrong/unused? How could it be "1"? return indent(info.plnum) - 1 " If previous line is a continuation return its indent. - " TODO: the || s:IsInString() thing worries me a bit. - elseif s:Match(info.plnum, s:non_bracket_continuation_regex) || s:IsInString(info.plnum, strlen(line)) + elseif s:Match(info.plnum, s:non_bracket_continuation_regex) return indent(info.plnum) endif endif @@ -695,7 +716,10 @@ endfunction " Check if the character at lnum:col is inside a string delimiter function! s:IsInStringDelimiter(lnum, col) abort - return s:IsInRubyGroup(['StringDelimiter'], a:lnum, a:col) + return s:IsInRubyGroup( + \ ['HeredocDelimiter', 'PercentStringDelimiter', 'StringDelimiter'], + \ a:lnum, a:col + \ ) endfunction function! s:IsAssignment(str, pos) abort diff --git a/runtime/indent/sh.vim b/runtime/indent/sh.vim index 3df6abbf97..d2fb1ba452 100644 --- a/runtime/indent/sh.vim +++ b/runtime/indent/sh.vim @@ -3,7 +3,7 @@ " Maintainer: Christian Brabandt <cb@256bit.org> " Original Author: Nikolai Weibull <now@bitwi.se> " Previous Maintainer: Peter Aronoff <telemachus@arpinum.org> -" Latest Revision: 2019-07-26 +" Latest Revision: 2019-10-24 " License: Vim (see :h license) " Repository: https://github.com/chrisbra/vim-sh-indent " Changelog: @@ -134,7 +134,7 @@ function! GetShIndent() " TODO: should we do the same for other "end" lines? if curline =~ '^\s*\%(fi\);\?\s*\%(#.*\)\=$' let ind = indent(v:lnum) - let previous_line = searchpair('\<if\>', '', '\<fi\>\zs', 'bnW', 'synIDattr(synID(line("."),col("."), 1),"name") =~? "comment"') + let previous_line = searchpair('\<if\>', '', '\<fi\>\zs', 'bnW', 'synIDattr(synID(line("."),col("."), 1),"name") =~? "comment\\|quote"') if previous_line > 0 let ind = indent(previous_line) endif @@ -195,7 +195,7 @@ endfunction function! s:is_function_definition(line) return a:line =~ '^\s*\<\k\+\>\s*()\s*{' || \ a:line =~ '^\s*{' || - \ a:line =~ '^\s*function\s*\w\S\+\s*\%(()\)\?\s*{' + \ a:line =~ '^\s*function\s*\k\+\s*\%(()\)\?\s*{' endfunction function! s:is_array(line) diff --git a/runtime/indent/sqlanywhere.vim b/runtime/indent/sqlanywhere.vim index ba35d76715..601c567adc 100644 --- a/runtime/indent/sqlanywhere.vim +++ b/runtime/indent/sqlanywhere.vim @@ -1,7 +1,8 @@ " Vim indent file " Language: SQL " Maintainer: David Fishburn <dfishburn dot vim at gmail dot com> -" Last Change: 2017 Jun 13 +" Last Change By Maintainer: 2017 Jun 13 +" Last Change: by Stephen Wall, #5578, 2020 Jun 07 " Version: 3.0 " Download: http://vim.sourceforge.net/script.php?script_id=495 @@ -67,68 +68,73 @@ set cpo&vim " IS is excluded, since it is difficult to determine when the " ending block is (especially for procedures/functions). let s:SQLBlockStart = '^\s*\%('. - \ 'if\|else\|elseif\|elsif\|'. - \ 'while\|loop\|do\|for\|'. - \ 'begin\|'. + \ 'if\>.*\<then\|'. + \ 'then\|else\>\|'. + \ 'elseif\>.*\<then\|'. + \ 'elsif\>.(\<then\|'. + \ 'while\>.*\<loop\|'. + \ 'for\>.*\<loop\|'. + \ 'foreach\>.*\<loop\|'. + \ 'loop\|do\|declare\|begin\|'. \ 'case\|when\|merge\|exception'. \ '\)\>' let s:SQLBlockEnd = '^\s*\(end\)\>' -" The indent level is also based on unmatched paranethesis +" The indent level is also based on unmatched parentheses " If a line has an extra "(" increase the indent " If a line has an extra ")" decrease the indent -function! s:CountUnbalancedParan( line, paran_to_check ) +function! s:CountUnbalancedParen( line, paren_to_check ) let l = a:line let lp = substitute(l, '[^(]', '', 'g') let l = a:line let rp = substitute(l, '[^)]', '', 'g') - if a:paran_to_check =~ ')' - " echom 'CountUnbalancedParan ) returning: ' . + if a:paren_to_check =~ ')' + " echom 'CountUnbalancedParen ) returning: ' . " \ (strlen(rp) - strlen(lp)) return (strlen(rp) - strlen(lp)) - elseif a:paran_to_check =~ '(' - " echom 'CountUnbalancedParan ( returning: ' . + elseif a:paren_to_check =~ '(' + " echom 'CountUnbalancedParen ( returning: ' . " \ (strlen(lp) - strlen(rp)) return (strlen(lp) - strlen(rp)) else - " echom 'CountUnbalancedParan unknown paran to check: ' . - " \ a:paran_to_check + " echom 'CountUnbalancedParen unknown paren to check: ' . + " \ a:paren_to_check return 0 endif endfunction " Unindent commands based on previous indent level -function! s:CheckToIgnoreRightParan( prev_lnum, num_levels ) +function! s:CheckToIgnoreRightParen( prev_lnum, num_levels ) let lnum = a:prev_lnum let line = getline(lnum) let ends = 0 - let num_right_paran = a:num_levels - let ignore_paran = 0 + let num_right_paren = a:num_levels + let ignore_paren = 0 let vircol = 1 - while num_right_paran > 0 + while num_right_paren > 0 silent! exec 'norm! '.lnum."G\<bar>".vircol."\<bar>" - let right_paran = search( ')', 'W' ) - if right_paran != lnum + let right_paren = search( ')', 'W' ) + if right_paren != lnum " This should not happen since there should be at least - " num_right_paran matches for this line + " num_right_paren matches for this line break endif let vircol = virtcol(".") " if getline(".") =~ '^)' - let matching_paran = searchpair('(', '', ')', 'bW', + let matching_paren = searchpair('(', '', ')', 'bW', \ 's:IsColComment(line("."), col("."))') - if matching_paran < 1 + if matching_paren < 1 " No match found " echom 'CTIRP - no match found, ignoring' break endif - if matching_paran == lnum - " This was not an unmatched parantenses, start the search again + if matching_paren == lnum + " This was not an unmatched parentheses, start the search again " again after this column " echom 'CTIRP - same line match, ignoring' continue @@ -136,23 +142,23 @@ function! s:CheckToIgnoreRightParan( prev_lnum, num_levels ) " echom 'CTIRP - match: ' . line(".") . ' ' . getline(".") - if getline(matching_paran) =~? '\(if\|while\)\>' + if getline(matching_paren) =~? '\(if\|while\)\>' " echom 'CTIRP - if/while ignored: ' . line(".") . ' ' . getline(".") - let ignore_paran = ignore_paran + 1 + let ignore_paren = ignore_paren + 1 endif " One match found, decrease and check for further matches - let num_right_paran = num_right_paran - 1 + let num_right_paren = num_right_paren - 1 endwhile " Fallback - just move back one " return a:prev_indent - shiftwidth() - return ignore_paran + return ignore_paren endfunction " Based on the keyword provided, loop through previous non empty -" non comment lines to find the statement that initated the keyword. +" non comment lines to find the statement that initiated the keyword. " Return its indent level " CASE .. " WHEN ... @@ -295,26 +301,26 @@ function! GetSQLIndent() " echom 'prevl - SQLBlockStart - indent ' . ind . ' line: ' . prevline elseif prevline =~ '[()]' if prevline =~ '(' - let num_unmatched_left = s:CountUnbalancedParan( prevline, '(' ) + let num_unmatched_left = s:CountUnbalancedParen( prevline, '(' ) else let num_unmatched_left = 0 endif if prevline =~ ')' - let num_unmatched_right = s:CountUnbalancedParan( prevline, ')' ) + let num_unmatched_right = s:CountUnbalancedParen( prevline, ')' ) else let num_unmatched_right = 0 - " let num_unmatched_right = s:CountUnbalancedParan( prevline, ')' ) + " let num_unmatched_right = s:CountUnbalancedParen( prevline, ')' ) endif if num_unmatched_left > 0 - " There is a open left paranethesis + " There is a open left parenthesis " increase indent let ind = ind + ( shiftwidth() * num_unmatched_left ) elseif num_unmatched_right > 0 - " if it is an unbalanced paranethesis only unindent if + " if it is an unbalanced parenthesis only unindent if " it was part of a command (ie create table(..) ) " instead of part of an if (ie if (....) then) which should " maintain the indent level - let ignore = s:CheckToIgnoreRightParan( prevlnum, num_unmatched_right ) + let ignore = s:CheckToIgnoreRightParen( prevlnum, num_unmatched_right ) " echom 'prevl - ) unbalanced - CTIRP - ignore: ' . ignore if prevline =~ '^\s*)' @@ -357,8 +363,8 @@ function! GetSQLIndent() " elseif line =~ '^\s*)\s*;\?\s*$' " elseif line =~ '^\s*)' elseif line =~ '^\s*)' - let num_unmatched_right = s:CountUnbalancedParan( line, ')' ) - let ignore = s:CheckToIgnoreRightParan( v:lnum, num_unmatched_right ) + let num_unmatched_right = s:CountUnbalancedParen( line, ')' ) + let ignore = s:CheckToIgnoreRightParen( v:lnum, num_unmatched_right ) " If the line ends in a ), then reduce the indent " This catches items like: " CREATE TABLE T1( @@ -368,7 +374,7 @@ function! GetSQLIndent() " But we do not want to unindent a line like: " IF ( c1 = 1 " AND c2 = 3 ) THEN - " let num_unmatched_right = s:CountUnbalancedParan( line, ')' ) + " let num_unmatched_right = s:CountUnbalancedParen( line, ')' ) " if num_unmatched_right > 0 " elseif strpart( line, strlen(line)-1, 1 ) =~ ')' " let ind = ind - shiftwidth() diff --git a/runtime/indent/sshconfig.vim b/runtime/indent/sshconfig.vim new file mode 100644 index 0000000000..b456a9e3aa --- /dev/null +++ b/runtime/indent/sshconfig.vim @@ -0,0 +1,34 @@ +" Vim indent file +" Language: ssh config file +" Maintainer: JasonKim <git@jasonk.me> +" Last Change: 2020 May 16 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetSshconfigIndent(v:lnum) +setlocal indentkeys=o,O,*<Return>,0=~host\ ,0=~match\ ,0#,!^F + +let b:undo_indent = "setlocal autoindent< indentexpr< indentkeys<" + +if exists("*GetSshconfigIndent") + finish +endif + +function GetSshconfigIndent(lnum) + let sw = shiftwidth() + let prev_lnum = prevnonblank(a:lnum - 1) + let curr_lnum = a:lnum + let prev_line = getline(prev_lnum) + let curr_line = getline(curr_lnum) + if curr_line =~? '^\s*\(host\|match\)\s' + return 0 + elseif prev_line =~? '^\s*\(host\|match\)\s' + return sw + else + return indent(prev_lnum) + endif +endfunction diff --git a/runtime/indent/systemverilog.vim b/runtime/indent/systemverilog.vim index 91fba4c3b6..590fd4d998 100644 --- a/runtime/indent/systemverilog.vim +++ b/runtime/indent/systemverilog.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: SystemVerilog " Maintainer: kocha <kocha.lsifrontend@gmail.com> -" Last Change: 12-Aug-2013. +" Last Change: 05-Feb-2017 by Bilal Wasim " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -74,7 +74,7 @@ function SystemVerilogIndent() " Indent after if/else/for/case/always/initial/specify/fork blocks elseif last_line =~ '`\@<!\<\(if\|else\)\>' || - \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\|do\|foreach\|randcase\)\>' || + \ last_line =~ '^\s*\<\(for\|case\%[[zx]]\|do\|foreach\|forever\|randcase\)\>' || \ last_line =~ '^\s*\<\(always\|always_comb\|always_ff\|always_latch\)\>' || \ last_line =~ '^\s*\<\(initial\|specify\|fork\|final\)\>' if last_line !~ '\(;\|\<end\>\)\s*' . sv_comment . '*$' || @@ -129,9 +129,9 @@ function SystemVerilogIndent() " De-indent for the end of one-line block elseif ( last_line !~ '\<begin\>' || \ last_line =~ '\(//\|/\*\).*\<begin\>' ) && - \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\|do\|foreach\|final\)\>.*' . + \ last_line2 =~ '\<\(`\@<!if\|`\@<!else\|for\|always\|initial\|do\|foreach\|forever\|final\)\>.*' . \ sv_comment . '*$' && - \ last_line2 !~ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\|do\|foreach\|final\)\>' && + \ last_line2 !~ '\(//\|/\*\).*\<\(`\@<!if\|`\@<!else\|for\|always\|initial\|do\|foreach\|forever\|final\)\>' && \ last_line2 !~ sv_openstat . '\s*' . sv_comment . '*$' && \ ( last_line2 !~ '\<begin\>' || \ last_line2 =~ '\(//\|/\*\).*\<begin\>' ) @@ -194,7 +194,7 @@ function SystemVerilogIndent() \ last_line !~ '^\s*\<\(property\|checker\|program\)\>' && \ last_line !~ '^\s*\()*\s*;\|)\+\)\s*' . sv_comment . '*$' && \ ( last_line =~ - \ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\|do\|foreach\|randcase\|final\)\>' || + \ '\<\(`\@<!if\|`\@<!else\|for\|case\%[[zx]]\|always\|initial\|do\|foreach\|forever\|randcase\|final\)\>' || \ last_line =~ ')\s*' . sv_comment . '*$' || \ last_line =~ sv_openstat . '\s*' . sv_comment . '*$' ) let ind = ind - offset diff --git a/runtime/indent/testdir/html.in b/runtime/indent/testdir/html.in index 9c776d61c6..1acf8c0402 100644 --- a/runtime/indent/testdir/html.in +++ b/runtime/indent/testdir/html.in @@ -2,6 +2,16 @@ " START_INDENT +<html> + <body> +<style> +div#d1 { color: red; } +div#d2 { color: green; } +</style> + <script> + var v1 = "v1"; +var v2 = "v2"; + </script> <div> <div> text @@ -23,4 +33,34 @@ bar"> text </div> +<dl> +<dd> +dd text +</dd> +<dt> +dt text +</dt> +</dl> + + </body> +</html> + " END_INDENT + +% START_INDENT +% INDENT_EXE let g:html_indent_style1 = "inc" +% INDENT_EXE let g:html_indent_script1 = "zero" +% INDENT_EXE call HtmlIndent_CheckUserSettings() +<html> + <body> +<style> +div#d1 { color: red; } +div#d2 { color: green; } +</style> + <script> + var v1 = "v1"; +var v2 = "v2"; + </script> +</body> +</html> +% END_INDENT diff --git a/runtime/indent/testdir/html.ok b/runtime/indent/testdir/html.ok index ad819333cc..c0dfc9dc72 100644 --- a/runtime/indent/testdir/html.ok +++ b/runtime/indent/testdir/html.ok @@ -2,25 +2,65 @@ " START_INDENT -<div> - <div> - text - </div> -</div> - -<div - class="foo bar"> - text -</div> - -<div class="foo bar" - data="something"> - text -</div> - -<div class="foo - bar"> - text -</div> +<html> + <body> + <style> +div#d1 { color: red; } +div#d2 { color: green; } + </style> + <script> + var v1 = "v1"; + var v2 = "v2"; + </script> + <div> + <div> + text + </div> + </div> + + <div + class="foo bar"> + text + </div> + + <div class="foo bar" + data="something"> + text + </div> + + <div class="foo + bar"> + text + </div> + + <dl> + <dd> + dd text + </dd> + <dt> + dt text + </dt> + </dl> + + </body> +</html> " END_INDENT + +% START_INDENT +% INDENT_EXE let g:html_indent_style1 = "inc" +% INDENT_EXE let g:html_indent_script1 = "zero" +% INDENT_EXE call HtmlIndent_CheckUserSettings() +<html> + <body> + <style> + div#d1 { color: red; } + div#d2 { color: green; } + </style> + <script> +var v1 = "v1"; +var v2 = "v2"; + </script> + </body> +</html> +% END_INDENT diff --git a/runtime/indent/testdir/matlab.in b/runtime/indent/testdir/matlab.in index 5bba1a56dd..b997ec8d57 100644 --- a/runtime/indent/testdir/matlab.in +++ b/runtime/indent/testdir/matlab.in @@ -37,6 +37,7 @@ end % START_INDENT if true A(1:end - 1) +C{1:end - 1} disp foo end % END_INDENT @@ -50,6 +51,14 @@ disp bar % END_INDENT % START_INDENT +if true +% end +%% end +disp foo +end +% END_INDENT + +% START_INDENT % INDENT_EXE let b:MATLAB_function_indent = 0 function foo disp foo diff --git a/runtime/indent/testdir/matlab.ok b/runtime/indent/testdir/matlab.ok index b1112263b2..df4e7b2e33 100644 --- a/runtime/indent/testdir/matlab.ok +++ b/runtime/indent/testdir/matlab.ok @@ -37,6 +37,7 @@ end % START_INDENT if true A(1:end - 1) + C{1:end - 1} disp foo end % END_INDENT @@ -50,6 +51,14 @@ disp bar % END_INDENT % START_INDENT +if true + % end + %% end + disp foo +end +% END_INDENT + +% START_INDENT % INDENT_EXE let b:MATLAB_function_indent = 0 function foo disp foo diff --git a/runtime/indent/testdir/runtest.vim b/runtime/indent/testdir/runtest.vim index 945c2753e9..6bbd33cacd 100644 --- a/runtime/indent/testdir/runtest.vim +++ b/runtime/indent/testdir/runtest.vim @@ -117,6 +117,7 @@ for fname in glob('testdir/*.in', 1, 1) echoerr 'Test ' . fname . ' FAILED!' else exe 'write ' . root . '.out' + echo "Test " . fname . " OK\n" endif quit! " close the indented file diff --git a/runtime/indent/testdir/sshconfig.in b/runtime/indent/testdir/sshconfig.in new file mode 100644 index 0000000000..87b998e465 --- /dev/null +++ b/runtime/indent/testdir/sshconfig.in @@ -0,0 +1,53 @@ +# vim: set filetype=sshconfig shiftwidth=4 expandtab : + +# START_INDENT +Host myhost +User myuser +PasswordAuthentication no +# END_INDENT + +# START_INDENT +Host aaa +User bbb +Host ccc +Host ddd +# END_INDENT + +# START_INDENT +host aaa +HOST bbb +hoSt ccc +match ddd +MATCH eee +MatCH fff +# END_INDENT + +# START_INDENT +Host aaa +User host +PasswordAuthentication no +Host * +User user +PasswordAuthentication no +Host match +User bbb +# END_INDENT + +# START_INDENT +Host tab +User myuser +# END_INDENT + +# START_INDENT +Host mix +User myuser +# END_INDENT + +# START_INDENT +Host aaa +User bbb +Match ccc +User ddd +HostKeyAlgorithms ssh-ed25519 +Match eee +# END_INDENT diff --git a/runtime/indent/testdir/sshconfig.ok b/runtime/indent/testdir/sshconfig.ok new file mode 100644 index 0000000000..b24b7cf4e1 --- /dev/null +++ b/runtime/indent/testdir/sshconfig.ok @@ -0,0 +1,53 @@ +# vim: set filetype=sshconfig shiftwidth=4 expandtab : + +# START_INDENT +Host myhost + User myuser + PasswordAuthentication no +# END_INDENT + +# START_INDENT +Host aaa + User bbb +Host ccc +Host ddd +# END_INDENT + +# START_INDENT +host aaa +HOST bbb +hoSt ccc +match ddd +MATCH eee +MatCH fff +# END_INDENT + +# START_INDENT +Host aaa + User host + PasswordAuthentication no +Host * + User user + PasswordAuthentication no +Host match + User bbb +# END_INDENT + +# START_INDENT +Host tab + User myuser +# END_INDENT + +# START_INDENT +Host mix + User myuser +# END_INDENT + +# START_INDENT +Host aaa + User bbb +Match ccc + User ddd + HostKeyAlgorithms ssh-ed25519 +Match eee +# END_INDENT diff --git a/runtime/indent/testdir/vim.in b/runtime/indent/testdir/vim.in index ca105f6eda..699e4c243d 100644 --- a/runtime/indent/testdir/vim.in +++ b/runtime/indent/testdir/vim.in @@ -10,6 +10,26 @@ let cmd = \ 'some ' \ 'string' +if 1 +let x = [ +\ ] +endif + +" TODO: add searchpair() to find matching { +"for x in [ +"{ +"key: 'value' +"}, +"] +"eval 0 +"endfor + +for x in [ +{key: 'value'}, +] +eval 0 +endfor + " END_INDENT " START_INDENT @@ -22,7 +42,26 @@ let cmd = " END_INDENT " START_INDENT +" INDENT_EXE let g:vim_indent_cont = 5 + +let list = [ +\ 'one', +\ 'two'] + +" END_INDENT + +" START_INDENT " INDENT_EXE unlet g:vim_indent_cont + +let list = [ +'one', +'two', +] +echo + +" END_INDENT + +" START_INDENT " INDENT_AT this-line func Some() let f = x " this-line @@ -44,3 +83,18 @@ let f = x " prev-line endfunc " END_INDENT + +" START_INDENT +let a =<< END +nothing +END +" END_INDENT + +" START_INDENT +" INDENT_AT this-line +let a=<< trim END + blah + blah + blah this-line +END +" END_INDENT diff --git a/runtime/indent/testdir/vim.ok b/runtime/indent/testdir/vim.ok index 542861ec9c..f597d97e80 100644 --- a/runtime/indent/testdir/vim.ok +++ b/runtime/indent/testdir/vim.ok @@ -10,6 +10,26 @@ let cmd = \ 'some ' \ 'string' +if 1 + let x = [ + \ ] +endif + +" TODO: add searchpair() to find matching { +"for x in [ +"{ +"key: 'value' +"}, +"] +"eval 0 +"endfor + +for x in [ + {key: 'value'}, + ] + eval 0 +endfor + " END_INDENT " START_INDENT @@ -22,7 +42,26 @@ let cmd = " END_INDENT " START_INDENT +" INDENT_EXE let g:vim_indent_cont = 5 + +let list = [ + \ 'one', + \ 'two'] + +" END_INDENT + +" START_INDENT " INDENT_EXE unlet g:vim_indent_cont + +let list = [ + 'one', + 'two', + ] +echo + +" END_INDENT + +" START_INDENT " INDENT_AT this-line func Some() let f = x " this-line @@ -44,3 +83,18 @@ func Some() " prev-line endfunc " END_INDENT + +" START_INDENT +let a =<< END + nothing +END +" END_INDENT + +" START_INDENT +" INDENT_AT this-line +let a=<< trim END + blah + blah + blah this-line +END +" END_INDENT diff --git a/runtime/indent/testdir/yaml.in b/runtime/indent/testdir/yaml.in new file mode 100644 index 0000000000..8515e1752c --- /dev/null +++ b/runtime/indent/testdir/yaml.in @@ -0,0 +1,19 @@ +# vim: set ft=yaml sw=2 et : + +# START_INDENT +map1: +sub1: +- list item +map2: +- another list +# END_INDENT + +# START_INDENT +map: &anchor +map: val +# END_INDENT + +# START_INDENT +map: multiline +value +# END_INDENT diff --git a/runtime/indent/testdir/yaml.ok b/runtime/indent/testdir/yaml.ok new file mode 100644 index 0000000000..5ca2871fc9 --- /dev/null +++ b/runtime/indent/testdir/yaml.ok @@ -0,0 +1,19 @@ +# vim: set ft=yaml sw=2 et : + +# START_INDENT +map1: + sub1: + - list item +map2: + - another list +# END_INDENT + +# START_INDENT +map: &anchor +map: val +# END_INDENT + +# START_INDENT +map: multiline + value +# END_INDENT diff --git a/runtime/indent/tilde.vim b/runtime/indent/tilde.vim index 13082c8692..e722a0994c 100644 --- a/runtime/indent/tilde.vim +++ b/runtime/indent/tilde.vim @@ -1,5 +1,5 @@ "Description: Indent scheme for the tilde weblanguage -"Author: Tobias Rundström <tobi@tobi.nu> +"Author: Tobias Rundström <tobi@tobi.nu> "URL: http://tilde.tildesoftware.net "Last Change: May 8 09:15:09 CEST 2002 diff --git a/runtime/indent/vim.vim b/runtime/indent/vim.vim index cd735c3a3c..ee3d39490d 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: 2016 Jun 27 +" Last Change: 2021 Apr 18 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -10,7 +10,8 @@ endif let b:did_indent = 1 setlocal indentexpr=GetVimIndent() -setlocal indentkeys+==end,=else,=cat,=fina,=END,0\\,0=\"\\\ +setlocal indentkeys+==end,=},=else,=cat,=finall,=END,0\\,0=\"\\\ +setlocal indentkeys-=0# let b:undo_indent = "setl indentkeys< indentexpr<" @@ -37,6 +38,9 @@ function GetVimIndentIntern() " Find a non-blank line above the current line. let lnum = prevnonblank(v:lnum - 1) + " The previous line, ignoring line continuation + let prev_text_end = lnum > 0 ? getline(lnum) : '' + " If the current line doesn't start with '\' or '"\ ' and below a line that " starts with '\' or '"\ ', use the indent of the line above it. let cur_text = getline(v:lnum) @@ -50,13 +54,43 @@ function GetVimIndentIntern() if lnum == 0 return 0 endif + + " the start of the previous line, skipping over line continuation let prev_text = getline(lnum) + let found_cont = 0 " Add a 'shiftwidth' after :if, :while, :try, :catch, :finally, :function " and :else. Add it three times for a line that starts with '\' or '"\ ' " after a line that doesn't (or g:vim_indent_cont if it exists). let ind = indent(lnum) + + " In heredoc indenting works completely differently. + if has('syntax_items') + let syn_here = synIDattr(synID(v:lnum, 1, 1), "name") + if syn_here =~ 'vimLetHereDocStop' + " End of heredoc: use indent of matching start line + let lnum = v:lnum - 1 + while lnum > 0 + let attr = synIDattr(synID(lnum, 1, 1), "name") + if attr != '' && attr !~ 'vimLetHereDoc' + return indent(lnum) + endif + let lnum -= 1 + endwhile + return 0 + endif + if syn_here =~ 'vimLetHereDoc' + if synIDattr(synID(lnum, 1, 1), "name") !~ 'vimLetHereDoc' + " First line in heredoc: increase indent + return ind + shiftwidth() + endif + " Heredoc continues: no change in indent + return ind + endif + endif + if cur_text =~ s:lineContPat && v:lnum > 1 && prev_text !~ s:lineContPat + let found_cont = 1 if exists("g:vim_indent_cont") let ind = ind + g:vim_indent_cont else @@ -66,8 +100,10 @@ function GetVimIndentIntern() 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]\)\>') + " A { may start a block or a dict. Assume that when a } follows it's a + " terminated dict. + if prev_text !~ '^\s*au\%[tocmd]' && prev_text !~ '^\s*{.*}' + let i = match(prev_text, '\(^\||\)\s*\(export\s\+\)\?\({\|\(if\|wh\%[ile]\|for\|try\|cat\%[ch]\|fina\|finall\%[y]\|fu\%[nction]\|def\|el\%[seif]\)\>\)') if i >= 0 let ind += shiftwidth() if strpart(prev_text, i, 1) == '|' && has('syntax_items') @@ -88,10 +124,54 @@ function GetVimIndentIntern() endif endif + " For a line starting with "}" find the matching "{". If it is at the start + " of the line align with it, probably end of a block. + " Use the mapped "%" from matchit to find the match, otherwise we may match + " a { inside a comment or string. + if cur_text =~ '^\s*}' + if maparg('%') != '' + exe v:lnum + silent! normal % + if line('.') < v:lnum && getline('.') =~ '^\s*{' + let ind = indent('.') + endif + else + " todo: use searchpair() to find a match + endif + endif + + " Below a line starting with "}" find the matching "{". If it is at the + " end of the line we must be below the end of a dictionary. + if prev_text =~ '^\s*}' + if maparg('%') != '' + exe lnum + silent! normal % + if line('.') == lnum || getline('.') !~ '^\s*{' + let ind = ind - shiftwidth() + endif + else + " todo: use searchpair() to find a match + endif + endif + + " Below a line starting with "]" we must be below the end of a list. + " Include a "}" and "},} in case a dictionary ends too. + if prev_text_end =~ '^\s*\(},\=\s*\)\=]' + let ind = ind - shiftwidth() + endif + + let ends_in_comment = has('syntax_items') + \ && synIDattr(synID(lnum, len(getline(lnum)), 1), "name") =~ '\(Comment\|String\)$' + + " A line ending in "{" or "[" is most likely the start of a dict/list literal, + " indent the next line more. Not for a continuation line or {{{. + if !ends_in_comment && prev_text_end =~ '\s[{[]\s*$' && !found_cont + let ind = ind + shiftwidth() + 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\+[eE][nN][dD]\)' + if cur_text =~ '^\s*\(ene\@!\|cat\|finall\|el\|aug\%[roup]\s\+[eE][nN][dD]\)' let ind = ind - shiftwidth() endif diff --git a/runtime/indent/xml.vim b/runtime/indent/xml.vim index 413a3ddb53..da65417939 100644 --- a/runtime/indent/xml.vim +++ b/runtime/indent/xml.vim @@ -2,8 +2,9 @@ " Maintainer: Christian Brabandt <cb@256bit.org> " Repository: https://github.com/chrisbra/vim-xml-ftplugin " Previous Maintainer: Johannes Zellner <johannes@zellner.org> -" Last Changed: 2019 Dec 02 +" Last Changed: 2020 Nov 4th " Last Change: +" 20200529 - Handle empty closing tags correctly " 20191202 - Handle docbk filetype " 20190726 - Correctly handle non-tagged data " 20190204 - correctly handle wrap tags @@ -45,7 +46,7 @@ if !exists('b:xml_indent_open') endif if !exists('b:xml_indent_close') - let b:xml_indent_close = '.\{-}</' + let b:xml_indent_close = '.\{-}</\|/>.\{-}' " end pre tag, e.g. </address> " let b:xml_indent_close = '.\{-}</\(address\)\@!' endif @@ -81,7 +82,7 @@ endfun " [-- return the sum of indents of a:lnum --] fun! <SID>XmlIndentSum(line, style, add) - if <SID>IsXMLContinuation(a:line) && a:style == 0 + if <SID>IsXMLContinuation(a:line) && a:style == 0 && !<SID>IsXMLEmptyClosingTag(a:line) " no complete tag, add one additional indent level " but only for the current line return a:add + shiftwidth() @@ -131,13 +132,25 @@ fun! XmlIndentGet(lnum, use_syntax_check) endif let syn_name_end = synIDattr(synID(a:lnum, strlen(curline) - 1, 1), 'name') let syn_name_start = synIDattr(synID(a:lnum, match(curline, '\S') + 1, 1), 'name') + let prev_syn_name_end = synIDattr(synID(ptag, strlen(pline) - 1, 1), 'name') + " not needed (yet?) + " let prev_syn_name_start = synIDattr(synID(ptag, match(pline, '\S') + 1, 1), 'name') endif if syn_name_end =~ 'Comment' && syn_name_start =~ 'Comment' return <SID>XmlIndentComment(a:lnum) elseif empty(syn_name_start) && empty(syn_name_end) && a:use_syntax_check " non-xml tag content: use indent from 'autoindent' - return pind + shiftwidth() + if pline =~ b:xml_indent_close + return pind + elseif !empty(prev_syn_name_end) + " only indent by an extra shiftwidth, if the previous line ends + " with an XML like tag + return pind + shiftwidth() + else + " no extra indent, looks like a text continuation line + return pind + endif endif " Get indent from previous tag line @@ -157,15 +170,28 @@ func! <SID>HasNoTagEnd(line) return a:line !~ '>\s*$' endfunc +func! <SID>IsXMLEmptyClosingTag(line) + " Checks whether the line ends with an empty closing tag such as <lb/> + return a:line =~? '<[^>]*/>\s*$' +endfunc + " return indent for a commented line, " the middle part might be indented one additional level func! <SID>XmlIndentComment(lnum) - let ptagopen = search(b:xml_indent_open, 'bnW') + let ptagopen = search('.\{-}<[:A-Z_a-z]\_[^/]\{-}>.\{-}', 'bnW') let ptagclose = search(b:xml_indent_close, 'bnW') if getline(a:lnum) =~ '<!--' " if previous tag was a closing tag, do not add " one additional level of indent if ptagclose > ptagopen && a:lnum > ptagclose + " If the previous tag was closed on the same line as it was + " declared, we should indent with its indent level. + if !<SID>IsXMLContinuation(getline(ptagclose)) + return indent(ptagclose) + else + return indent(ptagclose) - shiftwidth() + endif + elseif ptagclose == ptagopen return indent(ptagclose) else " start of comment, add one indentation level diff --git a/runtime/indent/yaml.vim b/runtime/indent/yaml.vim index 3eb16f845d..8dca5cd763 100644 --- a/runtime/indent/yaml.vim +++ b/runtime/indent/yaml.vim @@ -1,16 +1,14 @@ " Vim indent file -" Language: YAML -" Maintainer: Nikolai Pavlov <zyx.vim@gmail.com> -" Last Change: 2017 Jun 13 +" Language: YAML +" Maintainer: Nikolai Pavlov <zyx.vim@gmail.com> +" Last Update: Lukas Reineke +" Last Change: 2021 Jan 19 " Only load this indent file when no other was loaded. if exists('b:did_indent') finish endif -let s:save_cpo = &cpo -set cpo&vim - let b:did_indent = 1 setlocal indentexpr=GetYAMLIndent(v:lnum) @@ -24,12 +22,15 @@ if exists('*GetYAMLIndent') finish endif +let s:save_cpo = &cpo +set cpo&vim + function s:FindPrevLessIndentedLine(lnum, ...) let prevlnum = prevnonblank(a:lnum-1) let curindent = a:0 ? a:1 : indent(a:lnum) while prevlnum \&& indent(prevlnum) >= curindent - \&& getline(prevlnum) =~# '^\s*#' + \&& getline(prevlnum) !~# '^\s*#' let prevlnum = prevnonblank(prevlnum-1) endwhile return prevlnum @@ -53,7 +54,7 @@ let s:c_ns_anchor_name = s:c_ns_anchor_char.'+' let s:c_ns_anchor_property = '\v\&'.s:c_ns_anchor_name let s:ns_word_char = '\v[[:alnum:]_\-]' -let s:ns_tag_char = '\v%(%\x\x|'.s:ns_word_char.'|[#/;?:@&=+$.~*''()])' +let s:ns_tag_char = '\v%('.s:ns_word_char.'|[#/;?:@&=+$.~*''()])' let s:c_named_tag_handle = '\v\!'.s:ns_word_char.'+\!' let s:c_secondary_tag_handle = '\v\!\!' let s:c_primary_tag_handle = '\v\!' @@ -62,7 +63,7 @@ let s:c_tag_handle = '\v%('.s:c_named_tag_handle. \ '|'.s:c_primary_tag_handle.')' let s:c_ns_shorthand_tag = '\v'.s:c_tag_handle . s:ns_tag_char.'+' let s:c_non_specific_tag = '\v\!' -let s:ns_uri_char = '\v%(%\x\x|'.s:ns_word_char.'\v|[#/;?:@&=+$,.!~*''()[\]])' +let s:ns_uri_char = '\v%('.s:ns_word_char.'\v|[#/;?:@&=+$,.!~*''()[\]])' let s:c_verbatim_tag = '\v\!\<'.s:ns_uri_char.'+\>' let s:c_ns_tag_property = '\v'.s:c_verbatim_tag. \ '\v|'.s:c_ns_shorthand_tag. |