xref: /vim-8.2.3635/runtime/syntax/perl.vim (revision bb76f24a)
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
438
439" NOTE: If you're linking new highlight groups to perlString, please also put
440"       them into b:match_skip in ftplugin/perl.vim.
441
442" The default highlighting.
443hi def link perlSharpBang		PreProc
444hi def link perlControl		PreProc
445hi def link perlInclude		Include
446hi def link perlSpecial		Special
447hi def link perlString		String
448hi def link perlCharacter		Character
449hi def link perlNumber		Number
450hi def link perlFloat		Float
451hi def link perlType			Type
452hi def link perlIdentifier		Identifier
453hi def link perlLabel		Label
454hi def link perlStatement		Statement
455hi def link perlConditional		Conditional
456hi def link perlRepeat		Repeat
457hi def link perlOperator		Operator
458hi def link perlFunction		Keyword
459hi def link perlSubName		Function
460hi def link perlSubPrototype		Type
461hi def link perlSubAttributes	PreProc
462hi def link perlSubAttributesCont	perlSubAttributes
463hi def link perlComment		Comment
464hi def link perlTodo			Todo
465if exists("perl_string_as_statement")
466  hi def link perlStringStartEnd	perlStatement
467else
468  hi def link perlStringStartEnd	perlString
469endif
470hi def link perlVStringV		perlStringStartEnd
471hi def link perlList			perlStatement
472hi def link perlMisc			perlStatement
473hi def link perlVarPlain		perlIdentifier
474hi def link perlVarPlain2		perlIdentifier
475hi def link perlArrow		perlIdentifier
476hi def link perlFiledescRead		perlIdentifier
477hi def link perlFiledescStatement	perlIdentifier
478hi def link perlVarSimpleMember	perlIdentifier
479hi def link perlVarSimpleMemberName 	perlString
480hi def link perlVarNotInMatches	perlIdentifier
481hi def link perlVarSlash		perlIdentifier
482hi def link perlQQ			perlString
483hi def link perlHereDoc		perlString
484hi def link perlStringUnexpanded	perlString
485hi def link perlSubstitutionSQ	perlString
486hi def link perlSubstitutionGQQ	perlString
487hi def link perlTranslationGQ	perlString
488hi def link perlMatch		perlString
489hi def link perlMatchStartEnd	perlStatement
490hi def link perlFormatName		perlIdentifier
491hi def link perlFormatField		perlString
492hi def link perlPackageDecl		perlType
493hi def link perlStorageClass		perlType
494hi def link perlPackageRef		perlType
495hi def link perlStatementPackage	perlStatement
496hi def link perlStatementStorage	perlStatement
497hi def link perlStatementControl	perlStatement
498hi def link perlStatementScalar	perlStatement
499hi def link perlStatementRegexp	perlStatement
500hi def link perlStatementNumeric	perlStatement
501hi def link perlStatementList	perlStatement
502hi def link perlStatementHash	perlStatement
503hi def link perlStatementIOfunc	perlStatement
504hi def link perlStatementFiledesc	perlStatement
505hi def link perlStatementVector	perlStatement
506hi def link perlStatementFiles	perlStatement
507hi def link perlStatementFlow	perlStatement
508hi def link perlStatementInclude	perlStatement
509hi def link perlStatementProc	perlStatement
510hi def link perlStatementSocket	perlStatement
511hi def link perlStatementIPC		perlStatement
512hi def link perlStatementNetwork	perlStatement
513hi def link perlStatementPword	perlStatement
514hi def link perlStatementTime	perlStatement
515hi def link perlStatementMisc	perlStatement
516hi def link perlStatementIndirObj	perlStatement
517hi def link perlFunctionName		perlIdentifier
518hi def link perlMethod		perlIdentifier
519hi def link perlFunctionPRef		perlType
520hi def link perlPOD			perlComment
521hi def link perlShellCommand		perlString
522hi def link perlSpecialAscii		perlSpecial
523hi def link perlSpecialDollar	perlSpecial
524hi def link perlSpecialString	perlSpecial
525hi def link perlSpecialStringU	perlSpecial
526hi def link perlSpecialMatch		perlSpecial
527hi def link perlDATA			perlComment
528
529" NOTE: Due to a bug in Vim (or more likely, a misunderstanding on my part),
530"       I had to remove the transparent property from the following regions
531"       in order to get them to highlight correctly.  Feel free to remove
532"       these and reinstate the transparent property if you know how.
533hi def link perlParensSQ		perlString
534hi def link perlBracketsSQ		perlString
535hi def link perlBracesSQ		perlString
536hi def link perlAnglesSQ		perlString
537
538hi def link perlParensDQ		perlString
539hi def link perlBracketsDQ		perlString
540hi def link perlBracesDQ		perlString
541hi def link perlAnglesDQ		perlString
542
543hi def link perlSpecialStringU2	perlString
544
545" Possible errors
546hi def link perlNotEmptyLine		Error
547hi def link perlElseIfError		Error
548hi def link perlSubPrototypeError	Error
549hi def link perlSubError		Error
550
551
552" Syncing to speed up processing
553"
554if !exists("perl_no_sync_on_sub")
555  syn sync match perlSync	grouphere NONE "^\s*\<package\s"
556  syn sync match perlSync	grouphere NONE "^\s*\<sub\>"
557  syn sync match perlSync	grouphere NONE "^}"
558endif
559
560if !exists("perl_no_sync_on_global_var")
561  syn sync match perlSync	grouphere NONE "^$\I[[:alnum:]_:]+\s*=\s*{"
562  syn sync match perlSync	grouphere NONE "^[@%]\I[[:alnum:]_:]+\s*=\s*("
563endif
564
565if exists("perl_sync_dist")
566  execute "syn sync maxlines=" . perl_sync_dist
567else
568  syn sync maxlines=100
569endif
570
571syn sync match perlSyncPOD	grouphere perlPOD "^=pod"
572syn sync match perlSyncPOD	grouphere perlPOD "^=head"
573syn sync match perlSyncPOD	grouphere perlPOD "^=item"
574syn sync match perlSyncPOD	grouphere NONE "^=cut"
575
576let b:current_syntax = "perl"
577
578if exists('&regexpengine')
579  let &regexpengine=s:regexpengine
580  unlet s:regexpengine
581endif
582
583let &cpo = s:cpo_save
584unlet s:cpo_save
585
586" XXX Change to sts=4:sw=4
587" vim:ts=8:sts=2:sw=2:expandtab:ft=vim
588