diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-09-27 17:30:34 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-27 17:30:34 +0100 |
commit | 9fbdbb814f4ad67a14979aba4a6a49800c2f1a99 (patch) | |
tree | cbf6e2990b41ad67092e529497df96bd9199e353 /runtime/indent | |
parent | 26f09ea54b2c60abf21df42c60bdfc60eca17b0d (diff) |
Update runtime files
Diffstat (limited to 'runtime/indent')
-rw-r--r-- | runtime/indent/chatito.vim | 32 | ||||
-rw-r--r-- | runtime/indent/gyp.vim | 7 | ||||
-rw-r--r-- | runtime/indent/hare.vim | 138 | ||||
-rw-r--r-- | runtime/indent/solidity.vim | 442 | ||||
-rw-r--r-- | runtime/indent/testdir/vim.in | 778 | ||||
-rw-r--r-- | runtime/indent/testdir/vim.ok | 778 | ||||
-rw-r--r-- | runtime/indent/vim.vim | 224 | ||||
-rw-r--r-- | runtime/indent/vue.vim | 12 |
8 files changed, 2171 insertions, 240 deletions
diff --git a/runtime/indent/chatito.vim b/runtime/indent/chatito.vim new file mode 100644 index 0000000000..1ff5e9e3f1 --- /dev/null +++ b/runtime/indent/chatito.vim @@ -0,0 +1,32 @@ +" Vim indent file +" Language: Chatito +" Maintainer: ObserverOfTime <chronobserver@disroot.org> +" Last Change: 2022 Sep 20 + +if exists('b:did_indent') + finish +endif +let b:did_indent = 1 + +setlocal indentexpr=GetChatitoIndent() +setlocal indentkeys=o,O,*<Return>,0#,!^F + +let b:undo_indent = 'setl inde< indk<' + +if exists('*GetChatitoIndent') + finish +endif + +function GetChatitoIndent() + let l:prev = v:lnum - 1 + if getline(prevnonblank(l:prev)) =~# '^[~%@]\[' + " shift indent after definitions + return shiftwidth() + elseif getline(l:prev) !~# '^\s*$' + " maintain indent in sentences + return indent(l:prev) + else + " reset indent after a blank line + return 0 + end +endfunction diff --git a/runtime/indent/gyp.vim b/runtime/indent/gyp.vim new file mode 100644 index 0000000000..c3980ac568 --- /dev/null +++ b/runtime/indent/gyp.vim @@ -0,0 +1,7 @@ +" Vim indent file +" Language: GYP +" Maintainer: ObserverOfTime <chronobserver@disroot.org> +" Last Change: 2022 Sep 27 + +" JSON indent works well +runtime! indent/json.vim diff --git a/runtime/indent/hare.vim b/runtime/indent/hare.vim new file mode 100644 index 0000000000..bc4fea4e61 --- /dev/null +++ b/runtime/indent/hare.vim @@ -0,0 +1,138 @@ +" Vim indent file +" Language: Hare +" Maintainer: Amelia Clarke <me@rsaihe.dev> +" Last Change: 2022 Sep 22 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +if !has("cindent") || !has("eval") + finish +endif + +setlocal cindent + +" L0 -> don't deindent labels +" (s -> use one indent after a trailing ( +" m1 -> if ) starts a line, indent it the same as its matching ( +" ks -> add an extra indent to extra lines in an if expression or for expression +" j1 -> indent code inside {} one level when in parentheses +" J1 -> see j1 +" *0 -> don't search for unclosed block comments +" #1 -> don't deindent lines that begin with # +setlocal cinoptions=L0,(s,m1,ks,j1,J1,*0,#1 + +" Controls which keys reindent the current line. +" 0{ -> { at beginning of line +" 0} -> } at beginning of line +" 0) -> ) at beginning of line +" 0] -> ] at beginning of line +" !^F -> <C-f> (not inserted) +" o -> <CR> or `o` command +" O -> `O` command +" e -> else +" 0=case -> case +setlocal indentkeys=0{,0},0),0],!^F,o,O,e,0=case + +setlocal cinwords=if,else,for,switch,match + +setlocal indentexpr=GetHareIndent() + +function! FloorCindent(lnum) + return cindent(a:lnum) / shiftwidth() * shiftwidth() +endfunction + +function! GetHareIndent() + let line = getline(v:lnum) + let prevlnum = prevnonblank(v:lnum - 1) + let prevline = getline(prevlnum) + let prevprevline = getline(prevnonblank(prevlnum - 1)) + + " This is all very hacky and imperfect, but it's tough to do much better when + " working with regex-based indenting rules. + + " If the previous line ended with =, indent by one shiftwidth. + if prevline =~# '\v\=\s*(//.*)?$' + return indent(prevlnum) + shiftwidth() + endif + + " If the previous line ended in a semicolon and the line before that ended + " with =, deindent by one shiftwidth. + if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\s*(//.*)?$' + return indent(prevlnum) - shiftwidth() + endif + + " TODO: The following edge-case is still indented incorrectly: + " case => + " if (foo) { + " bar; + " }; + " | // cursor is incorrectly deindented by one shiftwidth. + " + " This only happens if the {} block is the first statement in the case body. + " If `case` is typed, the case will also be incorrectly deindented by one + " shiftwidth. Are you having fun yet? + + " Deindent cases. + if line =~# '\v^\s*case' + " If the previous line was also a case, don't do any special indenting. + if prevline =~# '\v^\s*case' + return indent(prevlnum) + end + + " If the previous line was a multiline case, deindent by one shiftwidth. + if prevline =~# '\v\=\>\s*(//.*)?$' + return indent(prevlnum) - shiftwidth() + endif + + " If the previous line started a block, deindent by one shiftwidth. + " This handles the first case in a switch/match block. + if prevline =~# '\v\{\s*(//.*)?$' + return FloorCindent(v:lnum) - shiftwidth() + end + + " If the previous line ended in a semicolon and the line before that wasn't + " a case, deindent by one shiftwidth. + if prevline =~# '\v;\s*(//.*)?$' && prevprevline !~# '\v\=\>\s*(//.*)?$' + return FloorCindent(v:lnum) - shiftwidth() + end + + let l:indent = FloorCindent(v:lnum) + + " If a normal cindent would indent the same amount as the previous line, + " deindent by one shiftwidth. This fixes some issues with `case let` blocks. + if l:indent == indent(prevlnum) + return l:indent - shiftwidth() + endif + + " Otherwise, do a normal cindent. + return l:indent + endif + + " Don't indent an extra shiftwidth for cases which span multiple lines. + if prevline =~# '\v\=\>\s*(//.*)?$' && prevline !~# '\v^\s*case\W' + return indent(prevlnum) + endif + + " Indent the body of a case. + " If the previous line ended in a semicolon and the line before that was a + " case, don't do any special indenting. + if prevline =~# '\v;\s*(//.*)?$' && prevprevline =~# '\v\=\>\s*(//.*)?$' && line !~# '\v^\s*}' + return indent(prevlnum) + endif + + let l:indent = FloorCindent(v:lnum) + + " If the previous line was a case and a normal cindent wouldn't indent, indent + " an extra shiftwidth. + if prevline =~# '\v\=\>\s*(//.*)?$' && l:indent == indent(prevlnum) + return l:indent + shiftwidth() + endif + + " If everything above is false, do a normal cindent. + return l:indent +endfunction + +" vim: tabstop=2 shiftwidth=2 expandtab diff --git a/runtime/indent/solidity.vim b/runtime/indent/solidity.vim new file mode 100644 index 0000000000..caed726c0a --- /dev/null +++ b/runtime/indent/solidity.vim @@ -0,0 +1,442 @@ +" Vim indent file +" Language: Solidity +" Acknowledgement: Based off of vim-javascript +" Maintainer: Cothi (jiungdev@gmail.com) +" Original Author: tomlion (https://github.com/tomlion/vim-solidity) +" Last Changed: 2022 Sep 27 +" +" 0. Initialization {{{1 +" ================= + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent + +" Now, set up our indentation expression and keys that trigger it. +setlocal indentexpr=GetSolidityIndent() +setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e + +" Only define the function once. +if exists("*GetSolidityIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" 1. Variables {{{1 +" ============ + +let s:js_keywords = '^\s*\(break\|case\|catch\|continue\|debugger\|default\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)' + +" Regex of syntax group names that are or delimit string or are comments. +let s:syng_strcom = 'string\|regex\|comment\c' + +" Regex of syntax group names that are strings. +let s:syng_string = 'regex\c' + +" Regex of syntax group names that are strings or documentation. +let s:syng_multiline = 'comment\c' + +" Regex of syntax group names that are line comment. +let s:syng_linecom = 'linecomment\c' + +" Expression used to check whether we should skip a match with searchpair(). +let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'" + +let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' + +" Regex that defines continuation lines, not including (, {, or [. +let s:continuation_regex = '\%([\\*+/.:]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\)' . s:line_term + +" Regex that defines continuation lines. +" TODO: this needs to deal with if ...: and so on +let s:msl_regex = '\%([\\*+/.:([]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\)' . s:line_term + +let s:one_line_scope_regex = '\<\%(if\|else\|for\|while\)\>[^{;]*' . s:line_term + +" Regex that defines blocks. +let s:block_regex = '\%([{[]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term + +let s:var_stmt = '^\s*var' + +let s:comma_first = '^\s*,' +let s:comma_last = ',\s*$' + +let s:ternary = '^\s\+[?|:]' +let s:ternary_q = '^\s\+?' + +" 2. Auxiliary Functions {{{1 +" ====================== + +" Check if the character at lnum:col is inside a string, comment, or is ascii. +function s:IsInStringOrComment(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom +endfunction + +" Check if the character at lnum:col is inside a string. +function s:IsInString(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string +endfunction + +" Check if the character at lnum:col is inside a multi-line comment. +function s:IsInMultilineComment(lnum, col) + return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline +endfunction + +" Check if the character at lnum:col is a line comment. +function s:IsLineComment(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_linecom +endfunction + +" Find line above 'lnum' that isn't empty, in a comment, or in a string. +function s:PrevNonBlankNonString(lnum) + let in_block = 0 + let lnum = prevnonblank(a:lnum) + while lnum > 0 + " Go in and out of blocks comments as necessary. + " If the line isn't empty (with opt. comment) or in a string, end search. + let line = getline(lnum) + if line =~ '/\*' + if in_block + let in_block = 0 + else + break + endif + elseif !in_block && line =~ '\*/' + let in_block = 1 + elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) + break + endif + let lnum = prevnonblank(lnum - 1) + endwhile + return lnum +endfunction + +" Find line above 'lnum' that started the continuation 'lnum' may be part of. +function s:GetMSL(lnum, in_one_line_scope) + " Start on the line we're at and use its indent. + let msl = a:lnum + let lnum = s:PrevNonBlankNonString(a:lnum - 1) + while lnum > 0 + " If we have a continuation line, or we're in a string, use line as MSL. + " Otherwise, terminate search as we have found our MSL already. + let line = getline(lnum) + let col = match(line, s:msl_regex) + 1 + if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line)) + let msl = lnum + else + " Don't use lines that are part of a one line scope as msl unless the + " flag in_one_line_scope is set to 1 + " + if a:in_one_line_scope + break + end + let msl_one_line = s:Match(lnum, s:one_line_scope_regex) + if msl_one_line == 0 + break + endif + endif + let lnum = s:PrevNonBlankNonString(lnum - 1) + endwhile + return msl +endfunction + +function s:RemoveTrailingComments(content) + let single = '\/\/\(.*\)\s*$' + let multi = '\/\*\(.*\)\*\/\s*$' + return substitute(substitute(a:content, single, '', ''), multi, '', '') +endfunction + +" Find if the string is inside var statement (but not the first string) +function s:InMultiVarStatement(lnum) + let lnum = s:PrevNonBlankNonString(a:lnum - 1) + +" let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') + + " loop through previous expressions to find a var statement + while lnum > 0 + let line = getline(lnum) + + " if the line is a js keyword + if (line =~ s:js_keywords) + " check if the line is a var stmt + " if the line has a comma first or comma last then we can assume that we + " are in a multiple var statement + if (line =~ s:var_stmt) + return lnum + endif + + " other js keywords, not a var + return 0 + endif + + let lnum = s:PrevNonBlankNonString(lnum - 1) + endwhile + + " beginning of program, not a var + return 0 +endfunction + +" Find line above with beginning of the var statement or returns 0 if it's not +" this statement +function s:GetVarIndent(lnum) + let lvar = s:InMultiVarStatement(a:lnum) + let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) + + if lvar + let line = s:RemoveTrailingComments(getline(prev_lnum)) + + " if the previous line doesn't end in a comma, return to regular indent + if (line !~ s:comma_last) + return indent(prev_lnum) - &sw + else + return indent(lvar) + &sw + endif + endif + + return -1 +endfunction + + +" Check if line 'lnum' has more opening brackets than closing ones. +function s:LineHasOpeningBrackets(lnum) + let open_0 = 0 + let open_2 = 0 + let open_4 = 0 + let line = getline(a:lnum) + let pos = match(line, '[][(){}]', 0) + while pos != -1 + if !s:IsInStringOrComment(a:lnum, pos + 1) + let idx = stridx('(){}[]', 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(line, '[][(){}]', pos + 1) + endwhile + return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) +endfunction + +function s:Match(lnum, regex) + let col = match(getline(a:lnum), a:regex) + 1 + return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0 +endfunction + +function s:IndentWithContinuation(lnum, ind, width) + " Set up variables to use and search for MSL to the previous line. + let p_lnum = a:lnum + let lnum = s:GetMSL(a:lnum, 1) + let line = getline(lnum) + + " If the previous line wasn't a MSL and is continuation return its indent. + " TODO: the || s:IsInString() thing worries me a bit. + if p_lnum != lnum + if s:Match(p_lnum,s:continuation_regex)||s:IsInString(p_lnum,strlen(line)) + return a:ind + endif + endif + + " Set up more variables now that we know we aren't continuation bound. + let msl_ind = indent(lnum) + + " If the previous line ended with [*+/.-=], start a continuation that + " indents an extra level. + if s:Match(lnum, s:continuation_regex) + if lnum == p_lnum + return msl_ind + a:width + else + return msl_ind + endif + endif + + return a:ind +endfunction + +function s:InOneLineScope(lnum) + let msl = s:GetMSL(a:lnum, 1) + if msl > 0 && s:Match(msl, s:one_line_scope_regex) + return msl + endif + return 0 +endfunction + +function s:ExitingOneLineScope(lnum) + let msl = s:GetMSL(a:lnum, 1) + if msl > 0 + " if the current line is in a one line scope .. + if s:Match(msl, s:one_line_scope_regex) + return 0 + else + let prev_msl = s:GetMSL(msl - 1, 1) + if s:Match(prev_msl, s:one_line_scope_regex) + return prev_msl + endif + endif + endif + return 0 +endfunction + +" 3. GetSolidityIndent Function {{{1 +" ========================= + +function GetSolidityIndent() + " 3.1. Setup {{{2 + " ---------- + + " Set up variables for restoring position in file. Could use v:lnum here. + let vcol = col('.') + + " 3.2. Work on the current line {{{2 + " ----------------------------- + + let ind = -1 + " Get the current line. + let line = getline(v:lnum) + " previous nonblank line number + let prevline = prevnonblank(v:lnum - 1) + + " If we got a closing bracket on an empty line, find its match and indent + " according to it. For parentheses we indent to its column - 1, for the + " others we indent to the containing line's MSL's level. Return -1 if fail. + let col = matchend(line, '^\s*[],})]') + if col > 0 && !s:IsInStringOrComment(v:lnum, col) + call cursor(v:lnum, col) + + let lvar = s:InMultiVarStatement(v:lnum) + if lvar + let prevline_contents = s:RemoveTrailingComments(getline(prevline)) + + " check for comma first + if (line[col - 1] =~ ',') + " if the previous line ends in comma or semicolon don't indent + if (prevline_contents =~ '[;,]\s*$') + return indent(s:GetMSL(line('.'), 0)) + " get previous line indent, if it's comma first return prevline indent + elseif (prevline_contents =~ s:comma_first) + return indent(prevline) + " otherwise we indent 1 level + else + return indent(lvar) + &sw + endif + endif + endif + + + let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) + if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 + if line[col-1]==')' && col('.') != col('$') - 1 + let ind = virtcol('.')-1 + else + let ind = indent(s:GetMSL(line('.'), 0)) + endif + endif + return ind + endif + + " If the line is comma first, dedent 1 level + if (getline(prevline) =~ s:comma_first) + return indent(prevline) - &sw + endif + + if (line =~ s:ternary) + if (getline(prevline) =~ s:ternary_q) + return indent(prevline) + else + return indent(prevline) + &sw + endif + endif + + " If we are in a multi-line comment, cindent does the right thing. + if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) + return cindent(v:lnum) + endif + + " Check for multiple var assignments +" let var_indent = s:GetVarIndent(v:lnum) +" if var_indent >= 0 +" return var_indent +" endif + + " 3.3. Work on the previous line. {{{2 + " ------------------------------- + + " If the line is empty and the previous nonblank line was a multi-line + " comment, use that comment's indent. Deduct one char to account for the + " space in ' */'. + if line =~ '^\s*$' && s:IsInMultilineComment(prevline, 1) + return indent(prevline) - 1 + endif + + " Find a non-blank, non-multi-line string line above the current line. + let lnum = s:PrevNonBlankNonString(v:lnum - 1) + + " If the line is empty and inside a string, use the previous line. + if line =~ '^\s*$' && lnum != prevline + return indent(prevnonblank(v:lnum)) + endif + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + " Set up variables for current line. + let line = getline(lnum) + let ind = indent(lnum) + + " If the previous line ended with a block opening, add a level of indent. + if s:Match(lnum, s:block_regex) + return indent(s:GetMSL(lnum, 0)) + &sw + endif + + " If the previous line contained an opening bracket, and we are still in it, + " add indent depending on the bracket type. + if line =~ '[[({]' + let counts = s:LineHasOpeningBrackets(lnum) + if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 + if col('.') + 1 == col('$') + return ind + &sw + else + return virtcol('.') + endif + elseif counts[1] == '1' || counts[2] == '1' + return ind + &sw + else + call cursor(v:lnum, vcol) + end + endif + + " 3.4. Work on the MSL line. {{{2 + " -------------------------- + + let ind_con = ind + let ind = s:IndentWithContinuation(lnum, ind_con, &sw) + + " }}}2 + " + " + let ols = s:InOneLineScope(lnum) + if ols > 0 + let ind = ind + &sw + else + let ols = s:ExitingOneLineScope(lnum) + while ols > 0 && ind > 0 + let ind = ind - &sw + let ols = s:InOneLineScope(ols - 1) + endwhile + endif + + return ind +endfunction + +" }}}1 + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/indent/testdir/vim.in b/runtime/indent/testdir/vim.in index 5eb262f50a..0582a930e6 100644 --- a/runtime/indent/testdir/vim.in +++ b/runtime/indent/testdir/vim.in @@ -1,7 +1,6 @@ " vim: set ft=vim sw=4 : " START_INDENT - func Some() let x = 1 endfunc @@ -15,15 +14,6 @@ let x = [ \ ] endif -" TODO: add searchpair() to find matching { -"for x in [ -"{ -"key: 'value' -"}, -"] -"eval 0 -"endfor - for x in [ {key: 'value'}, ] @@ -37,12 +27,11 @@ let t = [ \ ] def Func() - var d = dd - ->extend({ - }) - eval 0 +var d = dd +->extend({ +}) +eval 0 enddef - " END_INDENT " START_INDENT @@ -84,7 +73,7 @@ endfunc " START_INDENT " INDENT_NEXT next-line func Some() - " next-line + " next-line let f = x endfunc " END_INDENT @@ -104,6 +93,12 @@ END " END_INDENT " START_INDENT +let a =<< trim END +nothing +END +" END_INDENT + +" START_INDENT " INDENT_AT this-line let a=<< trim END blah @@ -111,3 +106,754 @@ let a=<< trim END blah this-line END " END_INDENT + +" START_INDENT +if v:true +echo 0 +end +" END_INDENT + +" START_INDENT +var result = Func( +arg1, +arg2 +) +" END_INDENT + +" START_INDENT +var result = Func(arg1, +arg2) +" END_INDENT + +" START_INDENT +filter(list, (k, v) => +v > 0) +" END_INDENT + +" START_INDENT +filter(list, (k, v) => { +const x = get(list, k, 0) +return x > 0 +}) +" END_INDENT + +" START_INDENT +if x > 0 +filter(list, (k, v) => { +const x = get(list, k, 1) +return x > 0 +}) +endif +" END_INDENT + +" START_INDENT +{ +var temp = 'temp' +} +" END_INDENT + +" START_INDENT +var text = lead +.. middle +.. end +" END_INDENT + +" START_INDENT +var text = lead .. +middle .. +end +" END_INDENT + +" START_INDENT +var total = start + +end - +correction +" END_INDENT + +" START_INDENT +var result = start +:+ print +" END_INDENT + +" START_INDENT +var result = positive +? PosFunc(arg) +: NegFunc(arg) +" END_INDENT + +" START_INDENT +var result = GetBuilder() +->BuilderSetWidth(333) +->BuilderSetHeight(777) +->BuilderBuild() +" END_INDENT + +" START_INDENT +var result = MyDict +.member +" END_INDENT + +" START_INDENT +autocmd BufNewFile *.match if condition +| echo 'match' +| endif +" END_INDENT + +" START_INDENT +set cpo+=C +var lines =<< trim END +| this works +END +set cpo-=C +" END_INDENT + +" START_INDENT +syn region Text +\ start='foo' +#\ comment +\ end='bar' +" END_INDENT + +" START_INDENT +au CursorHold * echom 'BEFORE bar' +#\ some comment +| echom 'AFTER bar' +" END_INDENT + +" START_INDENT +def MyFunc(text: string, +separator = '-' +): string +enddef +" END_INDENT + +" START_INDENT +def MyFunc( +text: string, +separator = '-' +): string +enddef +" END_INDENT + +" START_INDENT +[var1, var2] = +Func() +" END_INDENT + +" START_INDENT +const list = ['one', +'two'] +" END_INDENT + +" START_INDENT +const list = [ +'one', +'two', +] +" END_INDENT + +" START_INDENT +const dict = {one: 1, +two: 2 +} +" END_INDENT + +" START_INDENT +const dict = { +one: 1, +two: 2 +} +" END_INDENT + +" START_INDENT +if true +const dict = +{ +one: 1, +two: 2 +} +endif +" END_INDENT + +" START_INDENT +def Func() +return { +one: 1 +} +enddef +" END_INDENT + +" START_INDENT +echo { +a: 0, +# b +# c +} +" END_INDENT + +" START_INDENT +echo search( +# comment +'1' +.. '2' +) +" END_INDENT + +" START_INDENT +if true +var v = ( # trailing "(" starts line continuation +3 + 4 # nothing special +) # end of expression indicates continued line +var x: number # needs to align with previous "var" +endif +" END_INDENT + +" START_INDENT +def Func() # {{{ +# comment +if true +return +endif +enddef +" END_INDENT + +" START_INDENT +echo { +key: +'value', +} +" END_INDENT + +" START_INDENT +var id = time +->timer_start((_) => { +n = 0 +}) +" END_INDENT + +" START_INDENT +augroup Name +autocmd! +augroup END +" END_INDENT + +" START_INDENT +var n = +# comment +1 ++ 2 + +var s = '' +" END_INDENT + +" START_INDENT +var keys = { +J: 'j', +"\<Home>": '1G', +"\<End>": 'G', +z: 'zz' +} +" END_INDENT + +" START_INDENT +export def Func( +n: number, +s: string, +...l: list<bool> +) +enddef +" END_INDENT + +" START_INDENT +var heredoc =<< trim ENDD +var nested_heredoc =<< trim END +END +ENDD +" END_INDENT + +" START_INDENT +if true +else " comment +endif +" END_INDENT + +" START_INDENT +if true | echo 'one' | endif +if true | echo 'two' | endif +if true | echo 'three' | endif +" END_INDENT + +" START_INDENT +if true +:'<-1 mark < +else +echo '' +endif +" END_INDENT + +" START_INDENT +substitute/pat /rep / +echo +" END_INDENT + +" START_INDENT +try +echo 1 +catch /pat / # comment +echo 2 +endtry +" END_INDENT + +" START_INDENT +def Func() +Cmd % +enddef +" END_INDENT + +" START_INDENT +if end == 'xxx' || end == 'yyy' +echo +endif +" END_INDENT + +" START_INDENT +if true +popup_move(id, {col: 1, +line: 2}) +endif +setwinvar(id, 'name', 3) +" END_INDENT + +" START_INDENT +var d = [ +{a: 'x', +b: 'y'}, +FuncA(), +FuncB(), +] +" END_INDENT + +" START_INDENT +var ll = [[ +1, +2, +3], [ +4, +5, +6], [ +7, +8, +9]] +" END_INDENT + +" START_INDENT +var ld = [{ +a: 'xxx', +b: 'yyy'}, { +c: 'xxx', +d: 'yyy'}, { +e: 'xxx', +f: 'yyy'}, { +}] +" END_INDENT + +" START_INDENT +var d = { +a: { +b: { +c: [{ +d: 'e', +f: 'g', +h: 'i' +}], +j: 'k', +}, +}, +} +" END_INDENT + +" START_INDENT +if true +var end: any +if true +end = 0 +elseif true +echo +endif +endif +" END_INDENT + +" START_INDENT +nunmap <buffer> ( +nunmap <buffer> ) +inoremap [ { +inoremap ] } +silent! xunmap i{ +silent! xunmap a{ +" END_INDENT + +" START_INDENT +def Func( +s: string, +n = 1, +m = 2 +) +enddef +" END_INDENT + +" START_INDENT +var h =<< END +text +END + +def Func() +echo +enddef +" END_INDENT + +" START_INDENT +def Func() +var h =<< END +text +END +echo 'test' +enddef +" END_INDENT + +" START_INDENT +def Foo() +lcd - +enddef +def Bar() +echo +enddef +" END_INDENT + +" START_INDENT +if true +n = Func(1, 2, +3) +endif +" END_INDENT + +" START_INDENT +def Func(s: string, +n: number): bool +if true +return false +endif +enddef +" END_INDENT + +" START_INDENT +def Func( +n: number) +# +echo +enddef +" END_INDENT + +" START_INDENT +" INDENT_AT this-line +def Func( + n: number) + # +echo # this-line +enddef +" END_INDENT + +" START_INDENT +if true +if true +normal! == +endif +endif +" END_INDENT + +" START_INDENT +var d = { +a: () => true, +b: () => true +&& true +&& Foo(), +c: () => Bar(), +e: () => Baz(), +} +" END_INDENT + +" START_INDENT +def Select(Cont: func(func(any)), Pred: func(any): bool): func(func(any)) +return (Emit: func(any)) => { +Cont((t: any) => { +if Pred(t) +Emit(t) +endif +}) +} +enddef +" END_INDENT + +" START_INDENT +" INDENT_EXE let g:vim_indent = {'more_in_bracket_block': v:true} +def Select(Cont: func(func(any)), Pred: func(any): bool): func(func(any)) +return (Emit: func(any)) => { +Cont((t: any) => { +if Pred(t) +Emit(t) +endif +}) +} +enddef +" END_INDENT + +" START_INDENT +" INDENT_EXE unlet! g:vim_indent +" END_INDENT + +" START_INDENT +g:lightline = { +'active': { +'left': [ [ 'mode', 'paste' ], [ 'readonly', 'relativepath', 'modified' ] ], +}, +'inactive': { +'left': [ [ 'readonly', 'relativepath', 'modified' ] ], +} +} +" END_INDENT + +" START_INDENT +if getline(1, 10) +->map((_, v: string): number => strcharlen(v)) +->max() > 1'000 +&l:breakindent = false +&l:linebreak = false +else +&l:breakindent = true +&l:linebreak = true +endif +" END_INDENT + +" START_INDENT +var ext2cmd: dict<string> = { +doc: $'antiword {fname}', +docx: $'pandoc --from=docx --to=markdown {fname}', +epub: $'pandoc --from=epub --to=markdown {fname}', +odp: $'odt2txt {fname}', +odt: $'odt2txt {fname}', +pdf: $'pdftotext -nopgbrk -layout -q -eol unix {fname} -', +rtf: 'unrtf --text', +} +" END_INDENT + +" START_INDENT +const ptybuf: number = term_start(&shell, { +hidden: true, +exit_cb: (_, _) => { +if true +close +else |