runtime(vim): fix various indentation issues

fixes: #15123
closes: #17849

Signed-off-by: lacygoill <lacygoill@lacygoill.me>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
lacygoill
2025-07-25 18:16:09 +02:00
committed by Christian Brabandt
parent 1a2c4932a3
commit 827483054d
3 changed files with 75 additions and 36 deletions

View File

@ -2,12 +2,9 @@ vim9script
# Language: Vim script
# Maintainer: github user lacygoill
# Last Change: 2025 Apr 13
# Last Change: 2025 Jul 25
#
# Includes changes from The Vim Project:
# - 2024 Feb 09: Fix indent after literal Dict (A. Radev via #13966)
# - 2024 Nov 08: Fix indent after :silent! function (D. Kearns via #16009)
# - 2024 Dec 26: Fix indent for enums (Jim Zhou via #16293)
# NOTE: Whenever you change the code, make sure the tests are still passing:
#
@ -23,9 +20,8 @@ def IndentMoreInBracketBlock(): number # {{{2
if get(g:, 'vim_indent', {})
->get('more_in_bracket_block', false)
return shiftwidth()
else
return 0
endif
return 0
enddef
def IndentMoreLineContinuation(): number # {{{2
@ -35,9 +31,8 @@ def IndentMoreLineContinuation(): number # {{{2
if n->typename() == 'string'
return n->eval()
else
return n
endif
return n
enddef
# }}}2
@ -145,7 +140,7 @@ const HEREDOC_OPERATOR: string = '\s=<<\s\@=\%(\s\+\%(trim\|eval\)\)\{,2}'
# A better regex would be:
#
# [^-+*/%.:# \t[:alnum:]\"|]\@=.\|->\@!\%(=\s\)\@!\|[+*/%]\%(=\s\)\@!
# [^-+*/%.:#[:blank:][:alnum:]\"|]\|->\@!\%(=\s\)\@!\|[+*/%]\%(=\s\)\@!
#
# But sometimes, it can be too costly and cause `E363` to be given.
const PATTERN_DELIMITER: string = '[-+*/%]\%(=\s\)\@!'
@ -193,10 +188,9 @@ const MODIFIERS: dict<string> = {
patterns =<< trim eval END
argdo\>!\=
bufdo\>!\=
cdo\>!\=
[cl]f\=do\>!\=
folddoc\%[losed]\>
foldd\%[oopen]\>
ldo\=\>!\=
tabdo\=\>
windo\>
au\%[tocmd]\>!\=.*
@ -290,9 +284,9 @@ patterns = []
for kwds: list<string> in BLOCKS
for kwd: string in kwds[0 : -2]
if MODIFIERS->has_key(kwd->Unshorten())
patterns += [$'\%({MODIFIERS[kwd]}\)\={kwd}']
patterns->add($'\%({MODIFIERS[kwd]}\)\={kwd}')
else
patterns += [kwd]
patterns->add(kwd)
endif
endfor
endfor
@ -348,7 +342,8 @@ patterns =<< trim eval END
{'\'}<argd\%[elete]\s\+\*\s*$
\<[lt]\=cd!\=\s\+-\s*$
\<norm\%[al]!\=\s*\S\+$
\%(\<sil\%[ent]!\=\s\+\)\=\<[nvxsoilct]\=\%(nore\|un\)map!\=\s
\%(\<sil\%[ent]!\=\s\+\)\=\<[nvxsoilct]\=\%(nore\|un\)\=map!\=\s
\<set\%(\%[global]\|\%[local]\)\>.*,$
{PLUS_MINUS_COMMAND}
END
@ -430,6 +425,9 @@ export def Expr(lnum = v:lnum): number # {{{2
elseif line_A.lnum->IsRightBelow('HereDoc')
var ind: number = b:vimindent.startindent
unlet! b:vimindent
if line_A.text =~ ENDS_BLOCK_OR_CLAUSE
return ind - shiftwidth()
endif
return ind
endif
@ -444,9 +442,8 @@ export def Expr(lnum = v:lnum): number # {{{2
if line_A.text =~ BACKSLASH_AT_SOL
if line_B.text =~ BACKSLASH_AT_SOL
return Indent(line_B.lnum)
else
return Indent(line_B.lnum) + IndentMoreLineContinuation()
endif
return Indent(line_B.lnum) + IndentMoreLineContinuation()
endif
if line_A->AtStartOf('FuncHeader')
@ -459,9 +456,8 @@ export def Expr(lnum = v:lnum): number # {{{2
unlet! b:vimindent
if line_A.text =~ ENDS_FUNCTION
return startindent
else
return startindent + shiftwidth()
endif
return startindent + shiftwidth()
endif
var past_bracket_block: dict<any>
@ -542,8 +538,9 @@ export def Expr(lnum = v:lnum): number # {{{2
if line_B.text =~ STARTS_CURLY_BLOCK
return Indent(line_B.lnum) + shiftwidth() + IndentMoreInBracketBlock()
endif
elseif line_A.text =~ CLOSING_BRACKET_AT_SOL
if line_A.text =~ CLOSING_BRACKET_AT_SOL
var start: number = MatchingOpenBracket(line_A)
if start <= 0
return -1
@ -565,9 +562,8 @@ export def Expr(lnum = v:lnum): number # {{{2
var block_start: number = SearchPairStart(start, middle, end)
if block_start > 0
return Indent(block_start)
else
return -1
endif
return -1
endif
var base_ind: number
@ -591,8 +587,7 @@ export def Expr(lnum = v:lnum): number # {{{2
endif
endif
var ind: number = base_ind + Offset(line_A, line_B)
return [ind, 0]->max()
return base_ind + Offset(line_A, line_B)
enddef
def g:GetVimIndent(): number # {{{2
@ -611,29 +606,31 @@ def Offset( # {{{2
if line_B->AtStartOf('FuncHeader')
&& IsInInterface()
return 0
endif
# increase indentation inside a block
elseif line_B.text =~ STARTS_NAMED_BLOCK
if line_B.text =~ STARTS_NAMED_BLOCK
|| line_B->EndsWithCurlyBlock()
# But don't indent if the line starting the block also closes it.
if line_B->AlsoClosesBlock()
return 0
endif
# Indent twice for a line continuation in the block header itself, so that
# we can easily distinguish the end of the block header from the start of
# the block body.
elseif (line_B->EndsWithLineContinuation()
if (line_B->EndsWithLineContinuation()
&& !line_A.isfirst)
|| (line_A.text =~ LINE_CONTINUATION_AT_SOL
&& line_A.text !~ PLUS_MINUS_COMMAND)
|| line_A.text->Is_IN_KeywordForLoop(line_B.text)
return 2 * shiftwidth()
else
return shiftwidth()
endif
return shiftwidth()
endif
# increase indentation of a line if it's the continuation of a command which
# started on a previous line
elseif !line_A.isfirst
if !line_A.isfirst
&& (line_B->EndsWithLineContinuation()
|| line_A.text =~ LINE_CONTINUATION_AT_SOL)
&& !(line_B->EndsWithComma() && line_A.lnum->IsInside('EnumBlock'))
@ -653,12 +650,11 @@ def HereDocIndent(line_A: string): number # {{{2
# will need to be indented relative to the start of the heredoc. It
# must know where it starts; it needs the cache.
return 0
else
var ind: number = b:vimindent.startindent
# invalidate the cache so that it's not used for the next heredoc
unlet! b:vimindent
return ind
endif
var ind: number = b:vimindent.startindent
# invalidate the cache so that it's not used for the next heredoc
unlet! b:vimindent
return ind
endif
# In a non-trimmed heredoc, all of leading whitespace is semantic.
@ -700,7 +696,7 @@ def HereDocIndent(line_A: string): number # {{{2
b:vimindent.startindent = new_startindent
endif
return [0, Indent(v:lnum) + b:vimindent.offset]->max()
return Indent(v:lnum) + b:vimindent.offset
enddef
def CommentIndent(): number # {{{2
@ -727,9 +723,8 @@ def CommentIndent(): number # {{{2
endif
if getline(next) =~ ENDS_BLOCK
return ind + shiftwidth()
else
return ind
endif
return ind
enddef
def BracketBlockIndent(line_A: dict<any>, block: dict<any>): number # {{{2

View File

@ -196,3 +196,25 @@ silent! function Bar()
return 42
endfunction
" END_INDENT
" START_INDENT
if true
nmap xxx,
else
endif
" END_INDENT
" START_INDENT
if true
var heredoc =<< END
foo
bar
baz
END
endif
" END_INDENT
" START_INDENT
set path=.,,
set clipboard=unnamed,unnamedplus
" END_INDENT

View File

@ -196,3 +196,25 @@ silent! function Bar()
return 42
endfunction
" END_INDENT
" START_INDENT
if true
nmap xxx,
else
endif
" END_INDENT
" START_INDENT
if true
var heredoc =<< END
foo
bar
baz
END
endif
" END_INDENT
" START_INDENT
set path=.,,
set clipboard=unnamed,unnamedplus
" END_INDENT