runtime(sh): refactored sh.vim syntax script

Commit: 
https://github.com/vim/vim/commit/11bde1f16939ef4128d08488ae238c66b46aa056
Author: Bjoern Foersterling <[email protected]>
Date:   Tue Sep 23 19:47:29 2025 +0000

    runtime(sh): refactored sh.vim syntax script
    
    - unified bashStatement, kshStatement and shStatement as much as
      possible
    - separated builtin commands from external programs
    - cleaned up kornshell flavor logic
    - fixed alias syntax highlighting
    - added test for bash alias syntax highlighting
    - removed daemon keyword
    
    closes: #18355
    
    Signed-off-by: Bjoern Foersterling <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index 8dd62566c..5cf493065 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -4,20 +4,21 @@
 " Previous Maintainers:        Charles E. Campbell
 "              Lennart Schultz <[email protected]>
 " Last Change:         2024 Mar 04 by Vim Project {{{1
-"              2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> 
(improved bracket expressions, #15941)
-"              2025 Jan 06 add $PS0 to bashSpecialVariables (#16394)
-"              2025 Jan 18 add bash coproc, remove duplicate syn keywords 
(#16467)
-"              2025 Mar 21 update shell capability detection (#16939)
-"              2025 Apr 03 command substitution opening paren at EOL (#17026)
-"              2025 Apr 10 improve shell detection (#17084)
-"              2025 Apr 29 match escaped chars in test operands (#17221)
+"              2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> 
improved bracket expressions, #15941
+"              2025 Jan 06 add $PS0 to bashSpecialVariables #16394
+"              2025 Jan 18 add bash coproc, remove duplicate syn keywords 
#16467
+"              2025 Mar 21 update shell capability detection #16939
+"              2025 Apr 03 command substitution opening paren at EOL #17026
+"              2025 Apr 10 improve shell detection #17084
+"              2025 Apr 29 match escaped chars in test operands #17221
 "              2025 May 06 improve single-quote string matching in parameter 
expansions
 "              2025 May 06 match KornShell compound arrays
 "              2025 May 10 improve wildcard character class lists
 "              2025 May 21 improve supported KornShell features
-"              2025 Jun 16 change how sh_fold_enabled is reset (#17557)
-"              2025 Jul 18 properly delete :commands (#17785)
-"              2025 Aug 23 bash: add support for ${ cmd;} and ${|cmd;} (#18084)
+"              2025 Jun 16 change how sh_fold_enabled is reset #17557
+"              2025 Jul 18 properly delete :commands #17785
+"              2025 Aug 23 bash: add support for ${ cmd;} and ${|cmd;} #18084
+"              2025 Sep 23 simplify ksh logic, update sh statements #18355
 " }}}
 " Version:             208
 " Former URL:          http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
@@ -26,7 +27,7 @@
 
 " quit when a syntax file was already loaded {{{1
 if exists("b:current_syntax")
-  finish
+    finish
 endif
 
 " Ensure this is set unless we find another shell
@@ -36,36 +37,36 @@ let b:is_sh = 1
 let s:shebang = getline(1)
 
 if s:shebang =~ '^#!.\{-2,}\<ksh\>'
-  " The binary is too ambiguous (i.e. '/bin/ksh' or some such).
- let b:is_kornshell = 1
- let b:generic_korn = 1
+    " The binary is too ambiguous (i.e. '/bin/ksh' or some such).
+    let b:is_kornshell = 1
+    let b:generic_korn = 1
 elseif s:shebang =~ '^#!.\{-2,}\<ksh93u\+\>'
- " ksh93u+ (or 93u-) release (still much too common to encounter)
- let b:is_kornshell = 1
- let b:is_ksh93u = 1
+    " ksh93u+ (or 93u-) release (still much too common to encounter)
+    let b:is_kornshell = 1
+    let b:is_ksh93u = 1
 elseif s:shebang =~ '^#!.\{-2,}\<ksh93v\>'
- " ksh93v- alpha or beta
- let b:is_kornshell = 1
- let b:is_ksh93v = 1
+    " ksh93v- alpha or beta
+    let b:is_kornshell = 1
+    let b:is_ksh93v = 1
 elseif s:shebang =~ '^#!.\{-2,}\<ksh93\>'
- " Could be any ksh93 release
- let b:is_kornshell = 1
- let b:is_ksh93 = 1
+    " Could be any ksh93 release
+    let b:is_kornshell = 1
+    let b:is_ksh93 = 1
 elseif s:shebang =~ '^#!.\{-2,}\<ksh2020\>'
- let b:is_kornshell = 1
- let b:is_ksh2020 = 1
+    let b:is_kornshell = 1
+    let b:is_ksh2020 = 1
 elseif s:shebang =~ '^#!.\{-2,}\<ksh88\>'
- " The actual AT&T ksh88 and its feature set is assumed.
- let b:is_kornshell = 1
- let b:is_ksh88 = 1
+    " The actual AT&T ksh88 and its feature set is assumed.
+    let b:is_kornshell = 1
+    let b:is_ksh88 = 1
 elseif s:shebang =~ '^#!.\{-2,}\<mksh\>'
- " MirBSD Korn Shell
- let b:is_kornshell = 1
- let b:is_mksh = 1
+    " MirBSD Korn Shell
+    let b:is_kornshell = 1
+    let b:is_mksh = 1
 elseif s:shebang =~ '^#!.\{-2,}\<bash\>'
- let b:is_bash      = 1
+    let b:is_bash      = 1
 elseif s:shebang =~ '^#!.\{-2,}\<dash\>'
- let b:is_dash      = 1
+    let b:is_dash      = 1
 " handling /bin/sh with is_kornshell/is_sh {{{1
 " b:is_sh will be set when "#! /bin/sh" is found;
 " However, it often is just a masquerade by bash (typically Linux)
@@ -74,132 +75,132 @@ elseif s:shebang =~ '^#!.\{-2,}\<dash\>'
 " "g:is_posix" or "g:is_dash", a b:is_sh is converted into
 " b:is_kornshell/b:is_bash/b:is_posix/b:is_dash, respectively.
 elseif !exists("b:is_kornshell") && !exists("b:is_bash") && 
!exists("b:is_posix") && !exists("b:is_dash")
- if exists("g:is_kornshell")
-  let b:is_kornshell= 1
-  let b:generic_korn = 1
- elseif exists("g:is_bash")
-  let b:is_bash= 1
- elseif exists("g:is_dash")
-  let b:is_dash= 1
- elseif exists("g:is_posix")
-  let b:is_posix= 1
- elseif exists("g:is_sh")
-  let b:is_sh= 1
- else
-  " user did not specify which shell to use, and
-  " the script itself does not specify which shell to use. FYI: /bin/sh is 
ambiguous.
-  " Assuming /bin/sh is executable, and if its a link, find out what it links 
to.
-  let s:shell = ""
-  if executable("/bin/sh")
-   let s:shell = resolve("/bin/sh")
-  elseif executable("/usr/bin/sh")
-   let s:shell = resolve("/usr/bin/sh")
-  endif
-  if s:shell =~ '\<ksh\>'
-   " The binary is too ambiguous (i.e. '/bin/ksh' or some such).
-   let b:is_kornshell = 1
-   let b:generic_korn = 1
-  elseif s:shell =~ '\<ksh93u\+\>'
-   " ksh93u+ (or 93u-) release (still much too common to encounter)
-   let b:is_kornshell = 1
-   let b:is_ksh93u = 1
-  elseif s:shell =~ '\<ksh93v\>'
-   " ksh93v- alpha or beta
-   let b:is_kornshell = 1
-   let b:is_ksh93v = 1
-  elseif s:shell =~ '\<ksh93\>'
-   " Could be any ksh93 release
-   let b:is_kornshell = 1
-   let b:is_ksh93 = 1
-  elseif s:shebang =~ '\<ksh2020\>'
-   let b:is_kornshell = 1
-   let b:is_ksh2020 = 1
-  elseif s:shell =~ '\<ksh88\>'
-   " The actual AT&T ksh88 and its feature set is assumed.
-   let b:is_kornshell = 1
-   let b:is_ksh88 = 1
-  elseif s:shell =~ '\<mksh\>'
-   " MirBSD Korn Shell
-   let b:is_kornshell = 1
-   let b:is_mksh = 1
-  elseif s:shell =~ '\<bash\>'
-   let b:is_bash = 1
-  elseif s:shell =~ '\<dash\>'
-   let b:is_dash = 1
-  else
-   let b:is_posix = 1
-  endif
-  unlet s:shell
- endif
+    if exists("g:is_kornshell")
+        let b:is_kornshell= 1
+        let b:generic_korn = 1
+    elseif exists("g:is_bash")
+        let b:is_bash= 1
+    elseif exists("g:is_dash")
+        let b:is_dash= 1
+    elseif exists("g:is_posix")
+        let b:is_posix= 1
+    elseif exists("g:is_sh")
+        let b:is_sh= 1
+    else
+        " user did not specify which shell to use, and
+        " the script itself does not specify which shell to use. FYI: /bin/sh 
is ambiguous.
+        " Assuming /bin/sh is executable, and if its a link, find out what it 
links to.
+        let s:shell = ""
+        if executable("/bin/sh")
+            let s:shell = resolve("/bin/sh")
+        elseif executable("/usr/bin/sh")
+            let s:shell = resolve("/usr/bin/sh")
+        endif
+        if s:shell =~ '\<ksh\>'
+            " The binary is too ambiguous (i.e. '/bin/ksh' or some such).
+            let b:is_kornshell = 1
+            let b:generic_korn = 1
+        elseif s:shell =~ '\<ksh93u\+\>'
+            " ksh93u+ (or 93u-) release (still much too common to encounter)
+            let b:is_kornshell = 1
+            let b:is_ksh93u = 1
+        elseif s:shell =~ '\<ksh93v\>'
+            " ksh93v- alpha or beta
+            let b:is_kornshell = 1
+            let b:is_ksh93v = 1
+        elseif s:shell =~ '\<ksh93\>'
+            " Could be any ksh93 release
+            let b:is_kornshell = 1
+            let b:is_ksh93 = 1
+        elseif s:shebang =~ '\<ksh2020\>'
+            let b:is_kornshell = 1
+            let b:is_ksh2020 = 1
+        elseif s:shell =~ '\<ksh88\>'
+            " The actual AT&T ksh88 and its feature set is assumed.
+            let b:is_kornshell = 1
+            let b:is_ksh88 = 1
+        elseif s:shell =~ '\<mksh\>'
+            " MirBSD Korn Shell
+            let b:is_kornshell = 1
+            let b:is_mksh = 1
+        elseif s:shell =~ '\<bash\>'
+            let b:is_bash = 1
+        elseif s:shell =~ '\<dash\>'
+            let b:is_dash = 1
+        else
+            let b:is_posix = 1
+        endif
+        unlet s:shell
+    endif
 endif
 
 unlet s:shebang
 
 " if b:is_dash, set b:is_posix too
 if exists("b:is_dash")
- let b:is_posix= 1
+    let b:is_posix= 1
 endif
 
 if exists("b:is_kornshell") || exists("b:is_bash")
- if exists("b:is_sh")
-  unlet b:is_sh
- endif
+    if exists("b:is_sh")
+        unlet b:is_sh
+    endif
 endif
 
 " set up default g:sh_fold_enabled {{{1
 " ================================
 if !exists("g:sh_fold_enabled")
- let g:sh_fold_enabled= 0
+    let g:sh_fold_enabled= 0
 elseif g:sh_fold_enabled != 0 && !has("folding")
- echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile 
vim for +fold support"
- let g:sh_fold_enabled= 0
+    echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to 
re-compile vim for +fold support"
+    let g:sh_fold_enabled= 0
 endif
 let s:sh_fold_functions= and(g:sh_fold_enabled,1)
 let s:sh_fold_heredoc  = and(g:sh_fold_enabled,2)
 let s:sh_fold_ifdofor  = and(g:sh_fold_enabled,4)
 if g:sh_fold_enabled && &fdm == "manual"
- " Given that  the     user provided g:sh_fold_enabled
- "     AND     g:sh_fold_enabled is manual (usual default)
- "     implies a desire for syntax-based folding
- setl fdm=syntax
+    " Given that       the     user provided g:sh_fold_enabled
+    "  AND     g:sh_fold_enabled is manual (usual default)
+    "  implies a desire for syntax-based folding
+    setl fdm=syntax
 endif
 
 " set up the syntax-highlighting for iskeyword
 if (v:version == 704 && has("patch-7.4.1142")) || v:version > 704
- if !exists("g:sh_syntax_isk") || (exists("g:sh_syntax_isk") && 
g:sh_syntax_isk)
-  if exists("b:is_bash")
-   exe "syn iskeyword ".&iskeyword.",-,:"
-  else
-   exe "syn iskeyword ".&iskeyword.",-"
-  endif
- endif
+    if !exists("g:sh_syntax_isk") || (exists("g:sh_syntax_isk") && 
g:sh_syntax_isk)
+        if exists("b:is_bash")
+            exe "syn iskeyword ".&iskeyword.",-,:"
+        else
+            exe "syn iskeyword ".&iskeyword.",-"
+        endif
+    endif
 endif
 
 " Set up folding commands for shell {{{1
 " =================================
 if exists(":ShFoldFunctions") == 2
-  delc ShFoldFunctions
+    delc ShFoldFunctions
 endif
 if exists(":ShFoldIfHereDoc") == 2
-  delc ShFoldHereDoc
+    delc ShFoldHereDoc
 endif
 if exists(":ShFoldIfDoFor") == 2
-  delc ShFoldIfDoFor
+    delc ShFoldIfDoFor
 endif
 if s:sh_fold_functions
- com! -nargs=* ShFoldFunctions <args> fold
+    com! -nargs=* ShFoldFunctions <args> fold
 else
- com! -nargs=* ShFoldFunctions <args>
+    com! -nargs=* ShFoldFunctions <args>
 endif
 if s:sh_fold_heredoc
- com! -nargs=* ShFoldHereDoc <args> fold
+    com! -nargs=* ShFoldHereDoc <args> fold
 else
- com! -nargs=* ShFoldHereDoc <args>
+    com! -nargs=* ShFoldHereDoc <args>
 endif
 if s:sh_fold_ifdofor
- com! -nargs=* ShFoldIfDoFor <args> fold
+    com! -nargs=* ShFoldIfDoFor <args> fold
 else
- com! -nargs=* ShFoldIfDoFor <args>
+    com! -nargs=* ShFoldIfDoFor <args>
 endif
 
 " Generate bracket expression items {{{1
@@ -211,37 +212,37 @@ endif
 "   its value does not have "contained" among other optional arguments (":help
 "   :syn-arguments").
 fun! s:GenerateBracketExpressionItems(dict) abort
- let itemGroup = a:dict.itemGroup
- let bracketGroup = a:dict.bracketGroup
- let invGroup = itemGroup . 'Inv'
- let skipLeftBracketGroup = itemGroup . 'SkipLeftBracket'
- let skipRightBracketGroup = itemGroup . 'SkipRightBracket'
- let extraArgs = has_key(a:dict, 'extraArgs') ? a:dict.extraArgs : ''
-
- " Make the leading "[!^]" stand out in a NON-matching expression.
- exec 'syn match ' . invGroup . ' contained "\[\@<=[!^]"'
-
- " Set up indirections for unbalanced-bracket highlighting.
- exec 'syn region ' . skipRightBracketGroup . ' contained matchgroup=' . 
bracketGroup . ' start="\[\%([!^]\=\\=\]\)\@=" matchgroup=shCollSymb 
end="\[\.[^]]\{-}\][^]]\{-}\.\]" matchgroup=' . itemGroup . ' end="\]" 
contains=@shBracketExprList,shDoubleQuote,' . invGroup
- exec 'syn region ' . skipLeftBracketGroup . ' contained matchgroup=' . 
bracketGroup . ' start="\[\%([!^]\=\\=\]\)\@=" 
skip="[!^]\=\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\%(\[[:.=]\@!\)\@=" matchgroup=' . 
itemGroup . ' end="\[[:.=]\@!" contains=@shBracketExprList,shDoubleQuote,' . 
invGroup
-
- " Look for a general matching expression.
- exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' 
start="\[\S\@=" end="\]" contains=@shBracketExprList,shDoubleQuote ' . extraArgs
- " Look for a general NON-matching expression.
- exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' 
start="\[[!^]\@=" end="\]" contains=@shBracketExprList,shDoubleQuote,' . 
invGroup . ' ' . extraArgs
-
- " Accommodate unbalanced brackets in bracket expressions.  The supported
- " syntax for a plain "]" can be: "[]ws]" and "[^]ws]"; or, "[ws[.xs]ys.]zs]"
- " and "[^ws[.xs]ys.]zs]"; see §9.3.5 RE Bracket Expression (in XBD).
- exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\=\]" 
matchgroup=' . bracketGroup . ' end="\]" 
contains=@shBracketExprList,shDoubleQuote,' . skipRightBracketGroup . ' ' . 
extraArgs
- " Strive to handle "[]...[]" etc.
- exec 'syn region ' . itemGroup . ' matchgroup=NONE 
start="\[[!^]\=\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\[[:.=]\@!" matchgroup=' . 
bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . 
skipLeftBracketGroup . ' ' . extraArgs
-
- if !exists("g:skip_sh_syntax_inits")
-  exec 'hi def link ' . skipLeftBracketGroup . ' ' . itemGroup
-  exec 'hi def link ' . skipRightBracketGroup . ' ' . itemGroup
-  exec 'hi def link ' . invGroup . ' Underlined'
- endif
+    let itemGroup = a:dict.itemGroup
+    let bracketGroup = a:dict.bracketGroup
+    let invGroup = itemGroup . 'Inv'
+    let skipLeftBracketGroup = itemGroup . 'SkipLeftBracket'
+    let skipRightBracketGroup = itemGroup . 'SkipRightBracket'
+    let extraArgs = has_key(a:dict, 'extraArgs') ? a:dict.extraArgs : ''
+
+    " Make the leading "[!^]" stand out in a NON-matching expression.
+    exec 'syn match ' . invGroup . ' contained "\[\@<=[!^]"'
+
+    " Set up indirections for unbalanced-bracket highlighting.
+    exec 'syn region ' . skipRightBracketGroup . ' contained matchgroup=' . 
bracketGroup . ' start="\[\%([!^]\=\\=\]\)\@=" matchgroup=shCollSymb 
end="\[\.[^]]\{-}\][^]]\{-}\.\]" matchgroup=' . itemGroup . ' end="\]" 
contains=@shBracketExprList,shDoubleQuote,' . invGroup
+    exec 'syn region ' . skipLeftBracketGroup . ' contained matchgroup=' . 
bracketGroup . ' start="\[\%([!^]\=\\=\]\)\@=" 
skip="[!^]\=\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\%(\[[:.=]\@!\)\@=" matchgroup=' . 
itemGroup . ' end="\[[:.=]\@!" contains=@shBracketExprList,shDoubleQuote,' . 
invGroup
+
+    " Look for a general matching expression.
+    exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' 
start="\[\S\@=" end="\]" contains=@shBracketExprList,shDoubleQuote ' . extraArgs
+    " Look for a general NON-matching expression.
+    exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' 
start="\[[!^]\@=" end="\]" contains=@shBracketExprList,shDoubleQuote,' . 
invGroup . ' ' . extraArgs
+
+    " Accommodate unbalanced brackets in bracket expressions.  The supported
+    " syntax for a plain "]" can be: "[]ws]" and "[^]ws]"; or, 
"[ws[.xs]ys.]zs]"
+    " and "[^ws[.xs]ys.]zs]"; see §9.3.5 RE Bracket Expression (in XBD).
+    exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\=\]" 
matchgroup=' . bracketGroup . ' end="\]" 
contains=@shBracketExprList,shDoubleQuote,' . skipRightBracketGroup . ' ' . 
extraArgs
+    " Strive to handle "[]...[]" etc.
+    exec 'syn region ' . itemGroup . ' matchgroup=NONE 
start="\[[!^]\=\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\[[:.=]\@!" matchgroup=' . 
bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . 
skipLeftBracketGroup . ' ' . extraArgs
+
+    if !exists("g:skip_sh_syntax_inits")
+        exec 'hi def link ' . skipLeftBracketGroup . ' ' . itemGroup
+        exec 'hi def link ' . skipRightBracketGroup . ' ' . itemGroup
+        exec 'hi def link ' . invGroup . ' Underlined'
+    endif
 endfun
 
 call s:GenerateBracketExpressionItems({'itemGroup': 'shBracketExpr', 
'bracketGroup': 'shBracketExprDelim'})
@@ -253,7 +254,7 @@ syn case match
 "==================================
 syn cluster shErrorList        
contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError,shOK
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn cluster ErrorList add=shDTestError
+    syn cluster ErrorList add=shDTestError
 endif
 syn cluster shArithParenList   
contains=shArithmetic,shArithParen,shCaseEsac,shComment,shDeref,shDerefVarArray,shDo,shDerefSimple,shEcho,shEscape,shExpr,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
 syn cluster shArithList        contains=@shArithParenList,shParenError
@@ -261,7 +262,7 @@ syn cluster shBracketExprList       
contains=shCharClassOther,shCharClass,shCollSymb,s
 syn cluster shCaseEsacList     
contains=shCaseStart,shCaseLabel,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
 syn cluster shCaseList 
contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shComment,shDblBrace,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn cluster shCaseList        add=shForPP,shDblParen
+    syn cluster shCaseList     add=shForPP,shDblParen
 endif
 syn cluster shCommandSubList   
contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
 syn cluster shCurlyList        
contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
@@ -274,8 +275,8 @@ syn cluster shExprList1     
contains=shBracketExpr,shNumber,shOperator,shExSingleQuo
 syn cluster shExprList2        contains=@shExprList1,@shCaseList,shTest
 syn cluster shFunctionList     
contains=shBracketExpr,@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn cluster shFunctionList    add=shRepeat,shDblBrace,shDblParen,shForPP
- syn cluster shDerefList       add=shCommandSubList,shEchoDeref
+    syn cluster shFunctionList add=shRepeat,shDblBrace,shDblParen,shForPP
+    syn cluster shDerefList    add=shCommandSubList,shEchoDeref
 endif
 syn cluster shHereBeginList    contains=@shCommandSubList
 syn cluster shHereList contains=shBeginHere,shHerePayload
@@ -284,7 +285,7 @@ syn cluster shIdList        
contains=shArithmetic,shCommandSub,shCommandSubBQ,shDerefVa
 syn cluster shIfList   
contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
 syn cluster shLoopList 
contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shIf,shOption,shSet,shTest,shTestOpr,shTouch
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn cluster shLoopList        add=shForPP,shDblParen
+    syn cluster shLoopList     add=shForPP,shDblParen
 endif
 syn cluster shPPSLeftList      
contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
 syn cluster shPPSRightList     
contains=shDeref,shDerefSimple,shEscape,shPosnParm
@@ -297,15 +298,15 @@ syn cluster shForList     
contains=shTestOpr,shNumber,shDerefSimple,shDeref,shComman
 " ====
 " This one is needed INSIDE a CommandSub, so that `echo bla` be correct
 if (exists("b:is_kornshell") && !exists("b:is_ksh88"))
- syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 end="\ze[        
;]}" contains=@shEchoList skipwhite nextgroup=shQuickComment
- syn region shEcho matchgroup=shStatement start="\<print\>" skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 end="\ze[        
;]}" contains=@shEchoList skipwhite nextgroup=shQuickComment
+    syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 end="\ze[     
;]}" contains=@shEchoList skipwhite nextgroup=shQuickComment
+    syn region shEcho matchgroup=shStatement start="\<print\>" skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 end="\ze[     
;]}" contains=@shEchoList skipwhite nextgroup=shQuickComment
 else
- syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
- syn region shEcho matchgroup=shStatement start="\<print\>" skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
+    syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
+    syn region shEcho matchgroup=shStatement start="\<print\>" skip="\$" 
matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
 endif
 if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
- syn region shEchoDeref contained matchgroup=shStatement start="\<echo\>"  
skip="\$" matchgroup=shEchoDelim end="$" end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
- syn region shEchoDeref contained matchgroup=shStatement start="\<print\>" 
skip="\$" matchgroup=shEchoDelim end="$" end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
+    syn region shEchoDeref contained matchgroup=shStatement start="\<echo\>"  
skip="\$" matchgroup=shEchoDelim end="$" end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
+    syn region shEchoDeref contained matchgroup=shStatement start="\<print\>" 
skip="\$" matchgroup=shEchoDelim end="$" end="[<>;&|()`}]"me=e-1 
end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite 
nextgroup=shQuickComment
 endif
 syn match  shEchoQuote contained       '\%(\\\)*\["`'()]'
 
@@ -315,33 +316,31 @@ syn region shEmbeddedEcho contained 
matchgroup=shStatement start="\<print\>" ski
 " Alias: {{{1
 " =====
 if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
- syn match shStatement "\<alias\>"
- syn region shAlias matchgroup=shStatement 
start="\<alias\>\s\+\(\h[-._[:alnum:]]*\)\@="  skip="\$" end="\>\|`"
- syn region shAlias matchgroup=shStatement 
start="\<alias\>\s\+\(\h[-._[:alnum:]]*=\)\@=" skip="\$" end="="
-" syn region shAlias matchgroup=shStatement 
start="\<alias\>\s\+\(\h[-._[:alnum:]]\+\)\@="  skip="\$" end="\>\|`"
-" syn region shAlias matchgroup=shStatement 
start="\<alias\>\s\+\(\h[-._[:alnum:]]\+=\)\@=" skip="\$" end="="
-
- " Touch: {{{1
- " =====
- syn match shTouch     '\<touch\>[^;#]*'       skipwhite nextgroup=shComment 
contains=shTouchCmd,shDoubleQuote,shSingleQuote,shDeref,shDerefSimple
- syn match shTouchCmd  '\<touch\>'             contained
+    syn match shStatement "\<alias\>"
+    syn region shAlias matchgroup=shStatement 
start="\<alias\>\s\+\(\h[-._[:alnum:]]*\)\@="  skip="\$" end="\>\|`"
+    syn region shAlias matchgroup=shStatement 
start="\<alias\>\s\+\(\h[-._[:alnum:]]*=\)\@=" skip="\$" end="="
+
+    " Touch: {{{1
+    " =====
+    syn match shTouch  '\<touch\>[^;#]*'       skipwhite nextgroup=shComment 
contains=shTouchCmd,shDoubleQuote,shSingleQuote,shDeref,shDerefSimple
+    syn match shTouchCmd       '\<touch\>'             contained
 endif
 
 " Error Codes: {{{1
 " ============
 if !exists("g:sh_no_error")
- syn match   shDoError "\<done\>"
- syn match   shIfError "\<fi\>"
- syn match   shInError "\<in\>"
- syn match   shCaseError ";;"
- syn match   shEsacError "\<esac\>"
- syn match   shCurlyError "}"
- syn match   shParenError ")"
- syn match   shOK      '\.\(done\|fi\|in\|esac\)'
- if exists("b:is_kornshell") || exists("b:is_bash")
-  syn match     shDTestError "]]"
- endif
- syn match     shTestError "]"
+    syn match   shDoError "\<done\>"
+    syn match   shIfError "\<fi\>"
+    syn match   shInError "\<in\>"
+    syn match   shCaseError ";;"
+    syn match   shEsacError "\<esac\>"
+    syn match   shCurlyError "}"
+    syn match   shParenError ")"
+    syn match   shOK   '\.\(done\|fi\|in\|esac\)'
+    if exists("b:is_kornshell") || exists("b:is_bash")
+        syn match     shDTestError "]]"
+    endif
+    syn match     shTestError "]"
 endif
 
 " Options: {{{1
@@ -381,8 +380,8 @@ syn region shTestDoubleQuote        contained       
start='\%(\%(\\\)*\\)\@<!"' skip=+\\
 syn match  shTestSingleQuote   contained       '\.'    
nextgroup=shTestSingleQuote
 syn match  shTestSingleQuote   contained       "'[^']*'"
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn region  shDblBrace matchgroup=Delimiter start="\[\[\s\@=" 
skip=+\%(\\\)*\$+ end="\]\]"    
contains=@shTestList,shAstQuote,shNoQuote,shComment
- syn region  shDblParen matchgroup=Delimiter start="(("        
skip=+\%(\\\)*\$+ end="))"      contains=@shTestList,shComment
+    syn region  shDblBrace matchgroup=Delimiter start="\[\[\s\@="      
skip=+\%(\\\)*\$+ end="\]\]"    
contains=@shTestList,shAstQuote,shNoQuote,shComment
+    syn region  shDblParen matchgroup=Delimiter start="(("     
skip=+\%(\\\)*\$+ end="))"      contains=@shTestList,shComment
 endif
 
 " Character Class In Range: {{{1
@@ -398,20 +397,20 @@ ShFoldIfDoFor syn region shDo     transparent     
matchgroup=shConditional start="\<do\>
 ShFoldIfDoFor syn region shIf  transparent     matchgroup=shConditional 
start="\<if\_s" matchgroup=shConditional skip=+-fi\>+ end="\<;\_s*then\>" 
end="\<fi\>" contains=@shIfList
 ShFoldIfDoFor syn region shFor         matchgroup=shLoop 
start="\<for\ze\_s\s*\%(((\)\@!" end="\<in\>" end="\<do\>"me=e-2                
      contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
 if exists("b:is_kornshell") || exists("b:is_bash")
- ShFoldIfDoFor syn region shForPP      matchgroup=shLoop start='\<for\>\_s*((' 
end='))' contains=@shForList
+    ShFoldIfDoFor syn region shForPP   matchgroup=shLoop start='\<for\>\_s*((' 
end='))' contains=@shForList
 endif
 
 if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
- syn cluster shCaseList        add=shRepeat
- syn cluster shFunctionList    add=shRepeat
- syn region shRepeat   matchgroup=shLoop   start="\<while\_s" 
end="\<do\>"me=e-2       contains=@shLoopList,shDblParen,shDblBrace
- syn region shRepeat   matchgroup=shLoop   start="\<until\_s" 
end="\<do\>"me=e-2       contains=@shLoopList,shDblParen,shDblBrace
- if !exists("b:is_posix")
-  syn region shCaseEsac matchgroup=shConditional start="\<select\s" 
matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
- endif
+    syn cluster shCaseList     add=shRepeat
+    syn cluster shFunctionList add=shRepeat
+    syn region shRepeat   matchgroup=shLoop   start="\<while\_s" 
end="\<do\>"me=e-2    contains=@shLoopList,shDblParen,shDblBrace
+    syn region shRepeat   matchgroup=shLoop   start="\<until\_s" 
end="\<do\>"me=e-2    contains=@shLoopList,shDblParen,shDblBrace
+    if !exists("b:is_posix")
+        syn region shCaseEsac matchgroup=shConditional start="\<select\s" 
matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
+    endif
 else
- syn region shRepeat   matchgroup=shLoop   start="\<while\_s" 
end="\<do\>"me=e-2               contains=@shLoopList
- syn region shRepeat   matchgroup=shLoop   start="\<until\_s" 
end="\<do\>"me=e-2               contains=@shLoopList
+    syn region shRepeat   matchgroup=shLoop   start="\<while\_s" 
end="\<do\>"me=e-2            contains=@shLoopList
+    syn region shRepeat   matchgroup=shLoop   start="\<until\_s" 
end="\<do\>"me=e-2            contains=@shLoopList
 endif
 syn region shCurlyIn   contained       matchgroup=Delimiter start="{" end="}" 
contains=@shCurlyList
 syn match  shComma     contained       ","
@@ -422,39 +421,34 @@ syn match shCaseBar       contained skipwhite 
"\(^\|[^\]\)\(\\\)*\zs|"            nextgroup=s
 syn match shCaseStart  contained skipwhite skipnl "("                  
nextgroup=shCase,shCaseBar
 syn match shCaseLabel  contained skipwhite     "\%(\.\|[-a-zA-Z0-9_*.]\)\+"    
contains=shBracketExpr
 if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88") 
&& !exists("b:is_ksh93u") && !exists("b:is_ksh93v") && !exists("b:is_ksh2020"))
- ShFoldIfDoFor syn region      shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end=";&" end=";;&" end="esac"me=s-1      contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
+    ShFoldIfDoFor syn region   shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end=";&" end=";;&" end="esac"me=s-1      contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
 elseif exists("b:is_kornshell")
- ShFoldIfDoFor syn region      shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end=";&" end="esac"me=s-1        contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
+    ShFoldIfDoFor syn region   shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end=";&" end="esac"me=s-1        contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
 else
- ShFoldIfDoFor syn region      shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end="esac"me=s-1         contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
+    ShFoldIfDoFor syn region   shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end="esac"me=s-1         contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
 endif
 ShFoldIfDoFor syn region       shCaseEsac      matchgroup=shConditional 
start="\<case\>" end="\<esac\>"        contains=@shCaseEsacList
 
 syn keyword shCaseIn   contained skipwhite skipnl in                   
nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
 if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88"))
- syn region  shCaseExSingleQuote       matchgroup=shQuote start=+\$'+ 
skip=+\\\|\.+ end=+'+    contains=shStringSpecial,shSpecial      skipwhite 
skipnl nextgroup=shCaseBar    contained
+    syn region  shCaseExSingleQuote    matchgroup=shQuote start=+\$'+ 
skip=+\\\|\.+ end=+'+    contains=shStringSpecial,shSpecial      skipwhite 
skipnl nextgroup=shCaseBar    contained
 elseif !exists("g:sh_no_error")
- syn region  shCaseExSingleQuote       matchgroup=Error start=+\$'+ 
skip=+\\\|\.+ end=+'+      contains=shStringSpecial        skipwhite skipnl 
nextgroup=shCaseBar    contained
+    syn region  shCaseExSingleQuote    matchgroup=Error start=+\$'+ 
skip=+\\\|\.+ end=+'+      contains=shStringSpecial        skipwhite skipnl 
nextgroup=shCaseBar    contained
 endif
 syn region  shCaseSingleQuote  matchgroup=shQuote start=+'+ end=+'+            
contains=shStringSpecial                skipwhite skipnl nextgroup=shCaseBar    
contained
 syn region  shCaseDoubleQuote  matchgroup=shQuote start=+"+ skip=+\\\|\.+ 
end=+"+      contains=@shDblQuoteList,shStringSpecial        skipwhite skipnl 
nextgroup=shCaseBar    contained
 syn region  shCaseCommandSub   start=+`+ skip=+\\\|\.+ end=+`+         
contains=@shCommandSubList              skipwhite skipnl nextgroup=shCaseBar    
contained
 call s:GenerateBracketExpressionItems({'itemGroup': 'shCaseRange', 
'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'skip=+\\+ contained'})
 if exists("b:is_bash")
- syn match   shCharClass       
"\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]"
   contained
+    syn match   shCharClass    
"\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]"
   contained
 elseif exists("b:is_kornshell")
- syn match   shCharClass       
"\[:\%(alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]"
  contained
+    syn match   shCharClass    
"\[:\%(alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]"
  contained
 endif
 " Misc: {{{1
 "======
 syn match   shWrapLineOperator "\$"
 syn region  shCommandSubBQ     start="`" skip="\\\|\." end="`" 
contains=shBQComment,@shCommandSubList
-"COMBAK: see ksh13:50
-"syn match   shEscape  contained       '\%(^\)\@!\%(\\\)*\.'   
nextgroup=shSingleQuote,shDoubleQuote,shComment
-"COMBAK: see sh11:27
 syn match   shEscape   contained       '\%(^\)\@!\%(\\\)*\.'   
nextgroup=shComment
-"COMBAK: see ksh13:53
-"syn match   shEscape  contained       '\%(^\)\@!\%(\\\)*\.'
 
 " $() and $(()): {{{1
 " $(..) is not supported by sh (Bourne shell).  However, apparently
@@ -463,76 +457,76 @@ syn match   shEscape      contained       
'\%(^\)\@!\%(\\\)*\.'   nextgroup=shComment
 " systems too, however, so the following syntax will flag $(..) as
 " an Error under /bin/sh.  By consensus of vimdev'ers!
 if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
- syn region shCommandSub matchgroup=shCmdSubRegion start="\$((\@!"  
skip='\\\|\.' end=")"  contains=@shCommandSubList
- if exists("b:is_kornshell")
-  if !exists("b:is_ksh88")
-   if exists("b:is_mksh")
-    syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[     
]"  skip='\\\|\.' end="\zs[     
;]}"  contains=@shCommandSubList
-   else
-    syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[     
<]"  skip='\\\|\.' end="\zs[    
;]}"  contains=@shCommandSubList
-   endif
-  endif
-  if exists("b:is_mksh") || exists("b:generic_korn")
-   syn region shValsub matchgroup=shCmdSubRegion start="\${|"  skip='\\\|\.' 
end="}"  contains=@shCommandSubList
-  endif
- elseif exists("b:is_bash")
-  syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[       
]"  skip='\\\|\.' end="\zs[;
][      
]*}"  contains=@shCommandSubList
-  syn region shValsub matchgroup=shCmdSubRegion start="\${|"  skip='\\\|\.' 
end="[;
][      
]*}"  contains=@shCommandSubList
- endif
- syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\|\.' 
end="))" contains=@shArithList
- syn region shArithmetic matchgroup=shArithRegion  start="\$\[" skip='\\\|\.' 
end="\]" contains=@shArithList
- syn match  shSkipInitWS contained     "^\s\+"
- syn region shArithParen matchgroup=shArithRegion  contained start="(" end=")" 
contains=@shArithParenList
+    syn region shCommandSub matchgroup=shCmdSubRegion start="\$((\@!"  
skip='\\\|\.' end=")"  contains=@shCommandSubList
+    if exists("b:is_kornshell")
+        if !exists("b:is_ksh88")
+            if exists("b:is_mksh")
+       syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[  
]"  skip='\\\|\.' end="\zs[     
;]}"  contains=@shCommandSubList
+            else
+       syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[  
<]"  skip='\\\|\.' end="\zs[    
;]}"  contains=@shCommandSubList
+            endif
+        endif
+        if exists("b:is_mksh") || exists("b:generic_korn")
+            syn region shValsub matchgroup=shCmdSubRegion start="\${|"  
skip='\\\|\.' end="}"  contains=@shCommandSubList
+        endif
+    elseif exists("b:is_bash")
+        syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[         
]"  skip='\\\|\.' end="\zs[;
][      
]*}"  contains=@shCommandSubList
+        syn region shValsub matchgroup=shCmdSubRegion start="\${|"  
skip='\\\|\.' end="[;
][      
]*}"  contains=@shCommandSubList
+    endif
+    syn region shArithmetic matchgroup=shArithRegion  start="\$((" 
skip='\\\|\.' end="))" contains=@shArithList
+    syn region shArithmetic matchgroup=shArithRegion  start="\$\[" 
skip='\\\|\.' end="\]" contains=@shArithList
+    syn match  shSkipInitWS contained  "^\s\+"
+    syn region shArithParen matchgroup=shArithRegion  contained start="(" 
end=")" contains=@shArithParenList
 elseif !exists("g:sh_no_error")
- syn region shCommandSub matchgroup=Error start="\$(" end=")" 
contains=@shCommandSubList
+    syn region shCommandSub matchgroup=Error start="\$(" end=")" 
contains=@shCommandSubList
 endif
 syn region shCmdParenRegion matchgroup=shCmdSubRegion start="((\@!" 
skip='\\\|\.' end=")" contains=@shCommandSubList
 
 if exists("b:is_bash")
- syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
- syn cluster shCaseList add=bashAdminStatement,bashStatement
- syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES 
BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING 
BASH_LINENO BASHOPTS BASHPID BASH_REMATCH BASH_SOURCE BASH_SUBSHELL 
BASH_VERSINFO BASH_VERSION BASH_XTRACEFD CDPATH COLUMNS COMP_CWORD COMP_KEY 
COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS COPROC 
COPROC_PID DIRSTACK EMACS ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNEST GLOBIGNORE 
GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE 
HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG 
LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LINENO LINES MACHTYPE MAIL 
MAILCHECK MAILPATH MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS 
POSIXLY_CORRECT PPID PROMPT_COMMAND PS0 PS1 PS2 PS3 PS4 PWD RANDOM 
READLINE_LINE READLINE_POINT REPLY SECONDS SHELL SHELLOPTS SHLVL TIMEFORMAT 
TIMEOUT TMPDIR UID
- syn keyword bashStatement basename cat chgrp chmod chown cksum clear cmp comm 
command compgen complete cp cut date dirname du egrep expr fgrep find fmt fold 
getconf gnufind gnugrep grep head iconv id join less ln logname ls md5sum mkdir 
mkfifo mknod mktemp mv od paste pathchk readlink realpath rev rm rmdir rpm sed 
sha1sum sha224sum sha256sum sha384sum sha512sum sleep sort strip stty sum sync 
tail tee tr tty uname uniq wc which xargs xgrep
- syn keyword bashAdminStatement daemon killall killproc nice reload restart 
start status stop
-endif
-
-if exists("b:is_kornshell") || exists("b:is_posix")
- syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
- syn cluster shCaseList add=kshStatement
- syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV FCEDIT 
FIGNORE FPATH HISTCMD HISTEDIT HISTFILE HISTSIZE HOME IFS JOBMAX KSH_VERSION 
LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME LINENO LINES 
MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD 
RANDOM REPLY SECONDS SHELL SHLVL TMOUT VISUAL
- syn keyword kshStatement basename cat chgrp chmod chown cksum clear cmp comm 
command cp cut date dirname du egrep expr fgrep find fmt fold grep head iconv 
id join killall less ln logname ls md5sum mkdir mknod mkfifo mktemp mv nice od 
paste pathchk printenv readlink realpath rev rm rmdir sed setgroups setsenv 
sha1sum sha224sum sha256sum sha384sum sha512sum sort strip stty sum sync tail 
tee tput tr tty uname uniq wc which xargs xgrep
- if exists("b:is_ksh88")
-  syn keyword kshSpecialVariables contained ERRNO
- elseif exists("b:is_mksh")
-  syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL 
KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID
-  syn keyword kshStatement bind rename
- elseif exists("b:is_ksh93v") || exists("b:is_ksh2020")
-  syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE 
COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE
-  syn keyword kshStatement compgen complete
-  if exists("b:is_ksh93v")
-   syn keyword kshSpecialVariables contained VPATH CSWIDTH
-   syn keyword kshStatement vmstate alarm fds pids poll sha2sum
-  endif
- elseif exists("b:is_ksh93u")
-  " ksh93u+
-  syn keyword kshSpecialVariables contained VPATH CSWIDTH
-  syn keyword kshStatement alarm fds pids vmstate
- else
-  " 'ksh' is ambiguous; include everything
-  syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL 
KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID 
SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY 
COMP_WORDBREAKS COMP_TYPE VPATH SRANDOM CSWIDTH
-  if !exists("b:is_ksh93")
-   syn keyword kshSpecialVariables contained ERRNO
-  endif
-  syn keyword kshStatement vmstate alarm fds pids poll sha2sum alarm eloop fds 
mkservice pids compgen complete bind rename
- endif
+    syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
+    syn cluster shCaseList add=bashAdminStatement,bashStatement
+    syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES 
BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING 
BASH_LINENO BASHOPTS BASHPID BASH_REMATCH BASH_SOURCE BASH_SUBSHELL 
BASH_VERSINFO BASH_VERSION BASH_XTRACEFD CDPATH COLUMNS COMP_CWORD COMP_KEY 
COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS COPROC 
COPROC_PID DIRSTACK EMACS ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNEST GLOBIGNORE 
GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE 
HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG 
LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LINENO LINES MACHTYPE MAIL 
MAILCHECK MAILPATH MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS 
POSIXLY_CORRECT PPID PROMPT_COMMAND PS0 PS1 PS2 PS3 PS4 PWD RANDOM 
READLINE_LINE READLINE_POINT REPLY SECONDS SHELL SHELLOPTS SHLVL TIMEFORMAT 
TIMEOUT TMPDIR UID
+    syn keyword bashStatement bind builtin caller compgen complete compopt 
declare dirs disown enable fg help history let logout mapfile popd pushd 
readarray shopt source suspend time
+    syn keyword bashStatement typeset nextgroup=shSetOption
+    syn keyword bashAdminStatement reload restart start status stop
+endif
+
+" for all kornshells
+if exists("b:is_kornshell")
+    syn cluster shCaseList add=kshStatement
+    syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
+    syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV FCEDIT 
FIGNORE FPATH HISTCMD HISTEDIT HISTFILE HISTSIZE HOME IFS JOBMAX KSH_VERSION 
LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME LINENO LINES 
MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD 
RANDOM REPLY SECONDS SHELL SHLVL TMOUT VISUAL
+    syn keyword kshStatement autoload builtin compound disown enum fg float 
functions hist history integer let nameref r redirect source stop suspend time 
whence xgrep
+    syn keyword shStatement typeset skipwhite nextgroup=shSetOption
+endif
+
+" kornshell flavors
+if exists("b:generic_korn")
+    syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME ERRNO 
EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR 
USER_ID SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY 
COMPREPLY COMP_WORDBREAKS COMP_TYPE VPATH SRANDOM CSWIDTH
+    syn keyword kshStatement alarm bind compgen complete eloop fds mkservice 
pids poll sha2sum vmstate
+elseif exists("b:is_ksh88")
+    syn keyword kshSpecialVariables bind contained ERRNO
+elseif exists("b:is_ksh93")
+    syn keyword kshSpecialVariables contained BASHPID COMP_CWORD COMP_KEY 
COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS CSWIDTH 
EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS 
SH_OPTIONS SRANDOM TMPDIR USER_ID VPATH
+    syn keyword kshStatement alarm bind compgen complete eloop fds mkservice 
pids poll sha2sum vmstate
+elseif exists("b:is_ksh93v")
+    syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE 
COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE CSWIDTH VPATH
+    syn keyword kshStatement alarm compgen complete fds pids poll sha2sum 
vmstate
+elseif exists("b:is_ksh93u")
+    syn keyword kshSpecialVariables contained VPATH CSWIDTH
+    syn keyword kshStatement alarm fds pids vmstate
+elseif exists("b:is_ksh2020")
+    syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE 
COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE
+    syn keyword kshStatement compgen complete
+elseif exists("b:is_mksh")
+    syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL 
KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID
+    syn keyword kshStatement bind
 endif
 
 syn match   shSource   "^\.\s"
 syn match   shSource   "\s\.\s"
-"syn region  shColon   start="^\s*:" end="$" end="\s#"me=e-2 
contains=@shColonList
-"syn region  shColon   start="^\s*\zs:" end="$" end="\s#"me=e-2
 if exists("b:is_kornshell") || exists("b:is_posix")
- syn match   shColon   '^\s*\zs:'
+    syn match   shColon        '^\s*\zs:'
 endif
 
 " String And Character Constants: {{{1
@@ -541,13 +535,13 @@ syn match   shNumber      "\<\d\+\>#\="
 syn match   shNumber   "\<-\=\.\=\d\+\>#\="
 syn match   shCtrlSeq  "\\d\d\d\|\[abcfnrtv0]"                 contained
 if exists("b:is_bash") || exists("b:is_kornshell")
- syn match   shSpecial "[^\]\(\\\)*\zs\\o\o\o\|\x\x\x\|\c[^"]\|\[abefnrtv]"    
contained
- syn match   shSpecial "^\(\\\)*\zs\\o\o\o\|\x\x\x\|\c[^"]\|\[abefnrtv]"       
contained
- syn region  shExSingleQuote   matchgroup=shQuote start=+\$'+ skip=+\\\|\.+ 
end=+'+    contains=shStringSpecial,shSpecial              
nextgroup=shSpecialNxt
- syn region  shExDoubleQuote   matchgroup=shQuote start=+\$"+ 
skip=+\\\|\.\|\"+ end=+"+        
contains=@shDblQuoteList,shStringSpecial,shSpecial      nextgroup=shSpecialNxt
+    syn match   shSpecial      
"[^\]\(\\\)*\zs\\o\o\o\|\x\x\x\|\c[^"]\|\[abefnrtv]"    contained
+    syn match   shSpecial      
"^\(\\\)*\zs\\o\o\o\|\x\x\x\|\c[^"]\|\[abefnrtv]"       contained
+    syn region  shExSingleQuote        matchgroup=shQuote start=+\$'+ 
skip=+\\\|\.+ end=+'+    contains=shStringSpecial,shSpecial              
nextgroup=shSpecialNxt
+    syn region  shExDoubleQuote        matchgroup=shQuote start=+\$"+ 
skip=+\\\|\.\|\"+ end=+"+        
contains=@shDblQuoteList,shStringSpecial,shSpecial      nextgroup=shSpecialNxt
 elseif !exists("g:sh_no_error")
- syn region  shExSingleQuote   matchGroup=Error start=+\$'+ skip=+\\\|\.+ 
end=+'+      contains=shStringSpecial
- syn region  shExDoubleQuote   matchGroup=Error start=+\$"+ skip=+\\\|\.+ 
end=+"+      contains=shStringSpecial
+    syn region  shExSingleQuote        matchGroup=Error start=+\$'+ 
skip=+\\\|\.+ end=+'+      contains=shStringSpecial
+    syn region  shExDoubleQuote        matchGroup=Error start=+\$"+ 
skip=+\\\|\.+ end=+"+      contains=shStringSpecial
 endif
 syn region  shSingleQuote      matchgroup=shQuote start=+'+ end=+'+            
contains=@Spell nextgroup=shSpecialStart,shSpecialSQ
 syn region  shDoubleQuote      matchgroup=shQuote start=+\%(\%(\\\)*\\)\@<!"+ 
skip=+\.+ end=+"+                        
contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
@@ -559,16 +553,14 @@ syn match   shSpecialStart        "\%(\\\)*\[\"'`$()#]"   
                contained       nextgroup=shBks
 syn match   shSpecial  "^\%(\\\)*\[\"'`$()#]"
 syn match   shSpecialNoZS      contained       "\%(\\\)*\[\"'`$()#]"
 syn match   shSpecialNxt       contained       "\[\"'`$()#]"
-"syn region  shBkslshSnglQuote contained       matchgroup=shQuote start=+'+ 
end=+'+    contains=@Spell nextgroup=shSpecialStart
-"syn region  shBkslshDblQuote  contained       matchgroup=shQuote start=+"+ 
skip=+\"+ end=+"+  contains=@shDblQuoteList,shStringSpecial,@Spell 
nextgroup=shSpecialStart
 
 " Comments: {{{1
 "==========
 syn cluster    shCommentGroup  contains=shTodo,@Spell
 if exists("b:is_bash")
- syn match     shTodo  contained               
"\<\%(COMBAK\|FIXME\|TODO\|XXX\)\ze:\=\>"
+    syn match  shTodo  contained               
"\<\%(COMBAK\|FIXME\|TODO\|XXX\)\ze:\=\>"
 else
- syn keyword   shTodo  contained               COMBAK FIXME TODO XXX
+    syn keyword        shTodo  contained               COMBAK FIXME TODO XXX
 endif
 syn match      shComment               "^\s*\zs#.*$"   contains=@shCommentGroup
 syn match      shComment               "\s\zs#.*$"     contains=@shCommentGroup
@@ -601,7 +593,7 @@ ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc16 
start="<<-\s*\\_$\_s*
 " =============
 " available for: bash and ksh (except ksh88) but not if its a posix
 if exists("b:is_bash") || ((exists("b:is_kornshell") && !exists("b:is_ksh88")) 
&& !exists("b:is_posix"))
- syn match shHereString "<<<"  skipwhite       nextgroup=shCmdParenRegion
+    syn match shHereString "<<<"       skipwhite       
nextgroup=shCmdParenRegion
 endif
 
 " Identifiers: {{{1
@@ -609,112 +601,111 @@ endif
 syn match  shSetOption "\s\zs[-+][a-zA-Z0-9]\+\>"      contained
 syn match  shVariable  "\<\h\w*\ze="                   nextgroup=shVarAssign
 if exists("b:is_bash")
- " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
- syn region  shArrayValue      contained       start="\[\%(..\{-}\]=\)\@=" 
end="\]=\@="        contains=@shArrayValueList nextgroup=shVarAssign
- syn cluster shArrayValueList  
contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,bashSpecialVariables,shParenError
- syn region  shArrayRegion     contained matchgroup=shShellVariables start="(" 
skip='\\\|\.' end=")" contains=@shArrayValueList,shArrayValue,shComment
+    " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
+    syn region  shArrayValue   contained       start="\[\%(..\{-}\]=\)\@=" 
end="\]=\@="        contains=@shArrayValueList nextgroup=shVarAssign
+    syn cluster shArrayValueList       
contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,bashSpecialVariables,shParenError
+    syn region  shArrayRegion  contained matchgroup=shShellVariables start="(" 
skip='\\\|\.' end=")" contains=@shArrayValueList,shArrayValue,shComment
 elseif (exists("b:is_kornshell") && !exists("b:is_ksh88"))
- " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
- syn region  shArrayValue      contained       start="\[\%(..\{-}\]=\)\@=" 
end="\]=\@="        contains=@shArrayValueList nextgroup=shVarAssign
- syn cluster shArrayValueList  
contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,kshSpecialVariables,shParenError
- syn region  shArrayRegion     contained matchgroup=shShellVariables start="(" 
skip='\\\|\.' end=")" 
contains=@shArrayValueList,shArrayValue,shComment,shArrayRegion
+    " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
+    syn region  shArrayValue   contained       start="\[\%(..\{-}\]=\)\@=" 
end="\]=\@="        contains=@shArrayValueList nextgroup=shVarAssign
+    syn cluster shArrayValueList       
contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,kshSpecialVariables,shParenError
+    syn region  shArrayRegion  contained matchgroup=shShellVariables start="(" 
skip='\\\|\.' end=")" 
contains=@shArrayValueList,shArrayValue,shComment,shArrayRegion
 endif
 if exists("b:is_bash") || exists("b:is_kornshell")
- syn match shVariable  
"\<\h\w*\%(\[..\{-}\]\)\=\ze\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="   
contains=shDerefVarArray nextgroup=shVarAssign
- syn match shVarAssign contained       "\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="      
nextgroup=shArrayRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+    syn match shVariable       
"\<\h\w*\%(\[..\{-}\]\)\=\ze\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="   
contains=shDerefVarArray nextgroup=shVarAssign
+    syn match shVarAssign      contained       
"\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="      
nextgroup=shArrayRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
 else
- syn match  shVarAssign        contained       "="     
nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+    syn match  shVarAssign     contained       "="     
nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
 endif
 syn match  shVar       contained       "\h\w*"
 syn region shAtExpr    contained       start="@(" end=")" contains=@shIdList
 if exists("b:is_bash")
- syn match  shSet "^\s*set\ze\s\+$"
- syn region shSetList oneline matchgroup=shSet 
start="\<\%(declare\|local\|export\)\>\ze[/a-zA-Z_]\@!" end="$"         
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|="    
contains=@shIdList
- syn region shSetList oneline matchgroup=shSet 
start="\<\%(set\|unset\)\>[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"             
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+="       
contains=@shIdList nextgroup=shComment
+    syn match  shSet "^\s*set\ze\s\+$"
+    syn region shSetList oneline matchgroup=shSet 
start="\<\%(declare\|local\|export\)\>\ze[/a-zA-Z_]\@!" end="$"              
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|="    
contains=@shIdList
+    syn region shSetList oneline matchgroup=shSet 
start="\<\%(set\|unset\)\>[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"          
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+="       
contains=@shIdList nextgroup=shComment
 elseif exists("b:is_kornshell") || exists("b:is_posix")
- syn match  shSet "^\s*set\ze\s\+$"
- if exists("b:is_dash")
-  syn region shSetList oneline matchgroup=shSet 
start="\<\%(local\)\>\ze[/]\@!" end="$"                        
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList
- endif
- syn region shSetList oneline matchgroup=shSet start="\<\(export\)\>\ze[/]\@!" 
end="$"                 matchgroup=shSetListDelim end="\ze[}|);&]" 
matchgroup=NONE end="\ze\s\+[#=]"    contains=@shIdList
- syn region shSetList oneline matchgroup=shSet 
start="\<\%(set\|unset\>\)\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"          
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList nextgroup=shComment
+    syn match  shSet "^\s*set\ze\s\+$"
+    if exists("b:is_dash")
+        syn region shSetList oneline matchgroup=shSet 
start="\<\%(local\)\>\ze[/]\@!" end="$"                  
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList
+        syn keyword shStatement chdir
+    endif
+    syn region shSetList oneline matchgroup=shSet 
start="\<\(export\)\>\ze[/]\@!" end="$"                      
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList
+    syn region shSetList oneline matchgroup=shSet 
start="\<\%(set\|unset\>\)\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"               
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList nextgroup=shComment
 else
- syn region shSetList oneline matchgroup=shSet 
start="\<\(set\|export\|unset\)\>\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"   
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList
+    syn region shSetList oneline matchgroup=shSet 
start="\<\(set\|export\|unset\)\>\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"        
matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"    
contains=@shIdList
 endif
 
 " KornShell namespace: {{{1
 if exists("b:is_kornshell") && !exists("b:is_ksh88") && !exists("b:is_mksh")
- syn keyword shFunctionKey namespace skipwhite skipnl nextgroup=shFunctionTwo
+    syn keyword shFunctionKey namespace skipwhite skipnl 
nextgroup=shFunctionTwo
 endif
 
 " Functions: {{{1
 if !exists("b:is_posix")
- syn keyword shFunctionKey function    skipwhite skipnl nextgroup=shFunctionTwo
+    syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
 endif
 
 if exists("b:is_bash")
- syn keyword shFunctionKey coproc
- ShFoldFunctions syn region shFunctionOne      matchgroup=shFunction 
start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*{"                end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
- ShFoldFunctions syn region shFunctionTwo      matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*{"     
end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
- ShFoldFunctions syn region shFunctionThree    matchgroup=shFunction 
start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*("                end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
- ShFoldFunctions syn region shFunctionFour     matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*)"     
end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    syn keyword shFunctionKey coproc
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*{"                end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*{"     
end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*("                end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*)"     
end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
 else
- ShFoldFunctions syn region shFunctionOne      matchgroup=shFunction 
start="^\s*\h\w*\s*()\_s*{"                       end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
- ShFoldFunctions syn region shFunctionTwo      matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{"            end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
- ShFoldFunctions syn region shFunctionThree    matchgroup=shFunction 
start="^\s*\h\w*\s*()\_s*("                       end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
- ShFoldFunctions syn region shFunctionFour     matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*("            end=")" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\h\w*\s*()\_s*{"                       end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{"            end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\h\w*\s*()\_s*("                       end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*("            end=")" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
 endif
 
 " Parameter Dereferencing: {{{1
 " ========================
-" Note: sh04 failure with following line
-"if !exists("g:sh_no_error") && !(exists("b:is_bash") || 
exists("b:is_kornshell") || exists("b:is_posix"))
 if !exists("g:sh_no_error")
- syn match  shDerefWordError   "[^}$[~]"       contained
+    syn match  shDerefWordError        "[^}$[~]"       contained
 endif
 syn match  shDerefSimple       "\$\%(\h\w*\|\d\)"      nextgroup=@shNoZSList
 if exists("b:is_kornshell") && !exists("b:is_ksh88")
- if exists("b:is_mksh")
-  syn region shDeref   matchgroup=PreProc start="\${\ze[^      
|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
- elseif exists("b:generic_korn")
-  syn region shDeref   matchgroup=PreProc start="\${\ze[^      
<|]" end="}"    contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
- else
-  syn region shDeref   matchgroup=PreProc start="\${\ze[^      
<]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
- endif
+    if exists("b:is_mksh")
+        syn region shDeref     matchgroup=PreProc start="\${\ze[^      
|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
+    elseif exists("b:generic_korn")
+        syn region shDeref     matchgroup=PreProc start="\${\ze[^      
<|]" end="}"    contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
+    else
+        syn region shDeref     matchgroup=PreProc start="\${\ze[^      
<]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
+    endif
 elseif exists("b:is_bash")
- syn region shDeref    matchgroup=PreProc start="\${\ze[^      
|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
+    syn region shDeref matchgroup=PreProc start="\${\ze[^      
|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
 else
- syn region shDeref    matchgroup=PreProc start="\${" end="}"                  
contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
+    syn region shDeref matchgroup=PreProc start="\${" end="}"                  
contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
 endif
 syn match  shDerefSimple       "\$[-#*@!?]"    nextgroup=@shNoZSList
 syn match  shDerefSimple       "\$\$"  nextgroup=@shNoZSList
 syn match  shDerefSimple       "\${\d}"        nextgroup=@shNoZSList   
nextgroup=shSpecialStart
 if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
- syn region shDeref    matchgroup=PreProc start="\${##\=" end="}"      
contains=@shDerefList   nextgroup=@shSpecialNoZS,shSpecialStart
- syn region shDeref    matchgroup=PreProc start="\${\$\$" end="}"      
contains=@shDerefList   nextgroup=@shSpecialNoZS,shSpecialStart
+    syn region shDeref matchgroup=PreProc start="\${##\=" end="}"      
contains=@shDerefList   nextgroup=@shSpecialNoZS,shSpecialStart
+    syn region shDeref matchgroup=PreProc start="\${\$\$" end="}"      
contains=@shDerefList   nextgroup=@shSpecialNoZS,shSpecialStart
 endif
 
 " ksh: ${.sh.*} variables: {{{1
 " ========================================
 if exists("b:is_kornshell") && !exists("b:is_ksh88") && !exists("b:is_mksh")
- syn match  shDerefVar contained       "\.\+"  nextgroup=@shDerefVarList
- syn region shDeref    matchgroup=PreProc start="\${\ze[\.]" end="}"   
contains=@shDerefVarList,shDerefPSR,shDerefPPS
+    syn match  shDerefVar      contained       "\.\+"  
nextgroup=@shDerefVarList
+    syn region shDeref matchgroup=PreProc start="\${\ze[\.]" end="}"   
contains=@shDerefVarList,shDerefPSR,shDerefPPS
 endif
 
 " ksh: ${!var[*]} array index list syntax: {{{1
 " ========================================
 if (exists("b:is_kornshell") && !exists("b:is_ksh88")) || exists("b:is_posix")
- syn region shDeref    matchgroup=PreProc start="\${!" end="}" 
contains=@shDerefVarArray
+    syn region shDeref matchgroup=PreProc start="\${!" end="}" 
contains=@shDerefVarArray
 endif
 
 " bash: ${!prefix*} and ${#parameter}: {{{1
 " ====================================
 if exists("b:is_bash")
- syn region shDeref    matchgroup=PreProc start="\${!" end="\*\=}"     
contains=@shDerefList,shDerefOffset
- syn match  shDerefVar contained       "{\@<=!\h\w*"           
nextgroup=@shDerefVarList
+    syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}"     
contains=@shDerefList,shDerefOffset
+    syn match  shDerefVar      contained       "{\@<=!\h\w*"           
nextgroup=@shDerefVarList
 endif
 if (exists("b:is_kornshell") && !exists("b:is_ksh88"))
- syn match  shDerefVar contained       "{\@<=!\h\w*[[:alnum:]_.]*"     
nextgroup=@shDerefVarList
+    syn match  shDerefVar      contained       "{\@<=!\h\w*[[:alnum:]_.]*"     
nextgroup=@shDerefVarList
 endif
 
 syn match  shDerefSpecial      contained       "{\@<=[-*@?0]"          
nextgroup=shDerefOp,shDerefOffset,shDerefOpError
@@ -722,7 +713,7 @@ syn match  shDerefSpecial   contained       
"\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@s
 syn match  shDerefVar  contained       "{\@<=\h\w*"            
nextgroup=@shDerefVarList
 syn match  shDerefVar  contained       '\d'                            
nextgroup=@shDerefVarList
 if exists("b:is_kornshell") || exists("b:is_posix")
-  syn match  shDerefVar        contained       "{\@<=\h\w*[[:alnum:]_.]*"      
nextgroup=@shDerefVarList
+    syn match  shDerefVar      contained       "{\@<=\h\w*[[:alnum:]_.]*"      
nextgroup=@shDerefVarList
 endif
 
 " sh ksh bash : ${var[... ]...}  array reference: {{{1
@@ -745,50 +736,50 @@ syn region  shDerefVarArray   contained   
matchgroup=shDeref start="\[" end="]"   co
 "        bash : ${parameter@operator} transforms parameter 
(operator∈[uULqEPARa])
 syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
 if !exists("g:sh_no_error")
- syn match shDerefOpError      contained       ":[[:punct:]]"
+    syn match shDerefOpError   contained       ":[[:punct:]]"
 endif
 syn match  shDerefOp   contained       ":\=[-=?]"      
nextgroup=@shDerefPatternList
 syn match  shDerefOp   contained       ":\=+"  nextgroup=@shDerefPatternList
 if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
- syn match  shDerefOp  contained       "#\{1,2}"               
nextgroup=@shDerefPatternList
- syn match  shDerefOp  contained       "%\{1,2}"               
nextgroup=@shDerefPatternList
- syn match  shDerefPattern     contained       "[^{}]\+"               
contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape
 nextgroup=shDerefPattern skipnl
- syn region shDerefPattern     contained       start="{" end="}"       
contains=shDeref,shDerefSimple,shDerefString,shCommandSub 
nextgroup=shDerefPattern
- " Match parametric bracket expressions with a leading whitespace character.
- syn region shDerefPattern     contained       matchgroup=shBracketExprDelim 
start="\[" end="\]"       contains=@shBracketExprList,shDoubleQuote 
nextgroup=shDerefPattern
- call s:GenerateBracketExpressionItems({'itemGroup': 'shDerefPattern', 
'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'contained 
nextgroup=shDerefPattern'})
- syn match  shDerefEscape      contained       '\%(\\\)*\.'
+    syn match  shDerefOp       contained       "#\{1,2}"               
nextgroup=@shDerefPatternList
+    syn match  shDerefOp       contained       "%\{1,2}"               
nextgroup=@shDerefPatternList
+    syn match  shDerefPattern  contained       "[^{}]\+"               
contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape
 nextgroup=shDerefPattern skipnl
+    syn region shDerefPattern  contained       start="{" end="}"       
contains=shDeref,shDerefSimple,shDerefString,shCommandSub 
nextgroup=shDerefPattern
+    " Match parametric bracket expressions with a leading whitespace character.
+    syn region shDerefPattern  contained       matchgroup=shBracketExprDelim 
start="\[" end="\]"       contains=@shBracketExprList,shDoubleQuote 
nextgroup=shDerefPattern
+    call s:GenerateBracketExpressionItems({'itemGroup': 'shDerefPattern', 
'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'contained 
nextgroup=shDerefPattern'})
+    syn match  shDerefEscape   contained       '\%(\\\)*\.'
 endif
 if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88") 
&& !exists("b:is_mksh") && !exists("b:is_ksh93u") && !exists("b:is_ksh2020"))
- syn match  shDerefOp  contained       "[,^]\{1,2}"    
nextgroup=@shDerefPatternList
+    syn match  shDerefOp       contained       "[,^]\{1,2}"    
nextgroup=@shDerefPatternList
 endif
 if exists("b:is_bash")
- syn match  shDerefOp  contained       "@[uULQEPAKa]"
+    syn match  shDerefOp       contained       "@[uULQEPAKa]"
 endif
 syn region shDerefString       contained       matchgroup=shDerefDelim 
start=+\%(\\)\@<!'+ end=+'+
 syn region shDerefString       contained       matchgroup=shDerefDelim 
start=+\%(\\)\@<!"+ skip=+\"+ end=+"+   contains=@shDblQuoteList,shStringSpecial
 syn match  shDerefString       contained       "\["']" nextgroup=shDerefPattern
 
 if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88")) 
|| exists("b:is_posix")
- " bash ksh posix : ${parameter:offset}
- " bash ksh posix : ${parameter:offset:length}
- syn region shDerefOffset      contained       start=':[^-=?+]' end='\ze:'     
end='\ze}'      contains=shDeref,shDerefSimple,shDerefEscape    
nextgroup=shDerefLen,shDeref,shDerefSimple
- syn region shDerefOffset      contained       start=':\s-'    end='\ze:'      
end='\ze}'      contains=shDeref,shDerefSimple,shDerefEscape    
nextgroup=shDerefLen,shDeref,shDerefSimple
- syn match  shDerefLen contained       ":[^}]\+"       
contains=shDeref,shDerefSimple,shArithmetic
+    " bash ksh posix : ${parameter:offset}
+    " bash ksh posix : ${parameter:offset:length}
+    syn region shDerefOffset   contained       start=':[^-=?+]' end='\ze:'     
end='\ze}'      contains=shDeref,shDerefSimple,shDerefEscape    
nextgroup=shDerefLen,shDeref,shDerefSimple
+    syn region shDerefOffset   contained       start=':\s-'    end='\ze:'      
end='\ze}'      contains=shDeref,shDerefSimple,shDerefEscape    
nextgroup=shDerefLen,shDeref,shDerefSimple
+    syn match  shDerefLen      contained       ":[^}]\+"       
contains=shDeref,shDerefSimple,shArithmetic
 endif
 
 if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88"))
- " bash ksh : ${parameter/pattern/string}
- " bash ksh : ${parameter//pattern/string}
- syn match  shDerefPPS contained       '/\{1,2}'       nextgroup=shDerefPPSleft
- syn region shDerefPPSleft     contained       start='.'       
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}' end='"'      
nextgroup=shDerefPPSright       contains=@shPPSLeftList
- syn region shDerefPPSright    contained       start='.'       
skip=@\%(\\\)\+@                end='\ze}'                              
contains=@shPPSRightList
-
- " bash ksh : ${parameter/#pattern/string}
- " bash ksh : ${parameter/%pattern/string}
- syn match  shDerefPSR contained       '/[#%]' 
nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
- syn region shDerefPSRleft     contained       start='[^"']'   
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}'      
nextgroup=shDerefPSRright       contains=shBracketExpr
- syn region shDerefPSRright    contained       start='.'       
skip=@\%(\\\)\+@                end='\ze}'
+    " bash ksh : ${parameter/pattern/string}
+    " bash ksh : ${parameter//pattern/string}
+    syn match  shDerefPPS      contained       '/\{1,2}'       
nextgroup=shDerefPPSleft
+    syn region shDerefPPSleft  contained       start='.'       
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}' end='"'      
nextgroup=shDerefPPSright       contains=@shPPSLeftList
+    syn region shDerefPPSright contained       start='.'       
skip=@\%(\\\)\+@                end='\ze}'                              
contains=@shPPSRightList
+
+    " bash ksh : ${parameter/#pattern/string}
+    " bash ksh : ${parameter/%pattern/string}
+    syn match  shDerefPSR      contained       '/[#%]' 
nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
+    syn region shDerefPSRleft  contained       start='[^"']'   
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}'      
nextgroup=shDerefPSRright       contains=shBracketExpr
+    syn region shDerefPSRright contained       start='.'       
skip=@\%(\\\)\+@                end='\ze}'
 endif
 
 " Arithmetic Parenthesized Expressions: {{{1
@@ -797,49 +788,29 @@ syn region shParen matchgroup=shArithRegion 
start='\$\@!(\%(\ze[^(]\|$\)' end=')
 
 " Additional sh Keywords: {{{1
 " ===================
-syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd 
read readonly return shift test trap ulimit umask wait
+" builtins:
+syn keyword shStatement bg break cd continue command eval exec exit export fc 
getopts hash jobs local printf read readonly return shift times trap type 
ulimit umask unalias wait
+" external programs:
+syn keyword shStatement basename cat chgrp chmod chown cksum clear cmp comm cp 
cut date dirname du egrep expr false fgrep find fmt fold getconf grep head 
iconv id join kill killall less ln login logname ls md5sum mkdir mkfifo mknod 
mktemp mv newgrp nice nohup od paste pathchk printenv pwd readlink realpath 
rename rev rm rmdir sed sha1sum sha224sum sha256sum sha384sum sha512sum sleep 
sort strip stty sum sync tail tee test tput tr true tty uname uniq wc which 
xargs
 syn keyword shConditional contained elif else then
 if !exists("g:sh_no_error")
- syn keyword shCondError elif else then
-endif
-
-" Additional ksh Keywords and Aliases: {{{1
-" ===================================
-if exists("b:is_kornshell") || exists("b:is_posix")
- syn keyword shStatement bg builtin disown enum export false fg getconf 
getopts hist jobs let printf sleep true unalias whence
- syn keyword shStatement typeset skipwhite nextgroup=shSetOption
- syn keyword shStatement autoload compound fc float functions hash history 
integer nameref nohup r redirect source stop suspend times type
- if exists("b:is_posix")
-  syn keyword shStatement command
- else
-  syn keyword shStatement time
- endif
-
-" Additional bash Keywords: {{{1
-" =====================
-elseif exists("b:is_bash")
- syn keyword shStatement bg builtin disown export false fg getopts jobs let 
printf true unalias
- syn keyword shStatement typeset nextgroup=shSetOption
- syn keyword shStatement fc hash history source suspend times type
- syn keyword shStatement bind caller compopt declare dirs enable help logout 
local mapfile popd pushd readarray shopt typeset
-else
- syn keyword shStatement login newgrp
+    syn keyword shCondError elif else then
 endif
 
 " Synchronization: {{{1
 " ================
 if !exists("g:sh_minlines")
- let s:sh_minlines = 200
+    let s:sh_minlines = 200
 else
- let s:sh_minlines= g:sh_minlines
+    let s:sh_minlines= g:sh_minlines
 endif
 if !exists("g:sh_maxlines")
- let s:sh_maxlines = 2*s:sh_minlines
- if s:sh_maxlines < 25
-  let s:sh_maxlines= 25
- endif
+    let s:sh_maxlines = 2*s:sh_minlines
+    if s:sh_maxlines < 25
+        let s:sh_maxlines= 25
+    endif
 else
- let s:sh_maxlines= g:sh_maxlines
+    let s:sh_maxlines= g:sh_maxlines
 endif
 exec "syn sync minlines=" . s:sh_minlines . " maxlines=" . s:sh_maxlines
 syn sync match shCaseEsacSync  grouphere       shCaseEsac      "\<case\>"
@@ -856,147 +827,147 @@ syn sync match shWhileSync      grouphere       
shRepeat        "\<while\>"
 " Default Highlighting: {{{1
 " =====================
 if !exists("skip_sh_syntax_inits")
- hi def link shArithRegion     shShellVariables
- hi def link shArrayValue      shDeref
- hi def link shAstQuote        shDoubleQuote
- hi def link shAtExpr  shSetList
- hi def link shBkslshSnglQuote shSingleQuote
- hi def link shBkslshDblQuote  shDOubleQuote
- hi def link shBeginHere       shRedir
- hi def link shCaseBar shConditional
- hi def link shCaseCommandSub  shCommandSub
- hi def link shCaseDoubleQuote shDoubleQuote
- hi def link shCaseIn  shConditional
- hi def link shQuote   shOperator
- hi def link shCaseSingleQuote shSingleQuote
- hi def link shCaseStart       shConditional
- hi def link shCmdSubRegion    shShellVariables
- hi def link shColon   shComment
- hi def link shDerefOp shOperator
- hi def link shDerefPOL        shDerefOp
- hi def link shDerefPPS        shDerefOp
- hi def link shDerefPSR        shDerefOp
- hi def link shDeref   shShellVariables
- hi def link shDerefDelim      shOperator
- hi def link shDerefSimple     shDeref
- hi def link shDerefSpecial    shDeref
- hi def link shDerefString     shDoubleQuote
- hi def link shDerefVar        shDeref
- hi def link shDoubleQuote     shString
- hi def link shEcho    shString
- hi def link shEchoDelim       shOperator
- hi def link shEchoQuote       shString
- hi def link shForPP   shLoop
- hi def link shFunction        Function
- hi def link shEmbeddedEcho    shString
- hi def link shEscape  shCommandSub
- hi def link shExDoubleQuote   shDoubleQuote
- hi def link shExSingleQuote   shSingleQuote
- hi def link shHereDoc shString
- hi def link shHereString      shRedir
- hi def link shHerePayload     shHereDoc
- hi def link shLoop    shStatement
- hi def link shSpecialNxt      shSpecial
- hi def link shNoQuote shDoubleQuote
- hi def link shOption  shCommandSub
- hi def link shPattern shString
- hi def link shParen   shArithmetic
- hi def link shPosnParm        shShellVariables
- hi def link shQuickComment    shComment
- hi def link shBQComment       shComment
- hi def link shRange   shOperator
- hi def link shRedir   shOperator
- hi def link shSetListDelim    shOperator
- hi def link shSetOption       shOption
- hi def link shSingleQuote     shString
- hi def link shSource  shOperator
- hi def link shStringSpecial   shSpecial
- hi def link shSpecialStart    shSpecial
- hi def link shSubShRegion     shOperator
- hi def link shTestOpr shConditional
- hi def link shTestPattern     shString
- hi def link shTestDoubleQuote shString
- hi def link shTestSingleQuote shString
- hi def link shTouchCmd        shStatement
- hi def link shVariable        shSetList
- hi def link shWrapLineOperator        shOperator
-
- if exists("b:is_bash")
-   hi def link bashAdminStatement      shStatement
-   hi def link bashSpecialVariables    shShellVariables
-   hi def link bashStatement           shStatement
-   hi def link shCharClass             shSpecial
-   hi def link shDerefOffset           shDerefOp
-   hi def link shDerefLen              shDerefOffset
- endif
- if exists("b:is_kornshell") || exists("b:is_posix")
-   hi def link kshSpecialVariables     shShellVariables
-   hi def link kshStatement            shStatement
- endif
-
- if !exists("g:sh_no_error")
-  hi def link shCaseError              Error
-  hi def link shCondError              Error
-  hi def link shCurlyError             Error
-  hi def link shDerefOpError           Error
-  hi def link shDerefWordError         Error
-  hi def link shDoError                Error
-  hi def link shEsacError              Error
-  hi def link shIfError                Error
-  hi def link shInError                Error
-  hi def link shParenError             Error
-  hi def link shTestError              Error
-  if exists("b:is_kornshell") || exists("b:is_posix")
-    hi def link shDTestError           Error
-  endif
- endif
-
- hi def link shArithmetic              Special
- hi def link shBracketExprDelim                Delimiter
- hi def link shCharClass               Identifier
- hi def link shCollSymb                shCharClass
- hi def link shEqClass         shCharClass
- hi def link shSnglCase                Statement
- hi def link shCommandSub              Special
- hi def link shCommandSubBQ            shCommandSub
- hi def link shSubshare                shCommandSub
- hi def link shValsub          shCommandSub
- hi def link shComment         Comment
- hi def link shConditional             Conditional
- hi def link shCtrlSeq         Special
- hi def link shExprRegion              Delimiter
- hi def link shFunctionKey             Function
- hi def link shFunctionName            Function
- hi def link shNumber          Number
- hi def link shOperator                Operator
- hi def link shRepeat          Repeat
- hi def link shSet             Statement
- hi def link shSetList         Identifier
- hi def link shShellVariables          PreProc
- hi def link shSpecial         Special
- hi def link shSpecialDQ               Special
- hi def link shSpecialSQ               Special
- hi def link shSpecialNoZS             shSpecial
- hi def link shStatement               Statement
- hi def link shString          String
- hi def link shTodo            Todo
- hi def link shAlias           Identifier
- hi def link shHereDoc01               shRedir
- hi def link shHereDoc02               shRedir
- hi def link shHereDoc03               shRedir
- hi def link shHereDoc04               shRedir
- hi def link shHereDoc05               shRedir
- hi def link shHereDoc06               shRedir
- hi def link shHereDoc07               shRedir
- hi def link shHereDoc08               shRedir
- hi def link shHereDoc09               shRedir
- hi def link shHereDoc10               shRedir
- hi def link shHereDoc11               shRedir
- hi def link shHereDoc12               shRedir
- hi def link shHereDoc13               shRedir
- hi def link shHereDoc14               shRedir
- hi def link shHereDoc15               shRedir
- hi def link shHereDoc16               shRedir
+    hi def link shArithRegion  shShellVariables
+    hi def link shArrayValue   shDeref
+    hi def link shAstQuote     shDoubleQuote
+    hi def link shAtExpr       shSetList
+    hi def link shBkslshSnglQuote      shSingleQuote
+    hi def link shBkslshDblQuote       shDOubleQuote
+    hi def link shBeginHere    shRedir
+    hi def link shCaseBar      shConditional
+    hi def link shCaseCommandSub       shCommandSub
+    hi def link shCaseDoubleQuote      shDoubleQuote
+    hi def link shCaseIn       shConditional
+    hi def link shQuote        shOperator
+    hi def link shCaseSingleQuote      shSingleQuote
+    hi def link shCaseStart    shConditional
+    hi def link shCmdSubRegion shShellVariables
+    hi def link shColon        shComment
+    hi def link shDerefOp      shOperator
+    hi def link shDerefPOL     shDerefOp
+    hi def link shDerefPPS     shDerefOp
+    hi def link shDerefPSR     shDerefOp
+    hi def link shDeref        shShellVariables
+    hi def link shDerefDelim   shOperator
+    hi def link shDerefSimple  shDeref
+    hi def link shDerefSpecial shDeref
+    hi def link shDerefString  shDoubleQuote
+    hi def link shDerefVar     shDeref
+    hi def link shDoubleQuote  shString
+    hi def link shEcho shString
+    hi def link shEchoDelim    shOperator
+    hi def link shEchoQuote    shString
+    hi def link shForPP        shLoop
+    hi def link shFunction     Function
+    hi def link shEmbeddedEcho shString
+    hi def link shEscape       shCommandSub
+    hi def link shExDoubleQuote        shDoubleQuote
+    hi def link shExSingleQuote        shSingleQuote
+    hi def link shHereDoc      shString
+    hi def link shHereString   shRedir
+    hi def link shHerePayload  shHereDoc
+    hi def link shLoop shStatement
+    hi def link shSpecialNxt   shSpecial
+    hi def link shNoQuote      shDoubleQuote
+    hi def link shOption       shCommandSub
+    hi def link shPattern      shString
+    hi def link shParen        shArithmetic
+    hi def link shPosnParm     shShellVariables
+    hi def link shQuickComment shComment
+    hi def link shBQComment    shComment
+    hi def link shRange        shOperator
+    hi def link shRedir        shOperator
+    hi def link shSetListDelim shOperator
+    hi def link shSetOption    shOption
+    hi def link shSingleQuote  shString
+    hi def link shSource       shOperator
+    hi def link shStringSpecial        shSpecial
+    hi def link shSpecialStart shSpecial
+    hi def link shSubShRegion  shOperator
+    hi def link shTestOpr      shConditional
+    hi def link shTestPattern  shString
+    hi def link shTestDoubleQuote      shString
+    hi def link shTestSingleQuote      shString
+    hi def link shTouchCmd     shStatement
+    hi def link shVariable     shSetList
+    hi def link shWrapLineOperator     shOperator
+
+    if exists("b:is_bash")
+        hi def link bashAdminStatement shStatement
+        hi def link bashSpecialVariables       shShellVariables
+        hi def link bashStatement              shStatement
+        hi def link shCharClass                shSpecial
+        hi def link shDerefOffset              shDerefOp
+        hi def link shDerefLen         shDerefOffset
+    endif
+    if exists("b:is_kornshell") || exists("b:is_posix")
+        hi def link kshSpecialVariables        shShellVariables
+        hi def link kshStatement               shStatement
+    endif
+
+    if !exists("g:sh_no_error")
+        hi def link shCaseError                Error
+        hi def link shCondError                Error
+        hi def link shCurlyError               Error
+        hi def link shDerefOpError             Error
+        hi def link shDerefWordError           Error
+        hi def link shDoError          Error
+        hi def link shEsacError                Error
+        hi def link shIfError          Error
+        hi def link shInError          Error
+        hi def link shParenError               Error
+        hi def link shTestError                Error
+        if exists("b:is_kornshell") || exists("b:is_posix")
+            hi def link shDTestError           Error
+        endif
+    endif
+
+    hi def link shArithmetic           Special
+    hi def link shBracketExprDelim             Delimiter
+    hi def link shCharClass            Identifier
+    hi def link shCollSymb             shCharClass
+    hi def link shEqClass              shCharClass
+    hi def link shSnglCase             Statement
+    hi def link shCommandSub           Special
+    hi def link shCommandSubBQ         shCommandSub
+    hi def link shSubshare             shCommandSub
+    hi def link shValsub               shCommandSub
+    hi def link shComment              Comment
+    hi def link shConditional          Conditional
+    hi def link shCtrlSeq              Special
+    hi def link shExprRegion           Delimiter
+    hi def link shFunctionKey          Function
+    hi def link shFunctionName         Function
+    hi def link shNumber               Number
+    hi def link shOperator             Operator
+    hi def link shRepeat               Repeat
+    hi def link shSet          Statement
+    hi def link shSetList              Identifier
+    hi def link shShellVariables               PreProc
+    hi def link shSpecial              Special
+    hi def link shSpecialDQ            Special
+    hi def link shSpecialSQ            Special
+    hi def link shSpecialNoZS          shSpecial
+    hi def link shStatement            Statement
+    hi def link shString               String
+    hi def link shTodo         Todo
+    hi def link shAlias                Identifier
+    hi def link shHereDoc01            shRedir
+    hi def link shHereDoc02            shRedir
+    hi def link shHereDoc03            shRedir
+    hi def link shHereDoc04            shRedir
+    hi def link shHereDoc05            shRedir
+    hi def link shHereDoc06            shRedir
+    hi def link shHereDoc07            shRedir
+    hi def link shHereDoc08            shRedir
+    hi def link shHereDoc09            shRedir
+    hi def link shHereDoc10            shRedir
+    hi def link shHereDoc11            shRedir
+    hi def link shHereDoc12            shRedir
+    hi def link shHereDoc13            shRedir
+    hi def link shHereDoc14            shRedir
+    hi def link shHereDoc15            shRedir
+    hi def link shHereDoc16            shRedir
 endif
 
 " Delete shell folding commands {{{1
@@ -1012,13 +983,13 @@ delfun s:GenerateBracketExpressionItems
 " Set Current Syntax: {{{1
 " ===================
 if exists("b:is_bash")
- let b:current_syntax = "bash"
+    let b:current_syntax = "bash"
 elseif exists("b:is_kornshell")
- let b:current_syntax = "ksh"
+    let b:current_syntax = "ksh"
 elseif exists("b:is_posix")
- let b:current_syntax = "posix"
+    let b:current_syntax = "posix"
 else
- let b:current_syntax = "sh"
+    let b:current_syntax = "sh"
 endif
 
 " vim: ts=16 fdm=marker
diff --git a/runtime/syntax/testdir/dumps/sh_09_00.dump 
b/runtime/syntax/testdir/dumps/sh_09_00.dump
index 58ab2022e..57e561737 100644
--- a/runtime/syntax/testdir/dumps/sh_09_00.dump
+++ b/runtime/syntax/testdir/dumps/sh_09_00.dump
@@ -16,5 +16,5 @@
 |(+0#e000e06&| |c+0#af5f00255&|d| +0#e000e06&|$|{|H|O|M|E|}| |;+0#af5f00255&| 
+0#e000e06&|$|p|w|d| |)| +0#0000000&||| |w+0#af5f00255&|c| 
+0#0000000&|-+0#e000e06&|c| +0#0000000&@45
 |(+0#e000e06&| |c+0#af5f00255&|d| +0#e000e06&|$|{|H|O|M|E|}| |)| 
+0#0000000&||| |w+0#af5f00255&|c| +0#0000000&|-+0#e000e06&|c| +0#0000000&@52
 
|(|(+0#e000e06&|n+0#00e0e07&|=+0#0000000&|1+0#e000002&|+|2|)+0#e000e06&|)+0#ffffff16#ff404010|
 +0#0000000#ffffff0@65
-|l+0#af5f00255&|e|t| 
+0#0000000&|n+0#00e0e07&|=+0#0000000&|1+0#e000002&|++0#0000000&|2+0#e000002&| 
+0#0000000&@65
-|i|s|_|d|a|s|h|:| |1|,| |i|s|_|p|o|s|i|x|:| |1|,| |i|s|_|s|h|:| |1|,| 
@22|1|,|1| @10|A|l@1| 
+|#+0#0000e05&| |t|h|i|s| |i|s| |a| |s|y|n|t|a|x| |e|r@1|o|r|,| |"|l|e|t|"| 
|i|s| |n|o|t| |a| |k|e|y|w|o|r|d| |i|n| |d|a|s|h| +0#0000000&@18
+|i|s|_|d|a|s|h|:| |1|,| |i|s|_|p|o|s|i|x|:| |1|,| |i|s|_|s|h|:| |1|,| 
@22|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_09_01.dump 
b/runtime/syntax/testdir/dumps/sh_09_01.dump
new file mode 100644
index 000000000..817f705cc
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_09_01.dump
@@ -0,0 +1,20 @@
+|(+0#e000e06#ffffff0| |c+0#af5f00255&|d| +0#e000e06&|;+0#af5f00255&| 
+0#e000e06&|$|p|w|d| |)| +0#0000000&||| |w+0#af5f00255&|c| 
+0#0000000&|-+0#e000e06&|c| +0#0000000&@53
+|(+0#e000e06&| |c+0#af5f00255&|d| +0#e000e06&|$|H|O|M|E| |;+0#af5f00255&| 
+0#e000e06&|$|p|w|d| |)| +0#0000000&||| |w+0#af5f00255&|c| 
+0#0000000&|-+0#e000e06&|c| +0#0000000&@47
+|(+0#e000e06&| |c+0#af5f00255&|d| +0#e000e06&|$|{|H|O|M|E|}| |;+0#af5f00255&| 
+0#e000e06&|$|p|w|d| |)| +0#0000000&||| |w+0#af5f00255&|c| 
+0#0000000&|-+0#e000e06&|c| +0#0000000&@45
+|(+0#e000e06&| |c+0#af5f00255&|d| +0#e000e06&|$|{|H|O|M|E|}| |)| 
+0#0000000&||| |w+0#af5f00255&|c| +0#0000000&|-+0#e000e06&|c| +0#0000000&@52
+|(|(+0#e000e06&|n+0#00e0e07&|=+0#0000000&|1+0#e000002&|+|2|)+0#e000e06&|)+0#ffffff16#ff404010|
 +0#0000000#ffffff0@65
+>#+0#0000e05&| |t|h|i|s| |i|s| |a| |s|y|n|t|a|x| |e|r@1|o|r|,| |"|l|e|t|"| 
|i|s| |n|o|t| |a| |k|e|y|w|o|r|d| |i|n| |d|a|s|h| +0#0000000&@18
+|l|e|t| |n+0#00e0e07&|=+0#0000000&|1+0#e000002&|++0#0000000&|2+0#e000002&| 
+0#0000000&@65
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|9|,|1| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_bash_alias_00.dump 
b/runtime/syntax/testdir/dumps/sh_bash_alias_00.dump
new file mode 100644
index 000000000..ab76d049b
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_bash_alias_00.dump
@@ -0,0 +1,20 @@
+>#+0#0000e05#ffffff0|!|/|u|s|r|/|b|i|n|/|b|a|s|h| +0#0000000&@59
+@75
+|a+0#af5f00255&|l|i|a|s| |l+0#00e0e07&|s|=+0#af5f00255&|'|l+0#e000002&|s| 
|-@1|c|o|l|o|r|=|a|u|t|o|'+0#af5f00255&| +0#0000000&@48
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|i+0#0000000&|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|A|l@1| 
diff --git a/runtime/syntax/testdir/dumps/sh_ksh2020_05.dump 
b/runtime/syntax/testdir/dumps/sh_ksh2020_05.dump
index ba9f354d5..d1bc36855 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh2020_05.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh2020_05.dump
@@ -11,8 +11,8 @@
 |#+0#0000e05&| |m|k|s|e|r|v|i|c|e| |a|n|d| |e|l|o@1|p| |(|r|a|r|e|l|y| 
|p|r|o|v|i|d|e|d|;| |r|e|q|u|i|r|e|s| |S|H|O|P|T|_|M|K|S|E|R|V|I|C|E|)| 
+0#0000000&@9
 |m|k|s|e|r|v|i|c|e| |-+0#e000e06&@1|m|a|n|;+0#0000000&| |e|l|o@1|p| 
|-+0#e000e06&@1|h|e|l|p| +0#0000000&@45
 @75
-|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s| +0#0000000&@54
-|b|i|n|d|;| |r|e|n|a|m|e| @62
+|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s|,| |r|e|n|a|m|e| 
|s|h|o|u|l|d| |b|e| |h|i|g|h|l|i|g|h|t|e|d| |a|s| |e|x|t|e|r|n|a|l| 
|p|r|o|g|r|a|m| +0#0000000&@4
+|b|i|n|d|;| |r+0#af5f00255&|e|n|a|m|e| +0#0000000&@62
 @75
 |#+0#0000e05&| |;|&| |a|n|d| |;@1|&| |i|n| |c|a|s|e| |s|t|a|t|e|m|e|n|t|s| 
+0#0000000&@43
 |c+0#af5f00255&|a|s|e| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&@65
diff --git a/runtime/syntax/testdir/dumps/sh_ksh88_05.dump 
b/runtime/syntax/testdir/dumps/sh_ksh88_05.dump
index 95bea149c..107e2a9a7 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh88_05.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh88_05.dump
@@ -11,8 +11,8 @@
 |#+0#0000e05&| |m|k|s|e|r|v|i|c|e| |a|n|d| |e|l|o@1|p| |(|r|a|r|e|l|y| 
|p|r|o|v|i|d|e|d|;| |r|e|q|u|i|r|e|s| |S|H|O|P|T|_|M|K|S|E|R|V|I|C|E|)| 
+0#0000000&@9
 |m|k|s|e|r|v|i|c|e| |-+0#e000e06&@1|m|a|n|;+0#0000000&| |e|l|o@1|p| 
|-+0#e000e06&@1|h|e|l|p| +0#0000000&@45
 @75
-|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s| +0#0000000&@54
-|b|i|n|d|;| |r|e|n|a|m|e| @62
+|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s|,| |r|e|n|a|m|e| 
|s|h|o|u|l|d| |b|e| |h|i|g|h|l|i|g|h|t|e|d| |a|s| |e|x|t|e|r|n|a|l| 
|p|r|o|g|r|a|m| +0#0000000&@4
+|b|i|n|d|;| |r+0#af5f00255&|e|n|a|m|e| +0#0000000&@62
 @75
 |#+0#0000e05&| |;|&| |a|n|d| |;@1|&| |i|n| |c|a|s|e| |s|t|a|t|e|m|e|n|t|s| 
+0#0000000&@43
 |c+0#af5f00255&|a|s|e| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&@65
diff --git a/runtime/syntax/testdir/dumps/sh_ksh93u_05.dump 
b/runtime/syntax/testdir/dumps/sh_ksh93u_05.dump
index ba9f354d5..3a1b1ce16 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh93u_05.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh93u_05.dump
@@ -11,8 +11,8 @@
 |#+0#0000e05&| |m|k|s|e|r|v|i|c|e| |a|n|d| |e|l|o@1|p| |(|r|a|r|e|l|y| 
|p|r|o|v|i|d|e|d|;| |r|e|q|u|i|r|e|s| |S|H|O|P|T|_|M|K|S|E|R|V|I|C|E|)| 
+0#0000000&@9
 |m|k|s|e|r|v|i|c|e| |-+0#e000e06&@1|m|a|n|;+0#0000000&| |e|l|o@1|p| 
|-+0#e000e06&@1|h|e|l|p| +0#0000000&@45
 @75
-|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s| +0#0000000&@54
-|b|i|n|d|;| |r|e|n|a|m|e| @62
+|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s|,| |r|e|n|a|m|e| 
|s|h|o|u|l|d| |b|e| |h|i|g|h|l|i|g|h|t|e|d| |a|s| |e|x|t|e|r|n|a|l| 
|c|o|m@1|a|n|d| +0#0000000&@4
+|b|i|n|d|;| |r+0#af5f00255&|e|n|a|m|e| +0#0000000&@62
 @75
 |#+0#0000e05&| |;|&| |a|n|d| |;@1|&| |i|n| |c|a|s|e| |s|t|a|t|e|m|e|n|t|s| 
+0#0000000&@43
 |c+0#af5f00255&|a|s|e| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&@65
diff --git a/runtime/syntax/testdir/dumps/sh_ksh93v_05.dump 
b/runtime/syntax/testdir/dumps/sh_ksh93v_05.dump
index 479efcf81..80b2cc6c0 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh93v_05.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh93v_05.dump
@@ -11,8 +11,8 @@
 |#+0#0000e05&| |m|k|s|e|r|v|i|c|e| |a|n|d| |e|l|o@1|p| |(|r|a|r|e|l|y| 
|p|r|o|v|i|d|e|d|;| |r|e|q|u|i|r|e|s| |S|H|O|P|T|_|M|K|S|E|R|V|I|C|E|)| 
+0#0000000&@9
 |m|k|s|e|r|v|i|c|e| |-+0#e000e06&@1|m|a|n|;+0#0000000&| |e|l|o@1|p| 
|-+0#e000e06&@1|h|e|l|p| +0#0000000&@45
 @75
-|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s| +0#0000000&@54
-|b|i|n|d|;| |r|e|n|a|m|e| @62
+|#+0#0000e05&| |s|o|m|e| |m|k|s|h| |b|u|i|l|t|i|n|s|,| |r|e|n|a|m|e| 
|s|h|o|u|l|d| |b|e| |h|i|g|h|l|i|g|h|t|e|d| |a|s| |e|x|t|e|r|n|a|l| 
|p|r|o|g|r|a|m| +0#0000000&@4
+|b|i|n|d|;| |r+0#af5f00255&|e|n|a|m|e| +0#0000000&@62
 @75
 |#+0#0000e05&| |;|&| |a|n|d| |;@1|&| |i|n| |c|a|s|e| |s|t|a|t|e|m|e|n|t|s| 
+0#0000000&@43
 |c+0#af5f00255&|a|s|e| +0#0000000&|x| |i+0#af5f00255&|n| +0#0000000&@65
diff --git a/runtime/syntax/testdir/dumps/sh_sundrous_01.dump 
b/runtime/syntax/testdir/dumps/sh_sundrous_01.dump
index ad3449dc6..9d0fc5b1b 100644
--- a/runtime/syntax/testdir/dumps/sh_sundrous_01.dump
+++ b/runtime/syntax/testdir/dumps/sh_sundrous_01.dump
@@ -17,4 +17,4 @@
 |m+0#af5f00255&|k|f|i|f|o| +0#0000000&@68
 |m+0#af5f00255&|k|t|e|m|p| +0#0000000&@68
 |m+0#af5f00255&|v| +0#0000000&@72
-@57|1|9|,|1| @9|3|4|%| 
+@57|1|9|,|1| @9|3@1|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_sundrous_02.dump 
b/runtime/syntax/testdir/dumps/sh_sundrous_02.dump
index 073d29f27..32d6da125 100644
--- a/runtime/syntax/testdir/dumps/sh_sundrous_02.dump
+++ b/runtime/syntax/testdir/dumps/sh_sundrous_02.dump
@@ -17,4 +17,4 @@
 |s+0#af5f00255&|y|n|c| +0#0000000&@70
 |t+0#af5f00255&|a|i|l| +0#0000000&@70
 |t+0#af5f00255&|e@1| +0#0000000&@71
-@57|3|7|,|1| @9|8|1|%| 
+@57|3|7|,|1| @9|7|9|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_sundrous_03.dump 
b/runtime/syntax/testdir/dumps/sh_sundrous_03.dump
index 5a24b40d3..d9e4693e6 100644
--- a/runtime/syntax/testdir/dumps/sh_sundrous_03.dump
+++ b/runtime/syntax/testdir/dumps/sh_sundrous_03.dump
@@ -5,7 +5,8 @@
 |u+0#af5f00255&|n|i|q| +0#0000000&@70
 >w+0#af5f00255&|c| +0#0000000&@72
 |x+0#af5f00255&|a|r|g|s| +0#0000000&@69
-|x+0#af5f00255&|g|r|e|p| +0#0000000&@69
+|#+0#0000e05&| |x|g|r|e|p| |i|s| |n|e|i|t|h|e|r| |a| |b|u|i|l|t|i|n| |f|o|r| 
|b|a|s|h| |n|o|r| |a|n| |e|x|t|e|r|n|a|l| |p|r|o|g|r|a|m| +0#0000000&@13
+|x|g|r|e|p| @69
 |~+0#4040ff13&| @73
 |~| @73
 |~| @73
@@ -16,5 +17,4 @@
 |~| @73
 |~| @73
 |~| @73
-|~| @73
 | +0#0000000&@56|5@1|,|1| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/input/sh_09.sh 
b/runtime/syntax/testdir/input/sh_09.sh
index e736e06b6..ad22bfb40 100644
--- a/runtime/syntax/testdir/input/sh_09.sh
+++ b/runtime/syntax/testdir/input/sh_09.sh
@@ -16,4 +16,5 @@
 ( cd ${HOME} ; $pwd ) | wc -c
 ( cd ${HOME} ) | wc -c
 ((n=1+2))
+# this is a syntax error, "let" is not a keyword in dash
 let n=1+2
diff --git a/runtime/syntax/testdir/input/sh_bash_alias.sh 
b/runtime/syntax/testdir/input/sh_bash_alias.sh
new file mode 100644
index 000000000..7302fdf8a
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_bash_alias.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/bash
+
+alias ls='ls --color=auto'
diff --git a/runtime/syntax/testdir/input/sh_ksh2020.ksh 
b/runtime/syntax/testdir/input/sh_ksh2020.ksh
index edb1ab24b..a0ecf8df9 100644
--- a/runtime/syntax/testdir/input/sh_ksh2020.ksh
+++ b/runtime/syntax/testdir/input/sh_ksh2020.ksh
@@ -88,7 +88,7 @@ poll --man
 # mkservice and eloop (rarely provided; requires SHOPT_MKSERVICE)
 mkservice --man; eloop --help
 
-# some mksh builtins
+# some mksh builtins, rename should be highlighted as external program
 bind; rename
 
 # ;& and ;;& in case statements
diff --git a/runtime/syntax/testdir/input/sh_ksh88.ksh 
b/runtime/syntax/testdir/input/sh_ksh88.ksh
index 20ce31899..23d67db1d 100644
--- a/runtime/syntax/testdir/input/sh_ksh88.ksh
+++ b/runtime/syntax/testdir/input/sh_ksh88.ksh
@@ -88,7 +88,7 @@ poll --man
 # mkservice and eloop (rarely provided; requires SHOPT_MKSERVICE)
 mkservice --man; eloop --help
 
-# some mksh builtins
+# some mksh builtins, rename should be highlighted as external program
 bind; rename
 
 # ;& and ;;& in case statements
diff --git a/runtime/syntax/testdir/input/sh_ksh93u.ksh 
b/runtime/syntax/testdir/input/sh_ksh93u.ksh
index 4f7a3f6c9..526922d68 100644
--- a/runtime/syntax/testdir/input/sh_ksh93u.ksh
+++ b/runtime/syntax/testdir/input/sh_ksh93u.ksh
@@ -88,7 +88,7 @@ poll --man
 # mkservice and eloop (rarely provided; requires SHOPT_MKSERVICE)
 mkservice --man; eloop --help
 
-# some mksh builtins
+# some mksh builtins, rename should be highlighted as external command
 bind; rename
 
 # ;& and ;;& in case statements
diff --git a/runtime/syntax/testdir/input/sh_ksh93v.ksh 
b/runtime/syntax/testdir/input/sh_ksh93v.ksh
index 33649edb9..1878d2eaa 100644
--- a/runtime/syntax/testdir/input/sh_ksh93v.ksh
+++ b/runtime/syntax/testdir/input/sh_ksh93v.ksh
@@ -88,7 +88,7 @@ poll --man
 # mkservice and eloop (rarely provided; requires SHOPT_MKSERVICE)
 mkservice --man; eloop --help
 
-# some mksh builtins
+# some mksh builtins, rename should be highlighted as external program
 bind; rename
 
 # ;& and ;;& in case statements
diff --git a/runtime/syntax/testdir/input/sh_sundrous.bash 
b/runtime/syntax/testdir/input/sh_sundrous.bash
index 8456af267..2f4df51f2 100644
--- a/runtime/syntax/testdir/input/sh_sundrous.bash
+++ b/runtime/syntax/testdir/input/sh_sundrous.bash
@@ -54,4 +54,5 @@ uname
 uniq
 wc
 xargs
+# xgrep is neither a builtin for bash nor an external program
 xgrep

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1v19BE-007Fc9-RI%40256bit.org.

Raspunde prin e-mail lui