]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
runtime(sh): refactored sh.vim syntax script
authorBjoern Foersterling <bjoern.foersterling@gmail.com>
Tue, 23 Sep 2025 19:47:29 +0000 (19:47 +0000)
committerChristian Brabandt <cb@256bit.org>
Tue, 23 Sep 2025 19:48:09 +0000 (19:48 +0000)
- 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 <bjoern.foersterling@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
18 files changed:
runtime/syntax/sh.vim
runtime/syntax/testdir/dumps/sh_09_00.dump
runtime/syntax/testdir/dumps/sh_09_01.dump [new file with mode: 0644]
runtime/syntax/testdir/dumps/sh_bash_alias_00.dump [new file with mode: 0644]
runtime/syntax/testdir/dumps/sh_ksh2020_05.dump
runtime/syntax/testdir/dumps/sh_ksh88_05.dump
runtime/syntax/testdir/dumps/sh_ksh93u_05.dump
runtime/syntax/testdir/dumps/sh_ksh93v_05.dump
runtime/syntax/testdir/dumps/sh_sundrous_01.dump
runtime/syntax/testdir/dumps/sh_sundrous_02.dump
runtime/syntax/testdir/dumps/sh_sundrous_03.dump
runtime/syntax/testdir/input/sh_09.sh
runtime/syntax/testdir/input/sh_bash_alias.sh [new file with mode: 0644]
runtime/syntax/testdir/input/sh_ksh2020.ksh
runtime/syntax/testdir/input/sh_ksh88.ksh
runtime/syntax/testdir/input/sh_ksh93u.ksh
runtime/syntax/testdir/input/sh_ksh93v.ksh
runtime/syntax/testdir/input/sh_sundrous.bash

index 8dd62566cb645191ce5f6b01ff823d034468c51c..5cf4930658432130d14d83a8761e3adb69b52332 100644 (file)
@@ -4,20 +4,21 @@
 " Previous Maintainers:        Charles E. Campbell
 "              Lennart Schultz <Lennart.Schultz@ecmwf.int>
 " 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[ \t\n;]}" 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[ \t\n;]}" 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[ \t\n;]}" 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[ \t\n;]}" 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="\%(\\.\|[^#$()'" \t]\)\{-}\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="\%(\\.\|[^#$()'" \t]\)\{-}\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="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end=";&" end="esac"me=s-1     contains=@shCaseList    nextgroup=shCaseStart,shCase,shComment
   ShFoldIfDoFor syn region   shCase  contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\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="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end="esac"me=s-1              contains=@shCaseList    nextgroup=shCaseStart,shCase,shComment
   ShFoldIfDoFor syn region   shCase  contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\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[ \t\n]"  skip='\\\\\|\\.' end="\zs[ \t\n;]}"  contains=@shCommandSubList
-   else
-    syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[ \t\n<]"  skip='\\\\\|\\.' end="\zs[ \t\n;]}"  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[ \t\n]"  skip='\\\\\|\\.' end="\zs[;\n][ \t\n]*}"  contains=@shCommandSubList
-  syn region shValsub matchgroup=shCmdSubRegion start="\${|"  skip='\\\\\|\\.' end="[;\n][ \t\n]*}"  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[ \t\n]"  skip='\\\\\|\\.' end="\zs[ \t\n;]}"  contains=@shCommandSubList
+            else
+       syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[ \t\n<]"  skip='\\\\\|\\.' end="\zs[ \t\n;]}"  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[ \t\n]"  skip='\\\\\|\\.' end="\zs[;\n][ \t\n]*}"  contains=@shCommandSubList
+        syn region shValsub matchgroup=shCmdSubRegion start="\${|"  skip='\\\\\|\\.' end="[;\n][ \t\n]*}"  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[^ \t\n|]" end="}"      contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
- elseif exists("b:generic_korn")
-  syn region shDeref   matchgroup=PreProc start="\${\ze[^ \t\n<|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
- else
-  syn region shDeref   matchgroup=PreProc start="\${\ze[^ \t\n<]" end="}"      contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
- endif
   if exists("b:is_mksh")
+        syn region shDeref     matchgroup=PreProc start="\${\ze[^ \t\n|]" end="}"      contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
   elseif exists("b:generic_korn")
+        syn region shDeref     matchgroup=PreProc start="\${\ze[^ \t\n<|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
   else
+        syn region shDeref     matchgroup=PreProc start="\${\ze[^ \t\n<]" end="}"      contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
   endif
 elseif exists("b:is_bash")
syn region shDeref    matchgroup=PreProc start="\${\ze[^ \t\n|]" end="}"      contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
   syn region shDeref matchgroup=PreProc start="\${\ze[^ \t\n|]" 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
index 58ab2022e0cbcc4688a06d31426c24e42af6cd23..57e5617376b30c7ed40477f2069c2cdbfe7fd7eb 100644 (file)
@@ -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 (file)
index 0000000..817f705
--- /dev/null
@@ -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 (file)
index 0000000..ab76d04
--- /dev/null
@@ -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| 
index ba9f354d5731264e1590ba90b593a0b9a74a1297..d1bc36855df1a8341bcb8a462077eefb0356de01 100644 (file)
@@ -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
index 95bea149ca25e7a663626316bf0d55b8f1e0b277..107e2a9a7ccb80c458f07d0a8626d814281dfa15 100644 (file)
@@ -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
index ba9f354d5731264e1590ba90b593a0b9a74a1297..3a1b1ce168faf8704806595fa1bd4b016f951c55 100644 (file)
@@ -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
index 479efcf81f2dd7dba03360db58afde9ec4de38b7..80b2cc6c011c8c27ef5da15fac441fd17c086c47 100644 (file)
@@ -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
index ad3449dc62ca5dbe7a3cdb6d4295f306aa43b995..9d0fc5b1b75945a562a7c0868039003be259c7c8 100644 (file)
@@ -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|%| 
index 073d29f2794e205181defea7748e8db6ae2cc6b5..32d6da125d0b2af9c7a646dd5c597e0ccacb32af 100644 (file)
@@ -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|%| 
index 5a24b40d3b0fa5452bb9d9cfb5da248b3ff0f21b..d9e4693e6387c7e98fb0a3838bae677e1bd91052 100644 (file)
@@ -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| 
index e736e06b64da7e07e3affedaafca084021ff2805..ad22bfb40041d13dbfb001df1e28f0dc7ae08c6e 100644 (file)
@@ -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 (file)
index 0000000..7302fdf
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/bash
+
+alias ls='ls --color=auto'
index edb1ab24bd95b39e1937c37e48f77992e791d257..a0ecf8df989dfca788927aa35118c87cb9145dbb 100644 (file)
@@ -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
index 20ce31899e01c309afbc2f9a0a0f466491b1b428..23d67db1d146b9d3b2f158cc21ac56b126d0e125 100644 (file)
@@ -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
index 4f7a3f6c947a141304c6bfc0415def4972c5b0cd..526922d687823ea2f05b570940fa7719082ba082 100644 (file)
@@ -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
index 33649edb977829f30172677de67520d522b97421..1878d2eaa9e91bd09d5e658529040059c708b4e9 100644 (file)
@@ -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
index 8456af2677d524327511b2fec1765c2532b0df3f..2f4df51f2b44c55cf80d17ca69c4c2f25227178b 100644 (file)
@@ -54,4 +54,5 @@ uname
 uniq
 wc
 xargs
+# xgrep is neither a builtin for bash nor an external program
 xgrep