neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

perl.vim (45185B)


      1 " Vim syntax file
      2 " Language:      Perl
      3 " Maintainer:    vim-perl <vim-perl@googlegroups.com> (need to be subscribed to post)
      4 " Homepage:      https://github.com/vim-perl/vim-perl
      5 " Bugs/requests: https://github.com/vim-perl/vim-perl/issues
      6 " License:       Vim License (see :help license)
      7 " Last Change:   2022 Jun 13
      8 " Contributors:  Andy Lester <andy@petdance.com>
      9 "                Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>
     10 "                Lukas Mai <l.mai.web.de>
     11 "                Nick Hibma <nick@van-laarhoven.org>
     12 "                Sonia Heimann <niania@netsurf.org>
     13 "                Rob Hoelz <rob@hoelz.ro>
     14 "                Doug Kearns <dougkearns@gmail.com>
     15 "                and many others.
     16 "
     17 " Please download the most recent version first, before mailing
     18 " any comments.
     19 "
     20 " The following parameters are available for tuning the
     21 " perl syntax highlighting, with defaults given:
     22 "
     23 " let perl_include_pod = 1
     24 " unlet perl_no_scope_in_variables
     25 " unlet perl_no_extended_vars
     26 " unlet perl_string_as_statement
     27 " unlet perl_no_sync_on_sub
     28 " unlet perl_no_sync_on_global_var
     29 " let perl_sync_dist = 100
     30 " unlet perl_fold
     31 " unlet perl_fold_blocks
     32 " unlet perl_nofold_packages
     33 " unlet perl_nofold_subs
     34 " unlet perl_fold_anonymous_subs
     35 " unlet perl_no_subprototype_error
     36 
     37 if exists("b:current_syntax")
     38  finish
     39 endif
     40 
     41 let s:cpo_save = &cpo
     42 set cpo&vim
     43 
     44 " POD starts with ^=<word> and ends with ^=cut
     45 
     46 if get(g:, 'perl_include_pod', 1)
     47  " Include a while extra syntax file
     48  syn include @Pod syntax/pod.vim
     49  unlet b:current_syntax
     50  if get(g:, 'perl_fold', 1)
     51    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend fold extend
     52    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend fold extend
     53  else
     54    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend
     55    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend
     56  endif
     57 else
     58  " Use only the bare minimum of rules
     59  if get(g:, 'perl_fold', 1)
     60    syn region perlPOD start="^=[a-z]" end="^=cut" fold
     61  else
     62    syn region perlPOD start="^=[a-z]" end="^=cut"
     63  endif
     64 endif
     65 
     66 
     67 syn cluster perlTop		contains=TOP
     68 
     69 syn region perlBraces start="{" end="}" transparent extend
     70 
     71 " All keywords
     72 "
     73 syn match perlConditional		"\<\%(if\|elsif\|unless\|given\|when\|default\)\>"
     74 syn match perlConditional		"\<else\%(\%(\_s\*if\>\)\|\>\)" contains=perlElseIfError skipwhite skipnl skipempty
     75 syn match perlRepeat			"\<\%(while\|for\%(each\)\=\|do\|until\|continue\)\>"
     76 syn match perlOperator			"\<\%(defined\|undef\|eq\|ne\|[gl][et]\|cmp\|not\|and\|or\|xor\|not\|bless\|ref\|do\)\>"
     77 " for some reason, adding this as the nextgroup for perlControl fixes BEGIN
     78 " folding issues...
     79 syn match perlFakeGroup 		"" contained
     80 syn match perlControl			"\<\%(BEGIN\|CHECK\|INIT\|END\|UNITCHECK\)\>\_s*" nextgroup=perlFakeGroup
     81 
     82 syn match perlStatementStorage		"\<\%(my\|our\|local\|state\)\>"
     83 syn match perlStatementControl		"\<\%(return\|last\|next\|redo\|goto\|break\)\>"
     84 syn match perlStatementScalar		"\<\%(chom\=p\|chr\|crypt\|r\=index\|lc\%(first\)\=\|length\|ord\|pack\|sprintf\|substr\|fc\|uc\%(first\)\=\)\>"
     85 syn match perlStatementRegexp		"\<\%(pos\|quotemeta\|split\|study\)\>"
     86 syn match perlStatementNumeric		"\<\%(abs\|atan2\|cos\|exp\|hex\|int\|log\|oct\|rand\|sin\|sqrt\|srand\)\>"
     87 syn match perlStatementList		"\<\%(splice\|unshift\|shift\|push\|pop\|join\|reverse\|grep\|map\|sort\|unpack\)\>"
     88 syn match perlStatementHash		"\<\%(delete\|each\|exists\|keys\|values\)\>"
     89 syn match perlStatementIOfunc		"\<\%(syscall\|dbmopen\|dbmclose\)\>"
     90 syn match perlStatementFiledesc		"\<\%(binmode\|close\%(dir\)\=\|eof\|fileno\|getc\|lstat\|printf\=\|read\%(dir\|line\|pipe\)\|rewinddir\|say\|select\|stat\|tell\%(dir\)\=\|write\)\>" nextgroup=perlFiledescStatementNocomma skipwhite
     91 syn match perlStatementFiledesc		"\<\%(fcntl\|flock\|ioctl\|open\%(dir\)\=\|read\|seek\%(dir\)\=\|sys\%(open\|read\|seek\|write\)\|truncate\)\>" nextgroup=perlFiledescStatementComma skipwhite
     92 syn match perlStatementVector		"\<vec\>"
     93 syn match perlStatementFiles		"\<\%(ch\%(dir\|mod\|own\|root\)\|glob\|link\|mkdir\|readlink\|rename\|rmdir\|symlink\|umask\|unlink\|utime\)\>"
     94 syn match perlStatementFiles		"-[rwxoRWXOezsfdlpSbctugkTBMAC]\>"
     95 syn match perlStatementFlow		"\<\%(caller\|die\|dump\|eval\|exit\|wantarray\|evalbytes\)\>"
     96 syn match perlStatementInclude		"\<\%(require\|import\|unimport\)\>"
     97 syn match perlStatementInclude		"\<\%(use\|no\)\s\+\%(\%(attributes\|attrs\|autodie\%(::\%(exception\%(::system\)\=\|hints\|skip\)\)\=\|autouse\|parent\|base\|big\%(int\|num\|rat\)\|blib\|bytes\|charnames\|constant\|deprecate\|diagnostics\|encoding\%(::warnings\)\=\|experimental\|feature\|fields\|filetest\|if\|integer\|less\|lib\|locale\|mro\|ok\|open\|ops\|overload\|overloading\|re\|sigtrap\|sort\|strict\|subs\|threads\%(::shared\)\=\|utf8\|vars\|version\|vmsish\|warnings\%(::register\)\=\)\>\)\="
     98 syn match perlStatementProc		"\<\%(alarm\|exec\|fork\|get\%(pgrp\|ppid\|priority\)\|kill\|pipe\|set\%(pgrp\|priority\)\|sleep\|system\|times\|wait\%(pid\)\=\)\>"
     99 syn match perlStatementSocket		"\<\%(accept\|bind\|connect\|get\%(peername\|sock\%(name\|opt\)\)\|listen\|recv\|send\|setsockopt\|shutdown\|socket\%(pair\)\=\)\>"
    100 syn match perlStatementIPC		"\<\%(msg\%(ctl\|get\|rcv\|snd\)\|sem\%(ctl\|get\|op\)\|shm\%(ctl\|get\|read\|write\)\)\>"
    101 syn match perlStatementNetwork		"\<\%(\%(end\|[gs]et\)\%(host\|net\|proto\|serv\)ent\|get\%(\%(host\|net\)by\%(addr\|name\)\|protoby\%(name\|number\)\|servby\%(name\|port\)\)\)\>"
    102 syn match perlStatementPword		"\<\%(get\%(pw\%(uid\|nam\)\|gr\%(gid\|nam\)\|login\)\)\|\%(end\|[gs]et\)\%(pw\|gr\)ent\>"
    103 syn match perlStatementTime		"\<\%(gmtime\|localtime\|time\)\>"
    104 
    105 syn match perlStatementMisc		"\<\%(warn\|format\|formline\|reset\|scalar\|prototype\|lock\|tied\=\|untie\)\>"
    106 
    107 syn keyword perlTodo			TODO TODO: TBD TBD: FIXME FIXME: XXX XXX: NOTE NOTE: contained
    108 
    109 syn region perlStatementIndirObjWrap   matchgroup=perlStatementIndirObj start="\%(\<\%(map\|grep\|sort\|printf\=\|say\|system\|exec\)\>\s*\)\@<={" end="}" transparent extend
    110 
    111 syn match perlLabel      "^\s*\h\w*\s*::\@!\%(\<v\d\+\s*:\)\@<!"
    112 
    113 " Perl Identifiers.
    114 "
    115 " Should be cleaned up to better handle identifiers in particular situations
    116 " (in hash keys for example)
    117 "
    118 " Plain identifiers: $foo, @foo, $#foo, %foo, &foo and dereferences $$foo, @$foo, etc.
    119 " We do not process complex things such as @{${"foo"}}. Too complicated, and
    120 " too slow. And what is after the -> is *not* considered as part of the
    121 " variable - there again, too complicated and too slow.
    122 
    123 " Special variables first ($^A, ...) and ($|, $', ...)
    124 syn match  perlVarPlain		 "$^[ACDEFHILMNOPRSTVWX]\="
    125 syn match  perlVarPlain		 "$[\\\"\[\]'&`+*.,;=%~!?@#$<>(-]"
    126 syn match  perlVarPlain		 "@[-+]"
    127 syn match  perlVarPlain		 "$\%(0\|[1-9]\d*\)"
    128 " Same as above, but avoids confusion in $::foo (equivalent to $main::foo)
    129 syn match  perlVarPlain		 "$::\@!"
    130 " These variables are not recognized within matches.
    131 syn match  perlVarNotInMatches	 "$[|)]"
    132 " This variable is not recognized within matches delimited by m//.
    133 syn match  perlVarSlash		 "$/"
    134 
    135 " And plain identifiers
    136 syn match  perlPackageRef	 "[$@#%*&]\%(\%(::\|'\)\=\I\i*\%(\%(::\|'\)\I\i*\)*\)\=\%(::\|'\)\I"ms=s+1,me=e-1 contained
    137 
    138 " To not highlight packages in variables as a scope reference - i.e. in
    139 " $pack::var, pack:: is a scope, just set "perl_no_scope_in_variables"
    140 " If you don't want complex things like @{${"foo"}} to be processed,
    141 " just set the variable "perl_no_extended_vars"...
    142 
    143 if !get(g:, 'perl_no_scope_in_variables', 0)
    144  syn match  perlVarPlain       "\%([@$]\|\$#\)\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref
    145  syn match  perlVarPlain2                   "%\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref
    146  syn match  perlFunctionName                "&\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref
    147 else
    148  syn match  perlVarPlain       "\%([@$]\|\$#\)\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref
    149  syn match  perlVarPlain2                   "%\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref
    150  syn match  perlFunctionName                "&\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref
    151 endif
    152 
    153 syn match  perlVarPlain2	 "%[-+]"
    154 
    155 if !get(g:, 'perl_no_extended_vars', 0)
    156  syn cluster perlExpr		contains=perlStatementIndirObjWrap,perlStatementScalar,perlStatementRegexp,perlStatementNumeric,perlStatementList,perlStatementHash,perlStatementFiles,perlStatementTime,perlStatementMisc,perlVarPlain,perlVarPlain2,perlVarNotInMatches,perlVarSlash,perlVarBlock,perlVarBlock2,perlShellCommand,perlFloat,perlNumber,perlStringUnexpanded,perlString,perlQ,perlQQ,perlQW,perlQR,perlArrow,perlBraces
    157  syn region perlArrow		matchgroup=perlArrow start="->\s*(" end=")" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref contained
    158  syn region perlArrow		matchgroup=perlArrow start="->\s*\[" end="\]" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref contained
    159  syn region perlArrow		matchgroup=perlArrow start="->\s*{" end="}" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref contained
    160  syn match  perlArrow		"->\s*{\s*\I\i*\s*}" contains=perlVarSimpleMemberName nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref contained
    161  syn region perlVarBlock	matchgroup=perlVarPlain start="\%($#\|[$@]\)\$*{" skip="\\}" end=+}\|\%(\%(<<\%('\|"\)\?\)\@=\)+ contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref extend
    162  syn region perlVarBlock2	matchgroup=perlVarPlain start="[%&*]\$*{" skip="\\}" end=+}\|\%(\%(<<\%('\|"\)\?\)\@=\)+ contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref extend
    163  syn match  perlVarPlain2	"[%&*]\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref extend
    164  syn match  perlVarPlain	"\%(\$#\|[@$]\)\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref extend
    165  syn region perlVarMember	matchgroup=perlVarPlain start="\%(->\)\={" skip="\\}" end="}" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref extend
    166  syn match  perlVarSimpleMember	"\%(->\)\={\s*\I\i*\s*}" nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref contains=perlVarSimpleMemberName contained extend
    167  syn match  perlVarSimpleMemberName	"\I\i*" contained
    168  syn region perlVarMember	matchgroup=perlVarPlain start="\%(->\)\=\[" skip="\\]" end="]" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlPostDeref extend
    169  syn match perlPackageConst	"__PACKAGE__" nextgroup=perlPostDeref
    170  syn match  perlPostDeref	"->\%($#\|[$@%&*]\)\*" contained nextgroup=perlVarSimpleMember,perlVarMember,perlPostDeref
    171  syn region  perlPostDeref	start="->\%($#\|[$@%&*]\)\[" skip="\\]" end="]" contained contains=@perlExpr nextgroup=perlVarSimpleMember,perlVarMember,perlPostDeref
    172  syn region  perlPostDeref	matchgroup=perlPostDeref start="->\%($#\|[$@%&*]\){" skip="\\}" end="}" keepend extend contained contains=@perlExpr nextgroup=perlVarSimpleMember,perlVarMember,perlPostDeref
    173 endif
    174 
    175 " File Descriptors
    176 syn match  perlFiledescRead	"<\h\w*>"
    177 
    178 syn match  perlFiledescStatementComma	"(\=\s*\<\u\w*\>\s*,"me=e-1 transparent contained contains=perlFiledescStatement
    179 syn match  perlFiledescStatementNocomma "(\=\s*\<\u\w*\>\s*[^, \t]"me=e-1 transparent contained contains=perlFiledescStatement
    180 
    181 syn match  perlFiledescStatement	"\<\u\w*\>" contained
    182 
    183 " Special characters in strings and matches
    184 syn match  perlSpecialString	"\\\%(\o\{1,3}\|x\%({\x\+}\|\x\{1,2}\)\|c.\|[^cx]\)" contained extend
    185 syn match  perlSpecialStringU2	"\\." extend contained contains=NONE
    186 syn match  perlSpecialStringU	"\\\\" contained
    187 syn match  perlSpecialMatch	"\\[1-9]" contained extend
    188 syn match  perlSpecialMatch	"\\g\%(\d\+\|{\%(-\=\d\+\|\h\w*\)}\)" contained
    189 syn match  perlSpecialMatch	"\\k\%(<\h\w*>\|'\h\w*'\)" contained
    190 syn match  perlSpecialMatch	"{\d\+\%(,\%(\d\+\)\=\)\=}" contained
    191 syn match  perlSpecialMatch	"\[[]-]\=[^\[\]]*[]-]\=\]" contained extend
    192 syn match  perlSpecialMatch	"[+*()?.]" contained
    193 syn match  perlSpecialMatch	"(?[#:=!]" contained
    194 syn match  perlSpecialMatch	"(?[impsx]*\%(-[imsx]\+\)\=)" contained
    195 syn match  perlSpecialMatch	"(?\%([-+]\=\d\+\|R\))" contained
    196 syn match  perlSpecialMatch	"(?\%(&\|P[>=]\)\h\w*)" contained
    197 syn match  perlSpecialMatch	"(\*\%(\%(PRUNE\|SKIP\|THEN\)\%(:[^)]*\)\=\|\%(MARK\|\):[^)]*\|COMMIT\|F\%(AIL\)\=\|ACCEPT\))" contained
    198 
    199 " Possible errors
    200 "
    201 " Highlight lines with only whitespace (only in blank delimited here documents) as errors
    202 syn match  perlNotEmptyLine	"^\s\+$" contained
    203 " Highlight "} else if (...) {", it should be "} else { if (...) { " or "} elsif (...) {"
    204 syn match perlElseIfError	"else\_s*if" containedin=perlConditional
    205 syn keyword perlElseIfError	elseif containedin=perlConditional
    206 
    207 " Variable interpolation
    208 "
    209 " These items are interpolated inside "" strings and similar constructs.
    210 syn cluster perlInterpDQ	contains=perlSpecialString,perlVarPlain,perlVarNotInMatches,perlVarSlash,perlVarBlock
    211 " These items are interpolated inside '' strings and similar constructs.
    212 syn cluster perlInterpSQ	contains=perlSpecialStringU,perlSpecialStringU2
    213 " These items are interpolated inside m// matches and s/// substitutions.
    214 syn cluster perlInterpSlash	contains=perlSpecialString,perlSpecialMatch,perlVarPlain,perlVarBlock
    215 " These items are interpolated inside m## matches and s### substitutions.
    216 syn cluster perlInterpMatch	contains=@perlInterpSlash,perlVarSlash
    217 
    218 " Shell commands
    219 syn region  perlShellCommand	matchgroup=perlMatchStartEnd start="`" end="`" contains=@perlInterpDQ keepend
    220 
    221 " Constants
    222 "
    223 " Numbers
    224 syn case   ignore
    225 syn match  perlNumber	"\<\%(0\|[1-9]\%(_\=\d\)*\)\>"
    226 syn match  perlNumber	"\<0\%(x\x\%(_\=\x\)*\|b[01]\%(_\=[01]\)*\|o\=\%(_\=\o\)*\)\>"
    227 syn match  perlFloat	"\<\d\%(_\=\d\)*e[-+]\=\d\%(_\=\d\)*"
    228 syn match  perlFloat	"\<\d\%(_\=\d\)*\.\%(\d\%(_\=\d\)*\)\=\%(e[-+]\=\d\%(_\=\d\)*\)\="
    229 syn match  perlFloat    "\.\d\%(_\=\d\)*\%(e[-+]\=\d\%(_\=\d\)*\)\="
    230 syn match  perlFloat	"\<0x\x\%(_\=\x\)*p[-+]\=\d\%(_\=\d\)*"
    231 syn match  perlFloat	"\<0x\x\%(_\=\x\)*\.\%(\x\%(_\=\x\)*\)\=\%(p[-+]\=\d\%(_\=\d\)*\)\="
    232 syn match  perlFloat    "\<0x\.\x\%(_\=\x\)*\%(p[-+]\=\d\%(_\=\d\)*\)\="
    233 syn case   match
    234 
    235 syn match  perlString	"\<\%(v\d\+\%(\.\d\+\)*\|\d\+\%(\.\d\+\)\{2,}\)\>" contains=perlVStringV
    236 syn match  perlVStringV	"\<v" contained
    237 
    238 
    239 syn region perlParensSQ		start=+(+ end=+)+ extend contained contains=perlParensSQ,@perlInterpSQ keepend
    240 syn region perlBracketsSQ	start=+\[+ end=+\]+ extend contained contains=perlBracketsSQ,@perlInterpSQ keepend
    241 syn region perlBracesSQ		start=+{+ end=+}+ extend contained contains=perlBracesSQ,@perlInterpSQ keepend
    242 syn region perlAnglesSQ		start=+<+ end=+>+ extend contained contains=perlAnglesSQ,@perlInterpSQ keepend
    243 
    244 syn region perlParensDQ		start=+(+ end=+)+ extend contained contains=perlParensDQ,@perlInterpDQ keepend
    245 syn region perlBracketsDQ	start=+\[+ end=+\]+ extend contained contains=perlBracketsDQ,@perlInterpDQ keepend
    246 syn region perlBracesDQ		start=+{+ end=+}+ extend contained contains=perlBracesDQ,@perlInterpDQ keepend
    247 syn region perlAnglesDQ		start=+<+ end=+>+ extend contained contains=perlAnglesDQ,@perlInterpDQ keepend
    248 
    249 
    250 " Simple version of searches and matches
    251 syn match  perlMatchModifiers "[msixpadluncgo]\+" contained
    252 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\>\s*\z([^[:space:]'([{<#]\)+ end=+\z1+ contains=@perlInterpMatch keepend extend nextgroup=perlMatchModifiers
    253 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m#+ end=+#+ contains=@perlInterpMatch keepend extend nextgroup=perlMatchModifiers
    254 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*'+ end=+'+ contains=@perlInterpSQ keepend extend nextgroup=perlMatchModifiers
    255 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*/+ end=+/+ contains=@perlInterpSlash keepend extend nextgroup=perlMatchModifiers
    256 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*(+ end=+)+ contains=@perlInterpMatch,perlParensDQ keepend extend nextgroup=perlMatchModifiers
    257 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*{+ end=+}+ contains=@perlInterpMatch,perlBracesDQ extend nextgroup=perlMatchModifiers
    258 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*<+ end=+>+ contains=@perlInterpMatch,perlAnglesDQ keepend extend nextgroup=perlMatchModifiers
    259 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*\[+ end=+\]+ contains=@perlInterpMatch,perlBracketsDQ keepend extend nextgroup=perlMatchModifiers
    260 
    261 " Below some hacks to recognise the // variant. This is virtually impossible to catch in all
    262 " cases as the / is used in so many other ways, but these should be the most obvious ones.
    263 syn region perlMatch	matchgroup=perlMatchStartEnd start="\%([$@%&*]\@<!\%(\<split\|\<while\|\<if\|\<unless\|\.\.\|[-+*!~(\[{=]\)\s*\)\@<=/\%(/=\)\@!" start=+^/\%(/=\)\@!+ start=+\s\@<=/\%(/=\)\@![^[:space:][:digit:]$@%=]\@=\%(/\_s*\%([([{$@%&*[:digit:]"'`]\|\_s\w\|[[:upper:]_abd-fhjklnqrt-wyz]\)\)\@!+ skip=+\\/+ end=+/+ contains=@perlInterpSlash extend nextgroup=perlMatchModifiers
    264 
    265 
    266 " Substitutions
    267 " perlMatch is the first part, perlSubstitution* is the substitution part
    268 syn match  perlSubstitutionModifiers "[msixpadluncgero]\+" contained
    269 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\>\s*\z([^[:space:]'([{<#]\)+ end=+\z1+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionGQQ keepend extend
    270 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*'+  end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlSubstitutionSQ keepend extend
    271 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*/+  end=+/+me=e-1 contains=@perlInterpSlash nextgroup=perlSubstitutionGQQ keepend extend
    272 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s#+  end=+#+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionGQQ keepend extend
    273 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*(+ end=+)+ contains=@perlInterpMatch,perlParensDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
    274 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*<+ end=+>+ contains=@perlInterpMatch,perlAnglesDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
    275 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*\[+ end=+\]+ contains=@perlInterpMatch,perlBracketsDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
    276 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*{+ end=+}+ contains=@perlInterpMatch,perlBracesDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
    277 syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+\z([^[:space:]'([{<]\)+ end=+\z1+ keepend contained contains=@perlInterpDQ extend nextgroup=perlSubstitutionModifiers
    278 syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+(+ end=+)+ contained contains=@perlInterpDQ,perlParensDQ keepend extend nextgroup=perlSubstitutionModifiers
    279 syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+\[+ end=+\]+ contained contains=@perlInterpDQ,perlBracketsDQ keepend extend nextgroup=perlSubstitutionModifiers
    280 syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+{+ end=+}+ contained contains=@perlInterpDQ,perlBracesDQ keepend extend extend nextgroup=perlSubstitutionModifiers
    281 syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+<+ end=+>+ contained contains=@perlInterpDQ,perlAnglesDQ keepend extend nextgroup=perlSubstitutionModifiers
    282 syn region perlSubstitutionSQ		matchgroup=perlMatchStartEnd start=+'+  end=+'+ contained contains=@perlInterpSQ keepend extend nextgroup=perlSubstitutionModifiers
    283 
    284 " Translations
    285 " perlMatch is the first part, perlTranslation* is the second, translator part.
    286 syn match  perlTranslationModifiers "[cdsr]\+" contained
    287 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\>\s*\z([^[:space:]([{<#]\)+ end=+\z1+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationGQ
    288 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)#+ end=+#+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationGQ
    289 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*\[+ end=+\]+ contains=@perlInterpSQ,perlBracketsSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
    290 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*(+ end=+)+ contains=@perlInterpSQ,perlParensSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
    291 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*<+ end=+>+ contains=@perlInterpSQ,perlAnglesSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
    292 syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*{+ end=+}+ contains=@perlInterpSQ,perlBracesSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
    293 syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+\z([^[:space:]([{<]\)+ end=+\z1+ contained nextgroup=perlTranslationModifiers
    294 syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+(+ end=+)+ contains=perlParensSQ contained nextgroup=perlTranslationModifiers
    295 syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+\[+ end=+\]+ contains=perlBracketsSQ contained nextgroup=perlTranslationModifiers
    296 syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+{+ end=+}+ contains=perlBracesSQ contained nextgroup=perlTranslationModifiers
    297 syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+<+ end=+>+ contains=perlAnglesSQ contained nextgroup=perlTranslationModifiers
    298 
    299 
    300 " Strings and q, qq, qw and qr expressions
    301 
    302 syn region perlStringUnexpanded	matchgroup=perlStringStartEnd start="'" end="'" contains=@perlInterpSQ keepend extend
    303 syn region perlString		matchgroup=perlStringStartEnd start=+"+  end=+"+ contains=@perlInterpDQ keepend extend
    304 syn region perlQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\>\s*\z([^[:space:]#([{<]\)+ end=+\z1+ contains=@perlInterpSQ keepend extend
    305 syn region perlQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q#+ end=+#+ contains=@perlInterpSQ keepend extend
    306 syn region perlQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*(+ end=+)+ contains=@perlInterpSQ,perlParensSQ keepend extend
    307 syn region perlQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*\[+ end=+\]+ contains=@perlInterpSQ,perlBracketsSQ keepend extend
    308 syn region perlQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*{+ end=+}+ contains=@perlInterpSQ,perlBracesSQ keepend extend
    309 syn region perlQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*<+ end=+>+ contains=@perlInterpSQ,perlAnglesSQ keepend extend
    310 
    311 syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\>\s*\z([^[:space:]#([{<]\)+ end=+\z1+ contains=@perlInterpDQ keepend extend
    312 syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]#+ end=+#+ contains=@perlInterpDQ keepend extend
    313 syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*(+ end=+)+ contains=@perlInterpDQ,perlParensDQ keepend extend
    314 syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*\[+ end=+\]+ contains=@perlInterpDQ,perlBracketsDQ keepend extend
    315 syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*{+ end=+}+ contains=@perlInterpDQ,perlBracesDQ keepend extend
    316 syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*<+ end=+>+ contains=@perlInterpDQ,perlAnglesDQ keepend extend
    317 
    318 syn region perlQW		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*\z([^[:space:]#([{<]\)+  end=+\z1+ contains=@perlInterpSQ keepend extend
    319 syn region perlQW		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw#+  end=+#+ contains=@perlInterpSQ keepend extend
    320 syn region perlQW		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*(+  end=+)+ contains=@perlInterpSQ,perlParensSQ keepend extend
    321 syn region perlQW		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*\[+  end=+\]+ contains=@perlInterpSQ,perlBracketsSQ keepend extend
    322 syn region perlQW		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*{+  end=+}+ contains=@perlInterpSQ,perlBracesSQ keepend extend
    323 syn region perlQW		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*<+  end=+>+ contains=@perlInterpSQ,perlAnglesSQ keepend extend
    324 
    325 syn match  perlQRModifiers "[msixpadluno]\+" contained
    326 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\>\s*\z([^[:space:]#([{<'/]\)+  end=+\z1+ contains=@perlInterpMatch keepend extend nextgroup=perlQRModifiers
    327 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*/+  end=+/+ contains=@perlInterpSlash keepend extend nextgroup=perlQRModifiers
    328 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr#+  end=+#+ contains=@perlInterpMatch keepend extend nextgroup=perlQRModifiers
    329 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*'+  end=+'+ contains=@perlInterpSQ keepend extend nextgroup=perlQRModifiers
    330 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*(+  end=+)+ contains=@perlInterpMatch,perlParensDQ keepend extend nextgroup=perlQRModifiers
    331 
    332 " A special case for qr{}, qr<> and qr[] which allows for comments and extra whitespace in the pattern
    333 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*{+  end=+}+ contains=@perlInterpMatch,perlBracesDQ,perlComment keepend extend nextgroup=perlQRModifiers
    334 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*<+  end=+>+ contains=@perlInterpMatch,perlAnglesDQ,perlComment keepend extend nextgroup=perlQRModifiers
    335 syn region perlQR		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*\[+  end=+\]+ contains=@perlInterpMatch,perlBracketsDQ,perlComment keepend extend nextgroup=perlQRModifiers
    336 
    337 " Constructs such as print <<EOF [...] EOF, 'here' documents
    338 "
    339 " XXX Any statements after the identifier are in perlString colour (i.e.
    340 " 'if $a' in 'print <<EOF if $a'). This is almost impossible to get right it
    341 " seems due to the 'auto-extending nature' of regions.
    342 " XXX Indented heredocs are not perfect - they sometimes seem to take a moment
    343 "     to update if switched from double to single quotes and vice versa.
    344 "
    345 " Note: bare delimiters such as << to mean <<"" are not supported. These are a
    346 "       fatal error since 5.28 and, apparently, a rarely used feature.
    347 
    348 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\I\i*+                         end=+$+     contains=@perlTop oneline
    349 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\\\I\i*+                       end=+$+     contains=@perlTop oneline
    350 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\s*"[^\\"]*\%(\\.[^\\"]*\)*"+  end=+$+     contains=@perlTop oneline
    351 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\s*'[^\\']*\%(\\.[^\\']*\)*'+  end=+$+     contains=@perlTop oneline
    352 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\s*`[^\\`]*\%(\\.[^\\`]*\)*`+  end=+$+     contains=@perlTop oneline
    353 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\s*""+                         end=+$+     contains=@perlTop oneline
    354 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\s*''+                         end=+$+     contains=@perlTop oneline
    355 syn region perlHereDocStart	matchgroup=perlStringStartEnd start=+<<\~\=\s*``+                         end=+$+     contains=@perlTop oneline
    356 
    357 if get(g:, 'perl_fold', 0)
    358  syn region perlHereDoc	start=+<<\z(\I\i*\)+                        matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpDQ fold extend
    359  syn region perlHereDoc	start=+<<\\\z(\I\i*\)+                      matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpSQ fold extend
    360  syn region perlHereDoc	start=+<<\s*"\z([^\\"]*\%(\\.[^\\"]*\)*\)"+ matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpDQ fold extend
    361  syn region perlHereDoc	start=+<<\s*'\z([^\\']*\%(\\.[^\\']*\)*\)'+ matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpSQ fold extend
    362  syn region perlHereDoc	start=+<<\s*`\z([^\\`]*\%(\\.[^\\`]*\)*\)`+ matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpDQ fold extend
    363  syn region perlHereDoc	start=+<<\s*""+                             matchgroup=perlStringStartEnd end=+^$+    contains=perlHereDocStart,@perlInterpDQ,perlNotEmptyLine fold extend
    364  syn region perlHereDoc	start=+<<\s*''+                             matchgroup=perlStringStartEnd end=+^$+    contains=perlHereDocStart,@perlInterpSQ,perlNotEmptyLine fold extend
    365  syn region perlHereDoc	start=+<<\s*``+                             matchgroup=perlStringStartEnd end=+^$+    contains=perlHereDocStart,@perlInterpDQ,perlNotEmptyLine fold extend
    366 else
    367  syn region perlHereDoc	start=+<<\z(\I\i*\)+                        matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpDQ
    368  syn region perlHereDoc	start=+<<\\\z(\I\i*\)+                      matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpSQ
    369  syn region perlHereDoc	start=+<<\s*"\z([^\\"]*\%(\\.[^\\"]*\)*\)"+ matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpDQ
    370  syn region perlHereDoc	start=+<<\s*'\z([^\\']*\%(\\.[^\\']*\)*\)'+ matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpSQ
    371  syn region perlHereDoc	start=+<<\s*`\z([^\\`]*\%(\\.[^\\`]*\)*\)`+ matchgroup=perlStringStartEnd end=+^\z1$+ contains=perlHereDocStart,@perlInterpDQ
    372  syn region perlHereDoc	start=+<<\s*""+                             matchgroup=perlStringStartEnd end=+^$+    contains=perlHereDocStart,@perlInterpDQ,perlNotEmptyLine
    373  syn region perlHereDoc	start=+<<\s*''+                             matchgroup=perlStringStartEnd end=+^$+    contains=perlHereDocStart,@perlInterpSQ,perlNotEmptyLine
    374  syn region perlHereDoc	start=+<<\s*``+                             matchgroup=perlStringStartEnd end=+^$+    contains=perlHereDocStart,@perlInterpDQ,perlNotEmptyLine
    375 endif
    376 
    377 if get(g:, 'perl_fold', 0)
    378  syn region perlIndentedHereDoc	start=+<<\~\z(\I\i*\)+                        matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlIndentedHereDocStart,@perlInterpDQ fold extend
    379  syn region perlIndentedHereDoc	start=+<<\~\\\z(\I\i*\)+                      matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlIndentedHereDocStart,@perlInterpSQ fold extend
    380  syn region perlIndentedHereDoc	start=+<<\~\s*"\z([^\\"]*\%(\\.[^\\"]*\)*\)"+ matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlIndentedHereDocStart,@perlInterpDQ fold extend
    381  syn region perlIndentedHereDoc	start=+<<\~\s*'\z([^\\']*\%(\\.[^\\']*\)*\)'+ matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlIndentedHereDocStart,@perlInterpSQ fold extend
    382  syn region perlIndentedHereDoc	start=+<<\~\s*`\z([^\\`]*\%(\\.[^\\`]*\)*\)`+ matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlIndentedHereDocStart,@perlInterpDQ fold extend
    383  syn region perlIndentedHereDoc	start=+<<\~\s*""+                             matchgroup=perlStringStartEnd end=+^$+       contains=perlIndentedHereDocStart,@perlInterpDQ,perlNotEmptyLine fold extend
    384  syn region perlIndentedHereDoc	start=+<<\~\s*''+                             matchgroup=perlStringStartEnd end=+^$+       contains=perlIndentedHereDocStart,@perlInterpSQ,perlNotEmptyLine fold extend
    385  syn region perlIndentedHereDoc	start=+<<\~\s*``+                             matchgroup=perlStringStartEnd end=+^$+       contains=perlIndentedHereDocStart,@perlInterpDQ,perlNotEmptyLine fold extend
    386 else
    387  syn region perlIndentedHereDoc	start=+<<\~\z(\I\i*\)+                        matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlHereDocStart,@perlInterpDQ
    388  syn region perlIndentedHereDoc	start=+<<\~\\\z(\I\i*\)+                      matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlHereDocStart,@perlInterpSQ
    389  syn region perlIndentedHereDoc	start=+<<\~\s*"\z([^\\"]*\%(\\.[^\\"]*\)*\)"+ matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlHereDocStart,@perlInterpDQ
    390  syn region perlIndentedHereDoc	start=+<<\~\s*'\z([^\\']*\%(\\.[^\\']*\)*\)'+ matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlHereDocStart,@perlInterpSQ
    391  syn region perlIndentedHereDoc	start=+<<\~\s*`\z([^\\`]*\%(\\.[^\\`]*\)*\)`+ matchgroup=perlStringStartEnd end=+^\s*\z1$+ contains=perlHereDocStart,@perlInterpDQ
    392  syn region perlIndentedHereDoc	start=+<<\~\s*""+                             matchgroup=perlStringStartEnd end=+^$+       contains=perlHereDocStart,@perlInterpDQ,perlNotEmptyLine
    393  syn region perlIndentedHereDoc	start=+<<\~\s*''+                             matchgroup=perlStringStartEnd end=+^$+       contains=perlHereDocStart,@perlInterpSQ,perlNotEmptyLine
    394  syn region perlIndentedHereDoc	start=+<<\~\s*``+                             matchgroup=perlStringStartEnd end=+^$+       contains=perlHereDocStart,@perlInterpDQ,perlNotEmptyLine
    395 endif
    396 
    397 
    398 " Class declarations
    399 "
    400 syn match   perlPackageDecl		"\<package\s\+\%(\h\|::\)\%(\w\|::\)*" contains=perlStatementPackage
    401 syn keyword perlStatementPackage	package contained
    402 
    403 " Functions
    404 if get(g:, "perl_sub_signatures", 0)
    405    syn match perlSubSignature "\s*([^)]*)" contained extend
    406 else
    407    syn match perlSubPrototype "\s*([\\$@%&*\[\];]*)" contained extend
    408 endif
    409 syn match perlSubAttribute "\s*:\s*\h\w*\%(([^)]*)\|\)" contained extend
    410 syn match perlSubName "\%(\h\|::\|'\w\)\%(\w\|::\|'\w\)*\s*" contained extend
    411 syn region perlSubDeclaration start="" end="[;{]" contains=perlSubName,perlSubPrototype,perlSubAttribute,perlSubSignature,perlComment contained transparent
    412 syn match perlFunction "\<sub\>\_s*" nextgroup=perlSubDeclaration
    413 
    414 " The => operator forces a bareword to the left of it to be interpreted as
    415 " a string
    416 syn match  perlString "\I\@<!-\?\I\i*\%(\s*=>\)\@="
    417 
    418 " All other # are comments, except ^#!
    419 syn match  perlComment		"#.*" contains=perlTodo,@Spell extend
    420 syn match  perlSharpBang	"^#!.*"
    421 
    422 " Formats
    423 syn region perlFormat		matchgroup=perlStatementIOFunc start="^\s*\<format\s\+\k\+\s*=\s*$"rs=s+6 end="^\s*\.\s*$" contains=perlFormatName,perlFormatField,perlVarPlain,perlVarPlain2
    424 syn match  perlFormatName	"format\s\+\k\+\s*="lc=7,me=e-1 contained
    425 syn match  perlFormatField	"[@^][|<>~]\+\%(\.\.\.\)\=" contained
    426 syn match  perlFormatField	"[@^]#[#.]*" contained
    427 syn match  perlFormatField	"@\*" contained
    428 syn match  perlFormatField	"@[^A-Za-z_|<>~#*]"me=e-1 contained
    429 syn match  perlFormatField	"@$" contained
    430 
    431 " __END__ and __DATA__ clauses
    432 
    433 " Vim excludes empty syn-region end lines from the fold region.  This is
    434 " probably a bug and means a DATA section ending with an empty line does not
    435 " have that final line included in the fold.
    436 "
    437 " As a workaround we exploit an unterminated syntax region here with an end
    438 " pattern that will (probably) never match.  This forces all lines to be
    439 " included in the fold region.  Of course, if it does match then there's
    440 " nothing to work around as it is a non-empty line.
    441 "
    442 " This problem also exists with empty string delimited heredocs but there's no
    443 " known workaround for that case.
    444 if get(g:, 'perl_fold', 0)
    445  syntax region perlDATA matchgroup=perlDATAStart start="^__DATA__$" end="VIM_PERL_EOF\%$" contains=@perlDATA fold
    446  syntax region perlEND  matchgroup=perlENDStart  start="^__END__$"  end="VIM_PERL_EOF\%$" contains=@perlDATA fold
    447 else
    448  syntax region perlDATA matchgroup=perlDATAStart start="^__DATA__$" end="\%$" contains=@perlDATA
    449  syntax region perlEND  matchgroup=perlENDStart  start="^__END__$"  end="\%$" contains=@perlDATA
    450 endif
    451 
    452 " TODO: generalise this to allow other filetypes
    453 if get(g:, 'perl_highlight_data', 0)
    454  syn cluster perlDATA add=perlPOD
    455 else
    456  syn cluster perlDATA remove=perlPOD
    457 endif
    458 
    459 "
    460 " Folding
    461 if get(g:, 'perl_fold', 0)
    462  " Note: this bit must come before the actual highlighting of the "package"
    463  " keyword, otherwise this will screw up Pod lines that match /^package/
    464  if !get(g:, 'perl_nofold_packages', 0)
    465    syn region perlPackageFold start="^package \S\+;\s*\%(#.*\)\=$" end="^1;\=\s*\%(#.*\)\=$" end="\n\+package"me=s-1 transparent fold keepend
    466    syn region perlPackageFold start="^\z(\s*\)package\s*\S\+\s*{" end="^\z1}" transparent fold keepend
    467  endif
    468  if !get(g:, 'perl_nofold_subs', 0)
    469    if get(g:, "perl_fold_anonymous_subs", 0)
    470      " EXPLANATION:
    471      " \<sub\>                  - "sub" keyword
    472      " \_[^;{]*                 - any characters, including new line, but not ";" or "{", zero or more times
    473      " \%(([\\$@%&*\[\];]*)\)\= - prototype definition, \$@%&*[]; characters between (), zero or 1 times
    474      " \_[^;]*                  - any characters, including new line, but not ";" or "{", zero or more times
    475      " {                        - start subroutine block
    476      syn region perlSubFold start="\<sub\>\_[^;{]*\%(([\\$@%&*\[\];]*)\)\=\_[^;{]*{" end="}" transparent fold keepend extend
    477    else
    478      " EXPLANATION:
    479      " same, as above, but first non-space character after "sub" keyword must
    480      " be [A-Za-z_] 
    481      syn region perlSubFold start="\<sub\>\s*\h\_[^;{]*\%(([\\$@%&*\[\];]*)\)\=\_[^;]*{" end="}" transparent fold keepend extend
    482    endif
    483 
    484    syn region perlSubFold start="\<\%(BEGIN\|END\|CHECK\|INIT\|UNITCHECK\)\>\_s*{" end="}" transparent fold keepend
    485  endif
    486 
    487  if get(g:, 'perl_fold_blocks', 0)
    488    syn region perlBlockFold start="^\z(\s*\)\%(if\|elsif\|unless\|for\|while\|until\|given\)\s*(.*)\%(\s*{\)\=\s*\%(#.*\)\=$" start="^\z(\s*\)for\%(each\)\=\s*\%(\%(my\|our\)\=\s*\S\+\s*\)\=(.*)\%(\s*{\)\=\s*\%(#.*\)\=$" end="^\z1}\s*;\=\%(#.*\)\=$" transparent fold keepend
    489 
    490    " TODO this is works incorrectly
    491    syn region perlBlockFold start="^\z(\s*\)\%(do\|else\)\%(\s*{\)\=\s*\%(#.*\)\=$" end="^\z1}\s*while" end="^\z1}\s*;\=\%(#.*\)\=$" transparent fold keepend
    492  else
    493    if get(g:, 'perl_fold_do_blocks', 0)
    494      syn region perlDoBlockDeclaration start="" end="{" contains=perlComment contained transparent
    495      syn match perlOperator "\<do\>\_s*" nextgroup=perlDoBlockDeclaration
    496 
    497      syn region perlDoBlockFold start="\<do\>\_[^{]*{" end="}" transparent fold keepend extend
    498    endif
    499  endif
    500 
    501  syn sync fromstart
    502 else
    503  " fromstart above seems to set minlines even if perl_fold is not set.
    504  syn sync minlines=0
    505 endif
    506 
    507 " NOTE: If you're linking new highlight groups to perlString, please also put
    508 "       them into b:match_skip in ftplugin/perl.vim.
    509 
    510 " The default highlighting.
    511 hi def link perlSharpBang		PreProc
    512 hi def link perlControl			PreProc
    513 hi def link perlInclude			Include
    514 hi def link perlSpecial			Special
    515 hi def link perlString			String
    516 hi def link perlCharacter		Character
    517 hi def link perlNumber			Number
    518 hi def link perlFloat			Float
    519 hi def link perlType			Type
    520 hi def link perlIdentifier		Identifier
    521 hi def link perlLabel			Label
    522 hi def link perlStatement		Statement
    523 hi def link perlConditional		Conditional
    524 hi def link perlRepeat			Repeat
    525 hi def link perlOperator		Operator
    526 hi def link perlFunction		Keyword
    527 hi def link perlSubName			Function
    528 hi def link perlSubPrototype		Type
    529 hi def link perlSubSignature		Type
    530 hi def link perlSubAttribute		PreProc
    531 hi def link perlComment			Comment
    532 hi def link perlTodo			Todo
    533 if get(g:, 'perl_string_as_statement', 0)
    534  hi def link perlStringStartEnd	perlStatement
    535 else
    536  hi def link perlStringStartEnd	perlString
    537 endif
    538 hi def link perlVStringV		perlStringStartEnd
    539 hi def link perlList			perlStatement
    540 hi def link perlMisc			perlStatement
    541 hi def link perlVarPlain		perlIdentifier
    542 hi def link perlVarPlain2		perlIdentifier
    543 hi def link perlArrow			perlIdentifier
    544 hi def link perlFiledescRead		perlIdentifier
    545 hi def link perlFiledescStatement	perlIdentifier
    546 hi def link perlVarSimpleMember		perlIdentifier
    547 hi def link perlVarSimpleMemberName	perlString
    548 hi def link perlVarNotInMatches		perlIdentifier
    549 hi def link perlVarSlash		perlIdentifier
    550 hi def link perlQ			perlString
    551 hi def link perlQQ			perlString
    552 hi def link perlQW			perlString
    553 hi def link perlQR			perlString
    554 hi def link perlMatchModifiers          perlMatchStartEnd
    555 hi def link perlSubstitutionModifiers   perlMatchStartEnd
    556 hi def link perlTranslationModifiers    perlMatchStartEnd
    557 hi def link perlQRModifiers             perlStringStartEnd
    558 hi def link perlHereDoc			perlString
    559 hi def link perlIndentedHereDoc		perlString
    560 hi def link perlStringUnexpanded	perlString
    561 hi def link perlSubstitutionSQ		perlString
    562 hi def link perlSubstitutionGQQ		perlString
    563 hi def link perlTranslationGQ		perlString
    564 hi def link perlMatch			perlString
    565 hi def link perlMatchStartEnd		perlStatement
    566 hi def link perlFormatName		perlIdentifier
    567 hi def link perlFormatField		perlString
    568 hi def link perlPackageDecl		perlType
    569 hi def link perlStorageClass		perlType
    570 hi def link perlPackageRef		perlType
    571 hi def link perlStatementPackage	perlStatement
    572 hi def link perlStatementStorage	perlStatement
    573 hi def link perlStatementControl	perlStatement
    574 hi def link perlStatementScalar		perlStatement
    575 hi def link perlStatementRegexp		perlStatement
    576 hi def link perlStatementNumeric	perlStatement
    577 hi def link perlStatementList		perlStatement
    578 hi def link perlStatementHash		perlStatement
    579 hi def link perlStatementIOfunc		perlStatement
    580 hi def link perlStatementFiledesc	perlStatement
    581 hi def link perlStatementVector		perlStatement
    582 hi def link perlStatementFiles		perlStatement
    583 hi def link perlStatementFlow		perlStatement
    584 hi def link perlStatementInclude	perlStatement
    585 hi def link perlStatementProc		perlStatement
    586 hi def link perlStatementSocket		perlStatement
    587 hi def link perlStatementIPC		perlStatement
    588 hi def link perlStatementNetwork	perlStatement
    589 hi def link perlStatementPword		perlStatement
    590 hi def link perlStatementTime		perlStatement
    591 hi def link perlStatementMisc		perlStatement
    592 hi def link perlStatementIndirObj	perlStatement
    593 hi def link perlFunctionName		perlIdentifier
    594 hi def link perlMethod			perlIdentifier
    595 hi def link perlPostDeref		perlIdentifier
    596 hi def link perlFunctionPRef		perlType
    597 
    598 if !get(g:, 'perl_include_pod', 1)
    599  hi def link perlPOD		perlComment
    600 endif
    601 hi def link perlShellCommand		perlString
    602 hi def link perlSpecialAscii		perlSpecial
    603 hi def link perlSpecialDollar		perlSpecial
    604 hi def link perlSpecialString		perlSpecial
    605 hi def link perlSpecialStringU		perlSpecial
    606 hi def link perlSpecialMatch		perlSpecial
    607 hi def link perlEND			perlComment
    608 hi def link perlENDStart		perlEND
    609 hi def link perlDATA			perlComment
    610 hi def link perlDATAStart		perlDATA
    611 
    612 " NOTE: Due to a bug in Vim (or more likely, a misunderstanding on my part),
    613 "	I had to remove the transparent property from the following regions
    614 "	in order to get them to highlight correctly.  Feel free to remove
    615 "	these and reinstate the transparent property if you know how.
    616 hi def link perlParensSQ		perlString
    617 hi def link perlBracketsSQ		perlString
    618 hi def link perlBracesSQ		perlString
    619 hi def link perlAnglesSQ		perlString
    620 
    621 hi def link perlParensDQ		perlString
    622 hi def link perlBracketsDQ		perlString
    623 hi def link perlBracesDQ		perlString
    624 hi def link perlAnglesDQ		perlString
    625 
    626 hi def link perlSpecialStringU2	perlString
    627 
    628 " Possible errors
    629 hi def link perlNotEmptyLine		Error
    630 hi def link perlElseIfError		Error
    631 
    632 " Syncing to speed up processing
    633 "
    634 if !get(g:, 'perl_no_sync_on_sub', 0)
    635  syn sync match perlSync	grouphere NONE "^\s*\<package\s"
    636  syn sync match perlSync	grouphere NONE "^\s*\<sub\>"
    637  syn sync match perlSync	grouphere NONE "^}"
    638 endif
    639 
    640 if !get(g:, 'perl_no_sync_on_global_var', 0)
    641  syn sync match perlSync	grouphere NONE "^$\I[[:alnum:]_:]+\s*=\s*{"
    642  syn sync match perlSync	grouphere NONE "^[@%]\I[[:alnum:]_:]+\s*=\s*("
    643 endif
    644 
    645 if get(g:, 'perl_sync_dist', 0)
    646  execute "syn sync maxlines=" . perl_sync_dist
    647 else
    648  syn sync maxlines=100
    649 endif
    650 
    651 syn sync match perlSyncPOD	grouphere perlPOD "^=pod"
    652 syn sync match perlSyncPOD	grouphere perlPOD "^=head"
    653 syn sync match perlSyncPOD	grouphere perlPOD "^=item"
    654 syn sync match perlSyncPOD	grouphere NONE "^=cut"
    655 
    656 let b:current_syntax = "perl"
    657 
    658 let &cpo = s:cpo_save
    659 unlet s:cpo_save
    660 
    661 " XXX Change to sts=4:sw=4
    662 " vim:ts=8:sts=2:sw=2:expandtab:ft=vim