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