runtime(vim): Update base-syntax, improve :let-heredoc highlighting

The end marker must appear on line of its own without any trailing
whitespace.

Whitespace is incorrectly allowed before all end markers.  Limiting this
only to heredocs where "trim" was specified, and with the correct
indent, is currently an intractable problem given that contained syntax
groups (in this case :let) cannot be limited to start patterns.

Highlight interpolated expressions when "eval" is specified.

cloess: #15511

Signed-off-by: Doug Kearns <dougkearns@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/syntax/generator/vim.vim.base b/runtime/syntax/generator/vim.vim.base
index 4666d71..883056b 100644
--- a/runtime/syntax/generator/vim.vim.base
+++ b/runtime/syntax/generator/vim.vim.base
@@ -3,7 +3,7 @@
 " Maintainer:	   Hirohito Higashi <h.east.727 ATMARK gmail.com>
 "	   Doug Kearns <dougkearns@gmail.com>
 " URL:	   https://github.com/vim-jp/syntax-vim-ex
-" Last Change:	   2024 Jul 18
+" Last Change:	   2024 Aug 16
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -525,7 +525,13 @@
 syn match	vimUnletBang	contained	"!"	skipwhite nextgroup=vimUnletVars
 syn region	vimUnletVars	contained	start="$\I\|\h" skip="\n\s*\\" end="$" end="|" contains=vimVar,vimEnvvar,vimContinue,vimString,vimNumber
 
-VimFoldh syn region vimLetHereDoc	matchgroup=vimLetHereDocStart start='=<<\s*\%(trim\s\+\%(eval\s\+\)\=\|eval\s\+\%(trim\s\+\)\=\)\=\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\s*\z1\s*$' extend
+" Note: This incorrectly matches end markers with leading whitespace even if
+"       "trim" was not specified.  Matching :let indent for "trim" indented
+"       end markers would require a contained :let that cannot be restricted
+"       to the start pattern.  A common internal testing use of heredocs is to
+"       specify code blocks where :let commonly appears in the heredoc text.
+VimFoldh syn region vimLetHereDoc	matchgroup=vimLetHereDocStart start='=<<\s*\%(trim\s\+\)\=\z(\L\S*\)'		             matchgroup=vimLetHereDocStop end='^\s*\z1$' extend
+VimFoldh syn region vimLetHereDoc	matchgroup=vimLetHereDocStart start='=<<\s*\%(trim\s\+\)\=eval\s\+\|eval\s\+\%(trim\s\+\)\=\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\s*\z1$' contains=vimStringInterpolationExpr,vimStringInterpolationBrace extend
 
 Vim9 syn keyword	vim9Const	const	skipwhite nextgroup=vim9Variable,vim9VariableList
 Vim9 syn keyword	vim9Final	final	skipwhite nextgroup=vim9Variable,vim9VariableList
diff --git a/runtime/syntax/testdir/dumps/vim_ex_function_fold_05.dump b/runtime/syntax/testdir/dumps/vim_ex_function_fold_05.dump
index 5511d0d..88ca355 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_function_fold_05.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_function_fold_05.dump
@@ -17,4 +17,4 @@
 @75
 |++0#0000e05#a8a8a8255|-@1| @1|5| |l|i|n|e|s|:| |f|u|n|c|t|i|o|n| |F|o@1|(|)|-@46
 | +0#0000000#ffffff0@74
-@57|1|4|3|,|0|-|1| @6|7|3|%| 
+@57|1|4|3|,|0|-|1| @6|7|4|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_function_fold_06.dump b/runtime/syntax/testdir/dumps/vim_ex_function_fold_06.dump
index 8925be9..a2f73a0 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_function_fold_06.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_function_fold_06.dump
@@ -14,7 +14,7 @@
 | +0#0000000#ffffff0@74
 |++0#0000e05#a8a8a8255|-@1| @1|3| |l|i|n|e|s|:| |f|u|n|c|t|i|o|n| |F|o@1|(|)|-@46
 | +0#0000000#ffffff0@74
-|++0#0000e05#a8a8a8255|-@1| @1|6| |l|i|n|e|s|:| |f|u|n|c|t|i|o|n| |F|o@1|(|)|-@46
+|++0#0000e05#a8a8a8255|-@1| @1|5| |l|i|n|e|s|:| |f|u|n|c|t|i|o|n| |F|o@1|(|)|-@46
 | +0#0000000#ffffff0@74
 |++0#0000e05#a8a8a8255|-@1| @1|5| |l|i|n|e|s|:| |f|u|n|c|t|i|o|n| |F|o@1|(|)|-@46
 | +0#0000000#ffffff0@56|1|8|0|,|1| @8|9|1|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_function_fold_07.dump b/runtime/syntax/testdir/dumps/vim_ex_function_fold_07.dump
index 393afe7..7a93653 100644
--- a/runtime/syntax/testdir/dumps/vim_ex_function_fold_07.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_function_fold_07.dump
@@ -17,4 +17,4 @@
 |~| @73
 |~| @73
 |~| @73
-| +0#0000000&@56|2@1|0|,|0|-|1| @6|B|o|t| 
+| +0#0000000&@56|2|1|9|,|0|-|1| @6|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_00.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_00.dump
new file mode 100644
index 0000000..2e3d0e6
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>"+0&#ffffff0| |V|i|m| |:|l|e|t| |h|e|r|e|d|o|c| |c|o|m@1|a|n|d| +0#0000000&@46
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|v|i|m|s|y|n|_|f|o|l|d|i|n|g| |=| |"+0#e000002&|h|"| +0#0000000&@29
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |s|e|t|l| |f|d|c|=|2| |f|d|l|=|9@1| |f|d|m|=|s|y|n|t|a|x| +0#0000000&@27
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |E|N|D| +0#0000000&@57
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|1| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|2| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |E|N|D| +0#0000000&@55
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|1| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|2| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@52
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|1| +0#0000000&@65
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|2| +0#0000000&@65
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+@57|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_01.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_01.dump
new file mode 100644
index 0000000..6e38ae7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_01.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@52
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|1| +0#0000000&@65
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|2| +0#0000000&@65
+||+0#0000e05#a8a8a8255| >E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@50
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|1| +0#0000000&@63
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|2| +0#0000000&@63
+||+0#0000e05#a8a8a8255| | +0#e000e06#ffffff0@1|E|N|D| +0#0000000&@67
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |i|n|t|e|r|p|o|l|a|t|i|o|n| +0#0000000&@57
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |e|v|a|l| |E|N|D| +0#0000000&@52
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|0+0#e000002&|}+0#e000e06&| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|1+0#e000002&|}+0#e000e06&| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+@57|1|9|,|1| @9|1|3|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_02.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_02.dump
new file mode 100644
index 0000000..3613d10
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_02.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |e|v|a|l| |E|N|D| +0#0000000&@50
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|0+0#e000002&|}+0#e000e06&| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|1+0#e000002&|}+0#e000e06&| +0#0000000&@61
+||+0#0000e05#a8a8a8255| >E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |e|v|a|l| |E|N|D| +0#0000000&@47
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|0+0#e000002&|}+0#e000e06&| +0#0000000&@59
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|1+0#e000002&|}+0#e000e06&| +0#0000000&@59
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |e|v|a|l| |E|N|D| +0#0000000&@45
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|0+0#e000002&|}+0#e000e06&| +0#0000000&@57
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|{+0#e000e06&|1+0#e000002&| +0#0000000&|++0#af5f00255&| +0#0000000&|1+0#e000002&|}+0#e000e06&| +0#0000000&@57
+||+0#0000e05#a8a8a8255| | +0#e000e06#ffffff0@1|E|N|D| +0#0000000&@67
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |n|o| |i|n|t|e|r|p|o|l|a|t|i|o|n| |(|e|s|c|a|p|e|d| |{| |a|n|d| |}|)| +0#0000000&@36
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+@57|3|7|,|1| @9|3|1|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_03.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_03.dump
new file mode 100644
index 0000000..de3f8fe
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_03.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |e|v|a|l| |E|N|D| +0#0000000&@52
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |0|}+0#e000e06&@1| +0#0000000&@59
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |1|}+0#e000e06&@1| +0#0000000&@59
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |e|v|a|l| |E|N|D| +0#0000000&@50
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |0|}+0#e000e06&@1| +0#0000000&@59
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |1|}+0#e000e06&@1| +0#0000000&@59
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |e|v|a|l| |E|N|D| +0#0000000&@47
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |0|}+0#e000e06&@1| +0#0000000&@57
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |1|}+0#e000e06&@1| +0#0000000&@57
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |e|v|a|l| |E|N|D| +0#0000000&@45
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |0|}+0#e000e06&@1| +0#0000000&@55
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |1|}+0#e000e06&@1| +0#0000000&@55
+@57|5@1|,|0|-|1| @7|5|0|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_04.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_04.dump
new file mode 100644
index 0000000..c6d1b4d
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_04.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|{+0#e000e06&@1|1+0#e000002&| |+| |1|}+0#e000e06&@1| +0#0000000&@55
+||+0#0000e05#a8a8a8255| | +0#e000e06#ffffff0@1|E|N|D| +0#0000000&@67
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |n|o| |i|n|t|e|r|p|o|l|a|t|i|o|n| +0#0000000&@54
+| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |E|N|D| +0#0000000&@57
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{|1| |+| |0|}| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{|1| |+| |1|}| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |E|N|D| +0#0000000&@55
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{|1| |+| |0|}| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |l+0#e000002#ffffff0|i|n|e|{|1| |+| |1|}| +0#0000000&@61
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@52
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{|1| |+| |0|}| +0#0000000&@59
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{|1| |+| |1|}| +0#0000000&@59
+@57|7|3|,|0|-|1| @7|6|9|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_05.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_05.dump
new file mode 100644
index 0000000..e66d1cc
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_05.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1|l|i|n|e|{|1| |+| |1|}| +0#0000000&@59
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@50
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|l|i|n|e|{|1| |+| |0|}| +0#0000000&@57
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3>l|i|n|e|{|1| |+| |1|}| +0#0000000&@57
+||+0#0000e05#a8a8a8255| | +0#e000e06#ffffff0@1|E|N|D| +0#0000000&@67
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |e|n|d| |m|a|r|k|e|r| |m|u|s|t| |n|o|t| |b|e| |f|o|l@1|o|w|e|d| |b|y| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@25
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |a|s@1|e|r|t|_|e|q|u|a|l|(|f|o@1|,| |[|"|E|N|D| |"|]|)| +0#0000000&@43
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |E|N|D| +0#0000000&@57
+||+0#0000e05#a8a8a8255| |E+0#e000002#ffffff0|N|D| | +0#0000000&@68
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |a|s@1|e|r|t|_|e|q|u|a|l|(|f|o@1|,| |[|"| |E|N|D| |"|]|)| +0#0000000&@42
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |E|N|D| +0#0000000&@57
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0|E|N|D| | +0#0000000&@67
+@57|9|1|,|5| @9|8|7|%| 
diff --git a/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_06.dump b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_06.dump
new file mode 100644
index 0000000..e3c4ca4
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_let_heredoc_06.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0|E|N|D| | +0#0000000&@67
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |a|s@1|e|r|t|_|e|q|u|a|l|(|f|o@1|,| |[|"|E|N|D| |"|]|)| +0#0000000&@43
+|-+0#0000e05#a8a8a8255| |l+0#af5f00255#ffffff0|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@52
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@1>E|N|D| | +0#0000000&@66
+||+0#0000e05#a8a8a8255| |E+0#e000e06#ffffff0|N|D| +0#0000000&@69
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|"+0&#ffffff0| |a|s@1|e|r|t|_|e|q|u|a|l|(|f|o@1|,| |[|"|E|N|D| |"|]|)| +0#0000000&@43
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@1|l+0#af5f00255&|e|t| +0#0000000&|f+0#00e0e07&|o@1| +0#0000000&|=+0#e000e06&|<@1| |t|r|i|m| |E|N|D| +0#0000000&@50
+||+0#0000e05#a8a8a8255| | +0#e000002#ffffff0@3|E|N|D| | +0#0000000&@64
+||+0#0000e05#a8a8a8255| | +0#e000e06#ffffff0@1|E|N|D| +0#0000000&@67
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|0|9|,|3| @8|B|o|t| 
diff --git a/runtime/syntax/testdir/input/vim_ex_def_fold.vim b/runtime/syntax/testdir/input/vim_ex_def_fold.vim
index d85f273..60b1151 100644
--- a/runtime/syntax/testdir/input/vim_ex_def_fold.vim
+++ b/runtime/syntax/testdir/input/vim_ex_def_fold.vim
@@ -120,7 +120,7 @@
 enddef
 
 def Foo()
-  let x =<< END
+  var x =<< trim END
     endfunction
   END
 enddef
diff --git a/runtime/syntax/testdir/input/vim_ex_function_fold.vim b/runtime/syntax/testdir/input/vim_ex_function_fold.vim
index dd260ca..fa7edbb 100644
--- a/runtime/syntax/testdir/input/vim_ex_function_fold.vim
+++ b/runtime/syntax/testdir/input/vim_ex_function_fold.vim
@@ -193,10 +193,9 @@
 endfunction
 
 function Foo()
-  let x =<< END
+  let x =<< trim END
     endfunction
   END
-
 endfunction
 
 function Foo()
diff --git a/runtime/syntax/testdir/input/vim_ex_let_heredoc.vim b/runtime/syntax/testdir/input/vim_ex_let_heredoc.vim
new file mode 100644
index 0000000..da9adff
--- /dev/null
+++ b/runtime/syntax/testdir/input/vim_ex_let_heredoc.vim
@@ -0,0 +1,116 @@
+" Vim :let heredoc command
+" VIM_TEST_SETUP let g:vimsyn_folding = "h"
+" VIM_TEST_SETUP setl fdc=2 fdl=99 fdm=syntax
+
+
+let foo =<< END
+line1
+line2
+END
+
+  let foo =<< END
+line1
+line2
+END
+
+let foo =<< trim END
+  line1
+  line2
+END
+
+  let foo =<< trim END
+    line1
+    line2
+  END
+
+
+" interpolation
+
+let foo =<< eval END
+line{1 + 0}
+line{1 + 1}
+END
+
+  let foo =<< eval END
+line{1 + 0}
+line{1 + 1}
+END
+
+let foo =<< trim eval END
+  line{1 + 0}
+  line{1 + 1}
+END
+
+  let foo =<< trim eval END
+    line{1 + 0}
+    line{1 + 1}
+  END
+
+" no interpolation (escaped { and })
+
+let foo =<< eval END
+line{{1 + 0}}
+line{{1 + 1}}
+END
+
+  let foo =<< eval END
+line{{1 + 0}}
+line{{1 + 1}}
+END
+
+let foo =<< trim eval END
+  line{{1 + 0}}
+  line{{1 + 1}}
+END
+
+  let foo =<< trim eval END
+    line{{1 + 0}}
+    line{{1 + 1}}
+  END
+
+
+" no interpolation
+
+let foo =<< END
+line{1 + 0}
+line{1 + 1}
+END
+
+  let foo =<< END
+line{1 + 0}
+line{1 + 1}
+END
+
+let foo =<< trim END
+  line{1 + 0}
+  line{1 + 1}
+END
+
+  let foo =<< trim END
+    line{1 + 0}
+    line{1 + 1}
+  END
+
+
+" end marker must not be followed by whitespace
+
+" assert_equal(foo, ["END "])
+let foo =<< END
+END 
+END
+
+" assert_equal(foo, [" END "])
+let foo =<< END
+ END 
+END
+
+" assert_equal(foo, ["END "])
+let foo =<< trim END
+  END 
+END
+
+" assert_equal(foo, ["END "])
+  let foo =<< trim END
+    END 
+  END
+
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index 8492463..441f74f 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -3,7 +3,7 @@
 " Maintainer:	   Hirohito Higashi <h.east.727 ATMARK gmail.com>
 "	   Doug Kearns <dougkearns@gmail.com>
 " URL:	   https://github.com/vim-jp/syntax-vim-ex
-" Last Change:	   2024 Jul 23
+" Last Change:	   2024 Aug 16
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -480,11 +480,12 @@
 syn match	vimEscape	contained	"\\<" contains=vimNotation
 syn match	vimEscape	contained	"\\<\*[^>]*>\=>"
 
-syn region	vimString	oneline start=+$'+ skip=+''+ end=+'+ contains=vimStringInterpolationBrace,vimStringInterpolationExpr
-syn region	vimString	oneline start=+$"+ end=+"+ contains=@vimStringGroup,vimStringInterpolationBrace,vimStringInterpolationExpr
+syn region	vimString	oneline start=+$'+ skip=+''+ end=+'+ contains=@vimStringInterpolation
+syn region	vimString	oneline start=+$"+ end=+"+ contains=@vimStringGroup,@vimStringInterpolation
 syn region	vimStringInterpolationExpr  oneline contained matchgroup=vimSep start=+{+ end=+}+ contains=@vimExprList
 syn match	vimStringInterpolationBrace contained "{{"
 syn match	vimStringInterpolationBrace contained "}}"
+syn cluster	vimStringInterpolation contains=vimStringInterpolationExpr,vimStringInterpolationBrace
 
 " Substitutions: {{{2
 " =============
@@ -564,7 +565,13 @@
 syn match	vimUnletBang	contained	"!"	skipwhite nextgroup=vimUnletVars
 syn region	vimUnletVars	contained	start="$\I\|\h" skip="\n\s*\\" end="$" end="|" contains=vimVar,vimEnvvar,vimContinue,vimString,vimNumber
 
-VimFoldh syn region vimLetHereDoc	matchgroup=vimLetHereDocStart start='=<<\s*\%(trim\s\+\%(eval\s\+\)\=\|eval\s\+\%(trim\s\+\)\=\)\=\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\s*\z1\s*$' extend
+" Note: This incorrectly matches end markers with leading whitespace even if
+"       "trim" was not specified.  Matching :let indent for "trim" indented
+"       end markers would require a contained :let that cannot be restricted
+"       to the start pattern.  A common internal testing use of heredocs is to
+"       specify code blocks where :let commonly appears in the heredoc text.
+VimFoldh syn region vimLetHereDoc	matchgroup=vimLetHereDocStart start='=<<\s*\%(trim\s\+\)\=\z(\L\S*\)'			matchgroup=vimLetHereDocStop end='^\s*\z1$' extend
+VimFoldh syn region vimLetHereDoc	matchgroup=vimLetHereDocStart start='=<<\s*\%(\%(trim\s\+\)\=eval\s\+\|eval\s\+\%(trim\s\+\)\=\)\z(\L\S*\)' matchgroup=vimLetHereDocStop end='^\s*\z1$' contains=@vimStringInterpolation extend
 
 Vim9 syn keyword	vim9Const	const	skipwhite nextgroup=vim9Variable,vim9VariableList
 Vim9 syn keyword	vim9Final	final	skipwhite nextgroup=vim9Variable,vim9VariableList