Update runtime files

This commit is contained in:
Bram Moolenaar
2022-09-27 17:30:34 +01:00
parent 26f09ea54b
commit 9fbdbb814f
45 changed files with 4223 additions and 379 deletions

View File

@ -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

7
runtime/indent/gyp.vim Normal file
View File

@ -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

138
runtime/indent/hare.vim Normal file
View File

@ -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

442
runtime/indent/solidity.vim Normal file
View File

@ -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

View File

@ -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
@ -103,6 +92,12 @@ nothing
END
" END_INDENT
" START_INDENT
let a =<< trim END
nothing
END
" END_INDENT
" START_INDENT
" INDENT_AT this-line
let a=<< trim END
@ -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
help
endif
}
})
" END_INDENT
" START_INDENT
var d = {
a: 0,
# a ' quote {{{
#}}}
b: 0,
}
" END_INDENT
" START_INDENT
echo printf('%s () %s',
1,
2
)
" END_INDENT
" START_INDENT
prop_add(1, col('.'), {
length: 2,
type: 'test'
})
" END_INDENT
" START_INDENT
echo (() => " string starting with space")()
echo
" END_INDENT
" START_INDENT
var variables = deepcopy(g:)
->filter((k: string, _): bool =>
k =~ '\c\V' .. keyword->escape('\')
&& k !~ '\%(loaded\|did_plugin_\)')
->items()
->map((_, v): string => v[0] .. ' = ' .. string(v[1]))
new
" END_INDENT
" START_INDENT
var d = freq
->map((_, v) =>
v * (
1
+ 2
))
for item in d
->items()
->sort((a, b) => b[1] - a[1])
echo
endfor
" END_INDENT
" START_INDENT
make_job = job_start([&shell, &shellcmdflag, make_cmd], {
callback: function(MakeProcessOutput, [qfid]),
close_cb: function(MakeCloseCb, [qfid]),
exit_cb: MakeCompleted,
in_io: 'null'
})
" END_INDENT
" START_INDENT
var matching_abbrev: list<dict<string>> = copy(ABBREV)
->filter((_, v: dict<string>): bool =>
stridx(v.lhs, word_to_complete) == 0)
->map((_, v: dict<string>) => ({
word: v.lhs,
menu: AbbrevRhs(v.rhs)->stridx('expand_') >= 0
? AbbrevRhs(v.rhs)->matchstr('.*,\s*''\zs.*\ze'')')
: AbbrevRhs(v.rhs)
}))
" END_INDENT
" START_INDENT
def Func()
if true
vimgrep /^\C\s*\%(fu\%[nction]\|def\)\s\+/ file
endif
enddef
" END_INDENT
" START_INDENT
setlocal iskeyword+=[
cword = expand('<cword>')
" END_INDENT
" START_INDENT
silent if true
echo
endif
" END_INDENT
" START_INDENT
def Func()
sort :^.*[\/]:
enddef
" END_INDENT
" START_INDENT
def Func()
d = {
}
hd =<< trim END
['
]'
END
enddef
" END_INDENT
" START_INDENT
def Func()
if true
var hd =<< trim END
if get(b:, 'current_syntax', '')
endif
END
elseif true
echo
endif
enddef
" END_INDENT
" START_INDENT
# test for control-flow keyword followed by commented fold marker {{{
if true
echo
endif #}}}
" END_INDENT
" START_INDENT
if winsz == 0|let winsz= ""|endif
exe "noswapfile ".winsz."wincmd s"
" END_INDENT
" START_INDENT
if true
if true
windo if true | echo | endif
augroup Name
autocmd WinLeave * if true | eval 1 + 2 | endif
augroup END
endif
endif
" END_INDENT
" START_INDENT
if true
echo ' =<< trim END'
->len()
endif
" END_INDENT
" START_INDENT
function Func()
if true
if true
if true | echo com | endif
if true | echo com | endif
endif
else
endif
endfunction
" END_INDENT
" START_INDENT
function Func()
if v:true
+
echo
-
endif
endfunction
" END_INDENT
" START_INDENT
var matchpairs: string = &matchpairs
var pairs: dict<list<string>>
for [opening: string, closing: string]
in matchpairs
->split(',')
->map((_, v: string): list<string> => split(v, ':'))
pairs[opening] = [escape(opening, '[]'), escape(closing, '[]'), 'nW', 'w$']
pairs[closing] = [escape(opening, '[]'), escape(closing, '[]'), 'bnW', 'w0']
endfor
" END_INDENT
" START_INDENT
{
echo []
+ []
+ [{a: 1,
b: 2}]
}
" END_INDENT
" START_INDENT
silent! argdel *
edit file
" END_INDENT

View File

@ -1,7 +1,6 @@
" vim: set ft=vim sw=4 :
" START_INDENT
func Some()
let x = 1
endfunc
@ -15,15 +14,6 @@ if 1
\ ]
endif
" TODO: add searchpair() to find matching {
"for x in [
"{
"key: 'value'
"},
"]
"eval 0
"endfor
for x in [
{key: 'value'},
]
@ -38,11 +28,10 @@ let t = [
def Func()
var d = dd
->extend({
})
->extend({
})
eval 0
enddef
" END_INDENT
" START_INDENT
@ -69,7 +58,7 @@ let list = [
let list = [
'one',
'two',
]
]
echo
" END_INDENT
@ -84,8 +73,8 @@ endfunc
" START_INDENT
" INDENT_NEXT next-line
func Some()
" next-line
let f = x
" next-line
let f = x
endfunc
" END_INDENT
@ -99,6 +88,12 @@ endfunc
" START_INDENT
let a =<< END
nothing
END
" END_INDENT
" START_INDENT
let a =<< trim END
nothing
END
" END_INDENT
@ -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
help
endif
}
})
" END_INDENT
" START_INDENT
var d = {
a: 0,
# a ' quote {{{
#}}}
b: 0,
}
" END_INDENT
" START_INDENT
echo printf('%s () %s',
1,
2
)
" END_INDENT
" START_INDENT
prop_add(1, col('.'), {
length: 2,
type: 'test'
})
" END_INDENT
" START_INDENT
echo (() => " string starting with space")()
echo
" END_INDENT
" START_INDENT
var variables = deepcopy(g:)
->filter((k: string, _): bool =>
k =~ '\c\V' .. keyword->escape('\')
&& k !~ '\%(loaded\|did_plugin_\)')
->items()
->map((_, v): string => v[0] .. ' = ' .. string(v[1]))
new
" END_INDENT
" START_INDENT
var d = freq
->map((_, v) =>
v * (
1
+ 2
))
for item in d
->items()
->sort((a, b) => b[1] - a[1])
echo
endfor
" END_INDENT
" START_INDENT
make_job = job_start([&shell, &shellcmdflag, make_cmd], {
callback: function(MakeProcessOutput, [qfid]),
close_cb: function(MakeCloseCb, [qfid]),
exit_cb: MakeCompleted,
in_io: 'null'
})
" END_INDENT
" START_INDENT
var matching_abbrev: list<dict<string>> = copy(ABBREV)
->filter((_, v: dict<string>): bool =>
stridx(v.lhs, word_to_complete) == 0)
->map((_, v: dict<string>) => ({
word: v.lhs,
menu: AbbrevRhs(v.rhs)->stridx('expand_') >= 0
? AbbrevRhs(v.rhs)->matchstr('.*,\s*''\zs.*\ze'')')
: AbbrevRhs(v.rhs)
}))
" END_INDENT
" START_INDENT
def Func()
if true
vimgrep /^\C\s*\%(fu\%[nction]\|def\)\s\+/ file
endif
enddef
" END_INDENT
" START_INDENT
setlocal iskeyword+=[
cword = expand('<cword>')
" END_INDENT
" START_INDENT
silent if true
echo
endif
" END_INDENT
" START_INDENT
def Func()
sort :^.*[\/]:
enddef
" END_INDENT
" START_INDENT
def Func()
d = {
}
hd =<< trim END
['
]'
END
enddef
" END_INDENT
" START_INDENT
def Func()
if true
var hd =<< trim END
if get(b:, 'current_syntax', '')
endif
END
elseif true
echo
endif
enddef
" END_INDENT
" START_INDENT
# test for control-flow keyword followed by commented fold marker {{{
if true
echo
endif #}}}
" END_INDENT
" START_INDENT
if winsz == 0|let winsz= ""|endif
exe "noswapfile ".winsz."wincmd s"
" END_INDENT
" START_INDENT
if true
if true
windo if true | echo | endif
augroup Name
autocmd WinLeave * if true | eval 1 + 2 | endif
augroup END
endif
endif
" END_INDENT
" START_INDENT
if true
echo ' =<< trim END'
->len()
endif
" END_INDENT
" START_INDENT
function Func()
if true
if true
if true | echo com | endif
if true | echo com | endif
endif
else
endif
endfunction
" END_INDENT
" START_INDENT
function Func()
if v:true
+
echo
-
endif
endfunction
" END_INDENT
" START_INDENT
var matchpairs: string = &matchpairs
var pairs: dict<list<string>>
for [opening: string, closing: string]
in matchpairs
->split(',')
->map((_, v: string): list<string> => split(v, ':'))
pairs[opening] = [escape(opening, '[]'), escape(closing, '[]'), 'nW', 'w$']
pairs[closing] = [escape(opening, '[]'), escape(closing, '[]'), 'bnW', 'w0']
endfor
" END_INDENT
" START_INDENT
{
echo []
+ []
+ [{a: 1,
b: 2}]
}
" END_INDENT
" START_INDENT
silent! argdel *
edit file
" END_INDENT

View File

@ -1,214 +1,22 @@
" Vim indent file
" Language: Vim script
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2022 Jun 24
vim9script
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
# Vim indent file
# Language: Vim script
# Maintainer: Bram Moolenaar <Bram@vim.org>
# Last Change: 2022 Sep 27
# Only load this indent file when no other was loaded.
if exists('b:did_indent')
finish
endif
let b:did_indent = 1
setlocal indentexpr=GetVimIndent()
setlocal indentkeys+==endif,=enddef,=endfu,=endfor,=endwh,=endtry,=},=else,=cat,=finall,=END,0\\,0=\"\\\
b:did_indent = true
b:undo_indent = 'setlocal indentkeys< indentexpr<'
import autoload '../autoload/dist/vimindent.vim'
setlocal indentexpr=vimindent.Expr(v:lnum)
setlocal indentkeys+==endif,=enddef,=endfu,=endfor,=endwh,=endtry,=},=else,=cat,=finall,=END,0\\
execute('setlocal indentkeys+=0=\"\\\ ,0=#\\\ ')
setlocal indentkeys-=0#
setlocal indentkeys-=:
let b:undo_indent = "setl indentkeys< indentexpr<"
" Only define the function once.
if exists("*GetVimIndent")
finish
endif
let s:keepcpo= &cpo
set cpo&vim
function GetVimIndent()
let ignorecase_save = &ignorecase
try
let &ignorecase = 0
return GetVimIndentIntern()
finally
let &ignorecase = ignorecase_save
endtry
endfunc
" Legacy script line continuation and Vim9 script operators that must mean an
" expression that continues from the previous line.
let s:lineContPat = '^\s*\(\\\|"\\ \|->\)'
function GetVimIndentIntern()
" If the current line has line continuation and the previous one too, use
" the same indent. This does not skip empty lines.
let cur_text = getline(v:lnum)
let cur_has_linecont = cur_text =~ s:lineContPat
if cur_has_linecont && v:lnum > 1 && getline(v:lnum - 1) =~ s:lineContPat
return indent(v:lnum - 1)
endif
" 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.
if !cur_has_linecont
while lnum > 0 && getline(lnum) =~ s:lineContPat
let lnum = lnum - 1
endwhile
endif
" At the start of the file use zero indent.
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
let ind = ind + shiftwidth() * 3
endif
elseif prev_text =~ '^\s*aug\%[roup]\s\+' && prev_text !~ '^\s*aug\%[roup]\s\+[eE][nN][dD]\>'
let ind = ind + shiftwidth()
else
" A line starting with :au does not increment/decrement indent.
" A { may start a block or a dict. Assume that when a } follows it's a
" terminated dict.
" ":function" starts a block but "function(" doesn't.
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]\|def\|el\%[seif]\)\>\|fu\%[nction][! ]\)')
if i >= 0
let ind += shiftwidth()
if strpart(prev_text, i, 1) == '|' && has('syntax_items')
\ && synIDattr(synID(lnum, i, 1), "name") =~ '\(Comment\|String\|PatSep\)$'
let ind -= shiftwidth()
endif
endif
endif
endif
" If the previous line contains an "end" after a pipe, but not in an ":au"
" command. And not when there is a backslash before the pipe.
" And when syntax HL is enabled avoid a match inside a string.
let i = match(prev_text, '[^\\]|\s*\(ene\@!\)')
if i > 0 && prev_text !~ '^\s*au\%[tocmd]'
if !has('syntax_items') || synIDattr(synID(lnum, i + 2, 1), "name") !~ '\(Comment\|String\)$'
let ind = ind - shiftwidth()
endif
endif
" For a line starting with "}" find the matching "{". Align with that line,
" it is either the matching block start or dictionary start.
" 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
let ind = indent('.')
endif
else
" todo: use searchpair() to find a match
endif
endif
" Look back for a line to align with
while lnum > 1
" Below a line starting with "}" find the matching "{".
if prev_text =~ '^\s*}'
if maparg('%') != ''
exe lnum
silent! normal %
if line('.') < lnum
let lnum = line('.')
let ind = indent(lnum)
let prev_text = getline(lnum)
else
break
endif
else
" todo: use searchpair() to find a match
break
endif
elseif prev_text =~ s:lineContPat
" looks like a continuation like, go back one line
let lnum = lnum - 1
let ind = indent(lnum)
let prev_text = getline(lnum)
else
break
endif
endwhile
" 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, :endfor, :catch, :finally,
" :endtry, :endfun, :enddef, :else and :augroup END.
" Although ":en" would be enough only match short command names as in
" 'indentkeys'.
if cur_text =~ '^\s*\(endif\|endwh\|endfor\|endtry\|endfu\|enddef\|cat\|finall\|else\|aug\%[roup]\s\+[eE][nN][dD]\)'
let ind = ind - shiftwidth()
if ind < 0
let ind = 0
endif
endif
return ind
endfunction
let &cpo = s:keepcpo
unlet s:keepcpo
" vim:sw=2

12
runtime/indent/vue.vim Normal file
View File

@ -0,0 +1,12 @@
" Vim indent file placeholder
" Language: Vue
" Maintainer: None, please volunteer if you have a real Vue indent script
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
" Html comes closest
runtime! indent/html.vim