From c165202b79be43c32ae8c5290acc784d5afbcd67 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 16 May 2026 16:26:51 +0800 Subject: [PATCH] vim-patch:f7e239b: runtime(sh): Update syntax, don't include parens in function name highlighting Parentheses are not part of the function name so highlight them differently. closes: vim/vim#20219 https://github.com/vim/vim/commit/f7e239bd0e8eccc78bf93c44cc9e241691153842 Co-authored-by: Doug Kearns --- runtime/syntax/sh.vim | 48 ++++++++++++---------- test/functional/legacy/matchparen_spec.lua | 4 +- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim index d022059d72..41570cce4f 100644 --- a/runtime/syntax/sh.vim +++ b/runtime/syntax/sh.vim @@ -25,6 +25,7 @@ " 2026 Mar 23 improve matching of function definitions #19638 " 2026 Apr 02 improve matching of function definitions #19849 " 2026 Apr 19 improve detection of special variables #20016 +" 2026 May 14 don't highlight parens as part of the function name #20219 " }}} " Version: 208 " Former URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH @@ -665,40 +666,42 @@ endif ShFoldFunctions syn region shFunctionExpr matchgroup=shFunctionExprRegion start="{" end="}" contains=@shFunctionList contained skipwhite skipnl nextgroup=shQuickComment ShFoldFunctions syn region shFunctionSubSh matchgroup=shFunctionSubShRegion start="(" end=")" contains=@shFunctionList contained skipwhite skipnl nextgroup=shQuickComment +syn match shFunctionParens "()" contained + if exists("b:is_bash") syn keyword shFunctionKey coproc - syn match shFunctionCmdOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionCmdTwo "\%#=1\%(\%(\<\k\+\>\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*\%(\<\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" contained skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionTwo "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "\%#=1^\s*\zs\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh - syn match shFunctionFour "\%#=1\%(\%(\<\k\+\|[^()<>|&$;\t ]\+\)\+\)\@>\ze\s*\%(\%(()\ze\)\=\)\@>\_s*((\@!" contained skipwhite skipnl nextgroup=shFunctionSubSh + 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 elseif exists("b:is_ksh88") " AT&T ksh88 - syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr + syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens syn match shFunctionTwo "\<\h\w*\>\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens elseif exists("b:is_mksh") " MirBSD ksh is the wild west of absurd and abstruse function names... - syn match shFunctionCmdOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionTwo "\%#=1\%(\%(\<\w\+\|[@!+.%,:-]\+\)*[-A-Za-z_.%,0-9:]\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionCmdOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionTwo "\%#=1\%(\%(\<\w\+\|[@!+.%,:-]\+\)*[-A-Za-z_.%,0-9:]\)\@>\ze\s*\%(()\ze\)\=\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionThree "^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens elseif exists("b:is_kornshell") " ksh93 - syn match shFunctionCmdOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr + syn match shFunctionCmdOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens syn match shFunctionTwo "\%(\<\h\+\|\.\)[A-Za-z_.0-9]*\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionThree "^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*((\@!" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens syn match shNamespaceOne "\<\h\w*\>\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr else - syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionCmdTwo "\<\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" contained skipwhite skipnl nextgroup=@shFunctionCmds - syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionTwo "\<\h\w*\>\s*()\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr - syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*(" skipwhite skipnl nextgroup=shFunctionSubSh - syn match shFunctionFour "\<\h\w*\>\s*()\ze\_s*(" contained skipwhite skipnl nextgroup=shFunctionSubSh + syn match shFunctionCmdOne "^\s*\zs\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionCmdTwo "\<\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" contained skipwhite skipnl nextgroup=@shFunctionCmds contains=shFunctionParens + syn match shFunctionOne "^\s*\zs\h\w*\s*()\ze\_s*{" skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionTwo "\<\h\w*\>\s*()\ze\_s*{" contained skipwhite skipnl nextgroup=shFunctionExpr contains=shFunctionParens + syn match shFunctionThree "^\s*\zs\h\w*\s*()\ze\_s*(" skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens + syn match shFunctionFour "\<\h\w*\>\s*()\ze\_s*(" contained skipwhite skipnl nextgroup=shFunctionSubSh contains=shFunctionParens endif if !exists("g:sh_no_error") @@ -987,6 +990,7 @@ if !exists("skip_sh_syntax_inits") hi def link shCtrlSeq Special hi def link shExprRegion Delimiter hi def link shFunctionKey Keyword + hi def link shFunctionParens Delimiter hi def link shFunctionOne Function hi def link shFunctionTwo shFunctionOne hi def link shFunctionThree shFunctionOne diff --git a/test/functional/legacy/matchparen_spec.lua b/test/functional/legacy/matchparen_spec.lua index 0338313bcf..083db22fcf 100644 --- a/test/functional/legacy/matchparen_spec.lua +++ b/test/functional/legacy/matchparen_spec.lua @@ -225,7 +225,7 @@ describe('matchparen', function() }) screen:expect([[ {18:#!/bin/sh} | - {25:SUSUWU_PRINT()} {15:(} | + {25:SUSUWU_PRINT}{16:()} {15:(} | {15:case} {15:"}{100:${LEVEL}}{15:"} {15:in} | {15:"}{100:$SUSUWU_SH_NOTICE}{15:"^)} | {100:${SUSUWU_S}} {15:&&} {15:return} {26:1} | @@ -246,7 +246,7 @@ describe('matchparen', function() end screen:expect([[ {18:#!/bin/sh} | - {25:SUSUWU_PRINT()} {15:(} | + {25:SUSUWU_PRINT}{16:()} {15:(} | {15:case} {15:"}{100:${LEVEL}}{15:"} {15:in} | {15:"}{100:$SUSUWU_SH_NOTICE}{15:")} foobar^ | {100:${SUSUWU_S}} {15:&&} {15:return} {26:1} |