vim-patch:90e8cb0: runtime(sh): Fix shFunctionTwo and shFunctionFour definitions for Bash

Claim e.g. "function f () { :; }" as shFunctionTwo while
observing that parentheses after the function name are
optional when the "function" word is used and do not delimit
its body if the latter follows them in "{}" (which should
not be taken for granted with limited backtracking).

closes: vim/vim#20878

90e8cb0094

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
This commit is contained in:
zeertzjq
2026-08-07 12:34:59 +08:00
parent ba823836cf
commit 925ddb190f

View File

@@ -651,9 +651,13 @@ if exists("b:is_bash")
syn match shFunctionCmdOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens
syn match shFunctionCmdTwo "\%#=1\%(\%(\<\k\+\>\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*\%(\<\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" contained skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens
syn match shFunctionOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens
syn match shFunctionTwo "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens
syn match shFunctionThree "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens
syn match shFunctionFour "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(\%(()\ze\)\=\)\@>\_s*((\@!" contained skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens
" Proof against future changes by inducing priority-driven "backtracking"
" between shFunctionFour (goes before) and shFunctionTwo (goes after) so
" that e.g. "function f () {}" is still claimed by shFunctionTwo (observe
" "f[[:blank:]]()").
syn match shFunctionFour "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\%(\%(\s*()\ze\)\=\)\@>\_s*((\@!" contained skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens
syn match shFunctionTwo "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\%(\%(\s*()\ze\)\=\)\@>\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens
" Claim empty array assignments.
syn match shArrayEmptyDecl "\%#=1\ze\%(\<\h\w*=\)\@>()" transparent nextgroup=shVariable
" Claim commented out function declaration headers.