changeset 36052:0dcc727d6447

runtime(java): Provide support for syntax preview features Commit: https://github.com/vim/vim/commit/8556e23ee90448f01b612d337599f6e8f86679ea Author: Aliaksei Budavei <0x000c70@gmail.com> Date: Tue Aug 27 22:32:13 2024 +0200 runtime(java): Provide support for syntax preview features Introduce a new API variable "g:java_syntax_previews" whose value must be a list of syntax preview feature numbers. Enumerate the currently supported numbers in a table at the end of the documentation entry for "ft-java-syntax". Also, disable the recognition of String Templates. Despite the withdrawal of this preview feature in its proposed form from the upcoming JDK 23 release and the fact that the JDK 22 release is coming to EOL this September, an earlier iteration of this preview feature was included in JDK 21 (LTS) whose EOL is projected to fall due in late 2028 and, therefore, retain the current implementation. Define "g:java_syntax_previews" and include number 430 in its list to enable the recognition of String Templates: ------------------------------------------------------------ let g:java_syntax_previews = [430] ------------------------------------------------------------ References: https://openjdk.org/jeps/430 (Preview) https://openjdk.org/jeps/459 (Second Preview) https://openjdk.org/jeps/465 (Third Preview) https://mail.openjdk.org/pipermail/amber-spec-experts/2024-April/004106.html closes: #15579 Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Tue, 27 Aug 2024 22:45:10 +0200
parents eacc13956f22
children 6bd46e2212ca
files runtime/doc/syntax.txt runtime/syntax/java.vim runtime/syntax/testdir/dumps/java_previews_430_00.dump runtime/syntax/testdir/dumps/java_previews_430_01.dump runtime/syntax/testdir/dumps/java_previews_430_02.dump runtime/syntax/testdir/dumps/java_previews_430_03.dump runtime/syntax/testdir/dumps/java_string_00.dump runtime/syntax/testdir/dumps/java_string_01.dump runtime/syntax/testdir/dumps/java_string_02.dump runtime/syntax/testdir/dumps/java_string_03.dump runtime/syntax/testdir/dumps/java_string_04.dump runtime/syntax/testdir/dumps/java_string_05.dump runtime/syntax/testdir/input/java_previews_430.java runtime/syntax/testdir/input/java_string.java
diffstat 14 files changed, 200 insertions(+), 144 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 Aug 22
+*syntax.txt*	For Vim version 9.1.  Last change: 2024 Aug 26
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -2164,6 +2164,22 @@ This will make the syntax synchronizatio
 displayed line.  The default value is 10.  The disadvantage of using a larger
 number is that redrawing can become slow.
 
+Significant changes to the Java platform are gradually introduced in the form
+of JDK Enhancement Proposals (JEPs) that can be implemented for a release and
+offered as its preview features.  It may take several JEPs and a few release
+cycles for such a feature to become either integrated into the platform or
+withdrawn from this effort.  To cater for early adopters, there is optional
+support in Vim for syntax related preview features that are implemented.  You
+can request it by specifying a list of preview feature numbers as follows: >
+	:let g:java_syntax_previews = [430]
+
+The supported JEP numbers are to be drawn from this table:
+	`430`: String Templates [JDK 21]
+
+Note that as soon as the particular preview feature will have been integrated
+into the Java platform, its entry will be removed from the table and related
+optionality will be discontinued.
+
 
 JSON			*json.vim* *ft-json-syntax* *g:vim_json_conceal*
 					       *g:vim_json_warnings*
--- a/runtime/syntax/java.vim
+++ b/runtime/syntax/java.vim
@@ -3,7 +3,7 @@
 " Maintainer:		Aliaksei Budavei <0x000c70 AT gmail DOT com>
 " Former Maintainer:	Claudio Fleiner <claudio@fleiner.com>
 " Repository:		https://github.com/zzzyxwvut/java-vim.git
-" Last Change:		2024 Aug 22
+" Last Change:		2024 Aug 26
 
 " Please check :help java.vim for comments on some of the options available.
 
@@ -30,6 +30,10 @@ function! s:ff.RightConstant(x, y) abort
   return a:y
 endfunction
 
+function! s:ff.IsRequestedPreviewFeature(n) abort
+  return exists("g:java_syntax_previews") && index(g:java_syntax_previews, a:n) + 1
+endfunction
+
 if !exists("*s:ReportOnce")
   function s:ReportOnce(message) abort
     echomsg 'syntax/java.vim: ' . a:message
@@ -367,9 +371,14 @@ syn match   javaSpecialChar	contained "\
 syn region  javaString		start=+"+ end=+"+ end=+$+ contains=javaSpecialChar,javaSpecialError,@Spell
 syn region  javaString		start=+"""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaSpecialChar,javaSpecialError,javaTextBlockError,@Spell
 syn match   javaTextBlockError	+"""\s*"""+
-syn region  javaStrTemplEmbExp	contained matchgroup=javaStrTempl start="\\{" end="}" contains=TOP
-exec 'syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="+ end=+"+ contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,@Spell'
-exec 'syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,javaTextBlockError,@Spell'
+
+if s:ff.IsRequestedPreviewFeature(430)
+  syn region javaStrTemplEmbExp	contained matchgroup=javaStrTempl start="\\{" end="}" contains=TOP
+  exec 'syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="+ end=+"+ contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,@Spell'
+  exec 'syn region javaStrTempl start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaStrTemplEmbExp,javaSpecialChar,javaSpecialError,javaTextBlockError,@Spell'
+  hi def link javaStrTempl	Macro
+endif
+
 syn match   javaCharacter	"'[^']*'" contains=javaSpecialChar,javaSpecialCharError
 syn match   javaCharacter	"'\\''" contains=javaSpecialChar
 syn match   javaCharacter	"'[^\\]'"
@@ -441,11 +450,16 @@ if exists("g:java_highlight_debug")
   syn match   javaDebugSpecial		contained "\\\%(u\x\x\x\x\|[0-3]\o\o\|\o\o\=\|[bstnfr"'\\]\)"
   syn region  javaDebugString		contained start=+"+ end=+"+ contains=javaDebugSpecial
   syn region  javaDebugString		contained start=+"""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaDebugSpecial,javaDebugTextBlockError
-  " The highlight groups of java{StrTempl,Debug{,Paren,StrTempl}}\,
-  " share one colour by default. Do not conflate unrelated parens.
-  syn region  javaDebugStrTemplEmbExp	contained matchgroup=javaDebugStrTempl start="\\{" end="}" contains=javaComment,javaLineComment,javaDebug\%(Paren\)\@!.*
-  exec 'syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="+ end=+"+ contains=javaDebugStrTemplEmbExp,javaDebugSpecial'
-  exec 'syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaDebugStrTemplEmbExp,javaDebugSpecial,javaDebugTextBlockError'
+
+  if s:ff.IsRequestedPreviewFeature(430)
+    " The highlight groups of java{StrTempl,Debug{,Paren,StrTempl}}\,
+    " share one colour by default. Do not conflate unrelated parens.
+    syn region javaDebugStrTemplEmbExp	contained matchgroup=javaDebugStrTempl start="\\{" end="}" contains=javaComment,javaLineComment,javaDebug\%(Paren\)\@!.*
+    exec 'syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="+ end=+"+ contains=javaDebugStrTemplEmbExp,javaDebugSpecial'
+    exec 'syn region javaDebugStrTempl contained start=+\%(\.[[:space:]\n]*\)\@' . s:ff.Peek('80', '') . '<="""[ \t\x0c\r]*$+hs=e+1 end=+"""+he=s-1 contains=javaDebugStrTemplEmbExp,javaDebugSpecial,javaDebugTextBlockError'
+    hi def link javaDebugStrTempl	Macro
+  endif
+
   syn match   javaDebugTextBlockError	contained +"""\s*"""+
   syn match   javaDebugCharacter	contained "'[^\\]'"
   syn match   javaDebugSpecialCharacter contained "'\\.'"
@@ -471,7 +485,6 @@ if exists("g:java_highlight_debug")
 
   hi def link javaDebug			Debug
   hi def link javaDebugString		DebugString
-  hi def link javaDebugStrTempl		Macro
   hi def link javaDebugTextBlockError	Error
   hi def link javaDebugType		DebugType
   hi def link javaDebugBoolean		DebugBoolean
@@ -580,7 +593,6 @@ hi def link javaSpecial			Special
 hi def link javaSpecialError		Error
 hi def link javaSpecialCharError	Error
 hi def link javaString			String
-hi def link javaStrTempl		Macro
 hi def link javaCharacter		Character
 hi def link javaSpecialChar		SpecialChar
 hi def link javaNumber			Number
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/java_previews_430_00.dump
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| |g|:|j|a|v|a|_|s|y|n|t|a|x|_|p|r|e|v|i|e|w|s| |=| |[|4|3|0|]| +0#0000000&@22
+@75
+@75
+@75
+|c+0#00e0003&|l|a|s@1| +0#0000000&|S|t|r|i|n|g|T|e|m|p|l|a|t|e|T|e|s|t|s| @2|/+0#0000e05&@1| |J|D|K| |2|1|+| |(|-@1|e|n|a|b|l|e|-|p|r|e|v|i|e|w| |-@1|r|e|l|e|a|s|e| |2|1|)|.| +0#0000000&@3
+|{| @73
+@4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|{| @62
+@8|S|y|s|t|e|m|.|o|u|t|.|p|r|i|n|t|l|n|(|S|T|R|.|"@2| @40
+| +0#e000e06&@7|"| +0#0000000&@65
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&| +0#0000000&@57
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@40
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&|"| +0#0000000&@39
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|\|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@26
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@29
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"@1| +0#0000000&@43
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"@1|\|"|"+0#0000000&@2|)|;| @36
+@75
+@8|S|t|r|i|n|g| |w|o@1|f| |=| |"+0#e000002&|W|o@1|f|"|,+0#0000000&| |d|o|g| |=| |"+0#e000002&|d|o|g|"|,+0#0000000&| |f|o|x| |=| |"+0#e000002&|f|o|x|"|;+0#0000000&| @19
+@75
+@57|1|,|1| @10|T|o|p| 
rename from runtime/syntax/testdir/dumps/java_string_03.dump
rename to runtime/syntax/testdir/dumps/java_previews_430_01.dump
--- a/runtime/syntax/testdir/dumps/java_string_03.dump
+++ b/runtime/syntax/testdir/dumps/java_previews_430_01.dump
@@ -1,14 +1,14 @@
 | +0#e000e06#ffffff0@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@29
 | +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"@1| +0#0000000&@43
-| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"@1|\|"|"+0#0000000&@2|)|;| @5|/+0#0000e05&@1| |J|D|K| |2|1|+|.| +0#0000000&@19
+| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"@1|\|"|"+0#0000000&@2|)|;| @36
 @75
 @8|S|t|r|i|n|g| |w|o@1|f| |=| |"+0#e000002&|W|o@1|f|"|,+0#0000000&| |d|o|g| |=| |"+0#e000002&|d|o|g|"|,+0#0000000&| |f|o|x| |=| |"+0#e000002&|f|o|x|"|;+0#0000000&| @19
 > @74
-@8|S|t|r|i|n|g| |s|6| |=| |S|T|R| @51
+@8|S|t|r|i|n|g| |s|1| |=| |S|T|R| @51
 @12|.|"+0#e000e06&|A| |q|u|i|c|k| |b|r|o|w|n| |\|{|f+0#0000000&|o|x|}+0#e000e06&| |j|u|m|p|s| |o|v|e|r| |t|h|e| |l|a|z|y| |\|{|d+0#0000000&|o|g|}+0#e000e06&|"|;+0#0000000&| @11
-@8|S|t|r|i|n|g| |s|7| |=| |S|T|R|.|p|r|o|c|e|s@1|(|S|t|r|i|n|g|T|e|m|p|l|a|t|e|.|R|A|W| @24
+@8|S|t|r|i|n|g| |s|2| |=| |S|T|R|.|p|r|o|c|e|s@1|(|S|t|r|i|n|g|T|e|m|p|l|a|t|e|.|R|A|W| @24
 @12|.|"+0#e000e06&|\|"|\|{|w+0#0000000&|o@1|f|}+0#e000e06&|\|s|!|\|"@1|)+0#0000000&|;| @43
-@8|S|t|r|i|n|g| |s|8| |=| |S|T|R|.|"@2| @47
+@8|S|t|r|i|n|g| |s|3| |=| |S|T|R|.|"@2| @47
 | +0#e000e06&@11|A|\|s|\| +0#0000000&@58
 | +0#e000e06&@11|q|u|i|c|k| |\| +0#0000000&@55
 | +0#e000e06&@11|b|r|o|w|n|\|s|\| +0#0000000&@54
@@ -17,4 +17,4 @@
 | +0#e000e06&@11|o|v|e|r| |\| +0#0000000&@56
 | +0#e000e06&@11|t|h|e|\|s|\| +0#0000000&@56
 | +0#e000e06&@11|l|a|z|y| |\| +0#0000000&@56
-@57|5@1|,|0|-|1| @7|5|7|%| 
+@57|1|9|,|0|-|1| @7|2|6|%| 
rename from runtime/syntax/testdir/dumps/java_string_04.dump
rename to runtime/syntax/testdir/dumps/java_previews_430_02.dump
--- a/runtime/syntax/testdir/dumps/java_string_04.dump
+++ b/runtime/syntax/testdir/dumps/java_previews_430_02.dump
@@ -1,20 +1,20 @@
 | +0#e000e06#ffffff0@11|l|a|z|y| |\| +0#0000000&@56
 | +0#e000e06&@11|\|{|d+0#0000000&|o|g|}+0#e000e06&|"+0#0000000&@2|;| @52
-@8|S|t|r|i|n|g| |s|9| |=| |S|T|R|.|p|r|o|c|e|s@1|(|S|t|r|i|n|g|T|e|m|p|l|a|t|e|.|R|A|W| @24
+@8|S|t|r|i|n|g| |s|4| |=| |S|T|R|.|p|r|o|c|e|s@1|(|S|t|r|i|n|g|T|e|m|p|l|a|t|e|.|R|A|W| @24
 @12|.| @61
 @12|"@2| @59
 | +0#e000e06&@11>"|\|{|w+0#0000000&|o@1|f|}+0#e000e06&|\|s|!|\|"|"+0#0000000&@2|)|;| @44
-@8|S|t|r|i|n|g| |s|1|0| |=| |j|a|v|a|.|u|t|i|l|.|F|o|r|m|a|t|P|r|o|c|e|s@1|o|r|.|F|M|T| @24
+@8|S|t|r|i|n|g| |s|5| |=| |j|a|v|a|.|u|t|i|l|.|F|o|r|m|a|t|P|r|o|c|e|s@1|o|r|.|F|M|T| @25
 @12|.| |"+0#e000e06&|%|-|1|4|s|\|{|"+0#e000002&|A|\+0#e000e06&|s|"+0#e000002&| +0#0000000&|+| |S|T|R| |.| |"+0#e000e06&|q|u|i|c|k|"| +0#0000000&|+| |"+0#e000002&|b|r|o|w|n|"|}+0#e000e06&|%|s|\|{|f+0#0000000&|o|x|}+0#e000e06&| |"| +0#0000000&@10
 @12|+| |j|a|v|a|.|u|t|i|l|.|F|o|r|m|a|t|P|r|o|c|e|s@1|o|r|.|F|M|T| @31
 @12|.| |"+0#e000e06&|%|-|2|0|s|\|{|"+0#e000002&|j|u|m|p|s|\+0#e000e06&|s|o+0#e000002&|v|e|r| |t|h|e|\+0#e000e06&|s|"+0#e000002&| +0#0000000&@33
 @20|+| |S|T|R| |.| |"+0#e000e06&|l|a|z|y|"|}|%|s|\|{|d+0#0000000&|o|g|}+0#e000e06&|"|;+0#0000000&| @29
-@8|S|t|r|i|n|g| |s|1@1| |=| |S|T|R|.|"@2| @46
+@8|S|t|r|i|n|g| |s|6| |=| |S|T|R|.|"@2| @47
 | +0#e000e06&@11|\|"|\|{| +0#0000000&@11|/+0#0000e05&@1| |A| |n|e|s|t|e|d| |c|o|m@1|e|n|t|.| +0#0000000&@26
 @8|(|n+0#af5f00255&|e|w| +0#0000000&|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|S|t|r|i|n|g|,| |S|t|r|i|n|g|>|(|)| |{| @14
 @12|p+0#00e0003&|u|b|l|i|c| +0#0000000&|S|t|r|i|n|g| |a|p@1|l|y|(|S|t|r|i|n|g| |b|a|y|)| |{| |r+0#af5f00255&|e|t|u|r|n| +0#0000000&|b|a|y|;| |}|;| @14
 @8|}|)|.|a|p@1|l|y|(|w|o@1|f|)| @52
 @12|}+0#e000e06&|\|s|!|\|"|"+0#0000000&@2|;| @52
-@8|S|t|r|i|n|g| |s|1|2| |=| |j|a|v|a|.|u|t|i|l|.|F|o|r|m|a|t|P|r|o|c|e|s@1|o|r|.|F|M|T| @24
+@8|S|t|r|i|n|g| |s|7| |=| |j|a|v|a|.|u|t|i|l|.|F|o|r|m|a|t|P|r|o|c|e|s@1|o|r|.|F|M|T| @25
 @12|.|"@2| @58
-@57|7|3|,|4|-|1|3| @6|7|8|%| 
+@57|3|7|,|4|-|1|3| @6|6|3|%| 
rename from runtime/syntax/testdir/dumps/java_string_05.dump
rename to runtime/syntax/testdir/dumps/java_previews_430_03.dump
--- a/runtime/syntax/testdir/dumps/java_string_05.dump
+++ b/runtime/syntax/testdir/dumps/java_previews_430_03.dump
@@ -10,11 +10,11 @@
 | +0#e000e06&@15|t|h|e|\|s|\| +0#0000000&@52
 | +0#e000e06&@15|\|{| +0#0000000&|"+0#e000002&|l|a|z|y|"| +0#0000000&|}+0#e000e06&| |"+0#0000000&@2|}+0#e000e06&|\| +0#0000000&@41
 | +0#e000e06&@11|%|s|\|{| +0#0000000&|d|o|g| |}+0#e000e06&|"+0#0000000&@2|;| @48
-@8|S|t|r|i|n|g| |s|1|3| |=| |S|T|R| @50
+@8|S|t|r|i|n|g| |s|8| |=| |S|T|R| @51
 @12|.|"+0#e000e06&|\|"|\|{| +0#0000000&@9|/+0#0000e05&|*| |A| |n|e|s|t|e|d| |c|o|m@1|e|n|t|.| |*|/| +0#0000000&@23
 @8|(@1|j|a|v|a|.|u|t|i|l|.|f|u|n|c|t|i|o|n|.|F|u|n|c|t|i|o|n|<|S|t|r|i|n|g|,| |S|t|r|i|n|g|>|)| |b|a|y| |-|>| |b|a|y|)| @8
 @28|.|a|p@1|l|y|(|w|o@1|f|)| @34
 @12|}+0#e000e06&|\|s|!|\|"@1|;+0#0000000&| @54
 @4|}| @69
 |}| @73
-@57|9|1|,|4|-|1|3| @6|B|o|t| 
+@57|5@1|,|4|-|1|3| @6|B|o|t| 
--- a/runtime/syntax/testdir/dumps/java_string_00.dump
+++ b/runtime/syntax/testdir/dumps/java_string_00.dump
@@ -1,4 +1,4 @@
->c+0#00e0003#ffffff0|l|a|s@1| +0#0000000&|S|t|r|i|n|g|T|e|s|t|s| @2|/+0#0000e05&@1| |J|D|K| |2|1|+| |(|-@1|e|n|a|b|l|e|-|p|r|e|v|i|e|w| |-@1|r|e|l|e|a|s|e| |2|1|)|.| +0#0000000&@11
+>c+0#00e0003#ffffff0|l|a|s@1| +0#0000000&|S|t|r|i|n|g|T|e|s|t|s| @57
 |{| @73
 @4|s+0#00e0003&|t|a|t|i|c| +0#0000000&|{| @62
 @8|S|t|r|i|n|g| |s|1| |=| |"+0#e000002&|A| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|s| |o|v|e|r| |t|h|e| |l|a|z|y| |d|o|g|"|;+0#0000000&| @10
--- a/runtime/syntax/testdir/dumps/java_string_01.dump
+++ b/runtime/syntax/testdir/dumps/java_string_01.dump
@@ -17,4 +17,4 @@
 @8|/+0#0000e05&@1| |T|h|e|r|e| |a|r|e| |S|P|A|C|E|,| |F@1|,| |H|T|,| |C|R|,| |a|n|d| |L|F| |a|f|t|e|r| |"@2|.| +0#0000000&@17
 @8|S|t|r|i|n|g| |e|m|p|t|y| |=| |"@2| |^+0#0000e05&|L| +0#0000000&@2|^+0#0000e05&|M| +0#0000000&@40
 | +0#e000002&@11|"+0#0000000&@2|;| @58
-@57|1|9|,|3|-|9| @7|1|5|%| 
+@57|1|9|,|3|-|9| @7|5|2|%| 
--- a/runtime/syntax/testdir/dumps/java_string_02.dump
+++ b/runtime/syntax/testdir/dumps/java_string_02.dump
@@ -9,12 +9,12 @@
 | +0#e000002&@7|"@1|\+0#e000e06&|"|"+0#e000002&@1|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1| +0#0000000&@48
 | +0#e000002&@7|"@1|\+0#e000e06&|"|"+0#e000002&@1|\+0#e000e06&|"|"+0#e000002&| +0#0000000&@57
 | +0#e000002&@7|"@1|\+0#e000e06&|"|"+0#e000002&@1|\+0#e000e06&|"|"+0#e000002&|\+0#e000e06&|"|"+0#0000000&@2|)|;| @50
-@75
-@8|S|y|s|t|e|m|.|o|u|t|.|p|r|i|n|t|l|n|(|S|T|R|.|"@2| @40
-| +0#e000e06&@7|"| +0#0000000&@65
-| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&| +0#0000000&@57
-| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@40
-| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&|"| +0#0000000&@39
-| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|\|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@26
-| +0#e000e06&@7|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|"|\|{|"+0#e000002&|\+0#e000e06&|"|\|"|"+0#e000002&|}+0#e000e06&|\|{|"+0#e000002&|\+0#e000e06&|u|0@1|5|c|\|u|0@1|2@1|"+0#e000002&|}+0#e000e06&| +0#0000000&@29
-@57|3|7|,|3|-|9| @7|3|6|%| 
+@4|}| @69
+|}| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|3|7|,|3|-|9| @7|B|o|t| 
new file mode 100644
--- /dev/null
+++ b/runtime/syntax/testdir/input/java_previews_430.java
@@ -0,0 +1,68 @@
+// VIM_TEST_SETUP let g:java_syntax_previews = [430]
+
+
+
+class StringTemplateTests	// JDK 21+ (--enable-preview --release 21).
+{
+	static {
+		System.out.println(STR."""
+		"
+		\{"\"\""}
+		\{"\"\""}\{"\u005c\u0022"}
+		\{"\"\""}\{"\u005c\u0022"}"
+		\{"\"\""}\"\{"\u005c\u0022\u005c\u0022"}
+		\{"\"\""}\"\{"\"\""}\{"\u005c\u0022"}
+		\{"\"\""}\"\{"\"\""}\""
+		\{"\"\""}\"\{"\"\""}\""\"""");
+
+		String woof = "Woof", dog = "dog", fox = "fox";
+
+		String s1 = STR
+			."A quick brown \{fox} jumps over the lazy \{dog}";
+		String s2 = STR.process(StringTemplate.RAW
+			."\"\{woof}\s!\"");
+		String s3 = STR."""
+			A\s\
+			quick \
+			brown\s\
+			\{fox} \
+			jumps\s\
+			over \
+			the\s\
+			lazy \
+			\{dog}""";
+		String s4 = STR.process(StringTemplate.RAW
+			.
+			"""
+			"\{woof}\s!\"""");
+		String s5 = java.util.FormatProcessor.FMT
+			. "%-14s\{"A\s" + STR . "quick" + "brown"}%s\{fox} "
+			+ java.util.FormatProcessor.FMT
+			. "%-20s\{"jumps\sover the\s"
+					+ STR . "lazy"}%s\{dog}";
+		String s6 = STR."""
+			\"\{			// A nested comment.
+		(new java.util.function.Function<String, String>() {
+			public String apply(String bay) { return bay; };
+		}).apply(woof)
+			}\s!\"""";
+		String s7 = java.util.FormatProcessor.FMT
+			."""
+			%-14s\{STR."""
+				A\s\
+				\{ "quick" } \
+				brown"""}\
+			%s\{ fox } \
+			%-20s\{STR."""
+				jumps\s\
+				over \
+				the\s\
+				\{ "lazy" } """}\
+			%s\{ dog }""";
+		String s8 = STR
+			."\"\{			/* A nested comment. */
+		((java.util.function.Function<String, String>) bay -> bay)
+							.apply(woof)
+			}\s!\"";
+	}
+}
--- a/runtime/syntax/testdir/input/java_string.java
+++ b/runtime/syntax/testdir/input/java_string.java
@@ -1,4 +1,4 @@
-class StringTests	// JDK 21+ (--enable-preview --release 21).
+class StringTests
 {
 	static {
 		String s1 = "A quick brown fox jumps over the lazy dog";
@@ -40,65 +40,5 @@ class StringTests	// JDK 21+ (--enable-p
 		""\"""\u005c\u0022
 		""\"""\""
 		""\"""\""\"""");
-
-		System.out.println(STR."""
-		"
-		\{"\"\""}
-		\{"\"\""}\{"\u005c\u0022"}
-		\{"\"\""}\{"\u005c\u0022"}"
-		\{"\"\""}\"\{"\u005c\u0022\u005c\u0022"}
-		\{"\"\""}\"\{"\"\""}\{"\u005c\u0022"}
-		\{"\"\""}\"\{"\"\""}\""
-		\{"\"\""}\"\{"\"\""}\""\"""");		// JDK 21+.
-
-		String woof = "Woof", dog = "dog", fox = "fox";
-
-		String s6 = STR
-			."A quick brown \{fox} jumps over the lazy \{dog}";
-		String s7 = STR.process(StringTemplate.RAW
-			."\"\{woof}\s!\"");
-		String s8 = STR."""
-			A\s\
-			quick \
-			brown\s\
-			\{fox} \
-			jumps\s\
-			over \
-			the\s\
-			lazy \
-			\{dog}""";
-		String s9 = STR.process(StringTemplate.RAW
-			.
-			"""
-			"\{woof}\s!\"""");
-		String s10 = java.util.FormatProcessor.FMT
-			. "%-14s\{"A\s" + STR . "quick" + "brown"}%s\{fox} "
-			+ java.util.FormatProcessor.FMT
-			. "%-20s\{"jumps\sover the\s"
-					+ STR . "lazy"}%s\{dog}";
-		String s11 = STR."""
-			\"\{			// A nested comment.
-		(new java.util.function.Function<String, String>() {
-			public String apply(String bay) { return bay; };
-		}).apply(woof)
-			}\s!\"""";
-		String s12 = java.util.FormatProcessor.FMT
-			."""
-			%-14s\{STR."""
-				A\s\
-				\{ "quick" } \
-				brown"""}\
-			%s\{ fox } \
-			%-20s\{STR."""
-				jumps\s\
-				over \
-				the\s\
-				\{ "lazy" } """}\
-			%s\{ dog }""";
-		String s13 = STR
-			."\"\{			/* A nested comment. */
-		((java.util.function.Function<String, String>) bay -> bay)
-							.apply(woof)
-			}\s!\"";
 	}
 }