runtime(sh): fix spurious nextgroup=shComment on shEscape
Commit:
https://github.com/vim/vim/commit/c68e64dac3eaa48d65bb333c66b3d34707dd6acc
Author: Bozhidar Batsov <
bozh...@batsov.dev>
Date: Sun Feb 15 14:53:55 2026 +0000
runtime(sh): fix spurious nextgroup=shComment on shEscape
Remove `nextgroup=shComment` from the `shEscape` syntax pattern.
This was causing `#` characters after escape sequences inside
double-quoted strings to be misinterpreted as comments, breaking
highlighting for the rest of the file.
Add a test case for escaped characters followed by # in double quotes.
fixes: #19053
closes: #19414
Signed-off-by: Bozhidar Batsov <
bozh...@batsov.dev>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index b3956d548..6b13ddacc 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -21,6 +21,7 @@
" 2025 Sep 23 simplify ksh logic, update sh statements #18355
" 2026 Jan 15 highlight command switches that contain a digit
" 2026 Feb 11 improve support for KornShell function names and variables
+" 2026 Feb 15 improve comment handling #19414
" }}}
" Version: 208
" Former URL:
http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
@@ -452,7 +453,7 @@ endif
"======
syn match shWrapLineOperator "\$"
syn region shCommandSubBQ start="`" skip="\\\|\." end="`" contains=shBQComment,@shCommandSubList
-syn match shEscape contained '\%(^\)\@!\%(\\\)*\.' nextgroup=shComment
+syn match shEscape contained '\%(^\)\@!\%(\\\)*\.'
" $() and $(()): {{{1
" $(..) is not supported by sh (Bourne shell). However, apparently
diff --git a/runtime/syntax/testdir/dumps/sh_15_00.dump b/runtime/syntax/testdir/dumps/sh_15_00.dump
new file mode 100644
index 000000000..7d97f3377
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_15_00.dump
@@ -0,0 +1,20 @@
+>#+0#0000e05#ffffff0|!|/|b|i|n|/|b|a|s|h| +0#0000000&@63
+|#+0#0000e05&| |I|s@1|u|e| |#|1|9|0|5|3| |(|s|h| |s|y|n|t|a|x|:| |e|s|c|a|p|e|d| |c|h|a|r|a|c|t|e|r|s| |f|o|l@1|o|w|e|d| |b|y| |#| |i|n| |d|o|u|b|l|e| |q|u|o|t|e
+|s|)| +0#0000000&@72
+@75
+|C+0#00e0e07&|L|E|A|N|U|R|L|=+0#0000000&|'+0#af5f00255&|h+0#e000002&|t@1|p|:|/@1|l|o|c|a|l|h|o|s|t|:|8|0|7@1|/|t|e|s|t|'+0#af5f00255&| +0#0000000&@37
+@75
+|F+0#00e0e07&|I|L|E|N|A|M|E|=+0#0000000&|$+0#e000e06&|(|s+0#af5f00255&|e|d| +0#e000e06&|-|r| |-|e| |"+0#af5f00255&|s+0#e000002&|#|[|:|/|]|+|#|\+0#e000e06&|.|#+0#e000002&|g|"+0#af5f00255&| +0#e000e06&|-|e| |"+0#af5f00255&|s+0#e000002&|#|[|^|a|-|z|A|-|Z|0|-|9|\+0#e000e06&|.|_+0#e000002&|]|*|#@1|g|"+0#af5f00255&| +0#e000e06&|<+0#af5f00255&@2|$+0#e000e06&|{|C|L|E|A|N|U|R
+|L|}|)| +0#0000000&@71
+|F+0#00e0e07&|I|L|E|N|A|M|E|=+0#0000000&|$+0#e000e06&|(|s+0#af5f00255&|e|d| +0#e000e06&|-|r| |-|e| |'+0#af5f00255&|s+0#e000002&|#|[|:|/|]|+|#|\|.|#|g|'+0#af5f00255&| +0#e000e06&|-|e| |'+0#af5f00255&|s+0#e000002&|#|[|^|a|-|z|A|-|Z|0|-|9|\|.|_|]|*|#@1|g|'+0#af5f00255&| +0#e000e06&|<+0#af5f00255&@2|$+0#e000e06&|{|C|L|E|A|N|U|R
+|L|}|)| +0#0000000&@71
+|H+0#00e0e07&|D|R|F|I|L|E|=+0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|F|I|L|E|N|A|M|E|}|.+0#e000002&|h|d|r|"+0#af5f00255&| +0#0000000&@49
+@75
+|:| |"+0#af5f00255&|\+0#e000e06&@1|#+0#e000002&| |n|o|t| |a| |c|o|m@1|e|n|t|"+0#af5f00255&| +0#0000000&@53
+|#+0#0000e05&| |\@1|"| |a| |c|o|m@1|e|n|t| +0#0000000&@59
+|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|\+0#e000e06&@1|#+0#e000002&|"+0#af5f00255&| +0#0000000&@64
+|:| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|i+0#0000000&|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|A|l@1|
diff --git a/runtime/syntax/testdir/input/sh_15.sh b/runtime/syntax/testdir/input/sh_15.sh
new file mode 100644
index 000000000..fe3dc93cf
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_15.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Issue #19053 (sh syntax: escaped characters followed by # in double quotes)
+
+CLEANURL='
http://localhost:8077/test'
+
+FILENAME=$(sed -r -e "s#[:/]+#\.#g" -e "s#[^a-zA-Z0-9\._]*##g" <<<${CLEANURL})
+FILENAME=$(sed -r -e 's#[:/]+#\.#g' -e 's#[^a-zA-Z0-9\._]*##g' <<<${CLEANURL})
+HDRFILE="${FILENAME}.hdr"
+
+: "\# not a comment"
+# \" a comment
+echo "\#"
+: