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 # Language: Vim script
# Maintainer: github user lacygoill # Maintainer: github user lacygoill
# Last Change: 2025 Apr 13 # Last Change: 2025 Jul 25
# #
# Includes changes from The Vim Project: # 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: # 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', {}) if get(g:, 'vim_indent', {})
->get('more_in_bracket_block', false) ->get('more_in_bracket_block', false)
return shiftwidth() return shiftwidth()
else
return 0
endif endif
return 0
enddef enddef
def IndentMoreLineContinuation(): number # {{{2 def IndentMoreLineContinuation(): number # {{{2
@ -35,9 +31,8 @@ def IndentMoreLineContinuation(): number # {{{2
if n->typename() == 'string' if n->typename() == 'string'
return n->eval() return n->eval()
else
return n
endif endif
return n
enddef enddef
# }}}2 # }}}2
@ -145,7 +140,7 @@ const HEREDOC_OPERATOR: string = '\s=<<\s\@=\%(\s\+\%(trim\|eval\)\)\{,2}'
# A better regex would be: # 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. # But sometimes, it can be too costly and cause `E363` to be given.
const PATTERN_DELIMITER: string = '[-+*/%]\%(=\s\)\@!' const PATTERN_DELIMITER: string = '[-+*/%]\%(=\s\)\@!'
@ -193,10 +188,9 @@ const MODIFIERS: dict<string> = {
patterns =<< trim eval END patterns =<< trim eval END
argdo\>!\= argdo\>!\=
bufdo\>!\= bufdo\>!\=
cdo\>!\= [cl]f\=do\>!\=
folddoc\%[losed]\> folddoc\%[losed]\>
foldd\%[oopen]\> foldd\%[oopen]\>
ldo\=\>!\=
tabdo\=\> tabdo\=\>
windo\> windo\>
au\%[tocmd]\>!\=.* au\%[tocmd]\>!\=.*
@ -290,9 +284,9 @@ patterns = []
for kwds: list<string> in BLOCKS for kwds: list<string> in BLOCKS
for kwd: string in kwds[0 : -2] for kwd: string in kwds[0 : -2]
if MODIFIERS->has_key(kwd->Unshorten()) if MODIFIERS->has_key(kwd->Unshorten())
patterns += [$'\%({MODIFIERS[kwd]}\)\={kwd}'] patterns->add($'\%({MODIFIERS[kwd]}\)\={kwd}')
else else
patterns += [kwd] patterns->add(kwd)
endif endif
endfor endfor
endfor endfor
@ -348,7 +342,8 @@ patterns =<< trim eval END
{'\'}<argd\%[elete]\s\+\*\s*$ {'\'}<argd\%[elete]\s\+\*\s*$
\<[lt]\=cd!\=\s\+-\s*$ \<[lt]\=cd!\=\s\+-\s*$
\<norm\%[al]!\=\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} {PLUS_MINUS_COMMAND}
END END
@ -430,6 +425,9 @@ export def Expr(lnum = v:lnum): number # {{{2
elseif line_A.lnum->IsRightBelow('HereDoc') elseif line_A.lnum->IsRightBelow('HereDoc')
var ind: number = b:vimindent.startindent var ind: number = b:vimindent.startindent
unlet! b:vimindent unlet! b:vimindent
if line_A.text =~ ENDS_BLOCK_OR_CLAUSE
return ind - shiftwidth()
endif
return ind return ind
endif endif
@ -444,9 +442,8 @@ export def Expr(lnum = v:lnum): number # {{{2
if line_A.text =~ BACKSLASH_AT_SOL if line_A.text =~ BACKSLASH_AT_SOL
if line_B.text =~ BACKSLASH_AT_SOL if line_B.text =~ BACKSLASH_AT_SOL
return Indent(line_B.lnum) return Indent(line_B.lnum)
else
return Indent(line_B.lnum) + IndentMoreLineContinuation()
endif endif
return Indent(line_B.lnum) + IndentMoreLineContinuation()
endif endif
if line_A->AtStartOf('FuncHeader') if line_A->AtStartOf('FuncHeader')
@ -459,9 +456,8 @@ export def Expr(lnum = v:lnum): number # {{{2
unlet! b:vimindent unlet! b:vimindent
if line_A.text =~ ENDS_FUNCTION if line_A.text =~ ENDS_FUNCTION
return startindent return startindent
else
return startindent + shiftwidth()
endif endif
return startindent + shiftwidth()
endif endif
var past_bracket_block: dict<any> 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 if line_B.text =~ STARTS_CURLY_BLOCK
return Indent(line_B.lnum) + shiftwidth() + IndentMoreInBracketBlock() 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) var start: number = MatchingOpenBracket(line_A)
if start <= 0 if start <= 0
return -1 return -1
@ -565,9 +562,8 @@ export def Expr(lnum = v:lnum): number # {{{2
var block_start: number = SearchPairStart(start, middle, end) var block_start: number = SearchPairStart(start, middle, end)
if block_start > 0 if block_start > 0
return Indent(block_start) return Indent(block_start)
else
return -1
endif endif
return -1
endif endif
var base_ind: number var base_ind: number
@ -591,8 +587,7 @@ export def Expr(lnum = v:lnum): number # {{{2
endif endif
endif endif
var ind: number = base_ind + Offset(line_A, line_B) return base_ind + Offset(line_A, line_B)
return [ind, 0]->max()
enddef enddef
def g:GetVimIndent(): number # {{{2 def g:GetVimIndent(): number # {{{2
@ -611,29 +606,31 @@ def Offset( # {{{2
if line_B->AtStartOf('FuncHeader') if line_B->AtStartOf('FuncHeader')
&& IsInInterface() && IsInInterface()
return 0 return 0
endif
# increase indentation inside a block # increase indentation inside a block
elseif line_B.text =~ STARTS_NAMED_BLOCK if line_B.text =~ STARTS_NAMED_BLOCK
|| line_B->EndsWithCurlyBlock() || line_B->EndsWithCurlyBlock()
# But don't indent if the line starting the block also closes it. # But don't indent if the line starting the block also closes it.
if line_B->AlsoClosesBlock() if line_B->AlsoClosesBlock()
return 0 return 0
endif
# Indent twice for a line continuation in the block header itself, so that # 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 # we can easily distinguish the end of the block header from the start of
# the block body. # the block body.
elseif (line_B->EndsWithLineContinuation() if (line_B->EndsWithLineContinuation()
&& !line_A.isfirst) && !line_A.isfirst)
|| (line_A.text =~ LINE_CONTINUATION_AT_SOL || (line_A.text =~ LINE_CONTINUATION_AT_SOL
&& line_A.text !~ PLUS_MINUS_COMMAND) && line_A.text !~ PLUS_MINUS_COMMAND)
|| line_A.text->Is_IN_KeywordForLoop(line_B.text) || line_A.text->Is_IN_KeywordForLoop(line_B.text)
return 2 * shiftwidth() return 2 * shiftwidth()
else
return shiftwidth()
endif endif
return shiftwidth()
endif
# increase indentation of a line if it's the continuation of a command which # increase indentation of a line if it's the continuation of a command which
# started on a previous line # started on a previous line
elseif !line_A.isfirst if !line_A.isfirst
&& (line_B->EndsWithLineContinuation() && (line_B->EndsWithLineContinuation()
|| line_A.text =~ LINE_CONTINUATION_AT_SOL) || line_A.text =~ LINE_CONTINUATION_AT_SOL)
&& !(line_B->EndsWithComma() && line_A.lnum->IsInside('EnumBlock')) && !(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 # will need to be indented relative to the start of the heredoc. It
# must know where it starts; it needs the cache. # must know where it starts; it needs the cache.
return 0 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 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 endif
# In a non-trimmed heredoc, all of leading whitespace is semantic. # 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 b:vimindent.startindent = new_startindent
endif endif
return [0, Indent(v:lnum) + b:vimindent.offset]->max() return Indent(v:lnum) + b:vimindent.offset
enddef enddef
def CommentIndent(): number # {{{2 def CommentIndent(): number # {{{2
@ -727,9 +723,8 @@ def CommentIndent(): number # {{{2
endif endif
if getline(next) =~ ENDS_BLOCK if getline(next) =~ ENDS_BLOCK
return ind + shiftwidth() return ind + shiftwidth()
else
return ind
endif endif
return ind
enddef enddef
def BracketBlockIndent(line_A: dict<any>, block: dict<any>): number # {{{2 def BracketBlockIndent(line_A: dict<any>, block: dict<any>): number # {{{2

View File

@ -196,3 +196,25 @@ silent! function Bar()
return 42 return 42
endfunction endfunction
" END_INDENT " 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 return 42
endfunction endfunction
" END_INDENT " 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