changeset 35334:f9613d63108f

runtime(vim): Update base-syntax, allow whitespace before :substitute pattern Commit: https://github.com/vim/vim/commit/92f4e915908962da2c1969a8d60f1563e06ee00e Author: Doug Kearns <dougkearns@gmail.com> Date: Wed Jun 5 19:45:43 2024 +0200 runtime(vim): Update base-syntax, allow whitespace before :substitute pattern Allow whitespace between the :substitute command and its pattern argument. Although unusual, it is supported and there are examples in the wild. Match Vi compatible :substitute commands like :s\/{string}/. See :help E1270. fixes: #14920 closes: #14923 Signed-off-by: Doug Kearns <dougkearns@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Wed, 05 Jun 2024 20:00:10 +0200
parents ec11ad45ac55
children 193e19c464cc
files runtime/doc/syntax.txt runtime/syntax/generator/vim.vim.base runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump runtime/syntax/testdir/dumps/vim_ex_substitute_05.dump runtime/syntax/testdir/dumps/vim_ex_substitute_06.dump runtime/syntax/testdir/dumps/vim_ex_substitute_07.dump runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump runtime/syntax/testdir/input/vim_ex_substitute.vim runtime/syntax/vim.vim
diffstat 12 files changed, 169 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1,4 +1,4 @@
-*syntax.txt*	For Vim version 9.1.  Last change: 2024 May 31
+*syntax.txt*	For Vim version 9.1.  Last change: 2024 Jun 05
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -3810,12 +3810,12 @@ embedded script highlighting they wish t
    g:vimsyn_embed =~ 't' : support embedded tcl
 <
 By default, g:vimsyn_embed is a string supporting interpreters that your vim
-itself supports.  Concatenate multiple characters to support multiple types
-of embedded interpreters; ie. g:vimsyn_embed= "mp" supports embedded mzscheme
-and embedded perl.
+itself supports.  Concatenate the indicated characters to support multiple
+types of embedded interpreters; ie. g:vimsyn_embed = "mp" supports embedded
+mzscheme and embedded perl.
 						*g:vimsyn_folding*
 
-Some folding is now supported with syntax/vim.vim: >
+Some folding is now supported with when 'foldmethod' is set to "syntax": >
 
    g:vimsyn_folding == 0 or doesn't exist: no syntax-based folding
    g:vimsyn_folding =~ 'a' : augroups
@@ -3828,8 +3828,12 @@ Some folding is now supported with synta
    g:vimsyn_folding =~ 'P' : fold python   script
    g:vimsyn_folding =~ 'r' : fold ruby     script
    g:vimsyn_folding =~ 't' : fold tcl      script
-let g:vimsyn_folding = 'acfhlmpPrt'
 <
+
+By default, g:vimsyn_folding is unset.  Concatenate the indicated characters
+to support folding of multiple syntax constructs; i.e.
+g:vimsyn_folding = "fh" will enable folding of both functions and heredocs.
+
 							*g:vimsyn_noerror*
 Not all error highlighting that syntax/vim.vim does may be correct; Vim script
 is a difficult language to highlight correctly.  A way to suppress error
--- 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 Apr 13
+" Last Change:	   2024 Jun 05
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -438,12 +438,10 @@ syn match	vimStringInterpolationBrace co
 syn cluster	vimSubstList	contains=vimPatSep,vimPatRegion,vimPatSepErr,vimSubstTwoBS,vimSubstRange,vimNotation
 syn cluster	vimSubstRepList	contains=vimSubstSubstr,vimSubstTwoBS,vimNotation
 syn cluster	vimSubstList	add=vimCollection
-syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>[\"#|]\@!"	nextgroup=vimSubstPat
-syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)_\@="	nextgroup=vimSubstPat
-syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#"	nextgroup=vimSubstPat
-syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>[\"#|]\@!"		nextgroup=vimSubstPat
-syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)_\@="			nextgroup=vimSubstPat
-syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#"		nextgroup=vimSubstPat
+syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>"			skipwhite nextgroup=vimSubstPat
+syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)[_#]\@="		skipwhite nextgroup=vimSubstPat
+syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>"		skipwhite nextgroup=vimSubstPat
+syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)[_#]\@="	skipwhite nextgroup=vimSubstPat
 " TODO: Vim9 illegal separators for abbreviated :s form are [-.:], :su\%[...] required
 "     : # is allowed but "not recommended" (see :h pattern-delimiter)
 syn region	vimSubstPat	contained	matchgroup=vimSubstDelim start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)"rs=s+1 skip="\\\\\|\\\z1" end="\z1"re=e-1,me=e-1	contains=@vimSubstList	nextgroup=vimSubstRep4	oneline
@@ -456,6 +454,10 @@ syn match	vimSubstTwoBS	contained	"\\\\"
 syn match	vimSubstFlagErr	contained	"[^< \t\r|]\+" contains=vimSubstFlags
 syn match	vimSubstFlags	contained	"[&cegiIlnpr#]\+"
 
+" Vi compatibility
+syn match	vimSubstDelim	contained	"\\"
+syn match	vimSubstPat	contained	"\\\ze[/?&]" contains=vimSubstDelim nextgroup=vimSubstRep4
+
 " 'String': {{{2
 syn match	vimString	"[^(,]'[^']\{-}\zs'"
 
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_01.dump
@@ -17,4 +17,4 @@
 |f+0#af5f00255&|u|n|c|t|i|o|n| +0#0000000&|F|o@1|(+0#e000e06&|)| +0#0000000&@60
 | +0#af5f00255&@1|s|u|b|s|t|i|t|u|t|e|/+0#e000e06&|f+0#0000000&|o@1|/+0#e000e06&|b+0#0000000&|a|r|/+0#e000e06&| +0#0000000&@53
 @2|l+0#af5f00255&|e|t| +0#0000000&|b+0#00e0e07&|a|r| +0#0000000&|=+0#af5f00255&| +0#0000000&|s|t|r|-+0#af5f00255&|>|s+0#00e0e07&|u|b|s|t|i|t|u|t|e|(+0#e000e06&|s+0#00e0e07&|t|r|,+0#0000000&| |p+0#00e0e07&|a|t|,+0#0000000&| |s+0#00e0e07&|u|b|,+0#0000000&| |f+0#00e0e07&|l|a|g|s|)+0#e000e06&| +0#0000000&@25
-@57|1|9|,|1| @9|1|9|%| 
+@57|1|9|,|1| @9|1|0|%| 
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_02.dump
@@ -17,4 +17,4 @@
 |s+0#af5f00255&|'+0#e000e06&|/+0#0000000&|'+0#e000e06&|/+0#0000000&@1|'+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
 |"+0#0000e05&| |F+0#0000001#ffff4012|I|X|M|E| +0#0000e05#ffffff0|-| |m|a|t|c|h|e|s| |v|i|m|U|s|e|r|F|u|n|c| +0#0000000&@45
 |"+0#0000e05&| |s|(|/|(|/@1|(| |"| |c|o|m@1|e|n|t| +0#0000000&@55
-@57|3|7|,|3| @9|4|6|%| 
+@57|3|7|,|3| @9|2|4|%| 
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_03.dump
@@ -17,4 +17,4 @@
 |"+0#0000e05&| |s|\|/|\|/@1|\| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@42
 |s+0#af5f00255&|]+0#e000e06&|/+0#0000000&|]+0#e000e06&|/+0#0000000&@1|]+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
 |s+0#af5f00255&|^+0#e000e06&|/+0#0000000&|^+0#e000e06&|/+0#0000000&@1|^+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-@57|5@1|,|1| @9|7|3|%| 
+@57|5@1|,|1| @9|3|9|%| 
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_04.dump
@@ -6,15 +6,15 @@
 >s+0#af5f00255&|}+0#e000e06&|/+0#0000000&|}+0#e000e06&|/+0#0000000&@1|}+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
 |s+0#af5f00255&|~+0#e000e06&|/+0#0000000&|~+0#e000e06&|/+0#0000000&@1|~+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
 @75
-@75
-|"+0#0000e05&| |I|s@1|u|e| |#|1|3|8@1|3| +0#0000000&@60
-@75
-|s|t|r|[|s|]| @68
-|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@68
-@75
-|d+0#af5f00255&|e|f| +0#0000000&|T|e|s|t|(+0#e000e06&|)| +0#0000000&@64
-@2|s|t|r|[|s|]| @66
-@2|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@66
-|e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
-@75
-@57|7|3|,|1| @9|B|o|t| 
+|s+0#af5f00255&| +0#0000000&|!+0#e000e06&|/+0#0000000&|!+0#e000e06&|/+0#0000000&@1|!+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |s| |"+0#e000002&|/|"|/+0#0000e05&@1|"| |"| |c|o|m@1|e|n|t| |(|w|o|r|k|s| |b|u|t| |d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@31
+|s+0#af5f00255&| +0#0000000&|#+0#e000e06&|/+0#0000000&|#+0#e000e06&|/+0#0000000&@1|#+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|$+0#e000e06&|/+0#0000000&|$+0#e000e06&|/+0#0000000&@1|$+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|%+0#e000e06&|/+0#0000000&|%+0#e000e06&|/+0#0000000&@1|%+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|&+0#e000e06&|/+0#0000000&|&+0#e000e06&|/+0#0000000&@1|&+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|'+0#e000e06&|/+0#0000000&|'+0#e000e06&|/+0#0000000&@1|'+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |F+0#0000001#ffff4012|I|X|M|E| +0#0000e05#ffffff0|-| |m|a|t|c|h|e|s| |v|i|m|U|s|e|r|F|u|n|c| +0#0000000&@45
+|"+0#0000e05&| |s| |(|/|(|/@1|(| |"| |c|o|m@1|e|n|t| +0#0000000&@54
+|s+0#af5f00255&| +0#0000000&|)+0#e000e06&|/+0#0000000&|)+0#e000e06&|/+0#0000000&@1|)+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|*+0#e000e06&|/+0#0000000&|*+0#e000e06&|/+0#0000000&@1|*+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+@57|7|3|,|1| @9|5|3|%| 
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_05.dump
@@ -0,0 +1,20 @@
+|s+0#af5f00255#ffffff0| +0#0000000&|*+0#e000e06&|/+0#0000000&|*+0#e000e06&|/+0#0000000&@1|*+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|++0#e000e06&|/+0#0000000&|++0#e000e06&|/+0#0000000&@1|++0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|,+0#e000e06&|/+0#0000000&|,+0#e000e06&|/+0#0000000&@1|,+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|-+0#e000e06&|/+0#0000000&|-+0#e000e06&|/+0#0000000&@1|-+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|.+0#e000e06&|/+0#0000000&|.+0#e000e06&|/+0#0000000&@1|.+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+>s+0#af5f00255&| +0#0000000&|/+0#e000e06&|X+0#0000000&|/+0#e000e06&|X+0#0000000&@1|/+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|:+0#e000e06&|/+0#0000000&|:+0#e000e06&|/+0#0000000&@1|:+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|;+0#e000e06&|/+0#0000000&|;+0#e000e06&|/+0#0000000&@1|;+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|<+0#e000e06&|/+0#0000000&|<+0#e000e06&|/+0#0000000&@1|<+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|=+0#e000e06&|/+0#0000000&|=+0#e000e06&|/+0#0000000&@1|=+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|>+0#e000e06&|/+0#0000000&|>+0#e000e06&|/+0#0000000&@1|>+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|?+0#e000e06&|/+0#0000000&|?+0#e000e06&|/+0#0000000&@1|?+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|@+0#e000e06&|/+0#0000000&|@+0#e000e06&|/+0#0000000&@1|@+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|[+0#e000e06&|/+0#0000000&|[+0#e000e06&|/+0#0000000&@1|[+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |s| |\|/|\|/@1|\| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@41
+|s+0#af5f00255&| +0#0000000&|]+0#e000e06&|/+0#0000000&|]+0#e000e06&|/+0#0000000&@1|]+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|^+0#e000e06&|/+0#0000000&|^+0#e000e06&|/+0#0000000&@1|^+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|_+0#e000e06&|/+0#0000000&|_+0#e000e06&|/+0#0000000&@1|_+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|`+0#e000e06&|/+0#0000000&|`+0#e000e06&|/+0#0000000&@1|`+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+@57|9|1|,|1| @9|6|8|%| 
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_06.dump
@@ -0,0 +1,20 @@
+|s+0#af5f00255#ffffff0| +0#0000000&|`+0#e000e06&|/+0#0000000&|`+0#e000e06&|/+0#0000000&@1|`+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|{+0#e000e06&|/+0#0000000&|{+0#e000e06&|/+0#0000000&@1|{+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|"+0#0000e05&| |s| |||/|||/@1||| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@41
+|s+0#af5f00255&| +0#0000000&|}+0#e000e06&|/+0#0000000&|}+0#e000e06&|/+0#0000000&@1|}+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+|s+0#af5f00255&| +0#0000000&|~+0#e000e06&|/+0#0000000&|~+0#e000e06&|/+0#0000000&@1|~+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@56
+> @74
+|s+0#af5f00255&|/+0#e000e06&@1|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@62
+|s+0#af5f00255&| +0#0000000&|/+0#e000e06&@1|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@61
+@75
+@75
+|"+0#0000e05&| |V|i| |c|o|m|p|a|t|i|b|i|l|i|t|y| +0#0000000&@56
+@75
+|s+0#af5f00255&|\+0#e000e06&|/|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@62
+|s+0#af5f00255&|\+0#e000e06&|?|{+0#0000000&|s|t|r|i|n|g|}|?+0#e000e06&| +0#0000000&@62
+|s+0#af5f00255&|\+0#e000e06&|&|{+0#0000000&|s|t|r|i|n|g|}|&+0#e000e06&| +0#0000000&@62
+@75
+|s+0#af5f00255&| +0#0000000&|\+0#e000e06&|/|{+0#0000000&|s|t|r|i|n|g|}|/+0#e000e06&| +0#0000000&@61
+|s+0#af5f00255&| +0#0000000&|\+0#e000e06&|?|{+0#0000000&|s|t|r|i|n|g|}|?+0#e000e06&| +0#0000000&@61
+|s+0#af5f00255&| +0#0000000&|\+0#e000e06&|&|{+0#0000000&|s|t|r|i|n|g|}|&+0#e000e06&| +0#0000000&@61
+@57|1|0|9|,|0|-|1| @6|8|2|%| 
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_07.dump
@@ -0,0 +1,20 @@
+|s+0#af5f00255#ffffff0| +0#0000000&|\+0#e000e06&|&|{+0#0000000&|s|t|r|i|n|g|}|&+0#e000e06&| +0#0000000&@61
+@75
+@75
+|"+0#0000e05&| |T|r|a|i|l|i|n|g| |c|o|m@1|e|n|t| |a|n|d| |b|a|r| +0#0000000&@48
+@75
+>"+0#0000e05&| +0#0000000&|F+0#0000001#ffff4012|I|X|M|E|:+0#e000e06#ffffff0| +0#0000e05&|t|r|a|i|l|i|n|g| |c|o|m@1|e|n|t|,| |n|o| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@34
+|s+0#af5f00255&|"+0#0000000&| |c|o|m@1|e|n|t| @64
+|s+0#af5f00255&||+0#0000000&| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@61
+@75
+|s+0#af5f00255&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@63
+|s+0#af5f00255&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@60
+@75
+@75
+|"+0#0000e05&| |I|s@1|u|e| |#|1|3|8@1|3| +0#0000000&@60
+@75
+|s|t|r|[|s|]| @68
+|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@68
+@75
+|d+0#af5f00255&|e|f| +0#0000000&|T|e|s|t|(+0#e000e06&|)| +0#0000000&@64
+@57|1|2|7|,|1| @8|9|6|%| 
--- a/runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump
+++ b/runtime/syntax/testdir/dumps/vim_ex_substitute_99.dump
@@ -1,10 +1,10 @@
-|s+0#af5f00255#ffffff0|^+0#e000e06&|/+0#0000000&|^+0#e000e06&|/+0#0000000&@1|^+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|_+0#e000e06&|/+0#0000000&|_+0#e000e06&|/+0#0000000&@1|_+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|`+0#e000e06&|/+0#0000000&|`+0#e000e06&|/+0#0000000&@1|`+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|{+0#e000e06&|/+0#0000000&|{+0#e000e06&|/+0#0000000&@1|{+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|"+0#0000e05&| |s|||/|||/@1||| |"| |c|o|m@1|e|n|t| |(|d|i|s|a|l@1|o|w|e|d|)| +0#0000000&@42
-|s+0#af5f00255&|}+0#e000e06&|/+0#0000000&|}+0#e000e06&|/+0#0000000&@1|}+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
-|s+0#af5f00255&|~+0#e000e06&|/+0#0000000&|~+0#e000e06&|/+0#0000000&@1|~+0#e000e06&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@57
+| +0&#ffffff0@74
+|"+0#0000e05&| +0#0000000&|F+0#0000001#ffff4012|I|X|M|E|:+0#e000e06#ffffff0| +0#0000e05&|t|r|a|i|l|i|n|g| |c|o|m@1|e|n|t|,| |n|o| |w|h|i|t|e|s|p|a|c|e| +0#0000000&@34
+|s+0#af5f00255&|"+0#0000000&| |c|o|m@1|e|n|t| @64
+|s+0#af5f00255&||+0#0000000&| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@61
+@75
+|s+0#af5f00255&| +0#0000000&|"+0#0000e05&| |c|o|m@1|e|n|t| +0#0000000&@63
+|s+0#af5f00255&| +0#0000000&||| |e+0#af5f00255&|c|h|o| +0#0000000&|"+0#e000002&|F|o@1|"| +0#0000000&@60
 @75
 @75
 |"+0#0000e05&| |I|s@1|u|e| |#|1|3|8@1|3| +0#0000000&@60
@@ -17,4 +17,4 @@
 @2|s|t|r|(+0#e000e06&|s+0#00e0e07&|)+0#e000e06&| +0#0000000&@66
 |e+0#af5f00255&|n|d@1|e|f| +0#0000000&@68
 > @74
-@57|8|6|,|0|-|1| @7|B|o|t| 
+@57|1|4@1|,|0|-|1| @6|B|o|t| 
--- a/runtime/syntax/testdir/input/vim_ex_substitute.vim
+++ b/runtime/syntax/testdir/input/vim_ex_substitute.vim
@@ -73,6 +73,64 @@ s{/{//{ " comment
 s}/}//} " comment
 s~/~//~ " comment
 
+s !/!//! " comment
+" s "/"//" " comment (works but disallowed)
+s #/#//# " comment
+s $/$//$ " comment
+s %/%//% " comment
+s &/&//& " comment
+s '/'//' " comment
+" FIXME - matches vimUserFunc
+" s (/(//( " comment
+s )/)//) " comment
+s */*//* " comment
+s +/+//+ " comment
+s ,/,//, " comment
+s -/-//- " comment
+s ././/. " comment
+s /X/XX/ " comment
+s :/://: " comment
+s ;/;//; " comment
+s </<//< " comment
+s =/=//= " comment
+s >/>//> " comment
+s ?/?//? " comment
+s @/@//@ " comment
+s [/[//[ " comment
+" s \/\//\ " comment (disallowed)
+s ]/]//] " comment
+s ^/^//^ " comment
+s _/_//_ " comment
+s `/`//` " comment
+s {/{//{ " comment
+" s |/|//| " comment (disallowed)
+s }/}//} " comment
+s ~/~//~ " comment
+
+s//{string}/
+s //{string}/
+
+
+" Vi compatibility
+
+s\/{string}/
+s\?{string}?
+s\&{string}&
+
+s \/{string}/
+s \?{string}?
+s \&{string}&
+
+
+" Trailing comment and bar
+
+" FIXME: trailing comment, no whitespace
+s" comment
+s| echo "Foo"
+
+s " comment
+s | echo "Foo"
+
 
 " Issue #13883
 
--- 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 Jun 03
+" Last Change:	   2024 Jun 05
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -477,12 +477,10 @@ syn match	vimStringInterpolationBrace co
 syn cluster	vimSubstList	contains=vimPatSep,vimPatRegion,vimPatSepErr,vimSubstTwoBS,vimSubstRange,vimNotation
 syn cluster	vimSubstRepList	contains=vimSubstSubstr,vimSubstTwoBS,vimNotation
 syn cluster	vimSubstList	add=vimCollection
-syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>[\"#|]\@!"	nextgroup=vimSubstPat
-syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)_\@="	nextgroup=vimSubstPat
-syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#"	nextgroup=vimSubstPat
-syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>[\"#|]\@!"		nextgroup=vimSubstPat
-syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)_\@="			nextgroup=vimSubstPat
-syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\ze#.\{-}#.\{-}#"		nextgroup=vimSubstPat
+syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)\>"			skipwhite nextgroup=vimSubstPat
+syn match	vimSubst	"^\s*\%(s\%[ubstitute]\|sm\%[agic]\|sno\%[magic]\)[_#]\@="		skipwhite nextgroup=vimSubstPat
+syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)\>"		skipwhite nextgroup=vimSubstPat
+syn match	vimSubst1	contained	"\%(s\%[ubstitute]\|sm\%[agic]\>\|sno\%[magic]\)[_#]\@="	skipwhite nextgroup=vimSubstPat
 " TODO: Vim9 illegal separators for abbreviated :s form are [-.:], :su\%[...] required
 "     : # is allowed but "not recommended" (see :h pattern-delimiter)
 syn region	vimSubstPat	contained	matchgroup=vimSubstDelim start="\z([!#$%&'()*+,-./:;<=>?@[\]^_`{}~]\)"rs=s+1 skip="\\\\\|\\\z1" end="\z1"re=e-1,me=e-1	contains=@vimSubstList	nextgroup=vimSubstRep4	oneline
@@ -495,6 +493,10 @@ syn match	vimSubstTwoBS	contained	"\\\\"
 syn match	vimSubstFlagErr	contained	"[^< \t\r|]\+" contains=vimSubstFlags
 syn match	vimSubstFlags	contained	"[&cegiIlnpr#]\+"
 
+" Vi compatibility
+syn match	vimSubstDelim	contained	"\\"
+syn match	vimSubstPat	contained	"\\\ze[/?&]" contains=vimSubstDelim nextgroup=vimSubstRep4
+
 " 'String': {{{2
 syn match	vimString	"[^(,]'[^']\{-}\zs'"