Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Incorporating Hinrik's import of syntax/perl6.vim from the pugs repo

  • Loading branch information...
commit 0833e6dcbb251ad90b0ce815c1601b5366bda38d 1 parent b489b30
@petdance petdance authored
Showing with 2,222 additions and 243 deletions.
  1. +2,222 −243 syntax/perl6.vim
View
2,465 syntax/perl6.vim
@@ -1,270 +1,2249 @@
" Vim syntax file
" Language: Perl 6
" Maintainer: Andy Lester <andy@petdance.com>
-" Last Change: ???? ?? ??
+" Homepage: http://github.com/petdance/vim-perl/tree/master
+" Last Change: 2009-07-04
+
+" Contributors: Luke Palmer <fibonaci@babylonia.flatirons.org>
+" Moritz Lenz <moritz@faui2k3.org>
+" Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>
+"
+" This is a big undertaking. Perl 6 is the sort of language that only Perl
+" can parse. But I'll do my best to get vim to.
+"
+" You can associate the extension ".pl" with the filetype "perl6" by setting
+" autocmd BufNewFile,BufRead *.pl setf perl6
+" in your ~/.vimrc. But that will infringe on Perl 5, so you might want to
+" put a modeline near the beginning or end of your Perl 6 files instead:
+" # vim: filetype=perl6
+
+" TODO:
+" * Deal with s:Perl5//
+" * m:s// is a match, not a substitution
+" * Make these highlight as strings, not operators:
+" <==> <=:=> <===> <=~> <« »> «>» «<»
+" * Allow more keywords to match as function calls(leave() is export(), etc)
+" * Optimization: use nextgroup instead of lookaround (:help syn-nextgroup)
+" * Fix s''' substitutions being matched as package names
+" * Match s/// and m/// better, so things like "$s/" won't match
+" * Add more support for folding (:help syn-fold)
+" * Add more syntax syncing hooks (:help syn-sync)
+" * Q//:
+" :to, :heredoc
+" interpolate \q:s{$scalar} (though the spec isn't very clear on it)
+"
+" Impossible TODO?:
+" * Unspace
+" * Unicode bracketing characters for quoting (there are so many)
+" * Various tricks depending on context. I.e. we can't know when Perl
+" expects «*» to be a string or a hyperoperator. The latter is presumably
+" more common, so that's what we assume.
+" * Selective highlighting of Pod formatting codes with the :allow option
+" * Arbitrary number, order, and negation of adverbs to Q//, q//, qq//.
+" Currently only the first adverb is considered significant. Anything
+" more would require an exponential amount of regexes, making this
+" already slow syntax file even slower.
+"
+" If you want to have Pir code inside Q:PIR// strings highlighted, do:
+" let perl6_embedded_pir=1
+"
+" The above requires pir.vim, which you can find in Parrot's repository:
+" https://svn.parrot.org/parrot/trunk/editor/
+"
+" Some less than crucial things have been made optional to speed things up.
+" Look at the comments near the if/else branches in this file to see exactly
+" which features are affected. "perl6_extended_all" enables everything.
"
-" TODO
-" * syntax for reading from stdin: =<> or from arbitrary file handles:
-" =<$fh>
-" * List initialization via the @a = <foo bar> construct brakes when there
-" is a newline between '<' and '>'
-" * The regex regex_name { ... } syntax for regexes/tokens seems to be
-" unsupported
+" The defaults are:
"
-" perl6.vim was created by Luke Palmer who said "Perl 6 is the sort
-" of language that only Perl can parse. But I'll do my best to get
-" vim to."
+" unlet perl6_extended_comments
+" unlet perl6_extended_q
+" unlet perl6_extended_all
-" Avoid infinite loop in this file
-if exists('b:perl6_syntax_init')
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
finish
endif
-let b:perl6_syntax_init = 1
+
+" identifiers
+syn match p6Normal display "\K\%(\k\|[-']\K\@=\)*"
+
+" This is used in the for loops below
+" Don't use the "syn keyword" construct because that always has higher
+" priority than matches/regions, so the words can't be autoquoted with
+" the "=>" and "p5=>" operators. All the lookaround stuff is to make sure
+" we don't match them as part of some other identifier.
+let s:before_keyword = " display \"\\%(\\k\\|\\K\\@<=[-']\\)\\@<!\\%("
+let s:after_keyword = "\\)\\%(\\k\\|[-']\\K\\@=\\)\\@!\""
" Billions of keywords
-syn keyword p6Attn TODO XXX contained
+let s:keywords = {
+ \ "p6Attention": [
+ \ "ACHTUNG ATTN ATTENTION FIXME NB TODO TBD WTF XXX NOTE",
+ \ ],
+ \ "p6DeclareRoutine": [
+ \ "macro sub submethod method multi proto only rule token regex category",
+ \ ],
+ \ "p6Module": [
+ \ "module class role package enum grammar slang subset",
+ \ ],
+ \ "p6Variable": [
+ \ "self",
+ \ ],
+ \ "p6Include": [
+ \ "use require",
+ \ ],
+ \ "p6Conditional": [
+ \ "if else elsif unless",
+ \ ],
+ \ "p6VarStorage": [
+ \ "let my our state temp has constant",
+ \ ],
+ \ "p6Repeat": [
+ \ "for loop repeat while until gather given",
+ \ ],
+ \ "p6FlowControl": [
+ \ "take do when next last redo return contend maybe defer",
+ \ "default exit make continue break goto leave async lift",
+ \ ],
+ \ "p6TypeConstraint": [
+ \ "is as but trusts of returns handles where augment supersede",
+ \ ],
+ \ "p6ClosureTrait": [
+ \ "BEGIN CHECK INIT START FIRST ENTER LEAVE KEEP",
+ \ "UNDO NEXT LAST PRE POST END CATCH CONTROL TEMP",
+ \ ],
+ \ "p6Exception": [
+ \ "die fail try warn",
+ \ ],
+ \ "p6Property": [
+ \ "prec irs ofs ors export deep binary unary reparsed rw parsed cached",
+ \ "readonly defequiv will ref copy inline tighter looser equiv assoc",
+ \ "required",
+ \ ],
+ \ "p6Number": [
+ \ "NaN Inf",
+ \ ],
+ \ "p6Pragma": [
+ \ "oo fatal",
+ \ ],
+ \ "p6Type": [
+ \ "Object Any Junction Whatever Capture Match",
+ \ "Signature Proxy Matcher Package Module Class",
+ \ "Grammar Scalar Array Hash KeyHash KeySet KeyBag",
+ \ "Pair List Seq Range Set Bag Mapping Void Undef",
+ \ "Failure Exception Code Block Routine Sub Macro",
+ \ "Method Submethod Regex Str Blob Char Byte",
+ \ "Codepoint Grapheme StrPos StrLen Version Num",
+ \ "Complex num complex Bit bit bool True False",
+ \ "Increasing Decreasing Ordered Callable AnyChar",
+ \ "Positional Associative Ordering KeyExtractor",
+ \ "Comparator OrderingPair IO KitchenSink Role",
+ \ "Int int int1 int2 int4 int8 int16 int32 int64",
+ \ "Rat rat rat1 rat2 rat4 rat8 rat16 rat32 rat64",
+ \ "Buf buf buf1 buf2 buf4 buf8 buf16 buf32 buf64",
+ \ "UInt uint uint1 uint2 uint4 uint8 uint16 uint32",
+ \ "uint64 Abstraction utf8 utf16 utf32",
+ \ ],
+ \ "p6Operator": [
+ \ "div x xx mod also leg cmp before after eq ne le lt",
+ \ "gt ge eqv ff fff and andthen Z X or xor",
+ \ "orelse extra m mm rx s tr",
+ \ ],
+\ }
+
+for [group, words] in items(s:keywords)
+ let s:words_space = join(words, " ")
+ let s:temp = split(s:words_space)
+ let s:words = join(s:temp, "\\|")
+ exec "syn match ". group ." ". s:before_keyword . s:words . s:after_keyword
+endfor
+unlet s:keywords s:words_space s:temp s:words
+
+" More operators
+" Don't put a "\+" at the end of the character class. That makes it so
+" greedy that the "%" " in "+%foo" won't be allowed to match as a sigil,
+" among other things
+syn match p6Operator display "[-+/*~?|=^!%&,<>.;\\]"
+syn match p6Operator display "\%(:\@<!::\@!\|::=\|\.::\)"
+" these require whitespace on the left side
+syn match p6Operator display "\%(\s\|^\)\@<=\%(xx=\|p5=>\)"
+" "i" requires a digit to the left, and no keyword char to the right
+syn match p6Operator display "\d\@<=i\k\@!"
+" index overloading
+syn match p6Operator display "\%(&\.(\@=\|@\.\[\@=\|%\.{\@=\)"
+
+" all infix operators except nonassocative ones
+let s:infix_a = [
+ \ "div % mod +& +< +> \\~& ?& \\~< \\~> +| +\\^ \\~| \\~\\^ ?| ?\\^ xx x",
+ \ "\\~ && & also <== ==> <<== ==>> == != < <= > >= \\~\\~ eq ne lt le gt",
+ \ "ge =:= === eqv before after \\^\\^ min max \\^ff ff\\^ \\^ff\\^",
+ \ "\\^fff fff\\^ \\^fff\\^ fff ff ::= := \\.= => , : p5=> Z minmax",
+ \ "\\.\\.\\. and andthen or orelse xor \\^ += -= /= \\*= \\~= //= ||=",
+ \ "+ - \\*\\* \\* // / \\~ || |",
+\ ]
+" nonassociative infix operators
+let s:infix_n = "but does <=> leg cmp \\.\\. \\.\\.\\^\\^ \\^\\.\\. \\^\\.\\.\\^"
+
+let s:infix_a_long = join(s:infix_a, " ")
+let s:infix_a_words = split(s:infix_a_long)
+let s:infix_a_pattern = join(s:infix_a_words, "\\|")
+
+let s:infix_n_words = split(s:infix_n)
+let s:infix_n_pattern = join(s:infix_n_words, "\\|")
+
+let s:both = [s:infix_a_pattern, s:infix_n_pattern]
+let s:infix = join(s:both, "\\|")
+
+let s:infix_assoc = "!\\?\\%(" . s:infix_a_pattern . "\\)"
+let s:infix = "!\\?\\%(" . s:infix . "\\)"
+
+unlet s:infix_a s:infix_a_long s:infix_a_words s:infix_a_pattern
+unlet s:infix_n s:infix_n_pattern s:both
+
+" [+] reduce
+exec "syn match p6ReduceOp display \"\\k\\@<!\\[[R\\\\]\\?!\\?". s:infix_assoc ."]\\%(«\\|<<\\)\\?\""
+unlet s:infix_assoc
+
+" Reverse and cross operators (Rop, Xop)
+exec "syn match p6ReverseCrossOp display \"[RX]". s:infix ."\""
+
+" q() or whatever() is always a function call
+syn match p6Normal display "\K\%(\k\|[-']\K\@=\)*(\@="
+
+" basically all builtins that can be followed by parentheses
+let s:routines = [
+ \ "eager hyper substr index rindex grep map sort join lines hints chmod",
+ \ "split reduce min max reverse truncate zip cat roundrobin classify",
+ \ "first sum keys values pairs defined delete exists elems end kv any",
+ \ "all one wrap shape key value name pop push shift splice unshift floor",
+ \ "ceiling abs exp log log10 rand sign sqrt sin cos tan round strand",
+ \ "roots cis unpolar polar atan2 pick chop p5chop chomp p5chomp lc",
+ \ "lcfirst uc ucfirst capitalize normalize pack unpack quotemeta comb",
+ \ "samecase sameaccent chars nfd nfc nfkd nfkc printf sprintf caller",
+ \ "evalfile run runinstead nothing want bless chr ord gmtime time eof",
+ \ "localtime gethost getpw chroot getlogin getpeername kill fork wait",
+ \ "perl graphs codes bytes clone print open read write readline say seek",
+ \ "close opendir readdir slurp pos fmt vec link unlink symlink uniq pair",
+ \ "asin atan sec cosec cotan asec acosec acotan sinh cosh tanh asinh",
+ \ "acos acosh atanh sech cosech cotanh sech acosech acotanh asech ok",
+ \ "plan_ok dies_ok lives_ok skip todo pass flunk force_todo use_ok isa_ok",
+ \ "diag is_deeply isnt like skip_rest unlike cmp_ok eval_dies_ok nok_error",
+ \ "eval_lives_ok approx is_approx throws_ok version_lt plan eval succ pred",
+ \ "times nonce once signature new connect operator undef undefine sleep",
+ \ "from to infix postfix prefix circumfix postcircumfix minmax lazy count",
+ \ "unwrap getc pi e context void quasi body each contains rewinddir subst",
+ \ "can isa flush arity assuming rewind callwith callsame nextwith nextsame",
+ \ "attr eval_elsewhere none srand trim trim_start trim_end lastcall WHAT",
+ \ "WHERE HOW WHICH VAR WHO WHENCE ACCEPTS REJECTS does not true iterator by",
+ \ "re im invert flip",
+\ ]
+
+" we want to highlight builtins like split() though, so this comes afterwards
+" TODO: check if this would be faster as one big regex
+let s:words_space = join(s:routines, " ")
+let s:temp = split(s:words_space)
+let s:words = join(s:temp, "\\|")
+exec "syn match p6Routine ". s:before_keyword . s:words . s:after_keyword
+unlet s:before_keyword s:after_keyword s:words_space s:temp s:words s:routines
+
+" packages, must come after all the keywords
+syn match p6Normal display "\%(::\)\@<=\K\%(\k\|[-']\K\@=\)*"
+syn match p6Normal display "\K\%(\k\|[-']\K\@=\)*\%(::\)\@="
+
+" some standard packages
+syn match p6Type display "\%(::\|\k\|\K\@<=[-']\)\@<!\%(Order\%(::Same\|::Increase\|::Decrease\)\?\)\%(\k\|[-']\K\@=\)\@!"
+syn match p6Type display "\%(::\|\k\|\K\@<=[-']\)\@<!\%(Bool\%(::True\|::False\)\?\)\%(\k\|[-']\K\@=\)\@!"
+
+
+syn match p6Shebang display "\%^#!.*"
+syn match p6BlockLabel display "\%(^\s*\)\@<=\h\w*\s*::\@!\_s\@="
+syn match p6Number display "\k\@<!_\@!\%(\d\|__\@!\)\+_\@<!\%([eE]_\@!+\?\%(\d\|_\)\+\)\?_\@<!"
+syn match p6Float display "\k\@<!_\@!\%(\d\|__\@!\)\+_\@<![eE]_\@!-\%(\d\|_\)\+"
+syn match p6Float display "\k\@<!_\@<!\%(\d\|__\@!\)*_\@<!\.\@<!\._\@!\.\@!\a\@!\%(\d\|_\)\+_\@<!\%([eE]_\@!\%(\d\|_\)\+\)\?"
+
+syn match p6NumberBase display "[obxd]" contained
+syn match p6Number display "\<0\%(o[0-7][0-7_]*\)\@=" nextgroup=p6NumberBase
+syn match p6Number display "\<0\%(b[01][01_]*\)\@=" nextgroup=p6NumberBase
+syn match p6Number display "\<0\%(x\x[[:xdigit:]_]*\)\@=" nextgroup=p6NumberBase
+syn match p6Number display "\<0\%(d\d[[:digit:]_]*\)\@=" nextgroup=p6NumberBase
+syn match p6Number display "\%(\<0o\)\@<=[0-7][0-7_]*"
+syn match p6Number display "\%(\<0b\)\@<=[01][01_]*"
+syn match p6Number display "\%(\<0x\)\@<=\x[[:xdigit:]_]*"
+syn match p6Number display "\%(\<0d\)\@<=\d[[:digit:]_]*"
+
+syn match p6Version display "\<v\d\@=" nextgroup=p6VersionNum
+syn match p6VersionNum display "\d\+" nextgroup=p6VersionDot contained
+syn match p6VersionDot display "\.\%(\d\|\*\)\@=" nextgroup=p6VersionNum contained
+
+" try to distinguish the "is" function from the "is" trail auxiliary
+syn match p6Routine display "\%(\%(\S\k\@<!\|^\)\s*\)\@<=is\>"
+
+" does is a type constraint sometimes
+syn match p6TypeConstraint display "does\%(\s*\%(\k\|[-']\K\@=\)\)\@="
+
+" int is a type sometimes
+syn match p6Type display "\<int\>\%(\s*(\|\s\+\d\)\@!"
+
+" these Routine names are also Properties, if preceded by "is"
+syn match p6Property display "\%(is\s\+\)\@<=\%(signature\|context\|also\|shape\)"
+
+" The sigil in ::*Package
+syn match p6PackageTwigil display "\%(::\)\@<=\*"
+
+" $<match>
+syn region p6MatchVarSigil
+ \ matchgroup=p6Variable
+ \ start="\$\%(<<\@!\)\@="
+ \ end=">\@<="
+ \ contains=p6MatchVar
+
+syn region p6MatchVar
+ \ matchgroup=p6Twigil
+ \ start="<"
+ \ end=">"
+ \ contained
+
+" Contextualizers
+syn match p6Context display "\<\%(item\|list\|slice\|hash\)\>"
+syn match p6Context display "\%(\$\|@\|%\|&\|@@\)(\@="
+
+" the "$" placeholder in "$var1, $, var2 = @list"
+syn match p6Placeholder display "\%(,\s*\)\@<=\$\%(\K\|\%([.^*?=!~]\|:\@<!::\@!\)\)\@!"
+syn match p6Placeholder display "\$\%(\K\|\%([.^*?=!~]\|:\@<!::\@!\)\)\@!\%(,\s*\)\@="
+
+" Quoting
+
+" one cluster for every quote adverb
+syn cluster p6Interp_s
+ \ add=p6InterpScalar
+syn cluster p6Interp_scalar
+ \ add=p6InterpScalar
+
+syn cluster p6Interp_a
+ \ add=p6InterpArray
+syn cluster p6Interp_array
+ \ add=p6InterpArray
+
+syn cluster p6Interp_h
+ \ add=p6InterpHash
+syn cluster p6Interp_hash
+ \ add=p6InterpHash
+
+syn cluster p6Interp_f
+ \ add=p6InterpFunction
+syn cluster p6Interp_f
+ \ add=p6InterpFunction
+
+syn cluster p6Interp_c
+ \ add=p6InterpClosure
+syn cluster p6Interp_closure
+ \ add=p6InterpClosure
+
+
+if exists("perl6_extended_q") || exists("perl6_extended_all")
+ syn cluster p6Interp_ww
+ \ add=p6StringSQ
+ \ add=p6StringDQ
+ syn cluster p6Interp_quotewords
+ \ add=p6StringSQ
+ \ add=p6StringDQ
+endif
+
+syn cluster p6Interp_q
+ \ add=p6EscQQ
+ \ add=p6EscBackSlash
+syn cluster p6Interp_single
+ \ add=p6EscQQ
+ \ add=p6EscBackSlash
+
+syn cluster p6Interp_b
+ \ add=@p6Interp_q
+ \ add=p6Escape
+ \ add=p6EscOpenCurly
+ \ add=p6EscCodePoint
+ \ add=p6EscHex
+ \ add=p6EscOct
+ \ add=p6EscOctOld
+ \ add=p6EscNull
+syn cluster p6Interp_backslash
+ \ add=@p6Interp_q
+ \ add=p6Escape
+ \ add=p6EscOpenCurly
+ \ add=p6EscCodePoint
+ \ add=p6EscHex
+ \ add=p6EscOct
+ \ add=p6EscOctOld
+ \ add=p6EscNull
+
+syn cluster p6Interp_qq
+ \ add=@p6Interp_scalar
+ \ add=@p6Interp_array
+ \ add=@p6Interp_hash
+ \ add=@p6Interp_function
+ \ add=@p6Interp_closure
+ \ add=@p6Interp_backslash
+syn cluster p6Interp_double
+ \ add=@p6Interp_scalar
+ \ add=@p6Interp_array
+ \ add=@p6Interp_hash
+ \ add=@p6Interp_function
+ \ add=@p6Interp_closure
+ \ add=@p6Interp_backslash
+
+syn region p6InterpScalar
+ \ start="\ze\z(\$\%(\%(\%(\d\+\|!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\@=\)\?\K\%(\k\|[-']\K\@=\)*\)\%(\.\%(\K\%(\k\|[-']\K\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
+ \ start="\ze\z(\$\%(\%(\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\@=\)\?\K\%(\k\|[-']\K\@=\)*\)\|\%(\d\+\|!\|/\|¢\)\)\)"
+ \ end="\z1\zs"
+ \ contained
+ \ contains=TOP
+ \ keepend
+
+syn region p6InterpScalar
+ \ matchgroup=p6Context
+ \ start="\$\ze()\@!"
+ \ skip="([^)]*)"
+ \ end=")\zs"
+ \ contained
+ \ contains=TOP
+
+syn region p6InterpArray
+ \ start="\ze\z(@\$*\%(\%(\%(!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\@=\)\?\K\%(\k\|[-']\K\@=\)*\)\%(\.\%(\K\%(\k\|[-']\K\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
+ \ end="\z1\zs"
+ \ contained
+ \ contains=TOP
+ \ keepend
+
+syn region p6InterpArray
+ \ matchgroup=p6Context
+ \ start="@\ze()\@!"
+ \ start="@@\ze()\@!"
+ \ skip="([^)]*)"
+ \ end=")\zs"
+ \ contained
+ \ contains=TOP
+
+syn region p6InterpHash
+ \ start="\ze\z(%\$*\%(\%(\%(!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\@=\)\?\K\%(\k\|[-']\K\@=\)*\)\%(\.\%(\K\%(\k\|[-']\K\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
+ \ end="\z1\zs"
+ \ contained
+ \ contains=TOP
+ \ keepend
+
+syn region p6InterpHash
+ \ matchgroup=p6Context
+ \ start="%\ze()\@!"
+ \ skip="([^)]*)"
+ \ end=")\zs"
+ \ contained
+ \ contains=TOP
+
+syn region p6InterpFunction
+ \ start="\ze\z(&\%(\%(!\|/\|¢\)\|\%(\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\@=\)\?\K\%(\k\|[-']\K\@=\)*\%(\.\%(\K\%(\k\|[-']\K\@=\)*\)\|\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)*\)\.\?\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\)\)"
+ \ end="\z1\zs"
+ \ contained
+ \ contains=TOP
+ \ keepend
+
+syn region p6InterpFunction
+ \ matchgroup=p6Context
+ \ start="&\ze()\@!"
+ \ skip="([^)]*)"
+ \ end=")\zs"
+ \ contained
+ \ contains=TOP
+
+syn region p6InterpClosure
+ \ start="\\\@<!{}\@!"
+ \ skip="{[^}]*}"
+ \ end="}"
+ \ contained
+ \ contains=TOP
+ \ keepend
+
+" generic escape
+syn match p6Escape display "\\\S" contained
+
+" escaped closing delimiters
+syn match p6EscQuote display "\\'" contained
+syn match p6EscDoubleQuote display "\\\"" contained
+syn match p6EscCloseAngle display "\\>" contained
+syn match p6EscCloseFrench display "\\»" contained
+syn match p6EscBackTick display "\\`" contained
+syn match p6EscForwardSlash display "\\/" contained
+syn match p6EscVerticalBar display "\\|" contained
+syn match p6EscExclamation display "\\!" contained
+syn match p6EscComma display "\\," contained
+syn match p6EscDollar display "\\\$" contained
+syn match p6EscCloseCurly display "\\}" contained
+syn match p6EscCloseBracket display "\\\]" contained
+
+" misc escapes
+syn match p6EscOctOld display "\\\d\{1,3}" contained
+syn match p6EscNull display "\\0\d\@!" contained
+syn match p6EscCodePoint display "\%(\\c\)\@<=\%(\d\|\S\|\[\)\@=" contained nextgroup=p6CodePoint
+syn match p6EscHex display "\%(\\x\)\@<=\%(\x\|\[\)\@=" contained nextgroup=p6HexSequence
+syn match p6EscOct display "\%(\\o\)\@<=\%(\o\|\[\)\@=" contained nextgroup=p6OctSequence
+syn match p6EscQQ display "\\qq" contained nextgroup=p6QQSequence
+syn match p6EscOpenCurly display "\\{" contained
+syn match p6EscHash display "\\#" contained
+syn match p6EscBackSlash display "\\\\" contained
+
+syn region p6QQSequence
+ \ matchgroup=p6Escape
+ \ start="\["
+ \ skip="\[[^\]]*]"
+ \ end="]"
+ \ contained
+ \ transparent
+ \ contains=@p6Interp_qq
+
+syn match p6CodePoint display "\%(\d\+\|\S\)" contained
+syn region p6CodePoint
+ \ matchgroup=p6Escape
+ \ start="\["
+ \ end="]"
+ \ contained
+
+syn match p6HexSequence display "\x\+" contained
+syn region p6HexSequence
+ \ matchgroup=p6Escape
+ \ start="\["
+ \ end="]"
+ \ contained
+
+syn match p6OctSequence display "\o\+" contained
+syn region p6OctSequence
+ \ matchgroup=p6Escape
+ \ start="\["
+ \ end="]"
+ \ contained
+
+" matches :key, :!key, :$var, :key<var>, etc
+" Since we don't know in advance how the adverb ends, we use a trick.
+" Consume nothing with the start pattern (\ze at the beginning),
+" while capturing the whole adverb into \z1 and then putting it before
+" the match start (\zs) of the end pattern.
+syn region p6Adverb
+ \ start="\ze\z(:!\?\K\%(\k\|[-']\K\@=\)*\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\?\)"
+ \ start="\ze\z(:!\?[@$%]\$*\%(::\|\%(\$\@<=\d\+\|!\|/\|¢\)\|\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\)\|\%(\K\%(\k\|[-']\K\@=\)*\)\)\)"
+ \ end="\z1\zs"
+ \ contained
+ \ contains=TOP
+ \ keepend
+
+" <words>
+" FIXME: not sure how to distinguish this from the "less than" operator
+" in all cases. For now, it matches if any of the following is true:
+"
+" * There is whitespace missing on either side of the "<", since
+" people tend to put spaces around "less than"
+" * It comes after "enum", "for", "any", "all", or "none"
+" * It's the first or last thing on a line (ignoring whitespace)
+" * It's preceded by "= "
+"
+" It never matches when:
+"
+" * Preceded by [<+~=] (e.g. <<foo>>, =<$foo>)
+" * Followed by [-=] (e.g. <--, <=, <==)
+syn region p6StringAngle
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(enum\|for\|any\|all\|none\)\>\s*(\?\s*\)\@<=<\%(<\|=>\|[-=]\{1,2}>\@!\)\@!"
+ \ start="\%(\s\|[<+~=]\)\@<!<\%(<\|=>\|[-=]\{1,2}>\@!\)\@!"
+ \ start="[<+~=]\@<!<\%(\s\|<\|=>\|[-=]\{1,2}>\@!\)\@!"
+ \ start="\%(^\s*\)\@<=<\%(<\|=>\|[-=]\{1,2}>\@!\)\@!"
+ \ start="[<+~=]\@<!<\%(\s*$\)\@="
+ \ start="\%(=\s\+\)\@=<\%(<\|=>\|[-=]\{1,2}>\@!\)\@!"
+ \ skip="\\\@<!\\>"
+ \ end=">"
+ \ contains=p6InnerAnglesOne,p6EscBackSlash,p6EscCloseAngle
+
+syn region p6InnerAnglesOne
+ \ matchgroup=p6StringAngle
+ \ start="<"
+ \ skip="\\\@<!\\>"
+ \ end=">"
+ \ transparent
+ \ contained
+ \ contains=p6InnerAnglesOne
+
+" <<words>>
+syn region p6StringAngles
+ \ matchgroup=p6Quote
+ \ start="<<=\@!"
+ \ skip="\\\@<!\\>"
+ \ end=">>"
+ \ contains=p6InnerAnglesTwo,@p6Interp_qq,p6Comment,p6EscHash,p6EscCloseAngle,p6Adverb,p6StringSQ,p6StringDQ
+
+syn region p6InnerAnglesTwo
+ \ matchgroup=p6StringAngles
+ \ start="<<"
+ \ skip="\\\@<!\\>"
+ \ end=">>"
+ \ transparent
+ \ contained
+ \ contains=p6InnerAnglesTwo
+
+" «words»
+syn region p6StringFrench
+ \ matchgroup=p6Quote
+ \ start="«"
+ \ skip="\\\@<!\\»"
+ \ end="»"
+ \ contains=p6InnerFrench,@p6Interp_qq,p6Comment,p6EscHash,p6EscCloseFrench,p6Adverb,p6StringSQ,p6StringDQ
+
+syn region p6InnerFrench
+ \ matchgroup=p6StringFrench
+ \ start="«"
+ \ skip="\\\@<!\\»"
+ \ end="»"
+ \ transparent
+ \ contained
+ \ contains=p6InnerFrench
+
+" 'string'
+syn region p6StringSQ
+ \ matchgroup=p6Quote
+ \ start="'"
+ \ skip="\\\@<!\\'"
+ \ end="'"
+ \ contains=@p6Interp_q,p6EscQuote
+
+" "string"
+syn region p6StringDQ
+ \ matchgroup=p6Quote
+ \ start=+"+
+ \ skip=+\\\@<!\\"+
+ \ end=+"+
+ \ contains=@p6Interp_qq,p6EscDoubleQuote
+
+" Q// and friends.
+
+syn match p6QuoteQ display "\%([Qq]\%(ww\|to\|[qwxsahfcb]\)\?\)\>" nextgroup=p6QPairs skipwhite skipempty
+syn match p6QPairs contained transparent skipwhite skipempty nextgroup=p6StringQ,p6StringQ_PIR "\%(\_s*:!\?\K\%(\k\|[-']\K\@=\)*\%(([^)]*)\|\[[^\]]*]\|<[^>]*>\|«[^»]*»\|{[^}]*}\)\?\)*"
+
+if exists("perl6_embedded_pir")
+ syn include @p6PIR syntax/pir.vim
+endif
+
+" hardcoded set of delimiters
+let s:delims = [
+ \ ["\\\"", "\\\"", "p6EscDoubleQuote", "\\\\\\@<!\\\\\\\""],
+ \ ["'", "'", "p6EscQuote", "\\\\\\@<!\\\\'"],
+ \ ["/", "/", "p6EscForwardSlash", "\\\\\\@<!\\\\/"],
+ \ ["`", "`", "p6EscBackTick", "\\\\\\@<!\\\\`"],
+ \ ["|", "|", "p6EscVerticalBar", "\\\\\\@<!\\\\|"],
+ \ ["!", "!", "p6EscExclamation", "\\\\\\@<!\\\\!"],
+ \ [",", ",", "p6EscComma", "\\\\\\@<!\\\\,"],
+ \ ["\\$", "\\$", "p6EscDollar", "\\\\\\@<!\\\\\\$"],
+ \ ["{", "}", "p6EscCloseCurly", "\\%(\\\\\\@<!\\\\}\\|{[^}]*}\\)"],
+ \ ["<", ">", "p6EscCloseAngle", "\\%(\\\\\\@<!\\\\>\\|<[^>]*>\\)"],
+ \ ["«", "»", "p6EscCloseFrench", "\\%(\\\\\\@<!\\\\»\\|«[^»]*»\\)"],
+ \ ["\\\[", "]", "p6EscCloseBracket", "\\%(\\\\\\@<!\\\\]\\|\\[^\\]]*]\\)"],
+ \ ["\\s\\@<=(", ")", "p6EscCloseParen", "\\%(\\\\\\@<!\\\\)\\|([^)]*)\\)"],
+\ ]
+
+" double and triple delimiters too
+if exists("perl6_extended_q") || exists("perl6_extended_all")
+ call add(s:delims, ["««", "»»", "p6EscCloseFrench", "\\%(\\\\\\@<!\\\\»»\\|««\\%([^»]\\|»»\\@!\\)*»»\\)"])
+ call add(s:delims, ["«««", "»»»", "p6EscCloseFrench", "\\%(\\\\\\@<!\\\\»»»\\|«««\\%([^»]\\|»\\%(»»\\)\\@!\\)*»»»\\)"])
+ call add(s:delims, ["{{", "}}", "p6EscCloseCurly", "\\%(\\\\\\@<!\\\\}}\\|{{\\%([^}]\\|}}\\@!\\)*}}\\)"])
+ call add(s:delims, ["{{{", "}}}", "p6EscCloseCurly", "\\%(\\\\\\@<!\\\\}}}\\|{{{\\%([^}]\\|}\\%(}}\\)\\@!\\)*}}}\\)"])
+ call add(s:delims, ["\\\[\\\[", "]]", "p6EscCloseBracket", "\\%(\\\\\\@<!\\\\]]\\|\\[\\[\\%([^\\]]\\|]]\\@!\\)*]]\\)"])
+ call add(s:delims, ["\\\[\\\[\\\[", "]]]", "p6EscCloseBracket", "\\%(\\\\\\@<!\\\\]]]\\|\\[\\[\\[\\%([^\\]]\\|]\\%(]]\\)\\@!\\)*]]]\\)"])
+ call add(s:delims, ["\\s\\@<=((", "))", "p6EscCloseParen", "\\%(\\\\\\@<!\\\\))\\|((\\%([^)]\\|))\\@!\\)*))\\)"])
+ call add(s:delims, ["\\s\\@<=(((", ")))", "p6EscCloseParen", "\\%(\\\\\\@<!\\\\)))\\|(((\\%([^)]\\|)\\%())\\)\\@!\\)*)))\\)"])
+ call add(s:delims, ["\\s\\@<=<<", ">>", "p6EscCloseAngle", "\\%(\\\\\\@<!\\\\>>\\|<<\\%([^>]\\|>>\\@!\\)*>>\\)"])
+ call add(s:delims, ["\\s\\@<=<<<", ">>>", "p6EscCloseAngle", "\\%(\\\\\\@<!\\\\>>>\\|<<<\\%([^>]\\|>\\%(>>\\)\\@!\\)*>>>\\)"])
+endif
+
+if !exists("perl6_extended_q") && !exists("perl6_extended_all")
+ " simple version, no special highlighting within the string
+ for [start_delim, end_delim, end_group, skip] in s:delims
+ exec "syn region p6StringQ matchgroup=p6Quote start=\"".start_delim."\" skip=\"".skip."\" end=\"".end_delim."\" contains=".end_group." contained"
+ endfor
+
+ if exists("perl6_embedded_pir")
+ " highlight embedded PIR code
+ for [start_delim, end_delim, end_group, skip] in s:delims
+ exec "syn region p6StringQ_PIR matchgroup=p6Quote start=\"\\%(Q\\s*:PIR\\s*\\)\\@<=".start_delim."\" skip=\"".skip."\" end=\"".end_delim."\" contains=@p6PIR,".end_group." contained"
+ endfor
+ endif
+else
+ let s:before = "syn region p6StringQ matchgroup=p6Quote start=\"\\%("
+ let s:after = "\\%(\\_s*:!\\?\\K\\%(\\k\\|[-']\\K\\@=\\)*\\%(([^)]*)\\|\\[[^\\]]*]\\|<[^>]*>\\|«[^»]*»\\|{[^}]*}\\)\\?\\)*\\_s*\\)\\@<="
+
+ let s:adverbs = [
+ \ ["s", "scalar"],
+ \ ["a", "array"],
+ \ ["h", "hash"],
+ \ ["f", "function"],
+ \ ["c", "closure"],
+ \ ["b", "backslash"],
+ \ ["w", "words"],
+ \ ["ww", "quotewords"],
+ \ ["x", "exec"],
+ \ ]
+
+ " these can't be conjoined with q and qq (e.g. as qqq and qqqq)
+ let s:q_adverbs = [
+ \ ["q", "single"],
+ \ ["qq", "double"],
+ \ ]
+
+ for [start_delim, end_delim, end_group, skip] in s:delims
+ " Q, q, and qq with any number of (ignored) adverbs
+ exec s:before ."Q". s:after .start_delim."\" end=\"". end_delim ."\""." contained"
+ exec s:before ."q". s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_q"." contained"
+ exec s:before ."qq". s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_qq"." contained"
+
+ for [short, long] in s:adverbs
+ " Qs, qs, qqs, Qa, qa, qqa, etc, with ignored adverbs
+ exec s:before ."Q".short. s:after .start_delim ."\" end=\"". end_delim ."\" contains=@p6Interp_".long." contained"
+ exec s:before ."q".short. s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_q,@p6Interp_".long." contained"
+ exec s:before ."qq".short. s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_qq,@p6Interp_".long." contained"
+
+ " Q, q, and qq, with one significant adverb
+ exec s:before ."Q\\s*:\\%(".short."\\|".long."\\)". s:after .start_delim ."\" end=\"". end_delim ."\" contains=@p6Interp_".long." contained"
+ for [q_short, q_long] in s:q_adverbs
+ exec s:before ."Q\\s*:\\%(".q_short."\\|".q_long."\\)". s:after .start_delim ."\" end=\"". end_delim ."\" contains=@p6Interp_".q_long." contained"
+ endfor
+ exec s:before ."q\\s*:\\%(".short."\\|".long."\\)". s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_q,@p6Interp_".long." contained"
+ exec s:before ."qq\\s*:\\%(".short."\\|".long."\\)". s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_qq,@p6Interp_".long." contained"
+
+ for [short2, long2] in s:adverbs
+ " Qs, qs, qqs, Qa, qa, qqa, etc, with one significant adverb
+ exec s:before ."Q".short."\\s*:\\%(".short2."\\|".long2."\\)". s:after .start_delim ."\" end=\"". end_delim ."\" contains=@p6Interp_".long.",@p6Interp_".long2." contained"
+ for [q_short2, q_long2] in s:q_adverbs
+ exec s:before ."Q".short."\\s*:\\%(".q_short2."\\|".q_long2."\\)". s:after .start_delim ."\" end=\"". end_delim ."\" contains=@p6Interp_".long.",@p6Interp_".q_long2." contained"
+ endfor
+ exec s:before ."q".short."\\s*:\\%(".short2."\\|".long2."\\)". s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_q,@p6Interp_".long.",@p6Interp_".long2." contained"
+ exec s:before ."qq".short."\\s*:\\%(".short2."\\|".long2."\\)". s:after .start_delim ."\" skip=\"". skip ."\" end=\"". end_delim ."\" contains=". end_group .",@p6Interp_qq,@p6Interp_".long.",@p6Interp_".long2." contained"
+ endfor
+ endfor
+ endfor
+ unlet s:before s:after s:adverbs s:q_adverbs
+endif
+unlet s:delims
+
+" Match these so something else above can't. E.g. the "q" in "role q { }"
+" should not be considered a string
+syn match p6Normal display "\%(\<\%(role\|grammar\|slang\)\s\+\)\@<=\K\%(\k\|[-']\K\@=\)*"
+
+" :key
+syn match p6Operator display ":\@<!::\@!!\?" nextgroup=p6Key
+syn match p6Key display "\k\%(\k\|[-']\K\@=\)*" contained
+
+" => and p5=> autoquoting
+syn match p6StringP5Auto display "\K\%(\k\|[-']\K\@=\)*\ze\s\+p5=>"
+syn match p6StringAuto display "\K\%(\k\|[-']\K\@=\)*\ze\%(p5\)\@<!=>"
+syn match p6StringAuto display "\K\%(\k\|[-']\K\@=\)*\ze\s\+=>"
+syn match p6StringAuto display "\K\%(\k\|[-']\K\@=\)*p5\ze=>"
+
+" Hyperoperators. Needs to come after the quoting operators (<>, «», etc)
+exec "syn match p6HyperOp display \"»" .s:infix."»\\?\""
+exec "syn match p6HyperOp display \"«\\?".s:infix."«\""
+exec "syn match p6HyperOp display \"»" .s:infix."«\""
+exec "syn match p6HyperOp display \"«" .s:infix. "»\""
+
+exec "syn match p6HyperOp display \">>" .s:infix."\\%(>>\\)\\?\""
+exec "syn match p6HyperOp display \"\\%(<<\\)\\?".s:infix."<<\""
+exec "syn match p6HyperOp display \">>" .s:infix."<<\""
+exec "syn match p6HyperOp display \"<<" .s:infix.">>\""
+unlet s:infix
+
+" Regexes and grammars
+
+syn match p6RegexName display "\%(\<\%(regex\|rule\|token\)\s\+\)\@<=\K\%(\k\|[-']\K\@=\)*" nextgroup=p6RegexBlockCrap skipwhite skipempty
+syn match p6RegexBlockCrap "[^{]*" nextgroup=p6RegexBlock skipwhite skipempty transparent contained
+
+syn region p6RegexBlock
+ \ matchgroup=p6Normal
+ \ start="{"
+ \ end="}"
+ \ contained
+ \ contains=@p6Regexen,@p6Variables
+
+" Perl 6 regex bits
+
+syn cluster p6Regexen
+ \ add=p6RxMeta
+ \ add=p6RxEscape
+ \ add=p6EscHex
+ \ add=p6EscOct
+ \ add=p6EscNull
+ \ add=p6RxAnchor
+ \ add=p6RxCapture
+ \ add=p6RxGroup
+ \ add=p6RxAlternation
+ \ add=p6RxAdverb
+ \ add=p6RxAdverbArg
+ \ add=p6RxStorage
+ \ add=p6RxAssertion
+ \ add=p6RxQuoteWords
+ \ add=p6RxClosure
+ \ add=p6RxStringSQ
+ \ add=p6RxStringDQ
+ \ add=p6Comment
+
+syn match p6RxMeta display contained ".\%(\k\|\s\)\@<!"
+syn match p6RxAnchor display contained "[$^]"
+syn match p6RxEscape display contained "\\\S"
+syn match p6RxCapture display contained "[()]"
+syn match p6RxAlternation display contained "|"
+syn match p6RxRange display contained "\.\."
+
+syn region p6RxClosure
+ \ matchgroup=p6Normal
+ \ start="{"
+ \ end="}"
+ \ contained
+ \ containedin=p6RxClosure
+ \ contains=TOP
+syn region p6RxGroup
+ \ matchgroup=p6StringSpecial2
+ \ start="\["
+ \ end="]"
+ \ contained
+ \ contains=@p6Regexen,@p6Variables
+syn region p6RxAssertion
+ \ matchgroup=p6StringSpecial2
+ \ start="<"
+ \ end=">"
+ \ contained
+ \ contains=@p6Regexen,@p6Variables,p6RxCharClass,p6RxAssertCall
+syn region p6RxAssertCall
+ \ matchgroup=p6Normal
+ \ start="\%(::\|\%(\K\%(\k\|[-']\K\@=\)*\)\)\@<=(\@="
+ \ end=")\@<="
+ \ contained
+ \ contains=TOP
+syn region p6RxCharClass
+ \ matchgroup=p6StringSpecial2
+ \ start="\%(<[-!+]\?\)\@<=\["
+ \ skip="\\]"
+ \ end="]"
+ \ contained
+ \ contains=p6RxRange,p6RxEscape,p6EscHex,p6EscOct,p6EscNull
+syn region p6RxQuoteWords
+ \ matchgroup=p6StringSpecial2
+ \ start="< "
+ \ end=">"
+ \ contained
+syn region p6RxAdverb
+ \ start="\ze\z(:!\?\K\%(\k\|[-']\K\@=\)*\)"
+ \ end="\z1\zs"
+ \ contained
+ \ contains=TOP
+ \ keepend
+syn region p6RxAdverbArg
+ \ start="\%(:!\?\K\%(\k\|[-']\K\@=\)*\)\@<=("
+ \ skip="([^)]*)"
+ \ end=")"
+ \ contained
+ \ contains=TOP
+syn region p6RxStorage
+ \ matchgroup=p6Operator
+ \ start="\%(^\s*\)\@<=:\%(my\>\|temp\>\)\@="
+ \ end="$"
+ \ contains=TOP
+ \ contained
+
+" Perl 5 regex bits
+
+syn cluster p6RegexP5Base
+ \ add=p6RxP5Escape
+ \ add=p6RxP5Oct
+ \ add=p6RxP5Hex
+ \ add=p6RxP5EscMeta
+ \ add=p6RxP5CodePoint
+ \ add=p6RxP5Prop
+
+" normal regex stuff
+syn cluster p6RegexP5
+ \ add=@p6RegexP5Base
+ \ add=p6RxP5Quantifier
+ \ add=p6RxP5Meta
+ \ add=p6RxP5QuoteMeta
+ \ add=p6RxP5ParenMod
+ \ add=p6RxP5Verb
+ \ add=p6RxP5Count
+ \ add=p6RxP5Named
+ \ add=p6RxP5ReadRef
+ \ add=p6RxP5WriteRef
+ \ add=p6RxP5CharClass
+ \ add=p6RxP5Anchor
+
+" inside character classes
+syn cluster p6RegexP5Class
+ \ add=@p6RegexP5Base
+ \ add=p6RxP5Posix
+ \ add=p6RxP5Range
+
+syn match p6RxP5Escape display contained "\\\S"
+syn match p6RxP5CodePoint display contained "\\c\S\@=" nextgroup=p6RxP5CPId
+syn match p6RxP5CPId display contained "\S"
+syn match p6RxP5Oct display contained "\\\%(\o\{1,3}\)\@=" nextgroup=p6RxP5OctSeq
+syn match p6RxP5OctSeq display contained "\o\{1,3}"
+syn match p6RxP5Anchor display contained "[\^$]"
+syn match p6RxP5Hex display contained "\\x\%({\x\+}\|\x\{1,2}\)\@=" nextgroup=p6RxP5HexSeq
+syn match p6RxP5HexSeq display contained "\x\{1,2}"
+syn region p6RxP5HexSeq
+ \ matchgroup=p6RxP5Escape
+ \ start="{"
+ \ end="}"
+ \ contained
+syn region p6RxP5Named
+ \ matchgroup=p6RxP5Escape
+ \ start="\%(\\N\)\@<={"
+ \ end="}"
+ \ contained
+syn match p6RxP5Quantifier display contained "\%([+*]\|(\@<!?\)"
+syn match p6RxP5ReadRef display contained "\\[1-9]\d\@!"
+syn match p6RxP5ReadRef display contained "\\k<\@=" nextgroup=p6RxP5ReadRefId
+syn region p6RxP5ReadRefId
+ \ matchgroup=p6RxP5Escape
+ \ start="<"
+ \ end=">"
+ \ contained
+syn match p6RxP5WriteRef display contained "\\g\%(\d\|{\)\@=" nextgroup=p6RxP5WriteRefId
+syn match p6RxP5WriteRefId display contained "\d\+"
+syn region p6RxP5WriteRefId
+ \ matchgroup=p6RxP5Escape
+ \ start="{"
+ \ end="}"
+ \ contained
+syn match p6RxP5Prop display contained "\\[pP]\%(\a\|{\)\@=" nextgroup=p6RxP5PropId
+syn match p6RxP5PropId display contained "\a"
+syn region p6RxP5PropId
+ \ matchgroup=p6RxP5Escape
+ \ start="{"
+ \ end="}"
+ \ contained
+syn match p6RxP5Meta display contained "[(|).]"
+syn match p6RxP5ParenMod display contained "(\@<=?\@=" nextgroup=p6RxP5Mod,p6RxP5ModName,p6RxP5Code
+syn match p6RxP5Mod display contained "?\%(<\?=\|<\?!\|[#:|]\)"
+syn match p6RxP5Mod display contained "?-\?[impsx]\+"
+syn match p6RxP5Mod display contained "?\%([-+]\?\d\+\|R\)"
+syn match p6RxP5Mod display contained "?(DEFINE)"
+syn match p6RxP5Mod display contained "?\%(&\|P[>=]\)" nextgroup=p6RxP5ModDef
+syn match p6RxP5ModDef display contained "\h\w*"
+syn region p6RxP5ModName
+ \ matchgroup=p6StringSpecial
+ \ start="?'"
+ \ end="'"
+ \ contained
+syn region p6RxP5ModName
+ \ matchgroup=p6StringSpecial
+ \ start="?P\?<"
+ \ end=">"
+ \ contained
+syn region p6RxP5Code
+ \ matchgroup=p6StringSpecial
+ \ start="??\?{"
+ \ end="})\@="
+ \ contained
+ \ contains=TOP
+syn match p6RxP5EscMeta display contained "\\[?*.{}()[\]|\^$]"
+syn match p6RxP5Count display contained "\%({\d\+\%(,\%(\d\+\)\?\)\?}\)\@=" nextgroup=p6RxP5CountId
+syn region p6RxP5CountId
+ \ matchgroup=p6RxP5Escape
+ \ start="{"
+ \ end="}"
+ \ contained
+syn match p6RxP5Verb display contained "(\@<=\*\%(\%(PRUNE\|SKIP\|THEN\)\%(:[^)]*\)\?\|\%(MARK\|\):[^)]*\|COMMIT\|F\%(AIL\)\?\|ACCEPT\)"
+syn region p6RxP5QuoteMeta
+ \ matchgroup=p6RxP5Escape
+ \ start="\\Q"
+ \ end="\\E"
+ \ contained
+ \ contains=@p6Variables,p6EscBackSlash
+syn region p6RxP5CharClass
+ \ matchgroup=p6StringSpecial
+ \ start="\[\^\?"
+ \ skip="\\]"
+ \ end="]"
+ \ contained
+ \ contains=@p6RegexP5Class
+syn region p6RxP5Posix
+ \ matchgroup=p6RxP5Escape
+ \ start="\[:"
+ \ end=":]"
+ \ contained
+syn match p6RxP5Range display contained "-"
+
+" 'string' inside a regex
+syn region p6RxStringSQ
+ \ matchgroup=p6Quote
+ \ start="'"
+ \ skip="\\\@<!\\'"
+ \ end="'"
+ \ contained
+ \ contains=p6EscQuote,p6EscBackSlash
+
+" "string" inside a regex
+syn region p6RxStringDQ
+ \ matchgroup=p6Quote
+ \ start=+"+
+ \ skip=+\\\@<!\\"+
+ \ end=+"+
+ \ contained
+ \ contains=p6EscDoubleQuote,p6EscBackSlash
+
+" $!, $var, $!var, $::var, $package::var $*::package::var, etc
+" Thus must come after the matches for the "$" regex anchor, but before
+" the match for the $ regex delimiter
+syn cluster p6Variables
+ \ add=p6VarSlash
+ \ add=p6VarExclam
+ \ add=p6VarMatch
+ \ add=p6VarNum
+ \ add=p6Variable
+
+syn match p6VarSlash display "\$/"
+syn match p6VarExclam display "\$!"
+syn match p6VarMatch display "\$¢"
+syn match p6VarNum display "\$\d\+"
+syn match p6Variable display "\%(@@\|[@&$%]\$*\)\%(::\|\%(\%([.^*?=!~]\|:\@<!::\@!\)\K\)\|\K\)\@=" nextgroup=p6Twigil,p6VarName,p6PackageScope
+syn match p6VarName display "\K\%(\k\|[-']\K\@=\)*" contained
+syn match p6Twigil display "\%([.^*?=!~]\|:\@<!::\@!\)\K\@=" nextgroup=p6PackageScope,p6VarName contained
+syn match p6PackageScope display "\%(\K\%(\k\|[-']\K\@=\)*\)\?::" nextgroup=p6PackageScope,p6VarName contained
+
+" Perl 6 regex regions
+
+" /foo/
+" Below some hacks to recognise the // variant. This is virtually impossible
+" to catch in all cases as the / is used in so many other ways, but these
+" should be the most obvious ones.
+" TODO: mostly stolen from perl.vim, might need more work
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%([$@%&*]\@<!\%(\<\%(split\|while\|until\|if\|unless\)\|\.\.\|[-+*!~(\[{=]\)\s*\)\@<=//\@!"
+ \ start="^//\@!"
+ \ start=+\s\@<=/[^[:space:][:digit:]$@%=]\@=\%(/\_s*\%([([{$@%&*[:digit:]"'`]\|\_s\w\|[[:upper:]_abd-fhjklnqrt-wyz]\)\)\@!/\@!+
+ \ skip="\\/"
+ \ end="/"
+ \ contains=@p6Regexen,p6Variable,p6VarExclam,p6VarMatch,p6VarNum
+
+" m/foo/, mm/foo/, rx/foo/
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=//\@!"
+ \ skip="\\/"
+ \ end="/"
+ \ keepend
+ \ contains=@p6Regexen,p6Variable,p6VarExclam,p6VarMatch,p6VarNum
+
+" m!foo!, mm!foo!, rx!foo!
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=!!\@!"
+ \ skip="\\!"
+ \ end="!"
+ \ keepend
+ \ contains=@p6Regexen,p6Variable,p6VarSlash,p6VarMatch,p6VarNum
+
+" m$foo$, mm$foo$, rx$foo$, m|foo|, mm|foo|, rx|foo|, etc
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=\z([\"'`|,$]\)\$\@!"
+ \ skip="\\\z1"
+ \ end="\z1"
+ \ keepend
+ \ contains=@p6Regexen,@p6Variables
+
+" m (foo), mm (foo), rx (foo)
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s\+\)\@<=()\@!)\@!"
+ \ skip="\\)"
+ \ end=")"
+ \ contains=@p6Regexen,@p6Variables
+
+" m[foo], mm[foo], rx[foo]
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=\[]\@!]\@!"
+ \ skip="\\]"
+ \ end="]"
+ \ contains=@p6Regexen,@p6Variables
+
+" m{foo}, mm{foo}, rx{foo}
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<={}\@!}\@!"
+ \ skip="\\}"
+ \ end="}"
+ \ contains=@p6Regexen,@p6Variables
+
+" m<foo>, mm<foo>, rx<foo>
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=<>\@!>\@!"
+ \ skip="\\>"
+ \ end=">"
+ \ contains=@p6Regexen,@p6Variables
+
+" m«foo», mm«foo», rx«foo»
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<\%(mm\?\|rx\)\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=«»\@!»\@!"
+ \ skip="\\»"
+ \ end="»"
+ \ contains=@p6Regexen,@p6Variables
-syn keyword p6Module module class role use require package enum grammar
+" Substitutions
-syn keyword p6KeyDecl coro sub submethod method is but does trusts multi
-syn keyword p6KeyDecl rule token regex category
+" s/foo/bar/
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=/"
+ \ skip="\\/"
+ \ end="/"me=e-1
+ \ keepend
+ \ contains=@p6Regexen,p6Variable,p6VarExclam,p6VarMatch,p6VarNum
+ \ nextgroup=p6Substitution
-syn keyword p6KeyScopeDecl let my our state temp has constant proto
+syn region p6Substitution
+ \ matchgroup=p6Quote
+ \ start="/"
+ \ skip="\\/"
+ \ end="/"
+ \ contained
+ \ keepend
+ \ contains=@p6Interp_qq
-syn keyword p6KeyFlow if else elsif unless
-syn keyword p6KeyFlow for foreach loop while until when next last redo
-syn keyword p6KeyFlow given not or and err xor return default exit
+" s!foo!bar!
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=!"
+ \ skip="\\!"
+ \ end="!"me=e-1
+ \ keepend
+ \ contains=@p6Regexen,p6Variable,p6VarSlash,p6VarMatch,p6VarNum
+ \ nextgroup=p6Substitution
-syn keyword p6ClosureTrait BEGIN CHECK INIT START FIRST ENTER LEAVE KEEP UNDO NEXT LAST
-syn keyword p6ClosureTrait PRE POST END rw signature returns of parsed cached
-syn keyword p6ClosureTrait readonly ref copy
-syn keyword p6ClosureTrait inline tighter looser equiv assoc
+syn region p6Substitution
+ \ matchgroup=p6Quote
+ \ start="!"
+ \ skip="\\!"
+ \ end="!"
+ \ contained
+ \ keepend
+ \ contains=@p6Interp_qq
-syn keyword p6KeyException die fail try CATCH CONTROL warn
+" s$foo$bar$, s|foo|bar, etc
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=\z([\"'`|,$]\)"
+ \ skip="\\\z1"
+ \ end="\z1"me=e-1
+ \ keepend
+ \ contains=@p6Regexen,@p6Variables
+ \ nextgroup=p6Substitution
-syn keyword p6KeyIO print open read write readline say seek close slurp
-syn keyword p6KeyIO opendir readdir
+syn region p6Substitution
+ \ matchgroup=p6Quote
+ \ start="\z([\"'`|,$]\)"
+ \ skip="\\\z1"
+ \ end="\z1"
+ \ contained
+ \ keepend
+ \ contains=@p6Interp_qq
-syn keyword p6KeyProperty constant prec key value irs ofs ors pos export
-syn keyword p6KeyProperty float int str true false int1 int2 int4 int8
-syn keyword p6KeyProperty int16 int32 int64 uint1 uint2 uint4 uint8 uint16
-syn keyword p6KeyProperty uint32 uint64 num16 num32 num64 complex16 complex32
-syn keyword p6KeyProperty complex64 complex128 buf8 buf16 buf32 buf64
-syn keyword p6KeyProperty WHAT HOW
+" s{foo}
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<={}\@!"
+ \ skip="\\}"
+ \ end="}"
+ \ contains=@p6Regexen,@p6Variables
-syn keyword p6KeyType Array Bool Class Code Hash Int IO Num NumRange
-syn keyword p6KeyType Str StrRange Sub Role Rule Rat Complex Any
-syn keyword p6KeyType Scalar List
+" s[foo]
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=\[]\@!"
+ \ skip="\\]"
+ \ end="]"
+ \ contains=@p6Regexen,@p6Variables
-syn keyword p6KeyFunc substr index rindex
-syn keyword p6KeyFunc grep map sort
-syn keyword p6KeyFunc join split reduce min max reverse truncate zip
-syn keyword p6KeyFunc cat roundrobin classify first
-syn keyword p6KeyFunc keys values pairs defined delete exists elems end kv
-syn keyword p6KeyFunc arity assuming gather take any pick all none
-syn keyword p6KeyFunc pop push shift splice unshift
-syn keyword p6KeyFunc abs exp log log10 rand sign sqrt sin cos tan
-syn keyword p6KeyFunc floor ceiling round srand roots cis unpolar polar
-syn keyword p6KeyFunc p5chop chop p5chomp chomp lc lcfirst uc ucfirst
-syn keyword p6KeyFunc capitalize normalize pack unpack quotemeta comb
-syn keyword p6KeyFunc printf sprintf caller evalfile run runinstead
-syn keyword p6KeyFunc nothing want bless chr ord list item gmtime
-syn keyword p6KeyFunc localtime time gethost getpw chroot getlogin kill
-syn keyword p6KeyFunc fork wait perl context
+" s<foo>
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=<>\@!"
+ \ skip="\\>"
+ \ end=">"
+ \ contains=@p6Regexen,@p6Variables
-syn keyword p6KeySpecial eval operator undef undefine
-syn keyword p6KeySpecial infix postfix prefix cirumfix postcircumfix
+" s«foo»
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=«»\@!"
+ \ skip="\\»"
+ \ end="»"
+ \ contains=@p6Regexen,@p6Variables
-syn keyword p6KeyCompare eq ne lt le gt ge cmp == != < <= > >=
+" s (foo)
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<s\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s\+\)\@<=()\@!"
+ \ skip="\\)"
+ \ end=")"
+ \ contains=@p6Regexen,@p6Variables
-syn match p6Normal "\w*::\w\+"
+" Perl 5 regex regions
+
+" m:P5//
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<=/"
+ \ skip="\\/"
+ \ end="/"
+ \ contains=@p6RegexP5,p6Variable,p6VarExclam,p6VarMatch,p6VarNum
+
+" m:P5!!
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<=!"
+ \ skip="\\!"
+ \ end="!"
+ \ contains=@p6RegexP5,p6Variable,p6VarSlash,p6VarMatch,p6VarNum
+
+" m:P5$$, m:P5||, etc
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<=\z([\"'`|,$]\)"
+ \ skip="\\\z1"
+ \ end="\z1"
+ \ contains=@p6RegexP5,@p6Variables
+
+" m:P5 ()
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s\+\)\@<=()\@!"
+ \ skip="\\)"
+ \ end=")"
+ \ contains=@p6RegexP5,@p6Variables
+
+" m:P5[]
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<=[]\@!"
+ \ skip="\\]"
+ \ end="]"
+ \ contains=@p6RegexP5,@p6Variables
+
+" m:P5{}
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<={}\@!"
+ \ skip="\\}"
+ \ end="}"
+ \ contains=@p6RegexP5,p6Variables
+
+" m:P5<>
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<=<>\@!"
+ \ skip="\\>"
+ \ end=">"
+ \ contains=@p6RegexP5,p6Variables
+
+" m:P5«»
+syn region p6Match
+ \ matchgroup=p6Quote
+ \ start="\%(\<m\s*:P\%(erl\)\?5\s*\)\@<=«»\@!"
+ \ skip="\\»"
+ \ end="»"
+ \ contains=@p6RegexP5,p6Variables
+
+" Transliteration
+
+" tr/foo/bar/, tr|foo|bar, etc
+syn region p6String
+ \ matchgroup=p6Quote
+ \ start="\%(\<tr\%(\s*:!\?\k\%(\k\|[-']\K\@=\)*\%(([^)]*)\)\?\)*\s*\)\@<=\z([/\"'`|!,$]\)"
+ \ skip="\\\z1"
+ \ end="\z1"me=e-1
+ \ contains=p6RxRange
+ \ nextgroup=p6Transliteration
+
+syn region p6Transliteration
+ \ matchgroup=p6Quote
+ \ start="\z([/\"'`|!,$]\)"
+ \ skip="\\\z1"
+ \ end="\z1"
+ \ contained
+ \ contains=@p6Interp_qq
" Comments
-syn match p6Comment "#.*" contains=p6Attn
-syn region p6CommentMline start="^=begin \z([a-zA-Z0-9_]\+\)\>" end="^=end \z1\>" contains=p6Attn
-syn region p6CommentPara start="^=for [a-zA-Z0-9_]\+\>" end="^$" contains=p6Attn
-syn match p6Shebang "^#!.*"
-
-" POD
-" syn region p6POD start="^=\(cut\)\@!\w\+.\+$" end="^=cut" contains=p6Attn,p6PODVerbatim,p6PODHead,p6PODHeadKwid,p6PODSec,p6PODSecKwid
-
-syn match p6PODVerbatim "^\s.*" contained
-syn match p6PODHeadKwid "^=\{1,2\} " nextgroup=p6PODTitle contained
-syn match p6PODHead "^=head[12]" nextgroup=p6PODTitle contained
-syn match p6PODTitle ".*$" contained
-syn match p6PODSec "^=head[34]" nextgroup=p6PODSecTitle contained
-syn match p6PODSecKwid "^=\{3,4\} " nextgroup=p6PODSecTitle contained
-syn match p6PODSecTitle ".*$" contained
-
-" Variables, arrays, and hashes with ordinary \w+ names
-syn match p6KeyType "¢[:\.*^?]\?[a-zA-Z_]\w*"
-syn match p6VarPlain "\(::?\|[$@%][\!\.*^?]\?\)[a-zA-Z_]\w*"
-syn match p6VarException "\$![a-zA-Z]\@!"
-syn match p6VarCapt "\$[0-9\/]"
-syn match p6VarPunct "\$\d\+"
-syn match p6Invoke "\(&\|[.:]/\)[a-zA-Z_]\w*"
-
-syn cluster p6Interp contains=p6VarPlain,p6InterpExpression,p6VarPunct,p6VarException,p6InterpClosure
-
-" { ... } construct
-syn region p6InterpExpression contained matchgroup=p6Variable start=+{+ skip=+\\}+ end=+}+ contains=TOP
-
-" FIXME: This ugly hack will show up later on. Once again, don't try to fix it.
-syn region p6ParenExpression start="\(<\s*\)\@<!(" end=")" transparent
-syn region p6BracketExpression start="\[" end="]" transparent
-
-" Double-quoted, qq, qw, qx, `` strings
-syn region p6InterpString start=+"+ skip=+\\"+ end=+"+ contains=@p6Interp
-syn region p6InterpString start=+`+ skip=+\\`+ end=+`+ contains=@p6Interp
-syn region p6InterpString start=+«+ end=+»+ contains=@p6Interp
-syn region p6InterpString start=+<<+ end=+>>+ contains=@p6Interp
-" \w-delimited strings
-syn region p6InterpString start="\<q[qwx]\s\+\z([a-zA-Z0-9_]\)" skip="\\\z1" end="\z1" contains=@p6Interp
-" Punctuation-delimited strings
-syn region p6InterpString start="\<q[qwx]\s*\z([^a-zA-Z0-9_ ]\)" skip="\\\z1" end="\z1" contains=@p6Interp
-syn region p6InterpString start="\<q[qwx]\s*{" skip="\\}" end="}" contains=@p6Interp
-syn region p6InterpString start="\<q[qwx]\s*(" skip="\\)" end=")" contains=@p6Interp
-syn region p6InterpString start="\<q[qwx]\s*\[" skip="\\]" end="]" contains=@p6Interp
-syn region p6InterpString start="\<q[qwx]\s*<" skip="\\>" end=">" contains=@p6Interp
-
-" Single-quoted, q, '' strings
-syn region p6LiteralString start=+'+ skip=+\\'+ end=+'+
-syn region p6LiteralString start=+<<\@!\(.*>\)\@=+ end=+>\@<!>+
-" \w-delimited strings
-syn region p6LiteralString start="\<q\s\+\z([a-zA-Z0-9_]\)" skip="\\\z1" end="\z1"
-" Punctuation-delimited strings
-syn region p6LiteralString start="\<q\(\s*:[012]\)*\s*\z([^a-zA-Z0-9_ ]\)" skip="\\\z1" end="\z1"
-syn region p6LiteralString start="\<q\(\s*:[012]\)*\s*\[" skip="\\]" end="]"
-syn region p6LiteralString start="\<q\(\s*:[012]\)*\s*(" skip="\\)" end=")"
-syn region p6LiteralString start="\<q\(\s*:[012]\)*\s*{" skip="\\}" end="}"
-syn region p6LiteralString start="\<q\(\s*:[012]\)*\s*<" skip="\\>" end=">"
-
-" Numbers
-syn match p6Number "\<\(\d*\.\d\+\|\d\+\.\d*\|\d\+\)\(e\d\+\)\{0,1}"
-syn match p6Number "\<0o[0-7]\+"
-syn match p6Number "\<0x[0-9a-fA-F]\+"
-syn keyword p6Number NaN Inf
-
-" => Operator
-syn match p6InterpString "\w\+\s*=>"he=e-2
-" :key<val>
-syn match p6InterpString ":\w\+\(\s*\.\)\?\(<[^>]*>\)\?"hs=s+1
-
-
-" Sexeger!
-syn cluster p6Regexen contains=@p6Interp,p6Closure,p6Comment,p6CharClass,p6RuleCall,p6TestExpr,p6RegexSpecial
-
-" Here's how we get into regex mode
-" Standard /.../
-syn region p6Regex matchgroup=p6Keyword start="\(\w\_s*\)\@<!/" start="\(\(\<split\|\<grep\)\s*\)\@<=/" skip="\\/" end="/" contains=@p6Regexen
-" m:/.../
-syn region p6Regex matchgroup=p6Keyword start="\<\(m\|rx\)\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*\z([^a-zA-Z0-9_:(]\)" skip="\\\z1" end="\z1" contains=@p6Regexen
-" m:[] m:{} and m:<>
-syn region p6Regex matchgroup=p6Keyword start="\<\(m\|rx\)\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*\[" skip="\\]" end="]" contains=@p6Regexen
-syn region p6Regex matchgroup=p6Keyword start="\<\(m\|rx\)\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*{" skip="\\}" end="}" contains=@p6Regexen
-syn region p6Regex matchgroup=p6Keyword start="\<\(m\|rx\)\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*<"hs=e skip="\\>" end=">" contains=@p6Regexen
-
-
-" rule { }
-syn region p6Regex start="rule\(\_s\+\w\+\)\{0,1}\_s*{"hs=e end="}" contains=@p6Regexen
-
-" Closure (FIXME: Really icky hack, also doesn't support :blah modifiers)
-" However, don't do what you might _expect_ would work, because it won't.
-" And no variant of it will, either. I found this out through 4 hours from
-" miniscule tweaking to complete redesign. This is the only way I've found!
-syn region p6Closure start="\(\(rule\(\_s\+\w\+\)\{0,1}\|s\|rx\)\_s*\)\@<!{" end="}" matchgroup=p6Error end="[\])]" contains=TOP fold
-
-
-" s:///, tr:///, and all variants
-syn region p6Regex matchgroup=p6Keyword start="\<s\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*\z([^a-zA-Z0-9_:(]\)" skip="\\\z1" end="\z1"me=e-1 nextgroup=p6SubNonBracket contains=@p6Regexen
-syn region p6Regex matchgroup=p6KeyWord start="\<s\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*\[" skip="\\]" end="]\_s*" nextgroup=p6SubBracket contains=@p6Regexen
-syn region p6Regex matchgroup=p6Keyword start="\<s\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*{" skip="\\}" end="}\_s*" nextgroup=p6SubBracket contains=@p6Regexen
-syn region p6Regex matchgroup=p6Keyword start="\<s\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*<" skip="\\>" end=">\_s*" nextgroup=p6SubBracket contains=@p6Regexen
-syn region p6Regex matchgroup=p6Keyword start="\<tr\_s*\(\_s*:\_s*[a-zA-Z0-9_()]\+\)*\_s*\z([^a-zA-Z0-9_:(]\)" skip="\\\z1" end="\z1"me=e-1 nextgroup=p6TransNonBracket
-
-" This is kinda tricky. Since these are contained, they're "called" by the
-" previous four groups. They just pick up the delimiter at the current location
-" and behave like a string.
-
-syn region p6SubNonBracket matchgroup=p6Keyword contained start="\z(\W\)" skip="\\\z1" end="\z1" contains=@p6Interp
-syn region p6SubBracket matchgroup=p6Keyword contained start="\z(\W\)" skip="\\\z1" end="\z1" contains=@p6Interp
-syn region p6SubBracket matchgroup=p6Keyword contained start="\[" skip="\\]" end="]" contains=@p6Interp
-syn region p6SubBracket matchgroup=p6Keyword contained start="{" skip="\\}" end="}" contains=@p6Interp
-syn region p6SubBracket matchgroup=p6Keyword contained start="<" skip="\\>" end=">" contains=@p6Interp
-syn region p6TransNonBracket matchgroup=p6Keyword contained start="\z(\W\)" skip="\\\z1" end="\z1"
-
-
-syn match p6RuleCall contained "<\s*!\{0,1}\s*\w\+"hs=s+1
-syn match p6CharClass contained "<\s*!\{0,1}\s*\[\]\{0,1}[^]]*\]\s*>"
-syn match p6CharClass contained "<\s*!\{0,1}\s*-\{0,1}\(alpha\|digit\|sp\|ws\|null\)\s*>"
-syn match p6CharClass contained "\\[HhVvNnTtEeRrFfWwSs]"
-syn match p6CharClass contained "\\[xX]\(\[[0-9a-f;]\+\]\|\x\+\)"
-syn match p6CharClass contained "\\0\(\[[0-7;]\+\]\|\o\+\)"
-syn region p6CharClass contained start="\\[QqCc]\[" end="]" skip="\\]"
-syn match p6RegexSpecial contained "\\\@<!:\{1,3\}"
-syn match p6RegexSpecial contained "<\s*\(cut\|commit\)\s*>"
-"syn match p6RegexSpecial contained "\\\@<![+*|]"
-syn match p6RegexSpecial contained ":="
-syn region p6CharClass contained start=+<\s*!\{0,1}\s*\z(['"]\)+ skip=+\\\z1+ end=+\z1\s*>+
-syn region p6TestExpr contained start="<\s*!\{0,1}\s*(" end=")\s*>" contains=TOP
-
-
-" Hash quoting (sortof a hack)
-" syn match p6InterpString "{\s*\w\+\s*}"ms=s+1,me=e-1
-
-syn match p6Normal "//"
-
-hi link p6Shebang PreProc
-hi link p6Attn Todo
-hi link p6Normal Normal
-hi link p6Regex String
-hi link p6SubNonBracket p6String
-hi link p6SubBracket p6String
-hi link p6TransNonBracket p6String
-hi link p6CharClass Special
-hi link p6RuleCall Identifier
-hi link p6RegexSpecial Type
-
-hi link p6Error Error
-hi link p6Module p6Keyword
-hi link p6KeyCompare p6Keyword
-hi link p6KeyDecl p6Keyword
-hi link p6KeyScopeDecl p6Keyword
-hi link p6KeyFlow p6Keyword
-hi link p6ClosureTrait PreProc
-hi link p6KeyException Special
-hi link p6KeyIO p6Keyword
-hi link p6KeyProperty Type
-hi link p6KeyFunc p6Keyword
-hi link p6KeySpecial Special
-hi link p6KeyType Type
-
-hi link p6Pattern p6Keyword
-hi link p6VarPlain p6Variable
-hi link p6VarPunct p6Variable
-hi link p6VarCapt p6Variable
-hi link p6Invoke Type
-hi link p6InterpString p6String
-hi link p6LiteralString p6String
-
-hi link p6Keyword Statement
-hi link p6Number Number
-hi link p6Comment Comment
-hi link p6CommentMline Comment
-hi link p6CommentPara Comment
-hi link p6POD Comment
-hi link p6PODHead Comment
-hi link p6PODHeadKwid Comment
-hi link p6PODTitle Title
-hi link p6PODSec Comment
-hi link p6PODSecKwid Comment
-hi link p6PODSecTitle String
-hi link p6PODVerbatim Special
-hi link p6Variable Identifier
-hi link p6VarException Special
-hi link p6String String
-
-let b:current_syntax = 'perl6'
-unlet b:perl6_syntax_init
+
+" normal end-of-line comment
+syn match p6Comment display "#.*" contains=p6Attention
+
+" Multiline comments. Arbitrary numbers of opening brackets are allowed,
+" but we only define regions for 1 to 3
+syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#("
+ \ skip="([^)]*)"
+ \ end=")"
+ \ matchgroup=p6Error
+ \ start="^#("
+ \ contains=p6Attention,p6Comment
+syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#\["
+ \ skip="\[[^\]]*]"
+ \ end="]"
+ \ matchgroup=p6Error
+ \ start="^#\["
+ \ contains=p6Attention,p6Comment
+syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#{"
+ \ skip="{[^}]*}"
+ \ end="}"
+ \ matchgroup=p6Error
+ \ start="^#{"
+ \ contains=p6Attention,p6Comment
+syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ matchgroup=p6Error
+ \ start="^#<"
+ \ contains=p6Attention,p6Comment
+syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ matchgroup=p6Error
+ \ start="^#«"
+ \ contains=p6Attention,p6Comment
+
+" double and triple delimiters
+if exists("perl6_extended_comments") || exists("perl6_extended_all")
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#(("
+ \ skip="((\%([^)\|))\@!]\)*))"
+ \ end="))"
+ \ matchgroup=p6Error
+ \ start="^#(("
+ \ contains=p6Attention,p6Comment
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#((("
+ \ skip="(((\%([^)]\|)\%())\)\@!\)*)))"
+ \ end=")))"
+ \ matchgroup=p6Error
+ \ start="^#((("
+ \ contains=p6Attention,p6Comment
+
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#\[\["
+ \ skip="\[\[\%([^\]]\|]]\@!\)*]]"
+ \ end="]]"
+ \ matchgroup=p6Error
+ \ start="^#\[\["
+ \ contains=p6Attention,p6Comment
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#\[\[\["
+ \ skip="\[\[\[\%([^\]]\|]\%(]]\)\@!\)*]]]"
+ \ end="]]]"
+ \ matchgroup=p6Error
+ \ start="^#\[\[\["
+ \ contains=p6Attention,p6Comment
+
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#{{"
+ \ skip="{{\%([^}]\|}}\@!\)*}}"
+ \ end="}}"
+ \ matchgroup=p6Error
+ \ start="^#{{"
+ \ contains=p6Attention,p6Comment
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#{{{"
+ \ skip="{{{\%([^}]\|}\%(}}\)\@!\)*}}}"
+ \ end="}}}"
+ \ matchgroup=p6Error
+ \ start="^#{{{"
+ \ contains=p6Attention,p6Comment
+
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#<<"
+ \ skip="<<\%([^>]\|>>\@!\)*>>"
+ \ end=">>"
+ \ matchgroup=p6Error
+ \ start="^#<<"
+ \ contains=p6Attention,p6Comment
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#<<<"
+ \ skip="<<<\%([^>]\|>\%(>>\)\@!\)*>>>"
+ \ end=">>>"
+ \ matchgroup=p6Error
+ \ start="^#<<<"
+ \ contains=p6Attention,p6Comment
+
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#««"
+ \ skip="««\%([^»]\|»»\@!\)*»»"
+ \ end="»»"
+ \ matchgroup=p6Error
+ \ start="^#««"
+ \ contains=p6Attention,p6Comment
+ syn region p6Comment
+ \ matchgroup=p6Comment
+ \ start="^\@<!#«««"
+ \ skip="«««\%([^»]\|»\%(»»\)\@!\)*»»»"
+ \ end="»»»"
+ \ matchgroup=p6Error
+ \ start="^#«««"
+ \ contains=p6Attention,p6Comment
+endif
+
+" Pod
+
+" Abbreviated blocks (implicit code forbidden)
+syn region p6PodAbbrRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=\ze\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodAbbrNoCodeType
+ \ keepend
+
+syn region p6PodAbbrNoCodeType
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodName,p6PodAbbrNoCode
+
+syn match p6PodName contained ".\+" contains=@p6PodFormat
+syn match p6PodComment contained ".\+"
+
+syn region p6PodAbbrNoCode
+ \ start="^"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=@p6PodFormat
+
+" Abbreviated blocks (everything is code)
+syn region p6PodAbbrRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=\zecode\>"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodAbbrCodeType
+ \ keepend
+
+syn region p6PodAbbrCodeType
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodName,p6PodAbbrCode
+
+syn region p6PodAbbrCode
+ \ start="^"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+
+" Abbreviated blocks (everything is a comment)
+syn region p6PodAbbrRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=\zecomment\>"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodAbbrCommentType
+ \ keepend
+
+syn region p6PodAbbrCommentType
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodComment,p6PodAbbrNoCode
+
+" Abbreviated blocks (implicit code allowed)
+syn region p6PodAbbrRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=\ze\%(pod\|item\|nested\|\u\+\)\>"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodAbbrType
+ \ keepend
+
+syn region p6PodAbbrType
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodName,p6PodAbbr
+
+syn region p6PodAbbr
+ \ start="^"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=@p6PodFormat,p6PodImplicitCode
+
+" Abbreviated block to end-of-file
+syn region p6PodAbbrRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=\zeEND\>"
+ \ end="\%$"
+ \ contains=p6PodAbbrEOFType
+ \ keepend
+
+syn region p6PodAbbrEOFType
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="\%$"
+ \ contained
+ \ contains=p6PodName,p6PodAbbrEOF
+
+syn region p6PodAbbrEOF
+ \ start="^"
+ \ end="\%$"
+ \ contained
+ \ contains=@p6PodNestedBlocks,@p6PodFormat,p6PodImplicitCode
+
+" Directives
+syn region p6PodDirectRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=\%(config\|use\)\>"
+ \ end="^\ze\%([^=]\|=\K\|\s*$\)"
+ \ contains=p6PodDirectArgRegion
+ \ keepend
+
+syn region p6PodDirectArgRegion
+ \ matchgroup=p6PodType
+ \ start="\S\+"
+ \ end="^\ze\%([^=]\|=\K\|\s*$\)"
+ \ contained
+ \ contains=p6PodDirectConfigRegion
+
+syn region p6PodDirectConfigRegion
+ \ start=""
+ \ end="^\ze\%([^=]\|=\K\|\s*$\)"
+ \ contained
+ \ contains=@p6PodConfig
+
+" =encoding is a special directive
+syn region p6PodDirectRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=encoding\>"
+ \ end="^\ze\%([^=]\|=\K\|\s*$\)"
+ \ contains=p6PodEncodingArgRegion
+ \ keepend
+
+syn region p6PodEncodingArgRegion
+ \ matchgroup=p6PodName
+ \ start="\S\+"
+ \ end="^\ze\%([^=]\|=\K\|\s*$\)"
+ \ contained
+
+" Paragraph blocks (implicit code forbidden)
+syn region p6PodParaRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=for\>"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodParaNoCodeTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodParaNoCodeTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodParaNoCode,p6PodParaConfigRegion
+
+syn region p6PodParaConfigRegion
+ \ start=""
+ \ end="^\ze\%([^=]\|=\k\@<!\)"
+ \ contained
+ \ contains=@p6PodConfig
+
+syn region p6PodParaNoCode
+ \ start="^[^=]"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=@p6PodFormat
+
+" Paragraph blocks (everything is code)
+syn region p6PodParaRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=for\>\ze\s*code\>"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodParaCodeTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodParaCodeTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodParaCode,p6PodParaConfigRegion
+
+syn region p6PodParaCode
+ \ start="^[^=]"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+
+" Paragraph blocks (implicit code allowed)
+syn region p6PodParaRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=for\>\ze\s*\%(pod\|item\|nested\|\u\+\)\>"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contains=p6PodParaTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodParaTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=p6PodPara,p6PodParaConfigRegion
+
+syn region p6PodPara
+ \ start="^[^=]"
+ \ end="^\ze\%(\s*$\|=\K\)"
+ \ contained
+ \ contains=@p6PodFormat,p6PodImplicitCode
+
+" Paragraph block to end-of-file
+syn region p6PodParaRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=for\>\ze\s\+END\>"
+ \ end="\%$"
+ \ contains=p6PodParaEOFTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodParaEOFTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="\%$"
+ \ contained
+ \ contains=p6PodParaEOF,p6PodParaConfigRegion
+
+syn region p6PodParaEOF
+ \ start="^[^=]"
+ \ end="\%$"
+ \ contained
+ \ contains=@p6PodNestedBlocks,@p6PodFormat,p6PodImplicitCode
+
+" Delimited blocks (implicit code forbidden)
+syn region p6PodDelimRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=begin\>"
+ \ end="^=end\>"
+ \ contains=p6PodDelimNoCodeTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodDelimNoCodeTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze=end\>"
+ \ contained
+ \ contains=p6PodDelimNoCode,p6PodDelimConfigRegion
+
+syn region p6PodDelimConfigRegion
+ \ start=""
+ \ end="^\ze\%([^=]\|=\K\|\s*$\)"
+ \ contained
+ \ contains=@p6PodConfig
+
+syn region p6PodDelimNoCode
+ \ start="^"
+ \ end="^\ze=end\>"
+ \ contained
+ \ contains=@p6PodNestedBlocks,@p6PodFormat
+
+" Delimited blocks (everything is code)
+syn region p6PodDelimRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=begin\>\ze\s*code\>"
+ \ end="^=end\>"
+ \ contains=p6PodDelimCodeTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodDelimCodeTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze=end\>"
+ \ contained
+ \ contains=p6PodDelimCode,p6PodDelimConfigRegion
+
+syn region p6PodDelimCode
+ \ start="^"
+ \ end="^\ze=end\>"
+ \ contained
+ \ contains=@p6PodNestedBlocks
+
+" Delimited blocks (implicit code allowed)
+syn region p6PodDelimRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=begin\>\ze\s*\%(pod\|item\|nested\|\u\+\)\>"
+ \ end="^=end\>"
+ \ contains=p6PodDelimTypeRegion
+ \ keepend
+ \ extend
+
+syn region p6PodDelimTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="^\ze=end\>"
+ \ contained
+ \ contains=p6PodDelim,p6PodDelimConfigRegion
+
+syn region p6PodDelim
+ \ start="^"
+ \ end="^\ze=end\>"
+ \ contained
+ \ contains=@p6PodNestedBlocks,@p6PodFormat,p6PodImplicitCode
+
+" Delimited block to end-of-file
+syn region p6PodDelimRegion
+ \ matchgroup=p6PodPrefix
+ \ start="^=begin\>\ze\s\+END\>"
+ \ end="\%$"
+ \ contains=p6PodDelimEOFTypeRegion
+ \ extend
+
+syn region p6PodDelimEOFTypeRegion
+ \ matchgroup=p6PodType
+ \ start="\K\k*"
+ \ end="\%$"
+ \ contained
+ \ contains=p6PodDelimEOF,p6PodDelimConfigRegion
+
+syn region p6PodDelimEOF
+ \ start="^"
+ \ end="\%$"
+ \ contained
+ \ contains=@p6PodNestedBlocks,@p6PodFormat,p6PodImplicitCode
+
+syn cluster p6PodConfig
+ \ add=p6PodConfigOperator
+ \ add=p6PodExtraConfig
+ \ add=p6StringAuto
+ \ add=p6PodAutoQuote
+ \ add=p6StringSQ
+
+syn region p6PodParens
+ \ start="("
+ \ end=")"
+ \ contained
+ \ contains=p6Number,p6StringSQ
+
+syn match p6PodAutoQuote display contained "=>"
+syn match p6PodConfigOperator display contained ":!\?" nextgroup=p6PodConfigOption
+syn match p6PodConfigOption display contained "[^[:space:](<]\+" nextgroup=p6PodParens,p6StringAngle
+syn match p6PodExtraConfig display contained "^="
+syn match p6PodVerticalBar display contained "|"
+syn match p6PodColon display contained ":"
+syn match p6PodSemicolon display contained ";"
+syn match p6PodComma display contained ","
+syn match p6PodImplicitCode display contained "^\s.*"
+
+syn region p6PodDelimEndRegion
+ \ matchgroup=p6PodType
+ \ start="\%(^=end\>\)\@<="
+ \ end="\K\k*"
+
+" These may appear inside delimited blocks
+syn cluster p6PodNestedBlocks
+ \ add=p6PodAbbrRegion
+ \ add=p6PodDirectRegion
+ \ add=p6PodParaRegion
+ \ add=p6PodDelimRegion
+ \ add=p6PodDelimEndRegion
+
+" Pod formatting codes
+
+syn cluster p6PodFormat
+ \ add=p6PodFormatOne
+ \ add=p6PodFormatTwo
+ \ add=p6PodFormatThree
+ \ add=p6PodFormatFrench
+
+" Balanced angles found inside formatting codes. Ensures proper nesting.
+
+syn region p6PodFormatAnglesOne
+ \ matchgroup=p6PodFormat
+ \ start="<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ transparent
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatAnglesOne
+
+syn region p6PodFormatAnglesTwo
+ \ matchgroup=p6PodFormat
+ \ start="<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ transparent
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatAnglesOne,p6PodFormatAnglesTwo
+
+syn region p6PodFormatAnglesThree
+ \ matchgroup=p6PodFormat
+ \ start="<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ transparent
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatAnglesOne,p6PodFormatAnglesTwo,p6PodFormatAnglesThree
+
+syn region p6PodFormatAnglesFrench
+ \ matchgroup=p6PodFormat
+ \ start="«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ transparent
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatAnglesOne,p6PodFormatAnglesTwo,p6PodFormatAnglesThree
+
+" All formatting codes
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="\u<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne,p6PodFormatFrench,p6PodFormatOne
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="\u<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAnglesTwo,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="\u<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="\u«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree
+
+" C<> and V<> don't allow nested formatting formatting codes
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="[CV]<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="[CV]<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAnglesTwo
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="[CV]<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="[CV]«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench
+
+" L<> can have a "|" separator
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="L<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne,p6PodFormatFrench,p6PodFormatOne,p6PodVerticalBar
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="L<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAnglesTwo,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodVerticalBar
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="L<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodVerticalBar
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="L«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodVerticalBar
+
+" E<> can have a ";" separator
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="E<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne,p6PodFormatFrench,p6PodFormatOne,p6PodSemiColon
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="E<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAnglesTwo,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodSemiColon
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="E<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodSemiColon
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="E«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodSemiColon
+
+" M<> can have a ":" separator
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="M<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne,p6PodFormatFrench,p6PodFormatOne,p6PodColon
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="M<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAnglesTwo,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodColon
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="M<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodColon
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="M«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodColon
+
+" D<> can have "|" and ";" separators
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="D<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne,p6PodFormatFrench,p6PodFormatOne,p6PodVerticalBar,p6PodSemiColon
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="D<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAngleTwo,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodVerticalBar,p6PodSemiColon
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="D<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodVerticalBar,p6PodSemiColon
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="D«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodVerticalBar,p6PodSemiColon
+
+" X<> can have "|", "," and ";" separators
+
+syn region p6PodFormatOne
+ \ matchgroup=p6PodFormatCode
+ \ start="X<"
+ \ skip="<[^>]*>"
+ \ end=">"
+ \ contained
+ \ contains=p6PodFormatAnglesOne,p6PodFormatFrench,p6PodFormatOne,p6PodVerticalBar,p6PodSemiColon,p6PodComma
+
+syn region p6PodFormatTwo
+ \ matchgroup=p6PodFormatCode
+ \ start="X<<"
+ \ skip="<<[^>]*>>"
+ \ end=">>"
+ \ contained
+ \ contains=p6PodFormatAnglesTwo,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodVerticalBar,p6PodSemiColon,p6PodComma
+
+syn region p6PodFormatThree
+ \ matchgroup=p6PodFormatCode
+ \ start="X<<<"
+ \ skip="<<<[^>]*>>>"
+ \ end=">>>"
+ \ contained
+ \ contains=p6PodFormatAnglesThree,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodVerticalBar,p6PodSemiColon,p6PodComma
+
+syn region p6PodFormatFrench
+ \ matchgroup=p6PodFormatCode
+ \ start="X«"
+ \ skip="«[^»]*»"
+ \ end="»"
+ \ contained
+ \ contains=p6PodFormatAnglesFrench,p6PodFormatFrench,p6PodFormatOne,p6PodFormatTwo,p6PodFormatThree,p6PodVerticalBar,p6PodSemiColon,p6PodComma
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_perl6_syntax_inits")
+ if version < 508
+ let did_perl6_syntax_inits = 1
+ command -nargs=+ HiLink hi link <args>
+ else
+ command -nargs=+ HiLink hi def link <args>
+ endif
+
+ HiLink p6EscOctOld p6Error
+ HiLink p6PackageTwigil p6Twigil
+ HiLink p6StringAngle p6String
+ HiLink p6StringFrench p6String
+ HiLink p6StringAngles p6String
+ HiLink p6StringSQ p6String
+ HiLink p6StringDQ p6String
+ HiLink p6StringQ p6String
+ HiLink p6RxStringSQ p6String
+ HiLink p6RxStringDQ p6String
+ HiLink p6Substitution p6String
+ HiLink p6Transliteration p6String
+ HiLink p6StringAuto p6String
+ HiLink p6StringP5Auto p6String
+ HiLink p6Key p6String
+ HiLink p6Match p6String
+ HiLink p6RegexBlock p6String
+ HiLink p6RxP5CharClass p6String
+ HiLink p6RxP5QuoteMeta p6String
+ HiLink p6RxCharClass p6String
+ HiLink p6RxQuoteWords p6String
+ HiLink p6ReduceOp p6Operator
+ HiLink p6ReverseCrossOp p6Operator
+ HiLink p6HyperOp p6Operator
+ HiLink p6QuoteQ p6Operator
+ HiLink p6RxRange p6StringSpecial
+ HiLink p6RxAnchor p6StringSpecial
+ HiLink p6RxP5Anchor p6StringSpecial
+ HiLink p6CodePoint p6StringSpecial
+ HiLink p6RxMeta p6StringSpecial
+ HiLink p6RxP5Range p6StringSpecial
+ HiLink p6RxP5CPId p6StringSpecial
+ HiLink p6RxP5Posix p6StringSpecial
+ HiLink p6RxP5Mod p6StringSpecial
+ HiLink p6RxP5HexSeq p6StringSpecial
+ HiLink p6RxP5OctSeq p6StringSpecial
+ HiLink p6RxP5WriteRefId p6StringSpecial
+ HiLink p6HexSequence p6StringSpecial
+ HiLink p6OctSequence p6StringSpecial
+ HiLink p6RxP5Named p6StringSpecial
+ HiLink p6RxP5PropId p6StringSpecial
+ HiLink p6RxP5Quantifier p6StringSpecial
+ HiLink p6RxP5CountId p6StringSpecial
+ HiLink p6RxP5Verb p6StringSpecial
+ HiLink p6Escape p6StringSpecial2
+ HiLink p6EscNull p6StringSpecial2
+ HiLink p6EscHash p6StringSpecial2
+ HiLink p6EscQQ p6StringSpecial2
+ HiLink p6EscQuote p6StringSpecial2
+ HiLink p6EscDoubleQuote p6StringSpecial2
+ HiLink p6EscBackTick p6StringSpecial2
+ HiLink p6EscForwardSlash p6StringSpecial2
+ HiLink p6EscVerticalBar p6StringSpecial2
+ HiLink p6EscExclamation p6StringSpecial2
+ HiLink p6EscDollar p6StringSpecial2
+ HiLink p6EscOpenCurly p6StringSpecial2
+ HiLink p6EscCloseCurly p6StringSpecial2
+ HiLink p6EscCloseBracket p6StringSpecial2
+ HiLink p6EscCloseAngle p6StringSpecial2
+ HiLink p6EscCloseFrench p6StringSpecial2
+ HiLink p6EscBackSlash p6StringSpecial2
+ HiLink p6RxEscape p6StringSpecial2
+ HiLink p6RxCapture p6StringSpecial2
+ HiLink p6RxAlternation p6StringSpecial2
+ HiLink p6RxP5 p6StringSpecial2
+ HiLink p6RxP5ReadRef p6StringSpecial2
+ HiLink p6RxP5Oct p6StringSpecial2
+ HiLink p6RxP5Hex p6StringSpecial2
+ HiLink p6RxP5EscMeta p6StringSpecial2
+ HiLink p6RxP5Meta p6StringSpecial2
+ HiLink p6RxP5Escape p6StringSpecial2
+ HiLink p6RxP5CodePoint p6StringSpecial2
+ HiLink p6RxP5WriteRef p6StringSpecial2
+ HiLink p6RxP5Prop p6StringSpecial2
+
+ HiLink p6Property Tag
+ HiLink p6Attention Todo
+ HiLink p6Type Type
+ HiLink p6Error Error
+ HiLink p6BlockLabel Label
+ HiLink p6Float Float
+ HiLink p6Normal Normal
+ HiLink p6Package Normal
+ HiLink p6PackageScope Normal
+ HiLink p6Number Number