runtime(sh): add syntax highlighting support for ${ cmd;} and ${|cmd;}

Commit: 
https://github.com/vim/vim/commit/e06d81fe675794d6e849cfa78e31a78c8001bbe5
Author: Kevin Pulo <[email protected]>
Date:   Sat Aug 23 17:07:44 2025 +0200

    runtime(sh): add syntax highlighting support for ${ cmd;} and ${|cmd;}
    
    bash 5.3 (released July 2025) added support for ${ cmd;} and
    ${|cmd;} style command substitution, which is similar (but not
    identical) to ksh/mksh.
    
    closes: #18084
    
    Signed-off-by: Kevin Pulo <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index 9cee161ac..8dd62566c 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -16,7 +16,8 @@
 "              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 Jul 18 properly delete :commands (#17785)
+"              2025 Aug 23 bash: add support for ${ cmd;} and ${|cmd;} (#18084)
 " }}}
 " Version:             208
 " Former URL:          http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
@@ -474,6 +475,9 @@ if exists("b:is_kornshell") || exists("b:is_bash") || 
exists("b:is_posix")
   if exists("b:is_mksh") || exists("b:generic_korn")
    syn region shValsub matchgroup=shCmdSubRegion start="\${|"  skip='\\\|\.' 
end="}"  contains=@shCommandSubList
   endif
+ elseif exists("b:is_bash")
+  syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[       
]"  skip='\\\|\.' end="\zs[;
][      
]*}"  contains=@shCommandSubList
+  syn region shValsub matchgroup=shCmdSubRegion start="\${|"  skip='\\\|\.' 
end="[;
][      
]*}"  contains=@shCommandSubList
  endif
  syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\|\.' 
end="))" contains=@shArithList
  syn region shArithmetic matchgroup=shArithRegion  start="\$\[" skip='\\\|\.' 
end="\]" contains=@shArithList
@@ -677,6 +681,8 @@ if exists("b:is_kornshell") && !exists("b:is_ksh88")
  else
   syn region shDeref   matchgroup=PreProc start="\${\ze[^      
<]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
  endif
+elseif exists("b:is_bash")
+ syn region shDeref    matchgroup=PreProc start="\${\ze[^      
|]" end="}"     contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
 else
  syn region shDeref    matchgroup=PreProc start="\${" end="}"                  
contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
 endif
diff --git a/runtime/syntax/testdir/dumps/sh_bash_00.dump 
b/runtime/syntax/testdir/dumps/sh_bash_00.dump
new file mode 100644
index 000000000..85966ebd7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_bash_00.dump
@@ -0,0 +1,20 @@
+>#+0#0000e05#ffffff0|!|/|b|i|n|/|b|a|s|h| +0#0000000&@63
+@75
+|#+0#0000e05&| |b|a|s|h| |5|.|3|+| |s|u|p@1|o|r|t|s| |c|o|m@1|a|n|d| 
|s|u|b|s|t|i|t|u|t|i|o|n| |t|h|a|t| |i|s| |v|e|r|y| |s|i|m|i|l|a|r| 
+0#0000000&@12
+|#+0#0000e05&| |(|b|u|t| |n|o|t| |i|d|e|n|t|i|c|a|l|)| |t|o| 
|k|s|h|/|m|k|s|h|.| +0#0000000&@40
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|o|n|e|;+0#e000e06&|}| +0#0000000&@56
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|t|w|o| +0#0000000&@58
+|}+0#e000e06&| +0#0000000&@73
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| +0#0000000&@67
+|e+0#af5f00255&|c|h|o| +0#e000002&|t|h|r|e@1| @5|;+0#e000e06&|}| +0#0000000&@56
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|f+0#e000002&|o|u|r|'+0#af5f00255&|;+0#e000e06&| |}| 
+0#0000000&@52
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|f+0#e000002&|i|v|e|'+0#af5f00255&| 
+0#e000002&|;+0#e000e06&|}| +0#0000000&@52
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|s+0#e000002&|i|x|'+0#af5f00255&| +0#0000000&@56
+|}+0#e000e06&| +0#0000000&@73
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|s+0#e000002&|e|v|e|n|'+0#af5f00255&| 
+0#e000002&@3|;+0#e000e06&|}| +0#0000000&@48
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|e+0#e000002&|i|g|h|t|'+0#af5f00255&|;+0#e000e06&| 
@2|}| +0#0000000&@49
+|t+0#af5f00255&|y|p|e|s|e|t| 
+0#e000e06&|n+0#00e0e07&|i|n|e|=+0#0000000&|$+0#e000e06&|{| 
|p+0#af5f00255&|w|d|;| +0#e000e06&|}| +0#0000000&@52
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|n+0#e000002&|i|n|e|'+0#af5f00255&| 
+0#e000002&|;+0#e000e06&| | +0#0000000&@52
+| +0#e000e06&|}| +0#0000000&@72
+@75
+|i|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_bash_01.dump 
b/runtime/syntax/testdir/dumps/sh_bash_01.dump
new file mode 100644
index 000000000..18961a798
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_bash_01.dump
@@ -0,0 +1,20 @@
+|e+0#af5f00255#ffffff0|c|h|o| +0#e000002&|$+0#e000e06&|{| 
|e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|s+0#e000002&|e|v|e|n|'+0#af5f00255&| 
+0#e000002&@3|;+0#e000e06&|}| +0#0000000&@48
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|e+0#e000002&|i|g|h|t|'+0#af5f00255&|;+0#e000e06&| 
@2|}| +0#0000000&@49
+|t+0#af5f00255&|y|p|e|s|e|t| 
+0#e000e06&|n+0#00e0e07&|i|n|e|=+0#0000000&|$+0#e000e06&|{| 
|p+0#af5f00255&|w|d|;| +0#e000e06&|}| +0#0000000&@52
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{| |e+0#af5f00255&|c|h|o| 
+0#e000002&|'+0#af5f00255&|n+0#e000002&|i|n|e|'+0#af5f00255&| 
+0#e000002&|;+0#e000e06&| | +0#0000000&@52
+| +0#e000e06&|}| +0#0000000&@72
+> @74
+|v+0#e000e06&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@60
+| +0#e000e06&@7|R|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@58
+|}+0#e000e06&| +0#0000000&@73
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| 
|t|e|n|;|}| +0#0000000&@50
+|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| 
|e|l|e|v|e|n|;| |}|"+0#af5f00255&| +0#0000000&@44
+|p+0#af5f00255&|r|i|n|t|f| 
+0#e000e06&|'+0#af5f00255&|%+0#e000002&|s|\|n|'+0#af5f00255&| 
+0#e000e06&|"+0#af5f00255&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| |t|w|e|l|v|e| 
@4|;|}|"+0#af5f00255&| +0#0000000&@31
+|u+0#00e0e07&|n|l|u|c|k|y|=+0#0000000&|$+0#e000e06&|{||+0#af5f00255&|v+0#e000e06&|a|l|s|u|b|f|u|n|c|
 |t|h|i|r|t|e@1|n| +0#0000000&@44
+|}+0#e000e06&| +0#0000000&@73
+|t+0#af5f00255&|y|p|e|s|e|t| 
+0#e000e06&|n+0#00e0e07&|o|t|a|f|l|o|a|t|=+0#0000000&|$+0#e000e06&|{||+0#af5f00255&|v+0#e000e06&|a|l|s|u|b|f|u|n|c|
 |n|o|t|a|n|u|m|b|e|r| @5|;+0#af5f00255&| +0#e000e06&| +0#0000000&@24
+| +0#e000e06&|}| +0#0000000&@72
+|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|u|n|l|u|c|k|y| 
+0#e000002&|$+0#e000e06&|n|o|t|a|n|u|m|b|e|r| +0#0000000&@49
+|$+0#e000e06&|{||+0#af5f00255&|e|c|h|o| 
+0#e000002&|f|o|u|r|t|e@1|n|;+0#af5f00255&|}+0#e000e06&| +0#0000000&@56
+|$+0#e000e06&|{||+0#af5f00255&|e|c|h|o| +0#e000002&|f|i|f|t|e@1|n| 
+0#0000000&@59
+@57|1|9|,|0|-|1| @7|9|2|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_bash_02.dump 
b/runtime/syntax/testdir/dumps/sh_bash_02.dump
new file mode 100644
index 000000000..677a1ab12
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_bash_02.dump
@@ -0,0 +1,20 @@
+|$+0#e000e06#ffffff0|{||+0#af5f00255&|e|c|h|o| +0#e000002&|f|i|f|t|e@1|n| 
+0#0000000&@59
+>}+0#e000e06&| +0#0000000&@73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|3@1|,|1| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/input/sh_bash.bash 
b/runtime/syntax/testdir/input/sh_bash.bash
new file mode 100644
index 000000000..35b536c4e
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_bash.bash
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# bash 5.3+ supports command substitution that is very similar
+# (but not identical) to ksh/mksh.
+echo ${ echo one;}
+echo ${        echo two
+}
+echo ${
+echo three     ;}
+echo ${ echo 'four'; }
+echo ${ echo 'five' ;}
+echo ${ echo 'six'
+}
+echo ${        echo 'seven'    ;}
+echo ${ echo 'eight';  }
+typeset nine=${ pwd; }
+echo ${ echo 'nine' ; 
+ }
+
+valsubfunc() {
+       REPLY=$1
+}
+echo ${|valsubfunc ten;}
+echo "${|valsubfunc eleven; }"
+printf '%s
' "${|valsubfunc twelve ;}"
+unlucky=${|valsubfunc thirteen
+}
+typeset notafloat=${|valsubfunc notanumber     ; 
+ }
+echo $unlucky $notanumber
+${|echo fourteen;}
+${|echo fifteen
+}

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

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

Raspunde prin e-mail lui