xref: /vim-8.2.3635/runtime/syntax/perl.vim (revision 0ee8df9c)
1" Vim syntax file
2" Language:     Perl 5
3" Maintainer:   Andy Lester <[email protected]>
4" URL:          http://github.com/petdance/vim-perl/tree/master
5" Last Change:  2009-09-2
6" Contributors: Andy Lester <[email protected]>
7"               Hinrik Örn Sigurðsson <[email protected]>
8"               Lukas Mai <l.mai.web.de>
9"               Nick Hibma <[email protected]>
10"               Sonia Heimann <[email protected]>
11"               and many others.
12"
13" Please download most recent version first before mailing
14" any comments.
15"
16" The following parameters are available for tuning the
17" perl syntax highlighting, with defaults given:
18"
19" unlet perl_include_pod
20" unlet perl_no_scope_in_variables
21" unlet perl_no_extended_vars
22" unlet perl_string_as_statement
23" unlet perl_no_sync_on_sub
24" unlet perl_no_sync_on_global_var
25" let perl_sync_dist = 100
26" unlet perl_fold
27" unlet perl_fold_blocks
28" let perl_nofold_packages = 1
29" let perl_nofold_subs = 1
30
31if version < 600
32  echoerr ">=vim-6.0 is required to run perl.vim"
33  finish
34elseif exists("b:current_syntax")
35  finish
36endif
37
38"
39" Folding
40
41if exists("perl_fold")
42  " Note: this bit must come before the actual highlighting of the "package"
43  " keyword, otherwise this will screw up Pod lines that match /^package/
44  if !exists("perl_nofold_packages")
45    syn region perlPackageFold start="^package \S\+;\s*\%(#.*\)\=$" end="^1;\=\s*\%(#.*\)\=$" end="\n\+package"me=s-1 transparent fold keepend
46  endif
47  if !exists("perl_nofold_subs")
48    syn region perlSubFold     start="^\z(\s*\)\<sub\>.*[^};]$" end="^\z1}\s*\%(#.*\)\=$" transparent fold keepend
49    syn region perlSubFold start="^\z(\s*\)\<\%(BEGIN\|END\|CHECK\|INIT\|UNITCHECK\)\>.*[^};]$" end="^\z1}\s*$" transparent fold keepend
50  endif
51
52  if exists("perl_fold_blocks")
53    syn region perlBlockFold start="^\z(\s*\)\%(if\|elsif\|unless\|for\|while\|until\|given\)\s*(.*)\%(\s*{\)\=\s*\%(#.*\)\=$" start="^\z(\s*\)foreach\s*\%(\%(my\|our\)\=\s*\S\+\s*\)\=(.*)\%(\s*{\)\=\s*\%(#.*\)\=$" end="^\z1}\s*;\=\%(#.*\)\=$" transparent fold keepend
54    syn region perlBlockFold start="^\z(\s*\)\%(do\|else\)\%(\s*{\)\=\s*\%(#.*\)\=$" end="^\z1}\s*while" end="^\z1}\s*;\=\%(#.*\)\=$" transparent fold keepend
55  endif
56
57  setlocal foldmethod=syntax
58  syn sync fromstart
59else
60  " fromstart above seems to set minlines even if perl_fold is not set.
61  syn sync minlines=0
62endif
63
64
65" POD starts with ^=<word> and ends with ^=cut
66
67if exists("perl_include_pod")
68  " Include a while extra syntax file
69  syn include @Pod syntax/pod.vim
70  unlet b:current_syntax
71  if exists("perl_fold")
72    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend fold
73    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend fold
74  else
75    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend
76    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend
77  endif
78else
79  " Use only the bare minimum of rules
80  if exists("perl_fold")
81    syn region perlPOD start="^=[a-z]" end="^=cut" fold
82  else
83    syn region perlPOD start="^=[a-z]" end="^=cut"
84  endif
85endif
86
87
88syn cluster perlTop		contains=TOP
89syn region  perlGenericBlock	matchgroup=perlGenericBlock start="{" end="}" contained transparent
90
91
92" All keywords
93"
94syn match perlConditional		"\<\%(if\|elsif\|unless\|given\|when\|default\)\>"
95syn match perlConditional		"\<else\>" nextgroup=perlElseIfError skipwhite skipnl skipempty
96syn match perlRepeat			"\<\%(while\|for\%(each\)\=\|do\|until\|continue\)\>"
97syn match perlOperator			"\<\%(defined\|undef\|eq\|ne\|[gl][et]\|cmp\|not\|and\|or\|xor\|not\|bless\|ref\|do\)\>"
98syn match perlControl			"\<\%(BEGIN\|CHECK\|INIT\|END\|UNITCHECK\)\>"
99
100syn match perlStatementStorage		"\<\%(my\|our\|local\|state\)\>"
101syn match perlStatementControl		"\<\%(return\|last\|next\|redo\|goto\|break\)\>"
102syn match perlStatementScalar		"\<\%(chom\=p\|chr\|crypt\|r\=index\|lc\%(first\)\=\|length\|ord\|pack\|sprintf\|substr\|uc\%(first\)\=\)\>"
103syn match perlStatementRegexp		"\<\%(pos\|quotemeta\|split\|study\)\>"
104syn match perlStatementNumeric		"\<\%(abs\|atan2\|cos\|exp\|hex\|int\|log\|oct\|rand\|sin\|sqrt\|srand\)\>"
105syn match perlStatementList		"\<\%(splice\|unshift\|shift\|push\|pop\|join\|reverse\|grep\|map\|sort\|unpack\)\>"
106syn match perlStatementHash		"\<\%(delete\|each\|exists\|keys\|values\)\>"
107syn match perlStatementIOfunc		"\<\%(syscall\|dbmopen\|dbmclose\)\>"
108syn match perlStatementFiledesc		"\<\%(binmode\|close\%(dir\)\=\|eof\|fileno\|getc\|lstat\|printf\=\|read\%(dir\|line\|pipe\)\|rewinddir\|say\|select\|stat\|tell\%(dir\)\=\|write\)\>" nextgroup=perlFiledescStatementNocomma skipwhite
109syn match perlStatementFiledesc		"\<\%(fcntl\|flock\|ioctl\|open\%(dir\)\=\|read\|seek\%(dir\)\=\|sys\%(open\|read\|seek\|write\)\|truncate\)\>" nextgroup=perlFiledescStatementComma skipwhite
110syn match perlStatementVector		"\<vec\>"
111syn match perlStatementFiles		"\<\%(ch\%(dir\|mod\|own\|root\)\|glob\|link\|mkdir\|readlink\|rename\|rmdir\|symlink\|umask\|unlink\|utime\)\>"
112syn match perlStatementFiles		"-[rwxoRWXOezsfdlpSbctugkTBMAC]\>"
113syn match perlStatementFlow		"\<\%(caller\|die\|dump\|eval\|exit\|wantarray\)\>"
114syn match perlStatementInclude		"\<require\>"
115syn match perlStatementInclude		"\<\%(use\|no\)\s\+\%(\%(attributes\|attrs\|autouse\|parent\|base\|big\%(int\|num\|rat\)\|blib\|bytes\|charnames\|constant\|diagnostics\|encoding\%(::warnings\)\=\|feature\|fields\|filetest\|if\|integer\|less\|lib\|locale\|mro\|open\|ops\|overload\|re\|sigtrap\|sort\|strict\|subs\|threads\%(::shared\)\=\|utf8\|vars\|version\|vmsish\|warnings\%(::register\)\=\)\>\)\="
116syn match perlStatementProc		"\<\%(alarm\|exec\|fork\|get\%(pgrp\|ppid\|priority\)\|kill\|pipe\|set\%(pgrp\|priority\)\|sleep\|system\|times\|wait\%(pid\)\=\)\>"
117syn match perlStatementSocket		"\<\%(acept\|bind\|connect\|get\%(peername\|sock\%(name\|opt\)\)\|listen\|recv\|send\|setsockopt\|shutdown\|socket\%(pair\)\=\)\>"
118syn match perlStatementIPC		"\<\%(msg\%(ctl\|get\|rcv\|snd\)\|sem\%(ctl\|get\|op\)\|shm\%(ctl\|get\|read\|write\)\)\>"
119syn match perlStatementNetwork		"\<\%(\%(end\|[gs]et\)\%(host\|net\|proto\|serv\)ent\|get\%(\%(host\|net\)by\%(addr\|name\)\|protoby\%(name\|number\)\|servby\%(name\|port\)\)\)\>"
120syn match perlStatementPword		"\<\%(get\%(pw\%(uid\|nam\)\|gr\%(gid\|nam\)\|login\)\)\|\%(end\|[gs]et\)\%(pw\|gr\)ent\>"
121syn match perlStatementTime		"\<\%(gmtime\|localtime\|time\)\>"
122
123syn match perlStatementMisc		"\<\%(warn\|formline\|reset\|scalar\|prototype\|lock\|tied\=\|untie\)\>"
124
125syn keyword perlTodo			TODO TBD FIXME XXX NOTE contained
126
127syn region perlStatementIndirObjWrap	matchgroup=perlStatementIndirObj start="\<\%(map\|grep\|sort\|print\|system\|exec\)\>\s*{" end="}" contains=@perlTop,perlGenericBlock
128
129syn match perlLabel      "^\s*\h\w*\s*::\@!\%(\<v\d\+\s*:\)\@<!"
130
131" Perl Identifiers.
132"
133" Should be cleaned up to better handle identifiers in particular situations
134" (in hash keys for example)
135"
136" Plain identifiers: $foo, @foo, $#foo, %foo, &foo and dereferences $$foo, @$foo, etc.
137" We do not process complex things such as @{${"foo"}}. Too complicated, and
138" too slow. And what is after the -> is *not* considered as part of the
139" variable - there again, too complicated and too slow.
140
141" Special variables first ($^A, ...) and ($|, $', ...)
142syn match  perlVarPlain		 "$^[ACDEFHILMNOPRSTVWX]\="
143syn match  perlVarPlain		 "$[\\\"\[\]'&`+*.,;=%~!?@#$<>(-]"
144syn match  perlVarPlain		 "%+"
145syn match  perlVarPlain		 "$\%(0\|[1-9]\d*\)"
146" Same as above, but avoids confusion in $::foo (equivalent to $main::foo)
147syn match  perlVarPlain		 "$::\@!"
148" These variables are not recognized within matches.
149syn match  perlVarNotInMatches	 "$[|)]"
150" This variable is not recognized within matches delimited by m//.
151syn match  perlVarSlash		 "$/"
152
153" And plain identifiers
154syn match  perlPackageRef	 "[$@#%*&]\%(\%(::\|'\)\=\I\i*\%(\%(::\|'\)\I\i*\)*\)\=\%(::\|'\)\I"ms=s+1,me=e-1 contained
155
156" To not highlight packages in variables as a scope reference - i.e. in
157" $pack::var, pack:: is a scope, just set "perl_no_scope_in_variables"
158" If you don't want complex things like @{${"foo"}} to be processed,
159" just set the variable "perl_no_extended_vars"...
160
161if !exists("perl_no_scope_in_variables")
162  syn match  perlVarPlain       "\%([@$]\|\$#\)\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
163  syn match  perlVarPlain2                   "%\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" contains=perlPackageRef
164  syn match  perlFunctionName                "&\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
165else
166  syn match  perlVarPlain       "\%([@$]\|\$#\)\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
167  syn match  perlVarPlain2                   "%\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)"
168  syn match  perlFunctionName                "&\$*\%(\I\i*\)\=\%(\%(::\|'\)\I\i*\)*\%(::\|\i\@<=\)" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
169endif
170
171if !exists("perl_no_extended_vars")
172  syn cluster perlExpr		contains=perlStatementIndirObjWrap,perlStatementScalar,perlStatementRegexp,perlStatementNumeric,perlStatementList,perlStatementHash,perlStatementFiles,perlStatementTime,perlStatementMisc,perlVarPlain,perlVarPlain2,perlVarNotInMatches,perlVarSlash,perlVarBlock,perlVarBlock2,perlShellCommand,perlFloat,perlNumber,perlStringUnexpanded,perlString,perlQQ,perlArrow,perlGenericBlock
173  syn region perlArrow		matchgroup=perlArrow start="->\s*(" end=")" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod contained
174  syn region perlArrow		matchgroup=perlArrow start="->\s*\[" end="\]" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod contained
175  syn region perlArrow		matchgroup=perlArrow start="->\s*{" end="}" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod contained
176  syn match  perlArrow		"->\s*{\s*\I\i*\s*}" contains=perlVarSimpleMemberName nextgroup=perlVarMember,perlVarSimpleMember,perlMethod contained
177  syn region perlArrow		matchgroup=perlArrow start="->\s*\$*\I\i*\s*(" end=")" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod contained
178  syn region perlVarBlock	matchgroup=perlVarPlain start="\%($#\|[$@]\)\$*{" skip="\\}" end="}" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
179  syn region perlVarBlock2	matchgroup=perlVarPlain start="[%&*]\$*{" skip="\\}" end="}" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
180  syn match  perlVarPlain2	"[%&*]\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
181  syn match  perlVarPlain	"\%(\$#\|[@$]\)\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
182  syn region perlVarMember	matchgroup=perlVarPlain start="\%(->\)\={" skip="\\}" end="}" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
183  syn match  perlVarSimpleMember	"\%(->\)\={\s*\I\i*\s*}" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod contains=perlVarSimpleMemberName contained
184  syn match  perlVarSimpleMemberName	"\I\i*" contained
185  syn region perlVarMember	matchgroup=perlVarPlain start="\%(->\)\=\[" skip="\\]" end="]" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
186  syn match perlPackageConst	"__PACKAGE__" nextgroup=perlMethod
187  syn match  perlMethod		"->\$*\I\i*" contained nextgroup=perlVarSimpleMember,perlVarMember,perlMethod
188endif
189
190" File Descriptors
191syn match  perlFiledescRead	"<\h\w*>"
192
193syn match  perlFiledescStatementComma	"(\=\s*\u\w*\s*,"me=e-1 transparent contained contains=perlFiledescStatement
194syn match  perlFiledescStatementNocomma "(\=\s*\u\w*\s*[^, \t]"me=e-1 transparent contained contains=perlFiledescStatement
195
196syn match  perlFiledescStatement	"\u\w*" contained
197
198" Special characters in strings and matches
199syn match  perlSpecialString	"\\\%(\o\{1,3}\|x\%({\x\+}\|\x\{1,2}\)\|c.\|[^cx]\)" contained extend
200syn match  perlSpecialStringU2	"\\." extend contained transparent contains=NONE
201syn match  perlSpecialStringU	"\\\\" contained
202syn match  perlSpecialMatch	"\\[1-9]" contained extend
203syn match  perlSpecialMatch	"\\g\%(\d\+\|{\%(-\=\d\+\|\h\w*\)}\)" contained
204syn match  perlSpecialMatch	"\\k\%(<\h\w*>\|'\h\w*'\)" contained
205syn match  perlSpecialMatch	"{\d\+\%(,\%(\d\+\)\=\)\=}" contained
206syn match  perlSpecialMatch	"\[[]-]\=[^\[\]]*[]-]\=\]" contained
207syn match  perlSpecialMatch	"[+*()?.]" contained
208syn match  perlSpecialMatch	"(?[#:=!]" contained
209syn match  perlSpecialMatch	"(?[impsx]*\%(-[imsx]\+\)\=)" contained
210syn match  perlSpecialMatch	"(?\%([-+]\=\d\+\|R\))" contained
211syn match  perlSpecialMatch	"(?\%(&\|P[>=]\)\h\w*)" contained
212syn match  perlSpecialMatch	"(\*\%(\%(PRUNE\|SKIP\|THEN\)\%(:[^)]*\)\=\|\%(MARK\|\):[^)]*\|COMMIT\|F\%(AIL\)\=\|ACCEPT\))" contained
213
214" Possible errors
215"
216" Highlight lines with only whitespace (only in blank delimited here documents) as errors
217syn match  perlNotEmptyLine	"^\s\+$" contained
218" Highlight '} else if (...) {', it should be '} else { if (...) { ' or
219" '} elsif (...) {'.
220syn match perlElseIfError	"\s\+if" contained
221syn keyword perlElseIfError	elseif
222
223" Variable interpolation
224"
225" These items are interpolated inside "" strings and similar constructs.
226syn cluster perlInterpDQ	contains=perlSpecialString,perlVarPlain,perlVarNotInMatches,perlVarSlash,perlVarBlock
227" These items are interpolated inside '' strings and similar constructs.
228syn cluster perlInterpSQ	contains=perlSpecialStringU,perlSpecialStringU2
229" These items are interpolated inside m// matches and s/// substitutions.
230syn cluster perlInterpSlash	contains=perlSpecialString,perlSpecialMatch,perlVarPlain,perlVarBlock
231" These items are interpolated inside m## matches and s### substitutions.
232syn cluster perlInterpMatch	contains=@perlInterpSlash,perlVarSlash
233
234" Shell commands
235syn region  perlShellCommand	matchgroup=perlMatchStartEnd start="`" end="`" contains=@perlInterpDQ keepend
236
237" Constants
238"
239" Numbers
240syn match  perlNumber	"\<\%(0\%(x\x[[:xdigit:]_]*\|b[01][01_]*\|\o[0-7_]*\|\)\|[1-9][[:digit:]_]*\)\>"
241syn match  perlFloat	"\<\d[[:digit:]_]*[eE][\-+]\=\d\+"
242syn match  perlFloat	"\<\d[[:digit:]_]*\.[[:digit:]_]*\%([eE][\-+]\=\d\+\)\="
243syn match  perlFloat	"\.[[:digit:]_]\+\%([eE][\-+]\=\d\+\)\="
244
245syn match  perlString	"\<\%(v\d\+\%(\.\d\+\)*\|\d\+\%(\.\d\+\)\{2,}\)\>" contains=perlVStringV
246syn match  perlVStringV	"\<v" contained
247
248
249syn region perlParensSQ		start=+(+ end=+)+ extend contained transparent contains=perlParensSQ,@perlInterpSQ keepend
250syn region perlBracketsSQ	start=+\[+ end=+\]+ extend contained transparent contains=perlBracketsSQ,@perlInterpSQ keepend
251syn region perlBracesSQ		start=+{+ end=+}+ extend contained transparent contains=perlBracesSQ,@perlInterpSQ keepend
252syn region perlAnglesSQ		start=+<+ end=+>+ extend contained transparent contains=perlAnglesSQ,@perlInterpSQ keepend
253
254syn region perlParensDQ		start=+(+ end=+)+ extend contained transparent contains=perlParensDQ,@perlInterpDQ keepend
255syn region perlBracketsDQ	start=+\[+ end=+\]+ extend contained transparent contains=perlBracketsDQ,@perlInterpDQ keepend
256syn region perlBracesDQ		start=+{+ end=+}+ extend contained transparent contains=perlBracesDQ,@perlInterpDQ keepend
257syn region perlAnglesDQ		start=+<+ end=+>+ extend contained transparent contains=perlAnglesDQ,@perlInterpDQ keepend
258
259
260" Simple version of searches and matches
261syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\>\s*\z([^[:space:]'([{<#]\)+ end=+\z1[cgimopsx]*+ contains=@perlInterpMatch keepend
262syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m#+ end=+#[cgimopsx]*+ contains=@perlInterpMatch keepend
263syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*'+ end=+'[cgimopsx]*+ contains=@perlInterpSQ keepend
264syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*/+ end=+/[cgimopsx]*+ contains=@perlInterpSlash keepend
265syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*(+ end=+)[cgimopsx]*+ contains=@perlInterpMatch,perlParensDQ keepend
266
267" A special case for m{}, m<> and m[] which allows for comments and extra whitespace in the pattern
268syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*{+ end=+}[cgimopsx]*+ contains=@perlInterpMatch,perlComment,perlBracesDQ keepend
269syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*<+ end=+>[cgimopsx]*+ contains=@perlInterpMatch,perlAnglesDQ keepend
270syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*\[+ end=+\][cgimopsx]*+ contains=@perlInterpMatch,perlComment,perlBracketsDQ keepend
271
272" Below some hacks to recognise the // variant. This is virtually impossible to catch in all
273" cases as the / is used in so many other ways, but these should be the most obvious ones.
274syn 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=+/[cgimopsx]*+ contains=@perlInterpSlash
275
276
277" Substitutions
278" perlMatch is the first part, perlSubstitution* is the substitution part
279syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\>\s*\z([^[:space:]'([{<#]\)+ end=+\z1+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionGQQ keepend
280syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*'+  end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlSubstitutionSQ keepend
281syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*/+  end=+/+me=e-1 contains=@perlInterpSlash nextgroup=perlSubstitutionGQQ keepend
282syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s#+  end=+#+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionGQQ keepend
283syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*(+ end=+)+ contains=@perlInterpMatch,perlParensDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend
284syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*<+ end=+>+ contains=@perlInterpMatch,perlAnglesDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend
285syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*\[+ end=+\]+ contains=@perlInterpMatch,perlBracketsDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend
286syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*{+ end=+}+ contains=@perlInterpMatch,perlBracesDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend
287syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+\z([^[:space:]'([{<]\)+ end=+\z1[ecgimopsx]*+ keepend contained contains=@perlInterpDQ
288syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+(+ end=+)[ecgimopsx]*+ contained contains=@perlInterpDQ,perlParensDQ keepend
289syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+\[+ end=+\][ecgimopsx]*+ contained contains=@perlInterpDQ,perlBracketsDQ keepend
290syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+{+ end=+}[ecgimopsx]*+ contained contains=@perlInterpDQ,perlBracesDQ keepend
291syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+<+ end=+>[ecgimopsx]*+ contained contains=@perlInterpDQ,perlAnglesDQ keepend
292syn region perlSubstitutionSQ		matchgroup=perlMatchStartEnd start=+'+  end=+'[ecgimopsx]*+ contained contains=@perlInterpSQ keepend
293
294" Translations
295" perlMatch is the first part, perlTranslation* is the second, translator part.
296syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\>\s*\z([^[:space:]([{<#]\)+ end=+\z1+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationGQ
297syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)#+ end=+#+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationGQ
298syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*\[+ end=+\]+ contains=@perlInterpSQ,perlBracketsSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
299syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*(+ end=+)+ contains=@perlInterpSQ,perlParensSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
300syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*<+ end=+>+ contains=@perlInterpSQ,perlAnglesSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
301syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!\%(tr\|y\)\s*{+ end=+}+ contains=@perlInterpSQ,perlBracesSQ nextgroup=perlTranslationGQ skipwhite skipempty skipnl
302syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+\z([^[:space:]([{<]\)+ end=+\z1[cds]*+ contained
303syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+(+ end=+)[cds]*+ contains=perlParensSQ contained
304syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+\[+ end=+\][cds]*+ contains=perlBracketsSQ contained
305syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+{+ end=+}[cds]*+ contains=perlBracesSQ contained
306syn region perlTranslationGQ		matchgroup=perlMatchStartEnd start=+<+ end=+>[cds]*+ contains=perlAnglesSQ contained
307
308
309" Strings and q, qq, qw and qr expressions
310
311syn region perlStringUnexpanded	matchgroup=perlStringStartEnd start="'" end="'" contains=@perlInterpSQ keepend
312syn region perlString		matchgroup=perlStringStartEnd start=+"+  end=+"+ contains=@perlInterpDQ keepend
313syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\>\s*\z([^[:space:]#([{<]\)+ end=+\z1+ contains=@perlInterpSQ keepend
314syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q#+ end=+#+ contains=@perlInterpSQ keepend
315syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*(+ end=+)+ contains=@perlInterpSQ,perlParensSQ keepend
316syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*\[+ end=+\]+ contains=@perlInterpSQ,perlBracketsSQ keepend
317syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*{+ end=+}+ contains=@perlInterpSQ,perlBracesSQ keepend
318syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q\s*<+ end=+>+ contains=@perlInterpSQ,perlAnglesSQ keepend
319
320syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\>\s*\z([^[:space:]#([{<]\)+ end=+\z1+ contains=@perlInterpDQ keepend
321syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]#+ end=+#+ contains=@perlInterpDQ keepend
322syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*(+ end=+)+ contains=@perlInterpDQ,perlParensDQ keepend
323syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*\[+ end=+\]+ contains=@perlInterpDQ,perlBracketsDQ keepend
324syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*{+ end=+}+ contains=@perlInterpDQ,perlBracesDQ keepend
325syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!q[qx]\s*<+ end=+>+ contains=@perlInterpDQ,perlAnglesDQ keepend
326
327syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*\z([^[:space:]#([{<]\)+  end=+\z1+ contains=@perlInterpSQ keepend
328syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw#+  end=+#+ contains=@perlInterpSQ keepend
329syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*(+  end=+)+ contains=@perlInterpSQ,perlParensSQ keepend
330syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*\[+  end=+\]+ contains=@perlInterpSQ,perlBracketsSQ keepend
331syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*{+  end=+}+ contains=@perlInterpSQ,perlBracesSQ keepend
332syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qw\s*<+  end=+>+ contains=@perlInterpSQ,perlAnglesSQ keepend
333
334syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\>\s*\z([^[:space:]#([{<'/]\)+  end=+\z1[imosx]*+ contains=@perlInterpMatch keepend
335syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*/+  end=+/[imosx]*+ contains=@perlInterpSlash keepend
336syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr#+  end=+#[imosx]*+ contains=@perlInterpMatch keepend
337syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*'+  end=+'[imosx]*+ contains=@perlInterpSQ keepend
338syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*(+  end=+)[imosx]*+ contains=@perlInterpMatch,perlParensDQ keepend
339
340" A special case for qr{}, qr<> and qr[] which allows for comments and extra whitespace in the pattern
341syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*{+  end=+}[imosx]*+ contains=@perlInterpMatch,perlBracesDQ,perlComment keepend
342syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*<+  end=+>[imosx]*+ contains=@perlInterpMatch,perlAnglesDQ,perlComment keepend
343syn region perlQQ		matchgroup=perlStringStartEnd start=+\<\%(::\|'\|->\)\@<!qr\s*\[+  end=+\][imosx]*+ contains=@perlInterpMatch,perlBracketsDQ,perlComment keepend
344
345" Constructs such as print <<EOF [...] EOF, 'here' documents
346"
347" XXX Any statements after the identifier are in perlString colour (i.e.
348" 'if $a' in 'print <<EOF if $a'). This is almost impossible to get right it
349" seems due to the 'auto-extending nature' of regions.
350if exists("perl_fold")
351  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\z(\I\i*\).*+    end=+^\z1$+ contains=@perlInterpDQ fold
352  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*"\z([^\\"]*\%(\\.[^\\"]*\)*\)"+ end=+^\z1$+ contains=@perlInterpDQ fold
353  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*'\z([^\\']*\%(\\.[^\\']*\)*\)'+ end=+^\z1$+ contains=@perlInterpSQ fold
354  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*""+           end=+^$+    contains=@perlInterpDQ,perlNotEmptyLine fold
355  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*''+           end=+^$+    contains=@perlInterpSQ,perlNotEmptyLine fold
356  syn region perlAutoload	matchgroup=perlStringStartEnd start=+<<\s*\(['"]\=\)\z(END_\%(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)\1+ end=+^\z1$+ contains=ALL fold
357else
358  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\z(\I\i*\)+    end=+^\z1$+ contains=@perlInterpDQ
359  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*"\z([^\\"]*\%(\\.[^\\"]*\)*\)"+ end=+^\z1$+ contains=@perlInterpDQ
360  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*'\z([^\\']*\%(\\.[^\\']*\)*\)'+ end=+^\z1$+ contains=@perlInterpSQ
361  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*""+           end=+^$+    contains=@perlInterpDQ,perlNotEmptyLine
362  syn region perlHereDoc	matchgroup=perlStringStartEnd start=+<<\s*''+           end=+^$+    contains=@perlInterpSQ,perlNotEmptyLine
363  syn region perlAutoload	matchgroup=perlStringStartEnd start=+<<\s*\(['"]\=\)\z(END_\%(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)\1+ end=+^\z1$+ contains=ALL
364endif
365
366
367" Class declarations
368"
369syn match   perlPackageDecl		"\<package\s\+\%(\h\|::\)\%(\w\|::\)*" contains=perlStatementPackage
370syn keyword perlStatementPackage	package contained
371
372" Functions
373"       sub [name] [(prototype)] {
374"
375syn match perlSubError "[^[:space:];{#]" contained
376if v:version == 701 && !has('patch221')  " XXX I hope that's the right one
377    syn match perlSubAttributes ":" contained
378else
379    syn match perlSubAttributesCont "\h\w*\_s*\%(:\_s*\)\=" nextgroup=@perlSubAttrMaybe contained
380    syn region perlSubAttributesCont matchgroup=perlSubAttributesCont start="\h\w*(" end=")\_s*\%(:\_s*\)\=" nextgroup=@perlSubAttrMaybe contained contains=@perlInterpSQ,perlParensSQ
381    syn cluster perlSubAttrMaybe contains=perlSubAttributesCont,perlSubError
382    syn match perlSubAttributes "" contained nextgroup=perlSubError
383    syn match perlSubAttributes ":\_s*" contained nextgroup=@perlSubAttrMaybe
384endif
385syn match perlSubPrototypeError "(\%(\_s*\%(\%(\\\%([$@%&*]\|\[[$@%&*]\+\]\)\|[$&*]\|[@%]\%(\_s*)\)\@=\|;\%(\_s*[)$@%&*\\]\)\@=\|_\%(\_s*[);]\)\@=\)\_s*\)*\)\@>\zs\_[^)]\+" contained
386syn match perlSubPrototype +(\_[^)]*)\_s*\|+ nextgroup=perlSubAttributes contained contains=perlSubPrototypeError
387syn match perlSubName +\%(\h\|::\|'\w\)\%(\w\|::\|'\w\)*\_s*\|+ contained nextgroup=perlSubPrototype
388
389syn match perlFunction +\<sub\>\_s*+ nextgroup=perlSubName
390
391if !exists("perl_no_scope_in_variables")
392   syn match  perlFunctionPRef	"\h\w*::" contained
393   syn match  perlFunctionName	"\h\w*[^:]" contained
394else
395   syn match  perlFunctionName	"\h[[:alnum:]_:]*" contained
396endif
397
398" The => operator forces a bareword to the left of it to be interpreted as
399" a string
400syn match  perlString "\I\@<!-\?\I\i*\%(\s*=>\)\@="
401
402" All other # are comments, except ^#!
403syn match  perlComment		"#.*" contains=perlTodo,@Spell
404syn match  perlSharpBang	"^#!.*"
405
406" Formats
407syn region perlFormat		matchgroup=perlStatementIOFunc start="^\s*\<format\s\+\k\+\s*=\s*$"rs=s+6 end="^\s*\.\s*$" contains=perlFormatName,perlFormatField,perlVarPlain,perlVarPlain2
408syn match  perlFormatName	"format\s\+\k\+\s*="lc=7,me=e-1 contained
409syn match  perlFormatField	"[@^][|<>~]\+\%(\.\.\.\)\=" contained
410syn match  perlFormatField	"[@^]#[#.]*" contained
411syn match  perlFormatField	"@\*" contained
412syn match  perlFormatField	"@[^A-Za-z_|<>~#*]"me=e-1 contained
413syn match  perlFormatField	"@$" contained
414
415" __END__ and __DATA__ clauses
416if exists("perl_fold")
417  syntax region perlDATA		start="^__\%(DATA\|END\)__$" skip="." end="." contains=perlPOD,@perlDATA fold
418else
419  syntax region perlDATA		start="^__\%(DATA\|END\)__$" skip="." end="." contains=perlPOD,@perlDATA
420endif
421
422command -nargs=+ HiLink hi def link <args>
423
424" The default highlighting.
425HiLink perlSharpBang		PreProc
426HiLink perlControl		PreProc
427HiLink perlInclude		Include
428HiLink perlSpecial		Special
429HiLink perlString		String
430HiLink perlCharacter		Character
431HiLink perlNumber		Number
432HiLink perlFloat		Float
433HiLink perlType			Type
434HiLink perlIdentifier		Identifier
435HiLink perlLabel		Label
436HiLink perlStatement		Statement
437HiLink perlConditional		Conditional
438HiLink perlRepeat		Repeat
439HiLink perlOperator		Operator
440HiLink perlFunction		Keyword
441HiLink perlSubName		Function
442HiLink perlSubPrototype		Type
443HiLink perlSubAttributes	PreProc
444HiLink perlSubAttributesCont	perlSubAttributes
445HiLink perlComment		Comment
446HiLink perlTodo			Todo
447if exists("perl_string_as_statement")
448  HiLink perlStringStartEnd	perlStatement
449else
450  HiLink perlStringStartEnd	perlString
451endif
452HiLink perlVStringV		perlStringStartEnd
453HiLink perlList			perlStatement
454HiLink perlMisc			perlStatement
455HiLink perlVarPlain		perlIdentifier
456HiLink perlVarPlain2		perlIdentifier
457HiLink perlArrow		perlIdentifier
458HiLink perlFiledescRead		perlIdentifier
459HiLink perlFiledescStatement	perlIdentifier
460HiLink perlVarSimpleMember	perlIdentifier
461HiLink perlVarSimpleMemberName 	perlString
462HiLink perlVarNotInMatches	perlIdentifier
463HiLink perlVarSlash		perlIdentifier
464HiLink perlQQ			perlString
465HiLink perlHereDoc		perlString
466HiLink perlStringUnexpanded	perlString
467HiLink perlSubstitutionSQ	perlString
468HiLink perlSubstitutionGQQ	perlString
469HiLink perlTranslationGQ	perlString
470HiLink perlMatch		perlString
471HiLink perlMatchStartEnd	perlStatement
472HiLink perlFormatName		perlIdentifier
473HiLink perlFormatField		perlString
474HiLink perlPackageDecl		perlType
475HiLink perlStorageClass		perlType
476HiLink perlPackageRef		perlType
477HiLink perlStatementPackage	perlStatement
478HiLink perlStatementStorage	perlStatement
479HiLink perlStatementControl	perlStatement
480HiLink perlStatementScalar	perlStatement
481HiLink perlStatementRegexp	perlStatement
482HiLink perlStatementNumeric	perlStatement
483HiLink perlStatementList	perlStatement
484HiLink perlStatementHash	perlStatement
485HiLink perlStatementIOfunc	perlStatement
486HiLink perlStatementFiledesc	perlStatement
487HiLink perlStatementVector	perlStatement
488HiLink perlStatementFiles	perlStatement
489HiLink perlStatementFlow	perlStatement
490HiLink perlStatementInclude	perlStatement
491HiLink perlStatementProc	perlStatement
492HiLink perlStatementSocket	perlStatement
493HiLink perlStatementIPC		perlStatement
494HiLink perlStatementNetwork	perlStatement
495HiLink perlStatementPword	perlStatement
496HiLink perlStatementTime	perlStatement
497HiLink perlStatementMisc	perlStatement
498HiLink perlStatementIndirObj	perlStatement
499HiLink perlFunctionName		perlIdentifier
500HiLink perlMethod		perlIdentifier
501HiLink perlFunctionPRef		perlType
502HiLink perlPOD			perlComment
503HiLink perlShellCommand		perlString
504HiLink perlSpecialAscii		perlSpecial
505HiLink perlSpecialDollar	perlSpecial
506HiLink perlSpecialString	perlSpecial
507HiLink perlSpecialStringU	perlSpecial
508HiLink perlSpecialMatch		perlSpecial
509HiLink perlDATA			perlComment
510
511" Possible errors
512HiLink perlNotEmptyLine		Error
513HiLink perlElseIfError		Error
514HiLink perlSubPrototypeError	Error
515HiLink perlSubError		Error
516
517delcommand HiLink
518
519" Syncing to speed up processing
520"
521if !exists("perl_no_sync_on_sub")
522  syn sync match perlSync	grouphere NONE "^\s*\<package\s"
523  syn sync match perlSync	grouphere NONE "^\s*\<sub\>"
524  syn sync match perlSync	grouphere NONE "^}"
525endif
526
527if !exists("perl_no_sync_on_global_var")
528  syn sync match perlSync	grouphere NONE "^$\I[[:alnum:]_:]+\s*=\s*{"
529  syn sync match perlSync	grouphere NONE "^[@%]\I[[:alnum:]_:]+\s*=\s*("
530endif
531
532if exists("perl_sync_dist")
533  execute "syn sync maxlines=" . perl_sync_dist
534else
535  syn sync maxlines=100
536endif
537
538syn sync match perlSyncPOD	grouphere perlPOD "^=pod"
539syn sync match perlSyncPOD	grouphere perlPOD "^=head"
540syn sync match perlSyncPOD	grouphere perlPOD "^=item"
541syn sync match perlSyncPOD	grouphere NONE "^=cut"
542
543let b:current_syntax = "perl"
544
545" XXX Change to sts=4:sw=4
546" vim:ts=8:sts=2:sw=2:expandtab:ft=vim
547