1" Vim syntax file
2" Language:         Zsh shell script
3" Maintainer:       Nikolai Weibull <now@bitwi.se>
4" Latest Revision:  2010-01-23
5
6if exists("b:current_syntax")
7  finish
8endif
9
10let s:cpo_save = &cpo
11set cpo&vim
12
13setlocal iskeyword+=-
14
15syn keyword zshTodo             contained TODO FIXME XXX NOTE
16
17syn region  zshComment          oneline start='\%(^\|\s\)#' end='$'
18                                \ contains=zshTodo,@Spell
19
20syn match   zshPreProc          '^\%1l#\%(!\|compdef\|autoload\).*$'
21
22syn match   zshQuoted           '\\.'
23syn region  zshString           matchgroup=zshStringDelimiter start=+"+ end=+"+
24                                \ contains=zshQuoted,@zshDerefs,@zshSubst
25syn region  zshString           matchgroup=zshStringDelimiter start=+'+ end=+'+
26" XXX: This should probably be more precise, but Zsh seems a bit confused about it itself
27syn region  zshPOSIXString      matchgroup=zshStringDelimiter start=+\$'+
28                                \ end=+'+ contains=zshQuoted
29syn match   zshJobSpec          '%\(\d\+\|?\=\w\+\|[%+-]\)'
30
31syn keyword zshPrecommand       noglob nocorrect exec command builtin - time
32
33syn keyword zshDelimiter        do done
34
35syn keyword zshConditional      if then elif else fi case in esac select
36
37syn keyword zshRepeat           while until repeat
38
39syn keyword zshRepeat           for foreach nextgroup=zshVariable skipwhite
40
41syn keyword zshException        always
42
43syn keyword zshKeyword          function nextgroup=zshKSHFunction skipwhite
44
45syn match   zshKSHFunction      contained '\k\+'
46syn match   zshFunction         '^\s*\k\+\ze\s*()'
47
48syn match   zshOperator         '||\|&&\|;\|&!\='
49
50syn match   zshRedir            '\d\=\(<\|<>\|<<<\|<&\s*[0-9p-]\=\)'
51syn match   zshRedir            '\d\=\(>\|>>\|>&\s*[0-9p-]\=\|&>\|>>&\|&>>\)[|!]\='
52syn match   zshRedir            '|&\='
53
54syn region  zshHereDoc          matchgroup=zshRedir
55                                \ start='<\@<!<<\s*\z([^<]\S*\)'
56                                \ end='^\z1\>'
57                                \ contains=@zshSubst
58syn region  zshHereDoc          matchgroup=zshRedir
59                                \ start='<\@<!<<\s*\\\z(\S\+\)'
60                                \ end='^\z1\>'
61                                \ contains=@zshSubst
62syn region  zshHereDoc          matchgroup=zshRedir
63                                \ start='<\@<!<<-\s*\\\=\z(\S\+\)'
64                                \ end='^\s*\z1\>'
65                                \ contains=@zshSubst
66syn region  zshHereDoc          matchgroup=zshRedir
67                                \ start=+<\@<!<<\s*\(["']\)\z(\S\+\)\1+ 
68                                \ end='^\z1\>'
69syn region  zshHereDoc          matchgroup=zshRedir
70                                \ start=+<\@<!<<-\s*\(["']\)\z(\S\+\)\1+
71                                \ end='^\s*\z1\>'
72
73syn match   zshVariable         '\<\h\w*' contained
74
75syn match   zshVariableDef      '\<\h\w*\ze+\=='
76" XXX: how safe is this?
77syn region  zshVariableDef      oneline
78                                \ start='\$\@<!\<\h\w*\[' end='\]\ze+\=='
79                                \ contains=@zshSubst
80
81syn cluster zshDerefs           contains=zshShortDeref,zshLongDeref,zshDeref
82
83if !exists("g:zsh_syntax_variables")
84  let s:zsh_syntax_variables = 'all'
85else
86  let s:zsh_syntax_variables = g:zsh_syntax_variables
87endif
88
89if s:zsh_syntax_variables =~ 'short\|all'
90  syn match zshShortDeref       '\$[!#$*@?_-]\w\@!'
91  syn match zshShortDeref       '\$[=^~]*[#+]*\d\+\>'
92endif
93
94if s:zsh_syntax_variables =~ 'long\|all'
95  syn match zshLongDeref        '\$\%(ARGC\|argv\|status\|pipestatus\|CPUTYPE\|EGID\|EUID\|ERRNO\|GID\|HOST\|LINENO\|LOGNAME\)'
96  syn match zshLongDeref        '\$\%(MACHTYPE\|OLDPWD OPTARG\|OPTIND\|OSTYPE\|PPID\|PWD\|RANDOM\|SECONDS\|SHLVL\|signals\)'
97  syn match zshLongDeref        '\$\%(TRY_BLOCK_ERROR\|TTY\|TTYIDLE\|UID\|USERNAME\|VENDOR\|ZSH_NAME\|ZSH_VERSION\|REPLY\|reply\|TERM\)'
98endif
99
100if s:zsh_syntax_variables =~ 'all'
101  syn match zshDeref            '\$[=^~]*[#+]*\h\w*\>'
102else
103  syn match zshDeref            transparent contains=NONE '\$[=^~]*[#+]*\h\w*\>'
104endif
105
106syn match   zshCommands         '\%(^\|\s\)[.:]\ze\s'
107syn keyword zshCommands         alias autoload bg bindkey break bye cap cd
108                                \ chdir clone comparguments compcall compctl
109                                \ compdescribe compfiles compgroups compquote
110                                \ comptags comptry compvalues continue dirs
111                                \ disable disown echo echotc echoti emulate
112                                \ enable eval exec exit export false fc fg
113                                \ functions getcap getln getopts hash history
114                                \ jobs kill let limit log logout popd print
115                                \ printf pushd pushln pwd r read readonly
116                                \ rehash return sched set setcap setopt shift
117                                \ source stat suspend test times trap true
118                                \ ttyctl type ulimit umask unalias unfunction
119                                \ unhash unlimit unset unsetopt vared wait
120                                \ whence where which zcompile zformat zftp zle
121                                \ zmodload zparseopts zprof zpty zregexparse
122                                \ zsocket zstyle ztcp
123
124syn keyword zshTypes            float integer local typeset declare
125
126" XXX: this may be too much
127" syn match   zshSwitches         '\s\zs--\=[a-zA-Z0-9-]\+'
128
129syn match   zshNumber           '[+-]\=\<\d\+\>'
130syn match   zshNumber           '[+-]\=\<0x\x\+\>'
131syn match   zshNumber           '[+-]\=\<0\o\+\>'
132syn match   zshNumber           '[+-]\=\d\+#[-+]\=\w\+\>'
133syn match   zshNumber           '[+-]\=\d\+\.\d\+\>'
134
135" TODO: $[...] is the same as $((...)), so add that as well.
136syn cluster zshSubst            contains=zshSubst,zshOldSubst,zshMathSubst
137syn region  zshSubst            matchgroup=zshSubstDelim transparent
138                                \ start='\$(' skip='\\)' end=')' contains=TOP
139syn region  zshParentheses      transparent start='(' skip='\\)' end=')'
140syn region  zshMathSubst        matchgroup=zshSubstDelim transparent
141                                \ start='\$((' skip='\\)'
142                                \ matchgroup=zshSubstDelim end='))'
143                                \ contains=zshParentheses,@zshSubst,zshNumber,
144                                \ @zshDerefs,zshString
145syn region  zshBrackets         contained transparent start='{' skip='\\}'
146                                \ end='}'
147syn region  zshSubst            matchgroup=zshSubstDelim start='\${' skip='\\}'
148                                \ end='}' contains=@zshSubst,zshBrackets,zshQuoted,zshString
149syn region  zshOldSubst         matchgroup=zshSubstDelim start=+`+ skip=+\\`+
150                                \ end=+`+ contains=TOP,zshOldSubst
151
152syn sync    minlines=50
153syn sync    match zshHereDocSync    grouphere   NONE '<<-\=\s*\%(\\\=\S\+\|\(["']\)\S\+\1\)'
154syn sync    match zshHereDocEndSync groupthere  NONE '^\s*EO\a\+\>'
155
156hi def link zshTodo             Todo
157hi def link zshComment          Comment
158hi def link zshPreProc          PreProc
159hi def link zshQuoted           SpecialChar
160hi def link zshString           String
161hi def link zshStringDelimiter  zshString
162hi def link zshPOSIXString      zshString
163hi def link zshJobSpec          Special
164hi def link zshPrecommand       Special
165hi def link zshDelimiter        Keyword
166hi def link zshConditional      Conditional
167hi def link zshException        Exception
168hi def link zshRepeat           Repeat
169hi def link zshKeyword          Keyword
170hi def link zshFunction         None
171hi def link zshKSHFunction      zshFunction
172hi def link zshHereDoc          String
173if 0
174  hi def link zshOperator         Operator
175else
176  hi def link zshOperator         None
177endif
178if 1
179  hi def link zshRedir            Operator
180else
181  hi def link zshRedir            None
182endif
183hi def link zshVariable         None
184hi def link zshVariableDef      zshVariable
185hi def link zshDereferencing    PreProc
186if s:zsh_syntax_variables =~ 'short\|all'
187  hi def link zshShortDeref     zshDereferencing
188else
189  hi def link zshShortDeref     None
190endif
191if s:zsh_syntax_variables =~ 'long\|all'
192  hi def link zshLongDeref      zshDereferencing
193else
194  hi def link zshLongDeref      None
195endif
196if s:zsh_syntax_variables =~ 'all'
197  hi def link zshDeref          zshDereferencing
198else
199  hi def link zshDeref          None
200endif
201hi def link zshCommands         Keyword
202hi def link zshTypes            Type
203hi def link zshSwitches         Special
204hi def link zshNumber           Number
205hi def link zshSubst            PreProc
206hi def link zshMathSubst        zshSubst
207hi def link zshOldSubst         zshSubst
208hi def link zshSubstDelim       zshSubst
209
210let b:current_syntax = "zsh"
211
212let &cpo = s:cpo_save
213unlet s:cpo_save
214