" We do not process complex things such as @{${"foo"}}. Too complicated, and
" too slow. And what is after the -> is *not* considered as part of the
" variable - there again, too complicated and too slow.
" Special variables first ($^A, ...) and ($|, $', ...)
syn match perlVarPlain "$^[\u\\\"\[\]'&`+*.,;=%~^!@$<>(0-9-]"
syn match perlVarPlain "$[\\\"\[\]'&`+*.,;=%~^!@$<>(0-9-]"
" Same as above, but avoids confusion in $::hello (equivalent to $main::hello)
syn match perlVarPlain "$:[^:]"
" These variables are not recognized within matches.
syn match perlVarNotInMatches "$[|)]"
" This variable is not recognized within matches delimited by //.
syn match perlVarSlash "$/"
" And plain identifiers
syn match perlPackageRef "\(\h\w*\)\=\(::\|'\)\I"me=e-1 contained
" To highlight packages in variables as a scope reference - i.e. in $pack::var,
" pack:: is a scope, just set "perl_want_scope_in_variables"
" If you *want* complex things like @{${"foo"}} to be processed,
" just set the variable "perl_extended_vars"...
if exists("perl_want_scope_in_variables")
syn match perlVarPlain "\\\=\(\$#\|[@%&$]\)\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember
else
syn match perlVarPlain "\\\=\(\$#\|[@%&$]\)\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember
endif
if exists("perl_extended_vars")
syn region perlVarPlain start="\($#\|[@%\$]\){" skip="\\}" end="}" contains=perlVarPlain,perlVarNotInMatches,perlVarSlash nextgroup=perlVarMember
syn region perlVarMember start="\(->\)\={" skip="\\}" end="}" contained contains=perlVarPlain,perlVarNotInMatches,perlVarSlash nextgroup=perlVarMember
syn region perlVarMember start="\(->\)\=\[" skip="\\]" end="]" contained contains=perlVarPlain,perlVarNotInMatches,perlVarSlash nextgroup=perlVarMember
endif
"
" String and Character constants
"
" Highlight special characters (those which have a backslash) differently
syn match perlSpecial contained "\\\(\d\+\|[xX]\x\+\|.\)"
" "" String may contain variables
syn match perlCharacter "'[^\\]'"
syn match perlSpecialCharacter "'\\.'"
" version < 5.2f
"syn match perlSpecialCharacter "'\\[0-9][0-9][0-9]'"
" versions >= 5.2f
syn match perlSpecialCharacter "'\\\d\d\d'"
" Strings
syn region perlString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=perlSpecial,perlVarPlain,perlVarNotInMatches,perlVarSlash
" '' Strings may not contain anything
syn region perlStringUnexpanded start=+'+ skip=+\\\\\|\\"+ end=+'+
"contains=perlSpecial
syn region perlStringUnexpanded start="qw("hs=s+2 skip="\\\\\|\\)" end=")"
"contains=perlSpecial
" Shell commands
syn region perlShellCommand start=+`+ skip=+\\\\\|\\"+ end=+`+ contains=perlSpecial,perlVarPlain
" Numbers
syn match perlNumber "-\=\<\d\+L\=\>\|0[xX]\x\+\>"
" Constructs such as print <<EOF [...] EOF
syn region perlUntilEOF start=+<<\(["`]\=\)EOF\1+hs=s+2 end=+^EOF$+ contains=perlSpecial,perlVarPlain,perlVarNotInMatches,perlVarSlash
syn region perlUntilEOF start=+<<'EOF'+hs=s+2 end=+^EOF$+ contains=perlSpecial
" When vim supports it, try to use something as
" syntax region perlUntilEOF start=+<<\(["`]\=\)\([a-zA-Z]\+\)\1+s+2 end=+^\2$+
" to allow any keyword, not just EOF. The \2 in the end pattern refers of
" course to the second group in the start pattern.
"
" Perl regexps, second version, thanks to Michael Firestone
"
" any qq## expression
syn match perlQQ "\<q[qxw]\=\([^\s\w]\).*[^\\]\(\\\\\)*\1" contains=perlVarPlain, perlVarSlash
" Any m## match
syn match perlMatchAny "\<m\([^\s\w]\).*[^\\]\(\\\\\)*\1[xosmige]*" contains=perlVarPlain,perlVarSlash
" Plain m// match
syn match perlMatchAny "\<m/.*[^\\]\(\\\\\)*/[xosmige]*" contains=perlVarPlain
" Any s### substitute
" s/// is handled separately, since it can't contain $/ as a variable.
syn match perlSubstitute "\<s\([^\w\s]\).\{-}[^\\]\(\\\\\)*\1.\{-}[^\\]\(\\\\\)*\1[xosmige]*" contains=perlVarPlain,perlVarSlash
syn match perlSubstitute "\<\(s\|y\|tr\)/.\{-}[^\\]\(\\\\\)*/.\{-}[^\\]\(\\\\\)*/[xosmige]*" contains=perlVarPlain
" Note that the above rules don't match substitutions with empty
" replacement texts (like s/deleteme//); these rules cover those.
syn match perlSubstitute "\<s\([^\w\s]\).\{-}[^\\]\(\\\\\)*\1\1[xosmige]*" contains=perlVarPlain,perlVarSlash
syn match perlSubstitute "\<\(s\|y\|tr\)/.\{-}[^\\]\(\\\\\)*//[xosmige]*" contains=perlVarPlain
" The classical // construct
syn match perlMatch "/\(\\/\|[^/]\)*[^\\]\(\\\\\)*/[xosmige]*" contains=perlVarPlain
syn match perlClassDecl "^\s*package\>[^;]*"
"syn match perlLineSkip "\\$"
"
" Functions
"
" find ^sub foo { . Only highlight foo.
" Function is sub foo { , sub foo( , sub foo;
" Sneaky: Instead of terminating the region at a '(' (the start of a
" prototype), contain the prototype in the region and give it no
" highlighting; that way, things inside the prototype that look like
" variables won't be highlighted as variables.
syn region perlFunction start=+^\s*sub\s\++ end=+[;{]+me=s-1 contains=perlFunction,perlFunctionPrototype
syn match perlFunctionPrototype "([^)]*)" contained
syn match perlStatementSub "sub" contained
if !exists("did_perl_syntax_inits")
let did_perl_syntax_inits = 1
" The default methods for highlighting. Can be overridden later
hi link perlSharpBang PreProc
hi link perlLabel Label
hi link perlConditional Conditional
hi link perlRepeat Repeat
hi link perlOperator Operator
hi link perlList perlStatement
hi link perlMisc perlStatement
hi link perlVarPlain perlIdentifier
hi link perlVarMember perlIdentifier
hi link perlVarNotInMatches perlIdentifier
hi link perlVarSlash perlIdentifier
hi link perlQQ perlString
hi link perlUntilEOF perlString
hi link perlStringUnexpanded perlString
hi link perlCharacter Character
hi link perlSpecialCharacter perlSpecial
hi link perlMatchAny perlMatch
hi link perlSubstitute perlMatch
" I happen to prefer having matches and substitutions highlighted; if you
" agree, set the variable "perl_highlight_matches".