]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
runtime(cpp): add C++26 lexical constructs to syntax highlighting
authorGareth Lloyd <gareth@ignition-web.co.uk>
Sun, 21 Jun 2026 14:44:35 +0000 (14:44 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 21 Jun 2026 14:45:14 +0000 (14:45 +0000)
Add a guarded "C++ 26 extensions" block (cpp_no_cpp26) covering new
lexical surface introduced since C++23:

- [[ ... ]] attributes as a region, so P3394 annotations carrying a
  value expression (eg [[=foo{1}]]) no longer trip cErrInBracket on
  their braces/parens. A \w\@1<! look-behind keeps it from matching a
  subscripted immediately-invoked lambda (arr[[]{...}()]).
- ^^ reflection operator (P2996).
- [: :] splice brackets (P2996).
- contract_assert keyword (P2900).

Add input/cpp_cpp26.cpp exercising these constructs with screendumps,
and update dumps/cpp_noreturn_00.dump for the new [[ ]] attribute
delimiter highlighting.

closes: #20577

Signed-off-by: Gareth Lloyd <gareth@ignition-web.co.uk>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/syntax.txt
runtime/syntax/cpp.vim
runtime/syntax/testdir/dumps/cpp_cpp26_00.dump [new file with mode: 0644]
runtime/syntax/testdir/dumps/cpp_noreturn_00.dump
runtime/syntax/testdir/input/cpp_cpp26.cpp [new file with mode: 0644]

index e668de970b6b865c72f2740b6ef90868aaaf63dc..f50e12a9a1ec0b7dd936e25c78120e39f8a48be8 100644 (file)
@@ -1,4 +1,4 @@
-*syntax.txt*   For Vim version 9.2.  Last change: 2026 Jun 01
+*syntax.txt*   For Vim version 9.2.  Last change: 2026 Jun 21
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1261,6 +1261,7 @@ cpp_no_cpp14              don't highlight C++14 standard items
 cpp_no_cpp17           don't highlight C++17 standard items
 cpp_no_cpp20           don't highlight C++20 standard items
 cpp_no_cpp23           don't highlight C++23 standard items
+cpp_no_cpp26           don't highlight C++26 standard items
 
 
 CSH                                            *csh.vim* *ft-csh-syntax*
index 1c725a4bfd87f4d808529924ca9a5ddc649b8bb3..121eab2c6f5506ac16c36ca5b4187afba3be72df 100644 (file)
@@ -110,6 +110,15 @@ if !exists("cpp_no_cpp23")
   syn keyword cppType          float16_t float32_t float64_t float128_t bfloat16_t
 endif
 
+" C++ 26 extensions
+if !exists("cpp_no_cpp26")
+  " attribute [[ ... ]] with optional value expr, eg [[=foo{1}]]
+  syn region cppAttribute      matchgroup=cppAttributeBracket start="\w\@1<!\[\[" end="\]\]" contains=TOP,@Spell
+  syn match cppReflect         "\^\^"
+  syn match cppSpliceBracket   "\[:\|:\]"
+  syn keyword cppStatement     contract_assert
+endif
+
 " The minimum and maximum operators in GNU C++
 syn match cppMinMax "[<>]?"
 
@@ -134,6 +143,9 @@ hi def link cppString               String
 hi def link cppNumber          Number
 hi def link cppFloat           Number
 hi def link cppModule          Include
+hi def link cppAttributeBracket        Special
+hi def link cppReflect         Operator
+hi def link cppSpliceBracket   Special
 
 let b:current_syntax = "cpp"
 
diff --git a/runtime/syntax/testdir/dumps/cpp_cpp26_00.dump b/runtime/syntax/testdir/dumps/cpp_cpp26_00.dump
new file mode 100644 (file)
index 0000000..928d626
--- /dev/null
@@ -0,0 +1,20 @@
+>/+0#0000e05#ffffff0@1| |C|+@1|2|6| |l|e|x|i|c|a|l| |c|o|n|s|t|r|u|c|t|s| +0#0000000&@47
+@75
+|/+0#0000e05&@1| |P|3@1|9|4| |a|n@1|o|t|a|t|i|o|n|s|:| |[@1| |.@2| |]@1| |m|a|y| |c|a|r@1|y| |a| |v|a|l|u|e| |e|x|p|r|e|s@1|i|o|n|.| +0#0000000&@13
+|[+0#e000e06&@1|=+0#0000000&|r|e|n|a|m|e|{|"+0#e000002&|f|u|l@1|_|n|a|m|e|"|}+0#0000000&|]+0#e000e06&@1| +0#0000000&|i+0#00e0003&|n|t| +0#0000000&|b|r|a|c|e|d|;| @38
+|[+0#e000e06&@1|=+0#0000000&|k|e|y|(|8+0#e000002&|)+0#0000000&|]+0#e000e06&@1| +0#0000000&@13|i+0#00e0003&|n|t| +0#0000000&|p|a|r|e|n|e|d|;| @37
+|[+0#e000e06&@1|n+0#0000000&|o|d|i|s|c|a|r|d|]+0#e000e06&@1| +0#0000000&@11|i+0#00e0003&|n|t| +0#0000000&|p|l|a|i|n|(|)|;| @37
+@75
+|/+0#0000e05&@1| |P|2|9|0@1| |c|o|n|t|r|a|c|t|s|:| |c|o|n|t|r|a|c|t|_|a|s@1|e|r|t| |i|s| |a| |k|e|y|w|o|r|d|.| +0#0000000&@25
+|v+0#00e0003&|o|i|d| +0#0000000&|c|h|e|c|k|(|i+0#00e0003&|n|t| +0#0000000&|x|)| |{| |c+0#af5f00255&|o|n|t|r|a|c|t|_|a|s@1|e|r|t|(+0#0000000&|x| |!|=| |0+0#e000002&|)+0#0000000&|;| |}| @28
+@75
+|/+0#0000e05&@1| |P|2|9@1|6| |r|e|f|l|e|c|t|i|o|n| |(|^@1|)| |a|n|d| |s|p|l|i|c|i|n|g| |(|[|:| |:|]|)|.| +0#0000000&@28
+|c+0#00e0003&|o|n|s|t|e|x|p|r| +0#0000000&|a+0#00e0003&|u|t|o| +0#0000000&|r|e|f|l| |=| |^+0#af5f00255&@1|i+0#00e0003&|n|t|;+0#0000000&| @46
+|[+0#e000e06&|:|r+0#0000000&|e|f|l|:+0#e000e06&|]| +0#0000000&|s|p|l|i|c|e|d|{|}|;| @55
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1| 
index 2386ad118f7c917f4d57c1a5cc46e5190d15be57..2c94fc0f4218fb6176034cbf59cc2364230340fd 100644 (file)
@@ -6,7 +6,7 @@
 |#+0#e000e06&|i|n|c|l|u|d|e| |<+0#e000002&|s|t|d|i|o|.|h|>| +0#0000000&@56
 |#+0#e000e06&|i|n|c|l|u|d|e| |<+0#e000002&|s|t|d|l|i|b|.|h|>| +0#0000000&@55
 @75
-|[@1|n|o|r|e|t|u|r|n|]@1| |v+0#00e0003&|o|i|d| +0#0000000&|e|r@1|o|r|_|e|x|i|t|(|c+0#00e0003&|o|n|s|t| +0#0000000&|c+0#00e0003&|h|a|r|*+0#0000000&| |r|e|a|s|o|n|)| @26
+|[+0#e000e06&@1|n+0#0000000&|o|r|e|t|u|r|n|]+0#e000e06&@1| +0#0000000&|v+0#00e0003&|o|i|d| +0#0000000&|e|r@1|o|r|_|e|x|i|t|(|c+0#00e0003&|o|n|s|t| +0#0000000&|c+0#00e0003&|h|a|r|*+0#0000000&| |r|e|a|s|o|n|)| @26
 |{| @73
 @4|p|r|i|n|t|f|(|"+0#e000002&|E|r@1|o|r|:| |%+0#e000e06&|s|\|n|"+0#e000002&|,+0#0000000&| |r|e|a|s|o|n|)|;| @40
 @4|e|x|i|t|(|1+0#e000002&|)+0#0000000&|;| @62
diff --git a/runtime/syntax/testdir/input/cpp_cpp26.cpp b/runtime/syntax/testdir/input/cpp_cpp26.cpp
new file mode 100644 (file)
index 0000000..97fe4a6
--- /dev/null
@@ -0,0 +1,13 @@
+// C++26 lexical constructs
+
+// P3394 annotations: [[ ... ]] may carry a value expression.
+[[=rename{"full_name"}]] int braced;
+[[=key(8)]]              int parened;
+[[nodiscard]]            int plain();
+
+// P2900 contracts: contract_assert is a keyword.
+void check(int x) { contract_assert(x != 0); }
+
+// P2996 reflection (^^) and splicing ([: :]).
+constexpr auto refl = ^^int;
+[:refl:] spliced{};