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