runtime(vim): Update base-syntax, improve :echo highlighting (#14103)

- Normalise behaviour of :echo commands and improve expression matching.
- Allow continued argument lines.
- Refine string interpolation groups.
- Remove duplicated :menu and :map generated commands that are handled
  specially later in the file.

Signed-off-by: Doug Kearns <dougkearns@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/syntax/generator/gen_syntax_vim.vim b/runtime/syntax/generator/gen_syntax_vim.vim
index bc561dd..bbcdb06 100644
--- a/runtime/syntax/generator/gen_syntax_vim.vim
+++ b/runtime/syntax/generator/gen_syntax_vim.vim
@@ -2,8 +2,8 @@
 " Language: Vim script
 " Maintainer: Hirohito Higashi (h_east)
 " URL: https://github.com/vim-jp/syntax-vim-ex
-" Last Change: Feb 18, 2024
-" Version: 2.0.1
+" Last Change: Feb 27, 2024
+" Version: 2.0.3
 
 let s:keepcpo= &cpo
 set cpo&vim
@@ -264,20 +264,23 @@
 	" Return value:
 	"   0: normal
 	"   1: (Reserved)
-	"   2: abbrev (without un)
-	"   3: menu
-	"   4: map
-	"   5: mapclear
-	"   6: unmap
+	"   2: abbrev
+	"   3: echo
+	"   4: menu
+	"   5: map
+	"   6: mapclear
+	"   7: unmap
 	"   99: (Exclude registration of "syn keyword")
 	let menu_prefix = '^\%([acinosvx]\?\|tl\)'
 	let map_prefix  = '^[acilnostvx]\?'
+	let echo_suffix = '\%(n\|hl\|msg\|window\|err\|console\|\)$'
 	let exclude_list = [
 	\	'map', 'mapclear',
 	\	'substitute', 'smagic', 'snomagic',
 	\	'setlocal', 'setglobal', 'set', 'var',
 	\	'autocmd', 'doautocmd', 'doautoall',
-	\	'echo', 'echohl', 'execute',
+	\	'echohl',
+	\ 'execute',
 	\	'behave', 'augroup', 'normal', 'syntax',
 	\	'append', 'insert',
 	\	'Next', 'Print', 'X',
@@ -290,14 +293,16 @@
 		let ret = 99
 	elseif a:cmd_name =~# '^\%(\%(un\)\?abbreviate\|noreabbrev\|\l\%(nore\|un\)\?abbrev\)$'
 		let ret = 2
-	elseif a:cmd_name =~# menu_prefix . '\%(nore\|un\)\?menu$'
+	elseif a:cmd_name =~# '^echo' . echo_suffix
 		let ret = 3
-	elseif a:cmd_name =~# map_prefix . '\%(nore\)\?map$'
+	elseif a:cmd_name =~# menu_prefix . '\%(nore\|un\)\?menu$'
 		let ret = 4
-	elseif a:cmd_name =~# map_prefix . 'mapclear$'
+	elseif a:cmd_name =~# map_prefix . '\%(nore\)\?map$'
 		let ret = 5
-	elseif a:cmd_name =~# map_prefix . 'unmap$'
+	elseif a:cmd_name =~# map_prefix . 'mapclear$'
 		let ret = 6
+	elseif a:cmd_name =~# map_prefix . 'unmap$'
+		let ret = 7
 	else
 		let ret = 0
 	endif
@@ -566,10 +571,6 @@
 		" vimCommand - normal
 		let lnum = s:search_and_check('vimCommand normal', base_fname, str_info)
 		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 0)
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 3)		" menu
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 4)		" map
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 5)		" mapclear
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 6)		" unmap
 
 		" vimOption
 		let kword = 'vimOption'
@@ -620,16 +621,19 @@
 		let li = a:vim_info.cmd
 		let lnum = s:search_and_check(kword . ' abbrev', base_fname, str_info)
 		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 2)
-		" vimCommand - map
-		let lnum = s:search_and_check(kword . ' map', base_fname, str_info)
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 4)
-		let lnum = s:search_and_check(kword . ' mapclear', base_fname, str_info)
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 5)
-		let lnum = s:search_and_check(kword . ' unmap', base_fname, str_info)
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 6)
+		" vimCommand - echo
+		let lnum = s:search_and_check(kword . ' echo', base_fname, str_info)
+		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 3)
 		" vimCommand - menu
 		let lnum = s:search_and_check(kword . ' menu', base_fname, str_info)
-		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 3)
+		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 4)
+		" vimCommand - map
+		let lnum = s:search_and_check(kword . ' map', base_fname, str_info)
+		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 5)
+		let lnum = s:search_and_check(kword . ' mapclear', base_fname, str_info)
+		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 6)
+		let lnum = s:search_and_check(kword . ' unmap', base_fname, str_info)
+		let lnum = s:append_syn_vimcmd(lnum, str_info, li, 7)
 
 		update
 		quit!
diff --git a/runtime/syntax/generator/vim.vim.base b/runtime/syntax/generator/vim.vim.base
index 6527fe1..f74406e 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:	Feb 18, 2024
+" Last Change:	Feb 27, 2024
 " Former Maintainer: Charles E. Campbell
 " Base File URL:     http://www.drchip.org/astronaut/vim/index.html#SYNTAX_VIM
 " Base File Version: 9.0-25
@@ -176,6 +176,8 @@
 syn match vimFBVar      contained   "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>"
 syn keyword vimCommand  contained	in
 
+syn cluster vimExprList contains=vimEnvvar,vimFunc,vimFuncVar,vimNumber,vimOper,vimOperParen,vimLetRegister,vimString,vimVar
+
 " Insertions And Appends: insert append {{{2
 "   (buftype != nofile test avoids having append, change, insert show up in the command window)
 " =======================
@@ -344,11 +346,11 @@
 syn match	vimEscape	contained	"\\<" contains=vimNotation
 syn match	vimEscape	contained	"\\<\*[^>]*>\=>"
 
-syn region	vimString start=+$'+ end=+'+ skip=+''+ oneline contains=vimStringInterpolationBrace,vimStringInterpolationExpr
-syn region	vimString start=+$"+ end=+"+ oneline contains=@vimStringGroup,vimStringInterpolationBrace,vimStringInterpolationExpr
-syn region	vimStringInterpolationExpr matchgroup=vimSep start=+{+ end=+}+ oneline contains=vimFunc,vimFuncVar,vimOper,vimOperParen,vimNotation,vimNumber,vimString,vimVar
-syn match	vimStringInterpolationBrace "{{"
-syn match	vimStringInterpolationBrace "}}"
+syn region	vimString	oneline start=+$'+ skip=+''+ end=+'+ contains=vimStringInterpolationBrace,vimStringInterpolationExpr
+syn region	vimString	oneline start=+$"+ end=+"+ contains=@vimStringGroup,vimStringInterpolationBrace,vimStringInterpolationExpr
+syn region	vimStringInterpolationExpr  oneline contained matchgroup=vimSep start=+{+ end=+}+ contains=@vimExprList
+syn match	vimStringInterpolationBrace contained "{{"
+syn match	vimStringInterpolationBrace contained "}}"
 
 " Substitutions: {{{2
 " =============
@@ -442,13 +444,16 @@
 
 " Echo And Execute: -- prefer strings! {{{2
 " ================
-syn region	vimEcho	oneline excludenl matchgroup=vimCommand start="\<ec\%[ho]\>" skip="\(\\\\\)*\\|" end="$\||" contains=vimFunc,vimFuncVar,vimString,vimVar
-syn region	vimExecute	oneline excludenl matchgroup=vimCommand start="\<exe\%[cute]\>" skip="\(\\\\\)*\\|" end="$\||\|<[cC][rR]>" contains=vimFuncVar,vimIsCommand,vimOper,vimNotation,vimOperParen,vimString,vimVar
-syn match	vimEchoHL	"echohl\="	skipwhite nextgroup=vimGroup,vimHLGroup,vimEchoHLNone
+" GEN_SYN_VIM: vimCommand echo, START_STR='syn keyword vimEcho', END_STR='skipwhite nextgroup=vimEchoExpr'
+syn region	vimEchoExpr 	contained	start="[^[:space:]|]" skip=+\\\\\|\\|\|\n\s*\\\|\n\s*"\\ + matchgroup=vimCmdSep end="|" end="$" contains=@vimContinue,@vimExprList
+
+syn match	vimEchoHL	"\<echohl\=\>"	skipwhite nextgroup=vimGroup,vimHLGroup,vimEchoHLNone
 syn case ignore
 syn keyword	vimEchoHLNone	none
 syn case match
 
+syn region	vimExecute	oneline excludenl matchgroup=vimCommand start="\<exe\%[cute]\>" skip="\(\\\\\)*\\|" end="$\||\|<[cC][rR]>" contains=vimFuncVar,vimIsCommand,vimOper,vimNotation,vimOperParen,vimString,vimVar
+
 " Maps: {{{2
 " ====
 syn match	vimMap		"\<map\>\ze\s*(\@!" 	    skipwhite nextgroup=vimMapMod,vimMapLhs
@@ -949,6 +954,7 @@
  hi def link vimContinue	Special
  hi def link vimContinueComment	vimComment
  hi def link vimCtrlChar	SpecialChar
+ hi def link vimEcho	vimCommand
  hi def link vimEchoHLNone	vimGroup
  hi def link vimEchoHL	vimCommand
  hi def link vimElseIfErr	Error