xref: /vim-8.2.3635/runtime/syntax/raku.vim (revision 11e3c5ba)
1" Vim syntax file
2" Language:      Raku
3" Maintainer:    vim-perl <[email protected]>
4" Homepage:      https://github.com/Raku/vim-raku
5" Bugs/requests: https://github.com/Raku/vim-raku/issues
6" Last Change:   2021-04-16
7
8" Contributors:  Luke Palmer <[email protected]>
9"                Moritz Lenz <[email protected]>
10"                Hinrik Örn Sigurðsson <[email protected]>
11"
12" This is a big undertaking.
13"
14" The ftdetect/raku.vim file in this repository takes care of setting the
15" right filetype for Raku files. To set it explicitly you can also add this
16" line near the bottom of your source file:
17"   # vim: filetype=raku
18
19" TODO:
20"   * Go over the list of keywords/types to see what's deprecated/missing
21"   * Add more support for folding (:help syn-fold)
22"
23" If you want to have Pir code inside Q:PIR// strings highlighted, do:
24"   let raku_embedded_pir=1
25"
26" The above requires pir.vim, which you can find in Parrot's repository:
27" https://github.com/parrot/parrot/tree/master/editor
28"
29" To highlight Perl 5 regexes (m:P5//):
30"   let raku_perl5_regexes=1
31"
32" To enable folding:
33"   let raku_fold=1
34
35if version < 704 | throw "raku.vim uses regex syntax which Vim <7.4 doesn't support. Try 'make fix_old_vim' in the vim-perl repository." | endif
36
37" For version 5.x: Clear all syntax items
38" For version 6.x: Quit when a syntax file was already loaded
39if version < 600
40    syntax clear
41elseif exists("b:current_syntax")
42    finish
43endif
44let s:keepcpo= &cpo
45set cpo&vim
46
47" Patterns which will be interpolated by the preprocessor (tools/preproc.pl):
48"
49" @@IDENT_NONDIGIT@@     "[A-Za-z_\xC0-\xFF]"
50" @@IDENT_CHAR@@         "[A-Za-z_\xC0-\xFF0-9]"
51" @@IDENTIFIER@@         "\%(@@IDENT_NONDIGIT@@\%(@@IDENT_CHAR@@\|[-']@@IDENT_NONDIGIT@@\@=\)*\)"
52" @@IDENTIFIER_START@@   "@@IDENT_CHAR@@\@1<!\%(@@IDENT_NONDIGIT@@[-']\)\@2<!"
53" @@IDENTIFIER_END@@     "\%(@@IDENT_CHAR@@\|[-']@@IDENT_NONDIGIT@@\)\@!"
54" @@METAOP@@             #\%(\d\|[@%$][.?^=[:alpha:]]\)\@!\%(\.\|[^[{('".[:space:]]\)\+#
55" @@ADVERBS@@            "\%(\_s*:!\?@@IDENTIFIER@@\%(([^)]*)\)\?\)*"
56"
57" Same but escaped, for use in string eval
58" @@IDENT_NONDIGIT_Q@@   "[A-Za-z_\\xC0-\\xFF]"
59" @@IDENT_CHAR_Q@@       "[A-Za-z_\\xC0-\\xFF0-9]"
60" @@IDENTIFIER_Q@@       "\\%(@@IDENT_NONDIGIT_Q@@\\%(@@IDENT_CHAR_Q@@\\|[-']@@IDENT_NONDIGIT_Q@@\\@=\\)*\\)"
61" @@IDENTIFIER_START_Q@@ "@@IDENT_CHAR_Q@@\\@1<!\\%(@@IDENT_NONDIGIT_Q@@[-']\\)\\@2<!"
62" @@IDENTIFIER_END_Q@@   "\\%(@@IDENT_CHAR_Q@@\\|[-']@@IDENT_NONDIGIT_Q@@\\)\\@!"
63
64" Identifiers (subroutines, methods, constants, classes, roles, etc)
65syn match rakuIdentifier display "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
66
67let s:keywords = {
68 \ "rakuInclude": [
69 \   "use require import unit",
70 \ ],
71 \ "rakuConditional": [
72 \   "if else elsif unless with orwith without once",
73 \ ],
74 \ "rakuVarStorage": [
75 \   "let my our state temp has constant",
76 \ ],
77 \ "rakuRepeat": [
78 \   "for loop repeat while until gather given",
79 \   "supply react race hyper lazy quietly",
80 \ ],
81 \ "rakuFlowControl": [
82 \   "take take-rw do when next last redo return return-rw",
83 \   "start default exit make continue break goto leave",
84 \   "proceed succeed whenever emit done",
85 \ ],
86 \ "rakuClosureTrait": [
87 \   "BEGIN CHECK INIT FIRST ENTER LEAVE KEEP",
88 \   "UNDO NEXT LAST PRE POST END CATCH CONTROL",
89 \   "DOC QUIT CLOSE COMPOSE",
90 \ ],
91 \ "rakuException": [
92 \   "die fail try warn",
93 \ ],
94 \ "rakuPragma": [
95 \   "MONKEY-GUTS MONKEY-SEE-NO-EVAL MONKEY-TYPING MONKEY",
96 \   "experimental fatal isms lib newline nqp precompilation",
97 \   "soft strict trace variables worries",
98 \ ],
99 \ "rakuOperator": [
100 \   "div xx x mod also leg cmp before after eq ne le lt not",
101 \   "gt ge eqv ff fff and andthen or xor orelse lcm gcd o",
102 \   "unicmp notandthen minmax",
103 \ ],
104 \ "rakuType": [
105 \   "int int1 int2 int4 int8 int16 int32 int64",
106 \   "rat rat1 rat2 rat4 rat8 rat16 rat32 rat64",
107 \   "buf buf1 buf2 buf4 buf8 buf16 buf32 buf64",
108 \   "blob blob1 blob2 blob4 blob8 blob16 blob32 blob64",
109 \   "uint uint1 uint2 uint4 uint8 uint16 uint32 bit bool",
110 \   "uint64 utf8 utf16 utf32 bag set mix complex",
111 \   "num num32 num64 long longlong Pointer size_t str void",
112 \   "ulong ulonglong ssize_t atomicint",
113 \ ],
114\ }
115
116" These can be immediately followed by parentheses
117let s:types = [
118 \ "Object Any Cool Junction Whatever Capture Match",
119 \ "Signature Proxy Matcher Package Module Class",
120 \ "Grammar Scalar Array Hash KeyHash KeySet KeyBag",
121 \ "Pair List Seq Range Set Bag Map Mapping Void Undef",
122 \ "Failure Exception Code Block Routine Sub Macro",
123 \ "Method Submethod Regex Str Blob Char Byte Parcel",
124 \ "Codepoint Grapheme StrPos StrLen Version Num",
125 \ "Complex Bit True False Order Same Less More",
126 \ "Increasing Decreasing Ordered Callable AnyChar",
127 \ "Positional Associative Ordering KeyExtractor",
128 \ "Comparator OrderingPair IO KitchenSink Role",
129 \ "Int Rat Buf UInt Abstraction Numeric Real",
130 \ "Nil Mu SeekFromBeginning SeekFromEnd SeekFromCurrent",
131\ ]
132
133" We explicitly enumerate the alphanumeric infix operators allowed after [RSXZ]
134" to avoid matching package names that start with those letters.
135let s:alpha_metaops = [
136 \ "div mod gcd lcm xx x does but cmp leg eq ne gt ge lt le before after eqv",
137 \ "min max not so andthen and or orelse unicmp coll minmax",
138\ ]
139let s:words_space = join(s:alpha_metaops, " ")
140let s:temp = split(s:words_space)
141let s:alpha_metaops_or = join(s:temp, "\\|")
142
143" We don't use "syn keyword" here because that always has higher priority
144" than matches/regions, which would prevent these words from matching as
145" autoquoted strings before "=>".
146syn match rakuKeywordStart display "\%(\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\)\@!\)\@=[A-Za-z_\xC0-\xFF0-9]\@1<!\%([A-Za-z_\xC0-\xFF][-']\)\@2<!"
147    \ nextgroup=rakuAttention,rakuVariable,rakuInclude,rakuConditional,rakuVarStorage,rakuRepeat,rakuFlowControl,rakuClosureTrait,rakuException,rakuNumber,rakuPragma,rakuType,rakuOperator,rakuIdentifier
148
149for [s:group, s:words_list] in items(s:keywords)
150    let s:words_space = join(s:words_list, " ")
151    let s:temp = split(s:words_space)
152    let s:words = join(s:temp, "\\|")
153    exec "syn match ". s:group ." display \"[.^]\\@1<!\\%(". s:words . "\\)(\\@!\\%([A-Za-z_\\xC0-\\xFF0-9]\\|[-'][A-Za-z_\\xC0-\\xFF]\\)\\@!\" contained"
154endfor
155
156let s:words_space = join(s:types, " ")
157let s:temp = split(s:words_space)
158let s:words = join(s:temp, "\\|")
159exec "syn match rakuType display \"\\%(". s:words . "\\)\\%([A-Za-z_\\xC0-\\xFF0-9]\\|[-'][A-Za-z_\\xC0-\\xFF]\\)\\@!\" contained"
160unlet s:group s:words_list s:keywords s:types s:words_space s:temp s:words
161
162syn match rakuPreDeclare display "[.^]\@1<!\<\%(multi\|proto\|only\)\>" nextgroup=rakuDeclare,rakuIdentifier skipwhite skipempty
163syn match rakuDeclare display "[.^]\@1<!\<\%(macro\|sub\|submethod\|method\|module\|class\|role\|package\|enum\|grammar\|slang\|subset\)\>" nextgroup=rakuIdentifier skipwhite skipempty
164syn match rakuDeclareRegex display "[.^]\@1<!\<\%(regex\|rule\|token\)\>" nextgroup=rakuRegexName skipwhite skipempty
165
166syn match rakuTypeConstraint  display "\%([.^]\|^\s*\)\@<!\a\@=\%(does\|as\|but\|trusts\|of\|returns\|handles\|where\|augment\|supersede\)\>"
167syn match rakuTypeConstraint  display "\%([.^]\|^\s*\)\@<![A-Za-z_\xC0-\xFF0-9]\@1<!\%([A-Za-z_\xC0-\xFF][-']\)\@2<!is\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\)\@!" skipwhite skipempty nextgroup=rakuProperty
168syn match rakuProperty        display "\a\@=\%(signature\|context\|also\|shape\|prec\|irs\|ofs\|ors\|export\|deep\|binary\|unary\|reparsed\|rw\|parsed\|cached\|readonly\|defequiv\|will\|ref\|copy\|inline\|tighter\|looser\|equiv\|assoc\|required\|DEPRECATED\|raw\|repr\|dynamic\|hidden-from-backtrace\|nodal\|pure\)" contained
169
170" packages, must come after all the keywords
171syn match rakuIdentifier display "\%(::\)\@2<=\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)*"
172syn match rakuIdentifier display "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(::\)\@="
173
174" The sigil in ::*Package
175syn match rakuPackageTwigil display "\%(::\)\@2<=\*"
176
177" some standard packages
178syn match rakuType display "\%(::\)\@2<!\%(SeekType\%(::SeekFromBeginning\|::SeekFromCurrent\|::SeekFromEnd\)\|Order\%(::Same\|::More\|::Less\)\?\|Bool\%(::True\|::False\)\?\)\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\)\@!"
179
180" Don't put a "\+" at the end of the character class. That makes it so
181" greedy that the "%" " in "+%foo" won't be allowed to match as a sigil,
182" among other things
183syn match rakuOperator display "[-+/*~?|=^!%&,<>».;\\∈∉∋∌∩∪≼≽⊂⊃⊄⊅⊆⊇⊈⊉⊍⊎⊖∅∘]"
184syn match rakuOperator display "\%(:\@1<!::\@2!\|::=\|\.::\)"
185" these require whitespace on the left side
186syn match rakuOperator display "\%(\s\|^\)\@1<=\%(xx=\)"
187" index overloading
188syn match rakuOperator display "\%(&\.(\@=\|@\.\[\@=\|%\.{\@=\)"
189
190" Reduce metaoperators like [+]
191syn match rakuReduceOp display "\%(^\|\s\|(\)\@1<=!*\%([RSXZ\[]\)*[&RSXZ]\?\[\+(\?\%(\d\|[@%$][.?^=[:alpha:]]\)\@!\%(\.\|[^[{('".[:space:]]\)\+)\?]\+"
192syn match rakuSetOp    display "R\?(\%([-^.+|&]\|[<>][=+]\?\|cont\|elem\))"
193
194" Reverse, cross, and zip metaoperators
195exec "syn match rakuRSXZOp display \"[RSXZ]:\\@!\\%(\\a\\@=\\%(". s:alpha_metaops_or . "\\)\\>\\|[[:alnum:]]\\@!\\%([.,]\\|[^[,.[:alnum:][:space:]]\\)\\+\\|\\s\\@=\\|$\\)\""
196
197syn match rakuBlockLabel display "^\s*\zs\h\w*\s*::\@!\_s\@="
198
199syn match rakuNumber     display "[A-Za-z_\xC0-\xFF0-9]\@1<!\%(\%(\%(\_^\|\s\|[^*\a]\)\@1<=[-+]\)\?Inf\|NaN\)"
200syn match rakuNumber     display "[A-Za-z_\xC0-\xFF0-9]\@1<!\%(\%(\_^\|\s\|[^*\a]\)\@1<=[-+]\)\?\%(\%(\d\|__\@!\)*[._]\@1<!\.\)\?_\@!\%(\d\|_\)\+_\@1<!\%([eE]-\?_\@!\%(\d\|_\)\+\)\?i\?"
201syn match rakuNumber     display "[A-Za-z_\xC0-\xFF0-9]\@1<!\%(\%(\_^\|\s\|[^*\a]\)\@1<=[-+]\)\?0[obxd]\@="  nextgroup=rakuOctBase,rakuBinBase,rakuHexBase,rakuDecBase
202syn match rakuOctBase    display "o" contained nextgroup=rakuOctNumber
203syn match rakuBinBase    display "b" contained nextgroup=rakuBinNumber
204syn match rakuHexBase    display "x" contained nextgroup=rakuHexNumber
205syn match rakuDecBase    display "d" contained nextgroup=rakuDecNumber
206syn match rakuOctNumber  display "[0-7][0-7_]*" contained
207syn match rakuBinNumber  display "[01][01_]*" contained
208syn match rakuHexNumber  display "\x[[:xdigit:]_]*" contained
209syn match rakuDecNumber  display "\d[[:digit:]_]*" contained
210
211syn match rakuVersion    display "\<v\d\+\%(\.\%(\*\|\d\+\)\)*+\?"
212
213" Contextualizers
214syn match rakuContext display "\<\%(item\|list\|slice\|hash\)\>"
215syn match rakuContext display "\%(\$\|@\|%\|&\)(\@="
216
217" Quoting
218
219" one cluster for every quote adverb
220syn cluster rakuInterp_scalar
221    \ add=rakuInterpScalar
222
223syn cluster rakuInterp_array
224    \ add=rakuInterpArray
225
226syn cluster rakuInterp_hash
227    \ add=rakuInterpHash
228
229syn cluster rakuInterp_function
230    \ add=rakuInterpFunction
231
232syn cluster rakuInterp_closure
233    \ add=rakuInterpClosure
234
235syn cluster rakuInterp_q
236    \ add=rakuEscQQ
237    \ add=rakuEscBackSlash
238
239syn cluster rakuInterp_backslash
240    \ add=@rakuInterp_q
241    \ add=rakuEscape
242    \ add=rakuEscOpenCurly
243    \ add=rakuEscCodePoint
244    \ add=rakuEscHex
245    \ add=rakuEscOct
246    \ add=rakuEscOctOld
247    \ add=rakuEscNull
248
249syn cluster rakuInterp_qq
250    \ add=@rakuInterp_scalar
251    \ add=@rakuInterp_array
252    \ add=@rakuInterp_hash
253    \ add=@rakuInterp_function
254    \ add=@rakuInterp_closure
255    \ add=@rakuInterp_backslash
256    \ add=rakuMatchVarSigil
257
258syn region rakuInterpScalar
259    \ start="\ze\z(\$\%(\%(\%(\d\+\|!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\@=\)\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)\%(\.\^\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
260    \ start="\ze\z(\$\%(\%(\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\@=\)\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)\|\%(\d\+\|!\|/\|¢\)\)\)"
261    \ end="\z1\zs"
262    \ contained keepend
263    \ contains=TOP
264
265syn region rakuInterpScalar
266    \ matchgroup=rakuContext
267    \ start="\$\ze()\@!"
268    \ skip="([^)]*)"
269    \ end=")\zs"
270    \ contained
271    \ contains=TOP
272
273syn region rakuInterpArray
274    \ start="\ze\z(@\$*\%(\%(\%(!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\@=\)\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)\%(\.\^\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
275    \ end="\z1\zs"
276    \ contained keepend
277    \ contains=TOP
278
279syn region rakuInterpArray
280    \ matchgroup=rakuContext
281    \ start="@\ze()\@!"
282    \ skip="([^)]*)"
283    \ end=")\zs"
284    \ contained
285    \ contains=TOP
286
287syn region rakuInterpHash
288    \ start="\ze\z(%\$*\%(\%(\%(!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\@=\)\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)\%(\.\^\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
289    \ end="\z1\zs"
290    \ contained keepend
291    \ contains=TOP
292
293syn region rakuInterpHash
294    \ matchgroup=rakuContext
295    \ start="%\ze()\@!"
296    \ skip="([^)]*)"
297    \ end=")\zs"
298    \ contained
299    \ contains=TOP
300
301syn region rakuInterpFunction
302    \ start="\ze\z(&\%(\%(!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\@=\)\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(\.\^\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
303    \ end="\z1\zs"
304    \ contained keepend
305    \ contains=TOP
306
307syn region rakuInterpFunction
308    \ matchgroup=rakuContext
309    \ start="&\ze()\@!"
310    \ skip="([^)]*)"
311    \ end=")\zs"
312    \ contained
313    \ contains=TOP
314
315syn region rakuInterpClosure
316    \ start="\\\@1<!{}\@!"
317    \ skip="{[^}]*}"
318    \ end="}"
319    \ contained keepend
320    \ contains=TOP
321
322" generic escape
323syn match rakuEscape          display "\\\S" contained
324
325" escaped closing delimiters
326syn match rakuEscQuote        display "\\'" contained
327syn match rakuEscDoubleQuote  display "\\\"" contained
328syn match rakuEscCloseAngle   display "\\>" contained
329syn match rakuEscCloseFrench  display "\\»" contained
330syn match rakuEscBackTick     display "\\`" contained
331syn match rakuEscForwardSlash display "\\/" contained
332syn match rakuEscVerticalBar  display "\\|" contained
333syn match rakuEscExclamation  display "\\!" contained
334syn match rakuEscComma        display "\\," contained
335syn match rakuEscDollar       display "\\\$" contained
336syn match rakuEscCloseCurly   display "\\}" contained
337syn match rakuEscCloseBracket display "\\\]" contained
338
339" matches :key, :!key, :$var, :key<var>, etc
340" Since we don't know in advance how the adverb ends, we use a trick.
341" Consume nothing with the start pattern (\ze at the beginning),
342" while capturing the whole adverb into \z1 and then putting it before
343" the match start (\zs) of the end pattern.
344syn region rakuAdverb
345    \ start="\ze\z(:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\?\)"
346    \ start="\ze\z(:!\?[@$%]\$*\%(::\|\%(\$\@1<=\d\+\|!\|/\|¢\)\|\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\)\|\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)\)"
347    \ end="\z1\zs"
348    \ contained keepend
349    \ contains=TOP
350
351" <words>
352" Distinguishing this from the "less than" operator is tricky. For now,
353" it matches if any of the following is true:
354"
355" * There is whitespace missing on either side of the "<", since
356"   people tend to put spaces around "less than". We make an exception
357"   for " = < ... >" assignments though.
358" * It comes after "enum", "for", "any", "all", or "none"
359" * It's the first or last thing on a line (ignoring whitespace)
360" * It's preceded by "(\s*" or "=\s\+"
361" * It's empty and terminated on the same line (e.g. <> and < >)
362"
363" It never matches when:
364"
365" * Preceded by [<+~=!] (e.g. <<foo>>, =<$foo>, * !< 3)
366" * Followed by [-=] (e.g. <--, <=, <==, <->)
367syn region rakuStringAngle
368    \ matchgroup=rakuQuote
369    \ start="\%(\<\%(enum\|for\|any\|all\|none\)\>\s*(\?\s*\)\@<=<\%(<\|=>\|\%([=-]\{1,2}>\|[=-]\{2}\)\)\@!"
370    \ start="\%(\s\|[<+~=!]\)\@<!<\%(<\|=>\|\%([=-]\{1,2}>\|[=-]\{2}\)\)\@!"
371    \ start="[<+~=!]\@1<!<\%(\s\|<\|=>\|\%([=-]\{1,2}>\|[=-]\{1,2}\)\)\@!"
372    \ start="\%(^\s*\)\@<=<\%(<\|=>\|\%([=-]\{1,2}>\|[=-]\{2}\)\)\@!"
373    \ start="[<+~=!]\@1<!<\%(\s*$\)\@="
374    \ start="\%((\s*\|=\s\+\)\@<=<\%(<\|=>\|\%([=-]\{1,2}>\|[=-]\{2}\)\)\@!"
375    \ start="<\%(\s*>\)\@="
376    \ skip="\\\@1<!\\>"
377    \ end=">"
378    \ contains=rakuInnerAnglesOne,rakuEscBackSlash,rakuEscCloseAngle
379
380syn region rakuStringAngleFixed
381    \ matchgroup=rakuQuote
382    \ start="<"
383    \ skip="\\\@1<!\\>"
384    \ end=">"
385    \ contains=rakuInnerAnglesOne,rakuEscBackSlash,rakuEscCloseAngle
386    \ contained
387
388syn region rakuInnerAnglesOne
389    \ matchgroup=rakuStringAngle
390    \ start="\\\@1<!<"
391    \ skip="\\\@1<!\\>"
392    \ end=">"
393    \ transparent contained
394    \ contains=rakuInnerAnglesOne
395
396" <<words>>
397syn region rakuStringAngles
398    \ matchgroup=rakuQuote
399    \ start="<<=\@!"
400    \ skip="\\\@1<!\\>"
401    \ end=">>"
402    \ contains=rakuInnerAnglesTwo,@rakuInterp_qq,rakuComment,rakuBracketComment,rakuEscHash,rakuEscCloseAngle,rakuAdverb,rakuStringSQ,rakuStringDQ
403
404syn region rakuInnerAnglesTwo
405    \ matchgroup=rakuStringAngles
406    \ start="<<"
407    \ skip="\\\@1<!\\>"
408    \ end=">>"
409    \ transparent contained
410    \ contains=rakuInnerAnglesTwo
411
412" «words»
413syn region rakuStringFrench
414    \ matchgroup=rakuQuote
415    \ start="«"
416    \ skip="\\\@1<!\\»"
417    \ end="»"
418    \ contains=rakuInnerFrench,@rakuInterp_qq,rakuComment,rakuBracketComment,rakuEscHash,rakuEscCloseFrench,rakuAdverb,rakuStringSQ,rakuStringDQ
419
420syn region rakuInnerFrench
421    \ matchgroup=rakuStringFrench
422    \ start="\\\@1<!«"
423    \ skip="\\\@1<!\\»"
424    \ end="»"
425    \ transparent contained
426    \ contains=rakuInnerFrench
427
428" Hyperops. They need to come after "<>" and "«»" strings in order to override
429" them, but before other types of strings, to avoid matching those delimiters
430" as parts of hyperops.
431syn match rakuHyperOp display #[^[:digit:][{('",:[:space:]][^[{('",:[:space:]]*\%(«\|<<\)#
432syn match rakuHyperOp display "«\%(\d\|[@%$][.?^=[:alpha:]]\)\@!\%(\.\|[^[{('".[:space:]]\)\+[«»]"
433syn match rakuHyperOp display "»\%(\d\|[@%$][.?^=[:alpha:]]\)\@!\%(\.\|[^[{('".[:space:]]\)\+\%(«\|»\?\)"
434syn match rakuHyperOp display "<<\%(\d\|[@%$][.?^=[:alpha:]]\)\@!\%(\.\|[^[{('".[:space:]]\)\+\%(<<\|>>\)"
435syn match rakuHyperOp display ">>\%(\d\|[@%$][.?^=[:alpha:]]\)\@!\%(\.\|[^[{('".[:space:]]\)\+\%(<<\|\%(>>\)\?\)"
436
437" 'string'
438syn region rakuStringSQ
439    \ matchgroup=rakuQuote
440    \ start="'"
441    \ skip="\\\@1<!\\'"
442    \ end="'"
443    \ contains=@rakuInterp_q,rakuEscQuote
444    \ keepend extend
445
446" "string"
447syn region rakuStringDQ
448    \ matchgroup=rakuQuote
449    \ start=+"+
450    \ skip=+\\\@1<!\\"+
451    \ end=+"+
452    \ contains=@rakuInterp_qq,rakuEscDoubleQuote
453    \ keepend extend
454
455" Q// and friends
456
457syn match rakuQuoteQStart display "\%(:\|\%(sub\|role\)\s\)\@5<![Qq]\@=" nextgroup=rakuQuoteQ,rakuQuoteQ_q,rakuQuoteQ_qww,rakuQuoteQ_qq,rakuQuoteQ_to,rakuQuoteQ_qto,rakuQuoteQ_qqto,rakuIdentifier
458syn match rakuQuoteQ      display "Q\%(qq\|ww\|[abcfhpsqvwx]\)\?[A-Za-z(]\@!" nextgroup=rakuPairsQ skipwhite skipempty contained
459syn match rakuQuoteQ_q    display "q[abcfhpsvwx]\?[A-Za-z(]\@!" nextgroup=rakuPairsQ_q skipwhite skipempty contained
460syn match rakuQuoteQ_qww  display "qww[A-Za-z(]\@!" nextgroup=rakuPairsQ_qww skipwhite skipempty contained
461syn match rakuQuoteQ_qq   display "qq\%([pwx]\|ww\)\?[A-Za-z(]\@!" nextgroup=rakuPairsQ_qq skipwhite skipempty contained
462syn match rakuQuoteQ_to   display "Qto[A-Za-z(]\@!" nextgroup=rakuStringQ_to skipwhite skipempty contained
463syn match rakuQuoteQ_qto  display "qto[A-Za-z(]\@!" nextgroup=rakuStringQ_qto skipwhite skipempty contained
464syn match rakuQuoteQ_qqto display "qqto[A-Za-z(]\@!" nextgroup=rakuStringQ_qqto skipwhite skipempty contained
465syn match rakuQuoteQ_qto  display "q\_s*\%(\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*:\%(to\|heredoc\)\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*(\@!\)\@=" nextgroup=rakuPairsQ_qto skipwhite skipempty contained
466syn match rakuQuoteQ_qqto display "qq\_s*\%(\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*:\%(to\|heredoc\)\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*(\@!\)\@=" nextgroup=rakuPairsQ_qqto skipwhite skipempty contained
467syn match rakuPairsQ      "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuStringQ
468syn match rakuPairsQ_q    "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuStringQ_q
469syn match rakuPairsQ_qww  "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuStringQ_qww
470syn match rakuPairsQ_qq   "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuStringQ_qq
471syn match rakuPairsQ_qto  "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuStringQ_qto
472syn match rakuPairsQ_qqto "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuStringQ_qqto
473
474
475if exists("raku_embedded_pir") || exists("raku_extended_all")
476    syn include @rakuPIR syntax/pir.vim
477    syn match rakuQuote_QPIR display "Q[A-Za-z(]\@!\%(\_s*:PIR\)\@=" nextgroup=rakuPairsQ_PIR skipwhite skipempty
478    syn match rakuPairs_QPIR contained "\_s*:PIR" transparent skipwhite skipempty nextgroup=rakuStringQ_PIR
479endif
480
481" hardcoded set of delimiters
482let s:plain_delims = [
483  \ ["DQ",          "\\\"",         "\\\"", "rakuEscDoubleQuote",  "\\\\\\@1<!\\\\\\\""],
484  \ ["SQ",          "'",            "'",    "rakuEscQuote",        "\\\\\\@1<!\\\\'"],
485  \ ["Slash",       "/",            "/",    "rakuEscForwardSlash", "\\\\\\@1<!\\\\/"],
486  \ ["BackTick",    "`",            "`",    "rakuEscBackTick",     "\\\\\\@1<!\\\\`"],
487  \ ["Bar",         "|",            "|",    "rakuEscVerticalBar",  "\\\\\\@1<!\\\\|"],
488  \ ["Exclamation", "!",            "!",    "rakuEscExclamation",  "\\\\\\@1<!\\\\!"],
489  \ ["Comma",       ",",            ",",    "rakuEscComma",        "\\\\\\@1<!\\\\,"],
490  \ ["Dollar",      "\\$",          "\\$",  "rakuEscDollar",       "\\\\\\@1<!\\\\\\$"],
491\ ]
492let s:bracketing_delims = [
493  \ ["Curly",   "{",            "}",    "rakuEscCloseCurly",   "\\%(\\\\\\@1<!\\\\}\\|{[^}]*}\\)"],
494  \ ["Angle",   "<",            ">",    "rakuEscCloseAngle",   "\\%(\\\\\\@1<!\\\\>\\|<[^>]*>\\)"],
495  \ ["French",  "«",            "»",    "rakuEscCloseFrench",  "\\%(\\\\\\@1<!\\\\»\\|«[^»]*»\\)"],
496  \ ["Bracket", "\\\[",         "]",    "rakuEscCloseBracket", "\\%(\\\\\\@1<!\\\\]\\|\\[^\\]]*]\\)"],
497  \ ["Paren",   "\\s\\@1<=(",   ")",    "rakuEscCloseParen",   "\\%(\\\\\\@1<!\\\\)\\|([^)]*)\\)"],
498\ ]
499let s:all_delims = s:plain_delims + s:bracketing_delims
500
501for [s:name, s:start_delim, s:end_delim, s:end_group, s:skip] in s:all_delims
502    exec "syn region rakuStringQ matchgroup=rakuQuote start=\"".s:start_delim."\" end=\"".s:end_delim."\" contained"
503    exec "syn region rakuStringQ_q matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contains=@rakuInterp_q,".s:end_group." contained"
504    exec "syn region rakuStringQ_qww matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contains=@rakuInterp_q,rakuStringSQ,rakuStringDQ".s:end_group." contained"
505    exec "syn region rakuStringQ_qq matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contains=@rakuInterp_qq,".s:end_group." contained"
506    exec "syn region rakuStringQ_to matchgroup=rakuQuote start=\"".s:start_delim."\\z([^".s:end_delim."]\\+\\)".s:end_delim."\" end=\"^\\s*\\z1$\" contained"
507    exec "syn region rakuStringQ_qto matchgroup=rakuQuote start=\"".s:start_delim."\\z([^".s:end_delim."]\\+\\)".s:end_delim."\" skip=\"".s:skip."\" end=\"^\\s*\\z1$\" contains=@rakuInterp_q,".s:end_group." contained"
508    exec "syn region rakuStringQ_qqto matchgroup=rakuQuote start=\"".s:start_delim."\\z(\[^".s:end_delim."]\\+\\)".s:end_delim."\" skip=\"".s:skip."\" end=\"^\\s*\\z1$\" contains=@rakuInterp_qq,".s:end_group." contained"
509
510    if exists("raku_embedded_pir") || exists("raku_extended_all")
511        exec "syn region rakuStringQ_PIR matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contains=@rakuPIR,".s:end_group." contained"
512    endif
513endfor
514unlet s:name s:start_delim s:end_delim s:end_group s:skip s:plain_delims s:all_delims
515
516" :key
517syn match rakuOperator display ":\@1<!::\@!!\?" nextgroup=rakuKey,rakuStringAngleFixed,rakuStringAngles,rakuStringFrench
518syn match rakuKey display "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)" contained nextgroup=rakuStringAngleFixed,rakuStringAngles,rakuStringFrench
519
520" Regexes and grammars
521
522syn match rakuRegexName    display "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\?" nextgroup=rakuRegexBlockCrap skipwhite skipempty contained
523syn match rakuRegexBlockCrap "[^{]*" nextgroup=rakuRegexBlock skipwhite skipempty transparent contained
524
525syn region rakuRegexBlock
526    \ matchgroup=rakuNormal
527    \ start="{"
528    \ end="}"
529    \ contained
530    \ contains=@rakuRegexen,@rakuVariables
531
532" Perl 6 regex bits
533
534syn cluster rakuRegexen
535    \ add=rakuRxMeta
536    \ add=rakuRxEscape
537    \ add=rakuEscCodePoint
538    \ add=rakuEscHex
539    \ add=rakuEscOct
540    \ add=rakuEscNull
541    \ add=rakuRxAnchor
542    \ add=rakuRxCapture
543    \ add=rakuRxGroup
544    \ add=rakuRxAlternation
545    \ add=rakuRxBoundary
546    \ add=rakuRxAdverb
547    \ add=rakuRxAdverbArg
548    \ add=rakuRxStorage
549    \ add=rakuRxAssertion
550    \ add=rakuRxAssertGroup
551    \ add=rakuRxQuoteWords
552    \ add=rakuRxClosure
553    \ add=rakuRxStringSQ
554    \ add=rakuRxStringDQ
555    \ add=rakuComment
556    \ add=rakuBracketComment
557    \ add=rakuMatchVarSigil
558
559syn match rakuRxMeta        display contained ".\%([A-Za-z_\xC0-\xFF0-9]\|\s\)\@1<!"
560syn match rakuRxAnchor      display contained "[$^]"
561syn match rakuRxEscape      display contained "\\\S"
562syn match rakuRxCapture     display contained "[()]"
563syn match rakuRxAlternation display contained "|"
564syn match rakuRxRange       display contained "\.\."
565
566" misc escapes
567syn match rakuEscOctOld    display "\\[1-9]\d\{1,2}" contained
568syn match rakuEscNull      display "\\0\d\@!" contained
569syn match rakuEscCodePoint display "\\[cC]" contained nextgroup=rakuCodePoint
570syn match rakuEscHex       display "\\[xX]" contained nextgroup=rakuHexSequence
571syn match rakuEscOct       display "\\o" contained nextgroup=rakuOctSequence
572syn match rakuEscQQ        display "\\qq" contained nextgroup=rakuQQSequence
573syn match rakuEscOpenCurly display "\\{" contained
574syn match rakuEscHash      display "\\#" contained
575syn match rakuEscBackSlash display "\\\\" contained
576
577syn region rakuQQSequence
578    \ matchgroup=rakuEscape
579    \ start="\["
580    \ skip="\[[^\]]*]"
581    \ end="]"
582    \ contained transparent
583    \ contains=@rakuInterp_qq
584
585syn match rakuCodePoint   display "\%(\d\+\|\S\)" contained
586syn region rakuCodePoint
587    \ matchgroup=rakuEscape
588    \ start="\["
589    \ end="]"
590    \ contained
591
592syn match rakuHexSequence display "\x\+" contained
593syn region rakuHexSequence
594    \ matchgroup=rakuEscape
595    \ start="\["
596    \ end="]"
597    \ contained
598
599syn match rakuOctSequence display "\o\+" contained
600syn region rakuOctSequence
601    \ matchgroup=rakuEscape
602    \ start="\["
603    \ end="]"
604    \ contained
605
606" $<match>, @<match>
607syn region rakuMatchVarSigil
608    \ matchgroup=rakuVariable
609    \ start="[$@]\%(<<\@!\)\@="
610    \ end=">\@1<="
611    \ contains=rakuMatchVar
612
613syn region rakuMatchVar
614    \ matchgroup=rakuTwigil
615    \ start="<"
616    \ end=">"
617    \ contained
618
619syn region rakuRxClosure
620    \ matchgroup=rakuNormal
621    \ start="{"
622    \ end="}"
623    \ contained
624    \ containedin=rakuRxClosure
625    \ contains=TOP
626syn region rakuRxGroup
627    \ matchgroup=rakuStringSpecial2
628    \ start="\["
629    \ end="]"
630    \ contained
631    \ contains=@rakuRegexen,@rakuVariables,rakuMatchVarSigil
632syn region rakuRxAssertion
633    \ matchgroup=rakuStringSpecial2
634    \ start="<\%(?\?\%(before\|after\)\|\%(\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)=\)\|[+?*]\)\?"
635    \ end=">"
636    \ contained
637    \ contains=@rakuRegexen,rakuIdentifier,@rakuVariables,rakuRxCharClass,rakuRxAssertCall
638syn region rakuRxAssertGroup
639    \ matchgroup=rakuStringSpecial2
640    \ start="<\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)=\["
641    \ skip="\\\@1<!\\]"
642    \ end="]"
643    \ contained
644syn match rakuRxAssertCall display "\%(::\|\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)" contained nextgroup=rakuRxAssertArgs
645syn region rakuRxAssertArgs
646    \ start="("
647    \ end=")"
648    \ contained keepend
649    \ contains=TOP
650syn region rakuRxAssertArgs
651    \ start=":"
652    \ end="\ze>"
653    \ contained keepend
654    \ contains=TOP
655syn match rakuRxBoundary display contained "\%([«»]\|<<\|>>\)"
656syn region rakuRxCharClass
657    \ matchgroup=rakuStringSpecial2
658    \ start="\%(<[-!+?]\?\)\@2<=\["
659    \ skip="\\]"
660    \ end="]"
661    \ contained
662    \ contains=rakuRxRange,rakuRxEscape,rakuEscHex,rakuEscOct,rakuEscCodePoint,rakuEscNull
663syn region rakuRxQuoteWords
664    \ matchgroup=rakuStringSpecial2
665    \ start="<\s"
666    \ end="\s\?>"
667    \ contained
668syn region rakuRxAdverb
669    \ start="\ze\z(:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)"
670    \ end="\z1\zs"
671    \ contained keepend
672    \ contains=TOP
673syn region rakuRxAdverbArg
674    \ start="\%(:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\)\@<=("
675    \ skip="([^)]\{-})"
676    \ end=")"
677    \ contained
678    \ keepend
679    \ contains=TOP
680syn region rakuRxStorage
681    \ matchgroup=rakuOperator
682    \ start="\%(^\s*\)\@<=:\%(my\>\|temp\>\)\@="
683    \ end="$"
684    \ contains=TOP
685    \ contained
686    \ keepend
687
688" 'string' inside a regex
689syn region rakuRxStringSQ
690    \ matchgroup=rakuQuote
691    \ start="'"
692    \ skip="\\\@1<!\\'"
693    \ end="'"
694    \ contained
695    \ contains=rakuEscQuote,rakuEscBackSlash
696
697" "string" inside a regex
698syn region rakuRxStringDQ
699    \ matchgroup=rakuQuote
700    \ start=+"+
701    \ skip=+\\\@1<!\\"+
702    \ end=+"+
703    \ contained
704    \ contains=rakuEscDoubleQuote,rakuEscBackSlash,@rakuInterp_qq
705
706" $!, $var, $!var, $::var, $package::var $*::package::var, etc
707" Thus must come after the matches for the "$" regex anchor, but before
708" the match for the $ regex delimiter
709syn cluster rakuVariables
710    \ add=rakuVarSlash
711    \ add=rakuVarExclam
712    \ add=rakuVarMatch
713    \ add=rakuVarNum
714    \ add=rakuVariable
715
716syn match rakuBareSigil    display "[@$%&]\%(\s*\%([,)}=]\|where\>\)\)\@="
717syn match rakuVarSlash     display "\$/"
718syn match rakuVarExclam    display "\$!"
719syn match rakuVarMatch     display "\$¢"
720syn match rakuVarNum       display "\$\d\+"
721syn match rakuVariable     display "self"
722syn match rakuVariable     display "[@$%&]\?[@&$%]\$*\%(::\|\%(\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\)\|[A-Za-z_\xC0-\xFF]\)\@=" nextgroup=rakuTwigil,rakuVarName,rakuPackageScope
723syn match rakuVarName      display "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)" nextgroup=rakuPostHyperOp contained
724syn match rakuClose        display "[\])]" transparent nextgroup=rakuPostHyperOp
725syn match rakuPostHyperOp  display "\%(»\|>>\)" contained
726syn match rakuTwigil       display "\%([.^*?=!~]\|:\@1<!::\@!\)[A-Za-z_\xC0-\xFF]\@=" nextgroup=rakuPackageScope,rakuVarName contained
727syn match rakuPackageScope display "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\?::" nextgroup=rakuPackageScope,rakuVarName contained
728
729" Perl 6 regex regions
730
731syn match rakuMatchStart_m    display "\.\@1<!\<\%(mm\?\|rx\)\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\)\@!" skipwhite skipempty nextgroup=rakuMatchAdverbs_m
732syn match rakuMatchStart_s    display "\.\@1<!\<[sS]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\)\@!" skipwhite skipempty nextgroup=rakuMatchAdverbs_s
733syn match rakuMatchStart_tr   display "\.\@1<!\<tr\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\)\@!" skipwhite skipempty nextgroup=rakuMatchAdverbs_tr
734syn match rakuMatchAdverbs_m  "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuMatch
735syn match rakuMatchAdverbs_s  "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuSubstitution
736syn match rakuMatchAdverbs_tr "\%(\_s*:!\?\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\%(([^)]*)\)\?\)*" contained transparent skipwhite skipempty nextgroup=rakuTransliteration
737
738" /foo/
739syn region rakuMatchBare
740    \ matchgroup=rakuQuote
741    \ start="/\@1<!\%(\%(\_^\|[!\[,=~|&/:({]\|\^\?fff\?\^\?\|=>\|\<\%(if\|unless\|while\|when\|where\|so\)\)\s*\)\@<=/[/=]\@!"
742    \ skip="\\/"
743    \ end="/"
744    \ contains=@rakuRegexen,rakuVariable,rakuVarExclam,rakuVarMatch,rakuVarNum
745
746" m/foo/, m$foo$, m!foo!, etc
747syn region rakuMatch
748    \ matchgroup=rakuQuote
749    \ start=+\z([/!$,|`"]\)+
750    \ skip="\\\z1"
751    \ end="\z1"
752    \ contained
753    \ contains=@rakuRegexen,rakuVariable,rakuVarNum
754
755" m<foo>, m«foo», m{foo}, etc
756for [s:name, s:start_delim, s:end_delim, s:end_group, s:skip] in s:bracketing_delims
757    exec "syn region rakuMatch matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contained keepend contains=@rakuRegexen,@rakuVariables"
758endfor
759unlet s:name s:start_delim s:end_delim s:end_group s:skip
760
761" Substitutions
762
763" s/foo//, s$foo$$, s!foo!!, etc
764syn region rakuSubstitution
765    \ matchgroup=rakuQuote
766    \ start=+\z([/!$,|`"]\)+
767    \ skip="\\\z1"
768    \ end="\z1"me=e-1
769    \ contained
770    \ contains=@rakuRegexen,rakuVariable,rakuVarNum
771    \ nextgroup=rakuReplacement
772
773syn region rakuReplacement
774    \ matchgroup=rakuQuote
775    \ start="\z(.\)"
776    \ skip="\\\z1"
777    \ end="\z1"
778    \ contained
779    \ contains=@rakuInterp_qq
780
781" s<foo><bar>, s«foo»«bar», s{foo}{bar}, etc
782for [s:name, s:start_delim, s:end_delim, s:end_group, s:skip] in s:bracketing_delims
783    exec "syn region rakuSubstitution matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contained keepend contains=@rakuRegexen,@rakuVariables nextgroup=rakuRepl".s:name
784    exec "syn region rakuRepl".s:name." matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contained keepend contains=@rakuInterp_qq"
785endfor
786unlet s:name s:start_delim s:end_delim s:end_group s:skip
787
788" Transliteration
789
790" tr/foo/bar/, tr|foo|bar, etc
791syn region rakuTransliteration
792    \ matchgroup=rakuQuote
793    \ start=+\z([/!$,|`"]\)+
794    \ skip="\\\z1"
795    \ end="\z1"me=e-1
796    \ contained
797    \ contains=rakuRxRange
798    \ nextgroup=rakuTransRepl
799
800syn region rakuTransRepl
801    \ matchgroup=rakuQuote
802    \ start="\z(.\)"
803    \ skip="\\\z1"
804    \ end="\z1"
805    \ contained
806    \ contains=@rakuInterp_qq,rakuRxRange
807
808" tr<foo><bar>, tr«foo»«bar», tr{foo}{bar}, etc
809for [s:name, s:start_delim, s:end_delim, s:end_group, s:skip] in s:bracketing_delims
810    exec "syn region rakuTransliteration matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contained keepend contains=rakuRxRange nextgroup=rakuTransRepl".s:name
811    exec "syn region rakuTransRepl".s:name." matchgroup=rakuQuote start=\"".s:start_delim."\" skip=\"".s:skip."\" end=\"".s:end_delim."\" contained keepend contains=@rakuInterp_qq,rakuRxRange"
812endfor
813unlet s:name s:start_delim s:end_delim s:end_group s:skip s:bracketing_delims
814
815if exists("raku_perl5_regexes") || exists("raku_extended_all")
816
817" Perl 5 regex regions
818
819syn cluster rakuRegexP5Base
820    \ add=rakuRxP5Escape
821    \ add=rakuRxP5Oct
822    \ add=rakuRxP5Hex
823    \ add=rakuRxP5EscMeta
824    \ add=rakuRxP5CodePoint
825    \ add=rakuRxP5Prop
826
827" normal regex stuff
828syn cluster rakuRegexP5
829    \ add=@rakuRegexP5Base
830    \ add=rakuRxP5Quantifier
831    \ add=rakuRxP5Meta
832    \ add=rakuRxP5QuoteMeta
833    \ add=rakuRxP5ParenMod
834    \ add=rakuRxP5Verb
835    \ add=rakuRxP5Count
836    \ add=rakuRxP5Named
837    \ add=rakuRxP5ReadRef
838    \ add=rakuRxP5WriteRef
839    \ add=rakuRxP5CharClass
840    \ add=rakuRxP5Anchor
841
842" inside character classes
843syn cluster rakuRegexP5Class
844    \ add=@rakuRegexP5Base
845    \ add=rakuRxP5Posix
846    \ add=rakuRxP5Range
847
848syn match rakuRxP5Escape     display contained "\\\S"
849syn match rakuRxP5CodePoint  display contained "\\c\S\@=" nextgroup=rakuRxP5CPId
850syn match rakuRxP5CPId       display contained "\S"
851syn match rakuRxP5Oct        display contained "\\\%(\o\{1,3}\)\@=" nextgroup=rakuRxP5OctSeq
852syn match rakuRxP5OctSeq     display contained "\o\{1,3}"
853syn match rakuRxP5Anchor     display contained "[\^$]"
854syn match rakuRxP5Hex        display contained "\\x\%({\x\+}\|\x\{1,2}\)\@=" nextgroup=rakuRxP5HexSeq
855syn match rakuRxP5HexSeq     display contained "\x\{1,2}"
856syn region rakuRxP5HexSeq
857    \ matchgroup=rakuRxP5Escape
858    \ start="{"
859    \ end="}"
860    \ contained
861syn region rakuRxP5Named
862    \ matchgroup=rakuRxP5Escape
863    \ start="\%(\\N\)\@2<={"
864    \ end="}"
865    \ contained
866syn match rakuRxP5Quantifier display contained "\%([+*]\|(\@1<!?\)"
867syn match rakuRxP5ReadRef    display contained "\\[1-9]\d\@!"
868syn match rakuRxP5ReadRef    display contained "\[A-Za-z_\xC0-\xFF0-9]<\@=" nextgroup=rakuRxP5ReadRefId
869syn region rakuRxP5ReadRefId
870    \ matchgroup=rakuRxP5Escape
871    \ start="<"
872    \ end=">"
873    \ contained
874syn match rakuRxP5WriteRef   display contained "\\g\%(\d\|{\)\@=" nextgroup=rakuRxP5WriteRefId
875syn match rakuRxP5WriteRefId display contained "\d\+"
876syn region rakuRxP5WriteRefId
877    \ matchgroup=rakuRxP5Escape
878    \ start="{"
879    \ end="}"
880    \ contained
881syn match rakuRxP5Prop       display contained "\\[pP]\%(\a\|{\)\@=" nextgroup=rakuRxP5PropId
882syn match rakuRxP5PropId     display contained "\a"
883syn region rakuRxP5PropId
884    \ matchgroup=rakuRxP5Escape
885    \ start="{"
886    \ end="}"
887    \ contained
888syn match rakuRxP5Meta       display contained "[(|).]"
889syn match rakuRxP5ParenMod   display contained "(\@1<=?\@=" nextgroup=rakuRxP5Mod,rakuRxP5ModName,rakuRxP5Code
890syn match rakuRxP5Mod        display contained "?\%(<\?=\|<\?!\|[#:|]\)"
891syn match rakuRxP5Mod        display contained "?-\?[impsx]\+"
892syn match rakuRxP5Mod        display contained "?\%([-+]\?\d\+\|R\)"
893syn match rakuRxP5Mod        display contained "?(DEFINE)"
894syn match rakuRxP5Mod        display contained "?\%(&\|P[>=]\)" nextgroup=rakuRxP5ModDef
895syn match rakuRxP5ModDef     display contained "\h\w*"
896syn region rakuRxP5ModName
897    \ matchgroup=rakuStringSpecial
898    \ start="?'"
899    \ end="'"
900    \ contained
901syn region rakuRxP5ModName
902    \ matchgroup=rakuStringSpecial
903    \ start="?P\?<"
904    \ end=">"
905    \ contained
906syn region rakuRxP5Code
907    \ matchgroup=rakuStringSpecial
908    \ start="??\?{"
909    \ end="})\@="
910    \ contained
911    \ contains=TOP
912syn match rakuRxP5EscMeta    display contained "\\[?*.{}()[\]|\^$]"
913syn match rakuRxP5Count      display contained "\%({\d\+\%(,\%(\d\+\)\?\)\?}\)\@=" nextgroup=rakuRxP5CountId
914syn region rakuRxP5CountId
915    \ matchgroup=rakuRxP5Escape
916    \ start="{"
917    \ end="}"
918    \ contained
919syn match rakuRxP5Verb       display contained "(\@1<=\*\%(\%(PRUNE\|SKIP\|THEN\)\%(:[^)]*\)\?\|\%(MARK\|\):[^)]*\|COMMIT\|F\%(AIL\)\?\|ACCEPT\)"
920syn region rakuRxP5QuoteMeta
921    \ matchgroup=rakuRxP5Escape
922    \ start="\\Q"
923    \ end="\\E"
924    \ contained
925    \ contains=@rakuVariables,rakuEscBackSlash
926syn region rakuRxP5CharClass
927    \ matchgroup=rakuStringSpecial
928    \ start="\[\^\?"
929    \ skip="\\]"
930    \ end="]"
931    \ contained
932    \ contains=@rakuRegexP5Class
933syn region rakuRxP5Posix
934    \ matchgroup=rakuRxP5Escape
935    \ start="\[:"
936    \ end=":]"
937    \ contained
938syn match rakuRxP5Range      display contained "-"
939
940" m:P5//
941syn region rakuMatch
942    \ matchgroup=rakuQuote
943    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<=/"
944    \ skip="\\/"
945    \ end="/"
946    \ contains=@rakuRegexP5,rakuVariable,rakuVarExclam,rakuVarMatch,rakuVarNum
947
948" m:P5!!
949syn region rakuMatch
950    \ matchgroup=rakuQuote
951    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<=!"
952    \ skip="\\!"
953    \ end="!"
954    \ contains=@rakuRegexP5,rakuVariable,rakuVarSlash,rakuVarMatch,rakuVarNum
955
956" m:P5$$, m:P5||, etc
957syn region rakuMatch
958    \ matchgroup=rakuQuote
959    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<=\z([\"'`|,$]\)"
960    \ skip="\\\z1"
961    \ end="\z1"
962    \ contains=@rakuRegexP5,@rakuVariables
963
964" m:P5 ()
965syn region rakuMatch
966    \ matchgroup=rakuQuote
967    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s\+\)\@<=()\@!"
968    \ skip="\\)"
969    \ end=")"
970    \ contains=@rakuRegexP5,@rakuVariables
971
972" m:P5[]
973syn region rakuMatch
974    \ matchgroup=rakuQuote
975    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<=[]\@!"
976    \ skip="\\]"
977    \ end="]"
978    \ contains=@rakuRegexP5,@rakuVariables
979
980" m:P5{}
981syn region rakuMatch
982    \ matchgroup=rakuQuote
983    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<={}\@!"
984    \ skip="\\}"
985    \ end="}"
986    \ contains=@rakuRegexP5,rakuVariables
987
988" m:P5<>
989syn region rakuMatch
990    \ matchgroup=rakuQuote
991    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<=<>\@!"
992    \ skip="\\>"
993    \ end=">"
994    \ contains=@rakuRegexP5,rakuVariables
995
996" m:P5«»
997syn region rakuMatch
998    \ matchgroup=rakuQuote
999    \ start="\%(\%(::\|[$@%&][.!^:*?]\?\|\.\)\@2<!\<m\s*:P\%(erl\)\?5\s*\)\@<=«»\@!"
1000    \ skip="\\»"
1001    \ end="»"
1002    \ contains=@rakuRegexP5,rakuVariables
1003
1004endif
1005
1006" Comments
1007
1008syn match rakuAttention display "\<\%(ACHTUNG\|ATTN\|ATTENTION\|FIXME\|NB\|TODO\|TBD\|WTF\|XXX\|NOTE\)" contained
1009
1010" normal end-of-line comment
1011syn match rakuComment display "#.*" contains=rakuAttention
1012
1013" Multiline comments. Arbitrary numbers of opening brackets are allowed,
1014" but we only define regions for 1 to 3
1015syn region rakuBracketComment
1016    \ start="#[`|=]("
1017    \ skip="([^)]*)"
1018    \ end=")"
1019    \ contains=rakuAttention,rakuBracketComment
1020syn region rakuBracketComment
1021    \ start="#[`|=]\["
1022    \ skip="\[[^\]]*]"
1023    \ end="]"
1024    \ contains=rakuAttention,rakuBracketComment
1025syn region rakuBracketComment
1026    \ start="#[`|=]{"
1027    \ skip="{[^}]*}"
1028    \ end="}"
1029    \ contains=rakuAttention,rakuBracketComment
1030syn region rakuBracketComment
1031    \ start="#[`|=]<"
1032    \ skip="<[^>]*>"
1033    \ end=">"
1034    \ contains=rakuAttention,rakuBracketComment
1035syn region rakuBracketComment
1036    \ start="#[`|=]«"
1037    \ skip="«[^»]*»"
1038    \ end="»"
1039    \ contains=rakuAttention,rakuBracketComment
1040
1041" Comments with double and triple delimiters
1042syn region rakuBracketComment
1043    \ matchgroup=rakuBracketComment
1044    \ start="#[`|=](("
1045    \ skip="((\%([^)\|))\@!]\)*))"
1046    \ end="))"
1047    \ contains=rakuAttention,rakuBracketComment
1048syn region rakuBracketComment
1049    \ matchgroup=rakuBracketComment
1050    \ start="#[`|=]((("
1051    \ skip="(((\%([^)]\|)\%())\)\@!\)*)))"
1052    \ end=")))"
1053    \ contains=rakuAttention,rakuBracketComment
1054
1055syn region rakuBracketComment
1056    \ matchgroup=rakuBracketComment
1057    \ start="#[`|=]\[\["
1058    \ skip="\[\[\%([^\]]\|]]\@!\)*]]"
1059    \ end="]]"
1060    \ contains=rakuAttention,rakuBracketComment
1061syn region rakuBracketComment
1062    \ matchgroup=rakuBracketComment
1063    \ start="#[`|=]\[\[\["
1064    \ skip="\[\[\[\%([^\]]\|]\%(]]\)\@!\)*]]]"
1065    \ end="]]]"
1066    \ contains=rakuAttention,rakuBracketComment
1067
1068syn region rakuBracketComment
1069    \ matchgroup=rakuBracketComment
1070    \ start="#[`|=]{{"
1071    \ skip="{{\%([^}]\|}}\@!\)*}}"
1072    \ end="}}"
1073    \ contains=rakuAttention,rakuBracketComment
1074syn region rakuBracketComment
1075    \ matchgroup=rakuBracketComment
1076    \ start="#[`|=]{{{"
1077    \ skip="{{{\%([^}]\|}\%(}}\)\@!\)*}}}"
1078    \ end="}}}"
1079    \ contains=rakuAttention,rakuBracketComment
1080
1081syn region rakuBracketComment
1082    \ matchgroup=rakuBracketComment
1083    \ start="#[`|=]<<"
1084    \ skip="<<\%([^>]\|>>\@!\)*>>"
1085    \ end=">>"
1086    \ contains=rakuAttention,rakuBracketComment
1087syn region rakuBracketComment
1088    \ matchgroup=rakuBracketComment
1089    \ start="#[`|=]<<<"
1090    \ skip="<<<\%([^>]\|>\%(>>\)\@!\)*>>>"
1091    \ end=">>>"
1092    \ contains=rakuAttention,rakuBracketComment
1093
1094syn region rakuBracketComment
1095    \ matchgroup=rakuBracketComment
1096    \ start="#[`|=]««"
1097    \ skip="««\%([^»]\|»»\@!\)*»»"
1098    \ end="»»"
1099    \ contains=rakuAttention,rakuBracketComment
1100syn region rakuBracketComment
1101    \ matchgroup=rakuBracketComment
1102    \ start="#[`|=]«««"
1103    \ skip="«««\%([^»]\|»\%(»»\)\@!\)*»»»"
1104    \ end="»»»"
1105    \ contains=rakuAttention,rakuBracketComment
1106
1107syn match rakuShebang display "\%^#!.*"
1108
1109" => autoquoting
1110syn match rakuStringAuto   display "\.\@1<!\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\ze\%(p5\)\@2<![RSXZ]\@1<!=>"
1111syn match rakuStringAuto   display "\.\@1<!\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\ze\s\+=>"
1112syn match rakuStringAuto   display "\.\@1<!\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)p5\ze=>"
1113
1114" Pod
1115
1116" Abbreviated blocks (implicit code forbidden)
1117syn region rakuPodAbbrRegion
1118    \ matchgroup=rakuPodPrefix
1119    \ start="^\s*\zs=\ze\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1120    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1121    \ contains=rakuPodAbbrNoCodeType
1122    \ keepend
1123
1124syn region rakuPodAbbrNoCodeType
1125    \ matchgroup=rakuPodType
1126    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1127    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1128    \ contained
1129    \ contains=rakuPodName,rakuPodAbbrNoCode
1130
1131syn match rakuPodName contained ".\+" contains=@rakuPodFormat
1132syn match rakuPodComment contained ".\+"
1133
1134syn region rakuPodAbbrNoCode
1135    \ start="^"
1136    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1137    \ contained
1138    \ contains=@rakuPodFormat
1139
1140" Abbreviated blocks (everything is code)
1141syn region rakuPodAbbrRegion
1142    \ matchgroup=rakuPodPrefix
1143    \ start="^\s*\zs=\zecode\>"
1144    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1145    \ contains=rakuPodAbbrCodeType
1146    \ keepend
1147
1148syn region rakuPodAbbrCodeType
1149    \ matchgroup=rakuPodType
1150    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1151    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1152    \ contained
1153    \ contains=rakuPodName,rakuPodAbbrCode
1154
1155syn region rakuPodAbbrCode
1156    \ start="^"
1157    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1158    \ contained
1159
1160" Abbreviated blocks (everything is a comment)
1161syn region rakuPodAbbrRegion
1162    \ matchgroup=rakuPodPrefix
1163    \ start="^=\zecomment\>"
1164    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1165    \ contains=rakuPodAbbrCommentType
1166    \ keepend
1167
1168syn region rakuPodAbbrCommentType
1169    \ matchgroup=rakuPodType
1170    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1171    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1172    \ contained
1173    \ contains=rakuPodComment,rakuPodAbbrNoCode
1174
1175" Abbreviated blocks (implicit code allowed)
1176syn region rakuPodAbbrRegion
1177    \ matchgroup=rakuPodPrefix
1178    \ start="^=\ze\%(pod\|item\|nested\|\u\+\)\>"
1179    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1180    \ contains=rakuPodAbbrType
1181    \ keepend
1182
1183syn region rakuPodAbbrType
1184    \ matchgroup=rakuPodType
1185    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1186    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1187    \ contained
1188    \ contains=rakuPodName,rakuPodAbbr
1189
1190syn region rakuPodAbbr
1191    \ start="^"
1192    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1193    \ contained
1194    \ contains=@rakuPodFormat,rakuPodImplicitCode
1195
1196" Abbreviated block to end-of-file
1197syn region rakuPodAbbrRegion
1198    \ matchgroup=rakuPodPrefix
1199    \ start="^=\zeEND\>"
1200    \ end="\%$"
1201    \ contains=rakuPodAbbrEOFType
1202    \ keepend
1203
1204syn region rakuPodAbbrEOFType
1205    \ matchgroup=rakuPodType
1206    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1207    \ end="\%$"
1208    \ contained
1209    \ contains=rakuPodName,rakuPodAbbrEOF
1210
1211syn region rakuPodAbbrEOF
1212    \ start="^"
1213    \ end="\%$"
1214    \ contained
1215    \ contains=@rakuPodNestedBlocks,@rakuPodFormat,rakuPodImplicitCode
1216
1217" Directives
1218syn region rakuPodDirectRegion
1219    \ matchgroup=rakuPodPrefix
1220    \ start="^=\%(config\|use\)\>"
1221    \ end="^\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\|\s*$\)"
1222    \ contains=rakuPodDirectArgRegion
1223    \ keepend
1224
1225syn region rakuPodDirectArgRegion
1226    \ matchgroup=rakuPodType
1227    \ start="\S\+"
1228    \ end="^\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\|\s*$\)"
1229    \ contained
1230    \ contains=rakuPodDirectConfigRegion
1231
1232syn region rakuPodDirectConfigRegion
1233    \ start=""
1234    \ end="^\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\|\s*$\)"
1235    \ contained
1236    \ contains=@rakuPodConfig
1237
1238" =encoding is a special directive
1239syn region rakuPodDirectRegion
1240    \ matchgroup=rakuPodPrefix
1241    \ start="^=encoding\>"
1242    \ end="^\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\|\s*$\)"
1243    \ contains=rakuPodEncodingArgRegion
1244    \ keepend
1245
1246syn region rakuPodEncodingArgRegion
1247    \ matchgroup=rakuPodName
1248    \ start="\S\+"
1249    \ end="^\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\|\s*$\)"
1250    \ contained
1251
1252" Paragraph blocks (implicit code forbidden)
1253syn region rakuPodParaRegion
1254    \ matchgroup=rakuPodPrefix
1255    \ start="^\s*\zs=for\>"
1256    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1257    \ contains=rakuPodParaNoCodeTypeRegion
1258    \ keepend extend
1259
1260syn region rakuPodParaNoCodeTypeRegion
1261    \ matchgroup=rakuPodType
1262    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1263    \ end="^\s*\zs\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1264    \ contained
1265    \ contains=rakuPodParaNoCode,rakuPodParaConfigRegion
1266
1267syn region rakuPodParaConfigRegion
1268    \ start=""
1269    \ end="^\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\@1<!\)"
1270    \ contained
1271    \ contains=@rakuPodConfig
1272
1273syn region rakuPodParaNoCode
1274    \ start="^[^=]"
1275    \ end="^\s*\zs\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1276    \ contained
1277    \ contains=@rakuPodFormat
1278
1279" Paragraph blocks (everything is code)
1280syn region rakuPodParaRegion
1281    \ matchgroup=rakuPodPrefix
1282    \ start="^\s*\zs=for\>\ze\s*code\>"
1283    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1284    \ contains=rakuPodParaCodeTypeRegion
1285    \ keepend extend
1286
1287syn region rakuPodParaCodeTypeRegion
1288    \ matchgroup=rakuPodType
1289    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1290    \ end="^\s*\zs\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1291    \ contained
1292    \ contains=rakuPodParaCode,rakuPodParaConfigRegion
1293
1294syn region rakuPodParaCode
1295    \ start="^[^=]"
1296    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1297    \ contained
1298
1299" Paragraph blocks (implicit code allowed)
1300syn region rakuPodParaRegion
1301    \ matchgroup=rakuPodPrefix
1302    \ start="^\s*\zs=for\>\ze\s*\%(pod\|item\|nested\|\u\+\)\>"
1303    \ end="^\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1304    \ contains=rakuPodParaTypeRegion
1305    \ keepend extend
1306
1307syn region rakuPodParaTypeRegion
1308    \ matchgroup=rakuPodType
1309    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1310    \ end="^\s*\zs\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1311    \ contained
1312    \ contains=rakuPodPara,rakuPodParaConfigRegion
1313
1314syn region rakuPodPara
1315    \ start="^[^=]"
1316    \ end="^\s*\zs\ze\%(\s*$\|=[A-Za-z_\xC0-\xFF]\)"
1317    \ contained
1318    \ contains=@rakuPodFormat,rakuPodImplicitCode
1319
1320" Paragraph block to end-of-file
1321syn region rakuPodParaRegion
1322    \ matchgroup=rakuPodPrefix
1323    \ start="^=for\>\ze\s\+END\>"
1324    \ end="\%$"
1325    \ contains=rakuPodParaEOFTypeRegion
1326    \ keepend extend
1327
1328syn region rakuPodParaEOFTypeRegion
1329    \ matchgroup=rakuPodType
1330    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1331    \ end="\%$"
1332    \ contained
1333    \ contains=rakuPodParaEOF,rakuPodParaConfigRegion
1334
1335syn region rakuPodParaEOF
1336    \ start="^[^=]"
1337    \ end="\%$"
1338    \ contained
1339    \ contains=@rakuPodNestedBlocks,@rakuPodFormat,rakuPodImplicitCode
1340
1341" Delimited blocks (implicit code forbidden)
1342syn region rakuPodDelimRegion
1343    \ matchgroup=rakuPodPrefix
1344    \ start="^\z(\s*\)\zs=begin\>"
1345    \ end="^\z1\zs=end\>"
1346    \ contains=rakuPodDelimNoCodeTypeRegion
1347    \ keepend extend skipwhite
1348    \ nextgroup=rakuPodType
1349
1350syn region rakuPodDelimNoCodeTypeRegion
1351    \ matchgroup=rakuPodType
1352    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1353    \ end="^\s*\zs\ze=end\>"
1354    \ contained
1355    \ contains=rakuPodDelimNoCode,rakuPodDelimConfigRegion
1356
1357syn region rakuPodDelimConfigRegion
1358    \ start=""
1359    \ end="^\s*\zs\ze\%([^=]\|=[A-Za-z_\xC0-\xFF]\|\s*$\)"
1360    \ contained
1361    \ contains=@rakuPodConfig
1362
1363syn region rakuPodDelimNoCode
1364    \ start="^"
1365    \ end="^\s*\zs\ze=end\>"
1366    \ contained
1367    \ contains=@rakuPodNestedBlocks,@rakuPodFormat
1368
1369" Delimited blocks (everything is code)
1370syn region rakuPodDelimRegion
1371    \ matchgroup=rakuPodPrefix
1372    \ start="^\z(\s*\)\zs=begin\>\ze\s*code\>"
1373    \ end="^\z1\zs=end\>"
1374    \ contains=rakuPodDelimCodeTypeRegion
1375    \ keepend extend skipwhite
1376    \ nextgroup=rakuPodType
1377
1378syn region rakuPodDelimCodeTypeRegion
1379    \ matchgroup=rakuPodType
1380    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1381    \ end="^\s*\zs\ze=end\>"
1382    \ contained
1383    \ contains=rakuPodDelimCode,rakuPodDelimConfigRegion
1384
1385syn region rakuPodDelimCode
1386    \ start="^"
1387    \ end="^\s*\zs\ze=end\>"
1388    \ contained
1389    \ contains=@rakuPodNestedBlocks
1390
1391" Delimited blocks (implicit code allowed)
1392syn region rakuPodDelimRegion
1393    \ matchgroup=rakuPodPrefix
1394    \ start="^\z(\s*\)\zs=begin\>\ze\s*\%(pod\|item\|nested\|\u\+\)\>"
1395    \ end="^\z1\zs=end\>"
1396    \ contains=rakuPodDelimTypeRegion
1397    \ keepend extend skipwhite
1398    \ nextgroup=rakuPodType
1399
1400syn region rakuPodDelimTypeRegion
1401    \ matchgroup=rakuPodType
1402    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1403    \ end="^\s*\zs\ze=end\>"
1404    \ contained
1405    \ contains=rakuPodDelim,rakuPodDelimConfigRegion
1406
1407syn region rakuPodDelim
1408    \ start="^"
1409    \ end="^\s*\zs\ze=end\>"
1410    \ contained
1411    \ contains=@rakuPodNestedBlocks,@rakuPodFormat,rakuPodImplicitCode
1412
1413" Delimited block to end-of-file
1414syn region rakuPodDelimRegion
1415    \ matchgroup=rakuPodPrefix
1416    \ start="^=begin\>\ze\s\+END\>"
1417    \ end="\%$"
1418    \ extend
1419    \ contains=rakuPodDelimEOFTypeRegion
1420
1421syn region rakuPodDelimEOFTypeRegion
1422    \ matchgroup=rakuPodType
1423    \ start="\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1424    \ end="\%$"
1425    \ contained
1426    \ contains=rakuPodDelimEOF,rakuPodDelimConfigRegion
1427
1428syn region rakuPodDelimEOF
1429    \ start="^"
1430    \ end="\%$"
1431    \ contained
1432    \ contains=@rakuPodNestedBlocks,@rakuPodFormat,rakuPodImplicitCode
1433
1434syn cluster rakuPodConfig
1435    \ add=rakuPodConfigOperator
1436    \ add=rakuPodExtraConfig
1437    \ add=rakuStringAuto
1438    \ add=rakuPodAutoQuote
1439    \ add=rakuStringSQ
1440
1441syn region rakuPodParens
1442    \ start="("
1443    \ end=")"
1444    \ contained
1445    \ contains=rakuNumber,rakuStringSQ
1446
1447syn match rakuPodAutoQuote      display contained "=>"
1448syn match rakuPodConfigOperator display contained ":!\?" nextgroup=rakuPodConfigOption
1449syn match rakuPodConfigOption   display contained "[^[:space:](<]\+" nextgroup=rakuPodParens,rakuStringAngle
1450syn match rakuPodExtraConfig    display contained "^="
1451syn match rakuPodVerticalBar    display contained "|"
1452syn match rakuPodColon          display contained ":"
1453syn match rakuPodSemicolon      display contained ";"
1454syn match rakuPodComma          display contained ","
1455syn match rakuPodImplicitCode   display contained "^\s.*"
1456syn match rakuPodType           display contained "\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)"
1457
1458" These may appear inside delimited blocks
1459syn cluster rakuPodNestedBlocks
1460    \ add=rakuPodAbbrRegion
1461    \ add=rakuPodDirectRegion
1462    \ add=rakuPodParaRegion
1463    \ add=rakuPodDelimRegion
1464
1465" Pod formatting codes
1466
1467syn cluster rakuPodFormat
1468    \ add=rakuPodFormatOne
1469    \ add=rakuPodFormatTwo
1470    \ add=rakuPodFormatThree
1471    \ add=rakuPodFormatFrench
1472
1473" Balanced angles found inside formatting codes. Ensures proper nesting.
1474
1475syn region rakuPodFormatAnglesOne
1476    \ matchgroup=rakuPodFormat
1477    \ start="<"
1478    \ skip="<[^>]*>"
1479    \ end=">"
1480    \ transparent contained
1481    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatAnglesOne
1482
1483syn region rakuPodFormatAnglesTwo
1484    \ matchgroup=rakuPodFormat
1485    \ start="<<"
1486    \ skip="<<[^>]*>>"
1487    \ end=">>"
1488    \ transparent contained
1489    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatAnglesOne,rakuPodFormatAnglesTwo
1490
1491syn region rakuPodFormatAnglesThree
1492    \ matchgroup=rakuPodFormat
1493    \ start="<<<"
1494    \ skip="<<<[^>]*>>>"
1495    \ end=">>>"
1496    \ transparent contained
1497    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatAnglesOne,rakuPodFormatAnglesTwo,rakuPodFormatAnglesThree
1498
1499syn region rakuPodFormatAnglesFrench
1500    \ matchgroup=rakuPodFormat
1501    \ start="«"
1502    \ skip="«[^»]*»"
1503    \ end="»"
1504    \ transparent contained
1505    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatAnglesOne,rakuPodFormatAnglesTwo,rakuPodFormatAnglesThree
1506
1507" All formatting codes
1508
1509syn region rakuPodFormatOne
1510    \ matchgroup=rakuPodFormatCode
1511    \ start="\u<"
1512    \ skip="<[^>]*>"
1513    \ end=">"
1514    \ contained
1515    \ contains=rakuPodFormatAnglesOne,rakuPodFormatFrench,rakuPodFormatOne
1516
1517syn region rakuPodFormatTwo
1518    \ matchgroup=rakuPodFormatCode
1519    \ start="\u<<"
1520    \ skip="<<[^>]*>>"
1521    \ end=">>"
1522    \ contained
1523    \ contains=rakuPodFormatAnglesTwo,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo
1524
1525syn region rakuPodFormatThree
1526    \ matchgroup=rakuPodFormatCode
1527    \ start="\u<<<"
1528    \ skip="<<<[^>]*>>>"
1529    \ end=">>>"
1530    \ contained
1531    \ contains=rakuPodFormatAnglesThree,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree
1532
1533syn region rakuPodFormatFrench
1534    \ matchgroup=rakuPodFormatCode
1535    \ start="\u«"
1536    \ skip="«[^»]*»"
1537    \ end="»"
1538    \ contained
1539    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree
1540
1541" C<> and V<> don't allow nested formatting formatting codes
1542
1543syn region rakuPodFormatOne
1544    \ matchgroup=rakuPodFormatCode
1545    \ start="[CV]<"
1546    \ skip="<[^>]*>"
1547    \ end=">"
1548    \ contained
1549    \ contains=rakuPodFormatAnglesOne
1550
1551syn region rakuPodFormatTwo
1552    \ matchgroup=rakuPodFormatCode
1553    \ start="[CV]<<"
1554    \ skip="<<[^>]*>>"
1555    \ end=">>"
1556    \ contained
1557    \ contains=rakuPodFormatAnglesTwo
1558
1559syn region rakuPodFormatThree
1560    \ matchgroup=rakuPodFormatCode
1561    \ start="[CV]<<<"
1562    \ skip="<<<[^>]*>>>"
1563    \ end=">>>"
1564    \ contained
1565    \ contains=rakuPodFormatAnglesThree
1566
1567syn region rakuPodFormatFrench
1568    \ matchgroup=rakuPodFormatCode
1569    \ start="[CV]«"
1570    \ skip="«[^»]*»"
1571    \ end="»"
1572    \ contained
1573    \ contains=rakuPodFormatAnglesFrench
1574
1575" L<> can have a "|" separator
1576
1577syn region rakuPodFormatOne
1578    \ matchgroup=rakuPodFormatCode
1579    \ start="L<"
1580    \ skip="<[^>]*>"
1581    \ end=">"
1582    \ contained
1583    \ contains=rakuPodFormatAnglesOne,rakuPodFormatFrench,rakuPodFormatOne,rakuPodVerticalBar
1584
1585syn region rakuPodFormatTwo
1586    \ matchgroup=rakuPodFormatCode
1587    \ start="L<<"
1588    \ skip="<<[^>]*>>"
1589    \ end=">>"
1590    \ contained
1591    \ contains=rakuPodFormatAnglesTwo,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodVerticalBar
1592
1593syn region rakuPodFormatThree
1594    \ matchgroup=rakuPodFormatCode
1595    \ start="L<<<"
1596    \ skip="<<<[^>]*>>>"
1597    \ end=">>>"
1598    \ contained
1599    \ contains=rakuPodFormatAnglesThree,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodVerticalBar
1600
1601syn region rakuPodFormatFrench
1602    \ matchgroup=rakuPodFormatCode
1603    \ start="L«"
1604    \ skip="«[^»]*»"
1605    \ end="»"
1606    \ contained
1607    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodVerticalBar
1608
1609" E<> can have a ";" separator
1610
1611syn region rakuPodFormatOne
1612    \ matchgroup=rakuPodFormatCode
1613    \ start="E<"
1614    \ skip="<[^>]*>"
1615    \ end=">"
1616    \ contained
1617    \ contains=rakuPodFormatAnglesOne,rakuPodFormatFrench,rakuPodFormatOne,rakuPodSemiColon
1618
1619syn region rakuPodFormatTwo
1620    \ matchgroup=rakuPodFormatCode
1621    \ start="E<<"
1622    \ skip="<<[^>]*>>"
1623    \ end=">>"
1624    \ contained
1625    \ contains=rakuPodFormatAnglesTwo,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodSemiColon
1626
1627syn region rakuPodFormatThree
1628    \ matchgroup=rakuPodFormatCode
1629    \ start="E<<<"
1630    \ skip="<<<[^>]*>>>"
1631    \ end=">>>"
1632    \ contained
1633    \ contains=rakuPodFormatAnglesThree,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodSemiColon
1634
1635syn region rakuPodFormatFrench
1636    \ matchgroup=rakuPodFormatCode
1637    \ start="E«"
1638    \ skip="«[^»]*»"
1639    \ end="»"
1640    \ contained
1641    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodSemiColon
1642
1643" M<> can have a ":" separator
1644
1645syn region rakuPodFormatOne
1646    \ matchgroup=rakuPodFormatCode
1647    \ start="M<"
1648    \ skip="<[^>]*>"
1649    \ end=">"
1650    \ contained
1651    \ contains=rakuPodFormatAnglesOne,rakuPodFormatFrench,rakuPodFormatOne,rakuPodColon
1652
1653syn region rakuPodFormatTwo
1654    \ matchgroup=rakuPodFormatCode
1655    \ start="M<<"
1656    \ skip="<<[^>]*>>"
1657    \ end=">>"
1658    \ contained
1659    \ contains=rakuPodFormatAnglesTwo,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodColon
1660
1661syn region rakuPodFormatThree
1662    \ matchgroup=rakuPodFormatCode
1663    \ start="M<<<"
1664    \ skip="<<<[^>]*>>>"
1665    \ end=">>>"
1666    \ contained
1667    \ contains=rakuPodFormatAnglesThree,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodColon
1668
1669syn region rakuPodFormatFrench
1670    \ matchgroup=rakuPodFormatCode
1671    \ start="M«"
1672    \ skip="«[^»]*»"
1673    \ end="»"
1674    \ contained
1675    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodColon
1676
1677" D<> can have "|" and ";" separators
1678
1679syn region rakuPodFormatOne
1680    \ matchgroup=rakuPodFormatCode
1681    \ start="D<"
1682    \ skip="<[^>]*>"
1683    \ end=">"
1684    \ contained
1685    \ contains=rakuPodFormatAnglesOne,rakuPodFormatFrench,rakuPodFormatOne,rakuPodVerticalBar,rakuPodSemiColon
1686
1687syn region rakuPodFormatTwo
1688    \ matchgroup=rakuPodFormatCode
1689    \ start="D<<"
1690    \ skip="<<[^>]*>>"
1691    \ end=">>"
1692    \ contained
1693    \ contains=rakuPodFormatAngleTwo,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodVerticalBar,rakuPodSemiColon
1694
1695syn region rakuPodFormatThree
1696    \ matchgroup=rakuPodFormatCode
1697    \ start="D<<<"
1698    \ skip="<<<[^>]*>>>"
1699    \ end=">>>"
1700    \ contained
1701    \ contains=rakuPodFormatAnglesThree,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodVerticalBar,rakuPodSemiColon
1702
1703syn region rakuPodFormatFrench
1704    \ matchgroup=rakuPodFormatCode
1705    \ start="D«"
1706    \ skip="«[^»]*»"
1707    \ end="»"
1708    \ contained
1709    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodVerticalBar,rakuPodSemiColon
1710
1711" X<> can have "|", "," and ";" separators
1712
1713syn region rakuPodFormatOne
1714    \ matchgroup=rakuPodFormatCode
1715    \ start="X<"
1716    \ skip="<[^>]*>"
1717    \ end=">"
1718    \ contained
1719    \ contains=rakuPodFormatAnglesOne,rakuPodFormatFrench,rakuPodFormatOne,rakuPodVerticalBar,rakuPodSemiColon,rakuPodComma
1720
1721syn region rakuPodFormatTwo
1722    \ matchgroup=rakuPodFormatCode
1723    \ start="X<<"
1724    \ skip="<<[^>]*>>"
1725    \ end=">>"
1726    \ contained
1727    \ contains=rakuPodFormatAnglesTwo,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodVerticalBar,rakuPodSemiColon,rakuPodComma
1728
1729syn region rakuPodFormatThree
1730    \ matchgroup=rakuPodFormatCode
1731    \ start="X<<<"
1732    \ skip="<<<[^>]*>>>"
1733    \ end=">>>"
1734    \ contained
1735    \ contains=rakuPodFormatAnglesThree,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodVerticalBar,rakuPodSemiColon,rakuPodComma
1736
1737syn region rakuPodFormatFrench
1738    \ matchgroup=rakuPodFormatCode
1739    \ start="X«"
1740    \ skip="«[^»]*»"
1741    \ end="»"
1742    \ contained
1743    \ contains=rakuPodFormatAnglesFrench,rakuPodFormatFrench,rakuPodFormatOne,rakuPodFormatTwo,rakuPodFormatThree,rakuPodVerticalBar,rakuPodSemiColon,rakuPodComma
1744
1745" Define the default highlighting.
1746" For version 5.7 and earlier: only when not done already
1747" For version 5.8 and later: only when an item doesn't have highlighting yet
1748if version >= 508 || !exists("did_raku_syntax_inits")
1749    if version < 508
1750        let did_raku_syntax_inits = 1
1751        command -nargs=+ HiLink hi link <args>
1752    else
1753        command -nargs=+ HiLink hi def link <args>
1754    endif
1755
1756    HiLink rakuEscOctOld        rakuError
1757    HiLink rakuPackageTwigil    rakuTwigil
1758    HiLink rakuStringAngle      rakuString
1759    HiLink rakuStringAngleFixed rakuString
1760    HiLink rakuStringFrench     rakuString
1761    HiLink rakuStringAngles     rakuString
1762    HiLink rakuStringSQ         rakuString
1763    HiLink rakuStringDQ         rakuString
1764    HiLink rakuStringQ          rakuString
1765    HiLink rakuStringQ_q        rakuString
1766    HiLink rakuStringQ_qww      rakuString
1767    HiLink rakuStringQ_qq       rakuString
1768    HiLink rakuStringQ_to       rakuString
1769    HiLink rakuStringQ_qto      rakuString
1770    HiLink rakuStringQ_qqto     rakuString
1771    HiLink rakuRxStringSQ       rakuString
1772    HiLink rakuRxStringDQ       rakuString
1773    HiLink rakuReplacement      rakuString
1774    HiLink rakuReplCurly        rakuString
1775    HiLink rakuReplAngle        rakuString
1776    HiLink rakuReplFrench       rakuString
1777    HiLink rakuReplBracket      rakuString
1778    HiLink rakuReplParen        rakuString
1779    HiLink rakuTransliteration  rakuString
1780    HiLink rakuTransRepl        rakuString
1781    HiLink rakuTransReplCurly   rakuString
1782    HiLink rakuTransReplAngle   rakuString
1783    HiLink rakuTransReplFrench  rakuString
1784    HiLink rakuTransReplBracket rakuString
1785    HiLink rakuTransReplParen   rakuString
1786    HiLink rakuStringAuto       rakuString
1787    HiLink rakuKey              rakuString
1788    HiLink rakuMatch            rakuString
1789    HiLink rakuSubstitution     rakuString
1790    HiLink rakuMatchBare        rakuString
1791    HiLink rakuRegexBlock       rakuString
1792    HiLink rakuRxP5CharClass    rakuString
1793    HiLink rakuRxP5QuoteMeta    rakuString
1794    HiLink rakuRxCharClass      rakuString
1795    HiLink rakuRxQuoteWords     rakuString
1796    HiLink rakuReduceOp         rakuOperator
1797    HiLink rakuSetOp            rakuOperator
1798    HiLink rakuRSXZOp           rakuOperator
1799    HiLink rakuHyperOp          rakuOperator
1800    HiLink rakuPostHyperOp      rakuOperator
1801    HiLink rakuQuoteQ           rakuQuote
1802    HiLink rakuQuoteQ_q         rakuQuote
1803    HiLink rakuQuoteQ_qww       rakuQuote
1804    HiLink rakuQuoteQ_qq        rakuQuote
1805    HiLink rakuQuoteQ_to        rakuQuote
1806    HiLink rakuQuoteQ_qto       rakuQuote
1807    HiLink rakuQuoteQ_qqto      rakuQuote
1808    HiLink rakuQuoteQ_PIR       rakuQuote
1809    HiLink rakuMatchStart_m     rakuQuote
1810    HiLink rakuMatchStart_s     rakuQuote
1811    HiLink rakuMatchStart_tr    rakuQuote
1812    HiLink rakuBareSigil        rakuVariable
1813    HiLink rakuRxRange          rakuStringSpecial
1814    HiLink rakuRxAnchor         rakuStringSpecial
1815    HiLink rakuRxBoundary       rakuStringSpecial
1816    HiLink rakuRxP5Anchor       rakuStringSpecial
1817    HiLink rakuCodePoint        rakuStringSpecial
1818    HiLink rakuRxMeta           rakuStringSpecial
1819    HiLink rakuRxP5Range        rakuStringSpecial
1820    HiLink rakuRxP5CPId         rakuStringSpecial
1821    HiLink rakuRxP5Posix        rakuStringSpecial
1822    HiLink rakuRxP5Mod          rakuStringSpecial
1823    HiLink rakuRxP5HexSeq       rakuStringSpecial
1824    HiLink rakuRxP5OctSeq       rakuStringSpecial
1825    HiLink rakuRxP5WriteRefId   rakuStringSpecial
1826    HiLink rakuHexSequence      rakuStringSpecial
1827    HiLink rakuOctSequence      rakuStringSpecial
1828    HiLink rakuRxP5Named        rakuStringSpecial
1829    HiLink rakuRxP5PropId       rakuStringSpecial
1830    HiLink rakuRxP5Quantifier   rakuStringSpecial
1831    HiLink rakuRxP5CountId      rakuStringSpecial
1832    HiLink rakuRxP5Verb         rakuStringSpecial
1833    HiLink rakuRxAssertGroup    rakuStringSpecial2
1834    HiLink rakuEscape           rakuStringSpecial2
1835    HiLink rakuEscNull          rakuStringSpecial2
1836    HiLink rakuEscHash          rakuStringSpecial2
1837    HiLink rakuEscQQ            rakuStringSpecial2
1838    HiLink rakuEscQuote         rakuStringSpecial2
1839    HiLink rakuEscDoubleQuote   rakuStringSpecial2
1840    HiLink rakuEscBackTick      rakuStringSpecial2
1841    HiLink rakuEscForwardSlash  rakuStringSpecial2
1842    HiLink rakuEscVerticalBar   rakuStringSpecial2
1843    HiLink rakuEscExclamation   rakuStringSpecial2
1844    HiLink rakuEscDollar        rakuStringSpecial2
1845    HiLink rakuEscOpenCurly     rakuStringSpecial2
1846    HiLink rakuEscCloseCurly    rakuStringSpecial2
1847    HiLink rakuEscCloseBracket  rakuStringSpecial2
1848    HiLink rakuEscCloseAngle    rakuStringSpecial2
1849    HiLink rakuEscCloseFrench   rakuStringSpecial2
1850    HiLink rakuEscBackSlash     rakuStringSpecial2
1851    HiLink rakuEscCodePoint     rakuStringSpecial2
1852    HiLink rakuEscOct           rakuStringSpecial2
1853    HiLink rakuEscHex           rakuStringSpecial2
1854    HiLink rakuRxEscape         rakuStringSpecial2
1855    HiLink rakuRxCapture        rakuStringSpecial2
1856    HiLink rakuRxAlternation    rakuStringSpecial2
1857    HiLink rakuRxP5             rakuStringSpecial2
1858    HiLink rakuRxP5ReadRef      rakuStringSpecial2
1859    HiLink rakuRxP5Oct          rakuStringSpecial2
1860    HiLink rakuRxP5Hex          rakuStringSpecial2
1861    HiLink rakuRxP5EscMeta      rakuStringSpecial2
1862    HiLink rakuRxP5Meta         rakuStringSpecial2
1863    HiLink rakuRxP5Escape       rakuStringSpecial2
1864    HiLink rakuRxP5CodePoint    rakuStringSpecial2
1865    HiLink rakuRxP5WriteRef     rakuStringSpecial2
1866    HiLink rakuRxP5Prop         rakuStringSpecial2
1867
1868    HiLink rakuProperty       Tag
1869    HiLink rakuAttention      Todo
1870    HiLink rakuType           Type
1871    HiLink rakuError          Error
1872    HiLink rakuBlockLabel     Label
1873    HiLink rakuNormal         Normal
1874    HiLink rakuIdentifier     Normal
1875    HiLink rakuPackage        Normal
1876    HiLink rakuPackageScope   Normal
1877    HiLink rakuNumber         Number
1878    HiLink rakuOctNumber      Number
1879    HiLink rakuBinNumber      Number
1880    HiLink rakuHexNumber      Number
1881    HiLink rakuDecNumber      Number
1882    HiLink rakuString         String
1883    HiLink rakuRepeat         Repeat
1884    HiLink rakuPragma         Keyword
1885    HiLink rakuPreDeclare     Keyword
1886    HiLink rakuDeclare        Keyword
1887    HiLink rakuDeclareRegex   Keyword
1888    HiLink rakuVarStorage     Special
1889    HiLink rakuFlowControl    Special
1890    HiLink rakuOctBase        Special
1891    HiLink rakuBinBase        Special
1892    HiLink rakuHexBase        Special
1893    HiLink rakuDecBase        Special
1894    HiLink rakuTwigil         Special
1895    HiLink rakuStringSpecial2 Special
1896    HiLink rakuVersion        Special
1897    HiLink rakuComment        Comment
1898    HiLink rakuBracketComment Comment
1899    HiLink rakuInclude        Include
1900    HiLink rakuShebang        PreProc
1901    HiLink rakuClosureTrait   PreProc
1902    HiLink rakuOperator       Operator
1903    HiLink rakuContext        Operator
1904    HiLink rakuQuote          Delimiter
1905    HiLink rakuTypeConstraint PreCondit
1906    HiLink rakuException      Exception
1907    HiLink rakuVariable       Identifier
1908    HiLink rakuVarSlash       Identifier
1909    HiLink rakuVarNum         Identifier
1910    HiLink rakuVarExclam      Identifier
1911    HiLink rakuVarMatch       Identifier
1912    HiLink rakuVarName        Identifier
1913    HiLink rakuMatchVar       Identifier
1914    HiLink rakuRxP5ReadRefId  Identifier
1915    HiLink rakuRxP5ModDef     Identifier
1916    HiLink rakuRxP5ModName    Identifier
1917    HiLink rakuConditional    Conditional
1918    HiLink rakuStringSpecial  SpecialChar
1919
1920    HiLink rakuPodAbbr         rakuPod
1921    HiLink rakuPodAbbrEOF      rakuPod
1922    HiLink rakuPodAbbrNoCode   rakuPod
1923    HiLink rakuPodAbbrCode     rakuPodCode
1924    HiLink rakuPodPara         rakuPod
1925    HiLink rakuPodParaEOF      rakuPod
1926    HiLink rakuPodParaNoCode   rakuPod
1927    HiLink rakuPodParaCode     rakuPodCode
1928    HiLink rakuPodDelim        rakuPod
1929    HiLink rakuPodDelimEOF     rakuPod
1930    HiLink rakuPodDelimNoCode  rakuPod
1931    HiLink rakuPodDelimCode    rakuPodCode
1932    HiLink rakuPodImplicitCode rakuPodCode
1933    HiLink rakuPodExtraConfig  rakuPodPrefix
1934    HiLink rakuPodVerticalBar  rakuPodFormatCode
1935    HiLink rakuPodColon        rakuPodFormatCode
1936    HiLink rakuPodSemicolon    rakuPodFormatCode
1937    HiLink rakuPodComma        rakuPodFormatCode
1938    HiLink rakuPodFormatOne    rakuPodFormat
1939    HiLink rakuPodFormatTwo    rakuPodFormat
1940    HiLink rakuPodFormatThree  rakuPodFormat
1941    HiLink rakuPodFormatFrench rakuPodFormat
1942
1943    HiLink rakuPodType           Type
1944    HiLink rakuPodConfigOption   String
1945    HiLink rakuPodCode           PreProc
1946    HiLink rakuPod               Comment
1947    HiLink rakuPodComment        Comment
1948    HiLink rakuPodAutoQuote      Operator
1949    HiLink rakuPodConfigOperator Operator
1950    HiLink rakuPodPrefix         Statement
1951    HiLink rakuPodName           Identifier
1952    HiLink rakuPodFormatCode     SpecialChar
1953    HiLink rakuPodFormat         SpecialComment
1954
1955    delcommand HiLink
1956endif
1957
1958if exists("raku_fold") || exists("raku_extended_all")
1959    setl foldmethod=syntax
1960    syn region rakuBlockFold
1961        \ start="^\z(\s*\)\%(my\|our\|augment\|multi\|proto\|only\)\?\s*\%(\%([A-Za-z_\xC0-\xFF]\%([A-Za-z_\xC0-\xFF0-9]\|[-'][A-Za-z_\xC0-\xFF]\@=\)*\)\s\+\)\?\<\%(CATCH\|try\|ENTER\|LEAVE\|CHECK\|INIT\|BEGIN\|END\|KEEP\|UNDO\|PRE\|POST\|module\|package\|enum\|subset\|class\|sub\%(method\)\?\|multi\|method\|slang\|grammar\|regex\|token\|rule\)\>[^{]\+\%({\s*\%(#.*\)\?\)\?$"
1962        \ end="^\z1}"
1963        \ transparent fold keepend extend
1964endif
1965
1966let b:current_syntax = "raku"
1967
1968let &cpo = s:keepcpo
1969unlet s:keepcpo
1970
1971" vim:ts=8:sts=4:sw=4:expandtab:ft=vim
1972