xref: /vim-8.2.3635/runtime/syntax/perl.vim (revision cf2d8dee)
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-07-23
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" unlet perl_nofold_packages
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
70
71syn region perlBraces start="{" end="}" transparent extend
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\|import\)\>"
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		"\<\%(accept\|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\|format\|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,perlBraces 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,perlBraces
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 extend
165  syn match  perlVarPlain	"\%(\$#\|[@$]\)\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod extend
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:]][[: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 extend
245syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m#+ end=+#[msixpodualgc]*+ contains=@perlInterpMatch keepend extend
246syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*'+ end=+'[msixpodualgc]*+ contains=@perlInterpSQ keepend extend
247syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*/+ end=+/[msixpodualgc]*+ contains=@perlInterpSlash keepend extend
248syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*(+ end=+)[msixpodualgc]*+ contains=@perlInterpMatch,perlParensDQ keepend extend
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 extend
252syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*<+ end=+>[msixpodualgc]*+ contains=@perlInterpMatch,perlAnglesDQ keepend extend
253syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!m\s*\[+ end=+\][msixpodualgc]*+ contains=@perlInterpMatch,perlComment,perlBracketsDQ keepend extend
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 extend
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 extend
263syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*'+  end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlSubstitutionSQ keepend extend
264syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*/+  end=+/+me=e-1 contains=@perlInterpSlash nextgroup=perlSubstitutionGQQ keepend extend
265syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s#+  end=+#+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionGQQ keepend extend
266syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*(+ end=+)+ contains=@perlInterpMatch,perlParensDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
267syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*<+ end=+>+ contains=@perlInterpMatch,perlAnglesDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
268syn region perlMatch	matchgroup=perlMatchStartEnd start=+\<\%(::\|'\|->\)\@<!s\s*\[+ end=+\]+ contains=@perlInterpMatch,perlBracketsDQ nextgroup=perlSubstitutionGQQ skipwhite skipempty skipnl keepend extend
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 extend
271syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+(+ end=+)[msixpodualgcer]*+ contained contains=@perlInterpDQ,perlParensDQ keepend extend
272syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+\[+ end=+\][msixpodualgcer]*+ contained contains=@perlInterpDQ,perlBracketsDQ keepend extend
273syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+{+ end=+}[msixpodualgcer]*+ contained contains=@perlInterpDQ,perlBracesDQ keepend extend extend
274syn region perlSubstitutionGQQ		matchgroup=perlMatchStartEnd start=+<+ end=+>[msixpodualgcer]*+ contained contains=@perlInterpDQ,perlAnglesDQ keepend extend
275syn region perlSubstitutionSQ		matchgroup=perlMatchStartEnd start=+'+  end=+'[msixpodualgcer]*+ contained contains=@perlInterpSQ keepend extend
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    else
421      syn region perlSubFold     start="^\z(\s*\)\<sub\>.*[^};]$" end="^\z1}\s*\%(#.*\)\=$" transparent fold keepend
422      syn region perlSubFold start="^\z(\s*\)\<\%(BEGIN\|END\|CHECK\|INIT\|UNITCHECK\)\>.*[^};]$" end="^\z1}\s*$" transparent fold keepend
423    endif
424  endif
425
426  if exists("perl_fold_blocks")
427    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
428    syn region perlBlockFold start="^\z(\s*\)\%(do\|else\)\%(\s*{\)\=\s*\%(#.*\)\=$" end="^\z1}\s*while" end="^\z1}\s*;\=\%(#.*\)\=$" transparent fold keepend
429  endif
430
431  setlocal foldmethod=syntax
432  syn sync fromstart
433else
434  " fromstart above seems to set minlines even if perl_fold is not set.
435  syn sync minlines=0
436endif
437
438command -nargs=+ HiLink hi def link <args>
439
440" NOTE: If you're linking new highlight groups to perlString, please also put
441"       them into b:match_skip in ftplugin/perl.vim.
442
443" The default highlighting.
444HiLink perlSharpBang		PreProc
445HiLink perlControl		PreProc
446HiLink perlInclude		Include
447HiLink perlSpecial		Special
448HiLink perlString		String
449HiLink perlCharacter		Character
450HiLink perlNumber		Number
451HiLink perlFloat		Float
452HiLink perlType			Type
453HiLink perlIdentifier		Identifier
454HiLink perlLabel		Label
455HiLink perlStatement		Statement
456HiLink perlConditional		Conditional
457HiLink perlRepeat		Repeat
458HiLink perlOperator		Operator
459HiLink perlFunction		Keyword
460HiLink perlSubName		Function
461HiLink perlSubPrototype		Type
462HiLink perlSubAttributes	PreProc
463HiLink perlSubAttributesCont	perlSubAttributes
464HiLink perlComment		Comment
465HiLink perlTodo			Todo
466if exists("perl_string_as_statement")
467  HiLink perlStringStartEnd	perlStatement
468else
469  HiLink perlStringStartEnd	perlString
470endif
471HiLink perlVStringV		perlStringStartEnd
472HiLink perlList			perlStatement
473HiLink perlMisc			perlStatement
474HiLink perlVarPlain		perlIdentifier
475HiLink perlVarPlain2		perlIdentifier
476HiLink perlArrow		perlIdentifier
477HiLink perlFiledescRead		perlIdentifier
478HiLink perlFiledescStatement	perlIdentifier
479HiLink perlVarSimpleMember	perlIdentifier
480HiLink perlVarSimpleMemberName 	perlString
481HiLink perlVarNotInMatches	perlIdentifier
482HiLink perlVarSlash		perlIdentifier
483HiLink perlQQ			perlString
484HiLink perlHereDoc		perlString
485HiLink perlStringUnexpanded	perlString
486HiLink perlSubstitutionSQ	perlString
487HiLink perlSubstitutionGQQ	perlString
488HiLink perlTranslationGQ	perlString
489HiLink perlMatch		perlString
490HiLink perlMatchStartEnd	perlStatement
491HiLink perlFormatName		perlIdentifier
492HiLink perlFormatField		perlString
493HiLink perlPackageDecl		perlType
494HiLink perlStorageClass		perlType
495HiLink perlPackageRef		perlType
496HiLink perlStatementPackage	perlStatement
497HiLink perlStatementStorage	perlStatement
498HiLink perlStatementControl	perlStatement
499HiLink perlStatementScalar	perlStatement
500HiLink perlStatementRegexp	perlStatement
501HiLink perlStatementNumeric	perlStatement
502HiLink perlStatementList	perlStatement
503HiLink perlStatementHash	perlStatement
504HiLink perlStatementIOfunc	perlStatement
505HiLink perlStatementFiledesc	perlStatement
506HiLink perlStatementVector	perlStatement
507HiLink perlStatementFiles	perlStatement
508HiLink perlStatementFlow	perlStatement
509HiLink perlStatementInclude	perlStatement
510HiLink perlStatementProc	perlStatement
511HiLink perlStatementSocket	perlStatement
512HiLink perlStatementIPC		perlStatement
513HiLink perlStatementNetwork	perlStatement
514HiLink perlStatementPword	perlStatement
515HiLink perlStatementTime	perlStatement
516HiLink perlStatementMisc	perlStatement
517HiLink perlStatementIndirObj	perlStatement
518HiLink perlFunctionName		perlIdentifier
519HiLink perlMethod		perlIdentifier
520HiLink perlFunctionPRef		perlType
521HiLink perlPOD			perlComment
522HiLink perlShellCommand		perlString
523HiLink perlSpecialAscii		perlSpecial
524HiLink perlSpecialDollar	perlSpecial
525HiLink perlSpecialString	perlSpecial
526HiLink perlSpecialStringU	perlSpecial
527HiLink perlSpecialMatch		perlSpecial
528HiLink perlDATA			perlComment
529
530" NOTE: Due to a bug in Vim (or more likely, a misunderstanding on my part),
531"       I had to remove the transparent property from the following regions
532"       in order to get them to highlight correctly.  Feel free to remove
533"       these and reinstate the transparent property if you know how.
534HiLink perlParensSQ		perlString
535HiLink perlBracketsSQ		perlString
536HiLink perlBracesSQ		perlString
537HiLink perlAnglesSQ		perlString
538
539HiLink perlParensDQ		perlString
540HiLink perlBracketsDQ		perlString
541HiLink perlBracesDQ		perlString
542HiLink perlAnglesDQ		perlString
543
544HiLink perlSpecialStringU2	perlString
545
546" Possible errors
547HiLink perlNotEmptyLine		Error
548HiLink perlElseIfError		Error
549HiLink perlSubPrototypeError	Error
550HiLink perlSubError		Error
551
552delcommand HiLink
553
554" Syncing to speed up processing
555"
556if !exists("perl_no_sync_on_sub")
557  syn sync match perlSync	grouphere NONE "^\s*\<package\s"
558  syn sync match perlSync	grouphere NONE "^\s*\<sub\>"
559  syn sync match perlSync	grouphere NONE "^}"
560endif
561
562if !exists("perl_no_sync_on_global_var")
563  syn sync match perlSync	grouphere NONE "^$\I[[:alnum:]_:]+\s*=\s*{"
564  syn sync match perlSync	grouphere NONE "^[@%]\I[[:alnum:]_:]+\s*=\s*("
565endif
566
567if exists("perl_sync_dist")
568  execute "syn sync maxlines=" . perl_sync_dist
569else
570  syn sync maxlines=100
571endif
572
573syn sync match perlSyncPOD	grouphere perlPOD "^=pod"
574syn sync match perlSyncPOD	grouphere perlPOD "^=head"
575syn sync match perlSyncPOD	grouphere perlPOD "^=item"
576syn sync match perlSyncPOD	grouphere NONE "^=cut"
577
578let b:current_syntax = "perl"
579
580if exists('&regexpengine')
581  let &regexpengine=s:regexpengine
582  unlet s:regexpengine
583endif
584
585let &cpo = s:cpo_save
586unlet s:cpo_save
587
588" XXX Change to sts=4:sw=4
589" vim:ts=8:sts=2:sw=2:expandtab:ft=vim
590