2 " Language: shell (sh) Korn shell (ksh) bash (sh)
3 " Maintainer: Dr. Charles E. Campbell, Jr. <Charles.E.Campbell.1@gsfc.nasa.gov>
4 " Previous Maintainer: Lennart Schultz <Lennart.Schultz@ecmwf.int>
5 " Last Change: May 1, 2001
8 " Using the following VIM variables:
9 " b:is_kornshell if defined, enhance with kornshell syntax
10 " b:is_bash if defined, enhance with bash syntax
11 " is_kornshell if neither b:is_kornshell or b:is_bash is
12 " defined, then if is_kornshell is set
13 " b:is_kornshell is default
14 " is_bash if none of the previous three variables are
15 " defined, then if is_bash is set b:is_bash is default
17 " This file includes many ideas from Éric Brunet (eric.brunet@ens.fr)
19 " For version 5.x: Clear all syntax items
20 " For version 6.x: Quit when a syntax file was already loaded
23 elseif exists("b:current_syntax")
27 " b:is_sh is set when "#! /bin/sh" is found;
28 " However, it often is just a masquerade by bash or kornshell.
29 " So, when the user to set "is_bash" or "is_kornshell",
30 " a b:is_sh is converted into b:is_bash/b:is_kornshell,
32 if !exists("b:is_kornshell") && !exists("b:is_bash")
33 if exists("is_kornshell")
38 elseif exists("is_bash")
48 " sh syntax is case sensitive
51 " This one is needed INSIDE a CommandSub, so that
52 " `echo bla` be correct
53 syn cluster shEchoList contains=shNumber,shArithmetic,shCommandSub,shSinglequote,shDeref,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass
54 syn region shEcho matchgroup=shStatement start="\<echo\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList
55 syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList
57 " This must be after the strings, so that bla \" be correct
58 syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shSinglequote,shDeref,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass
61 syn match shDoError "\<done\>"
62 syn match shIfError "\<fi\>"
63 syn match shInError "\<in\>"
64 syn match shCaseError ";;"
65 syn match shEsacError "\<esac\>"
66 syn match shCurlyError "}"
67 syn match shParenError ")"
68 if exists("b:is_kornshell")
69 syn match shDTestError "]]"
71 syn match shTestError "]"
74 syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
75 syn match shOption "\s--\S\+"ms=s+1
79 syn cluster shErrorList contains=shCaseError,shCurlyError,shDTestError,shDerefError,shDoError,shEsacError,shIfError,shInError,shParenError,shTestError
80 syn cluster shErrorFuncList contains=shDerefError
81 syn cluster shErrorLoopList contains=shCaseError,shDTestError,shDerefError,shDoError,shInError,shParenError,shTestError
82 syn cluster shErrorCaseList contains=shCaseError,shDerefError,shDTestError,shDoError,shInError,shParenError,shTestError
83 syn cluster shErrorColonList contains=shDerefError
84 syn cluster shErrorNoneList contains=shDerefError
86 " clusters: contains=@... clusters
87 "==================================
88 syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shCommandSub
89 syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shSpecial
90 syn cluster shDblQuoteList contains=shCommandSub,shDeref,shSpecial,shPosnParm
92 " clusters: contains=ALLBUT,@... clusters
93 "=========================================
94 syn cluster shCaseList contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDerefOp,shDerefText,@shErrorCaseList,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
95 syn cluster shColonList contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDerefOp,shDerefText,shFunction,shTestOpr,@shErrorColonList,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
96 syn cluster shCommandSubList1 contains=shCase,shCaseStart,shCaseBar,shDblBrace,shCommandSub,shDerefOp,shDerefText,shEcho,shFunction,shTestOpr,@shErrorList,shDerefVar,shDerefOpError,shStringSpecial,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
97 syn cluster shCommandSubList2 contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDerefOp,shDerefText,shEcho,shFunction,shTestOpr,@shErrorList,shDerefVar,shDerefOpError,shStringSpecial,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
98 syn cluster shLoopList contains=@shErrorLoopList,shCase,shCaseStart,shInEsac,shCaseBar,shDerefOp,shDerefText,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
99 syn cluster shExprList1 contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDerefOp,shDerefText,shFunction,shSetList,@shErrorNoneList,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
100 syn cluster shExprList2 contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDerefOp,shDerefText,@shErrorNoneList,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
101 syn cluster shSubShList contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDerefOp,shDerefText,shParenError,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shDerefError,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
102 syn cluster shTestList contains=shCase,shCaseStart,shCaseBar,shDblBrace,shDTestError,shDerefError,shDerefOp,shDerefText,shExpr,shFunction,shSetList,shTestError,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
103 syn cluster shFunctionList contains=shCase,shCaseStart,shCaseBar,shDblBrace,@shErrorFuncList,shDerefOp,shDerefText,shFunction,shDerefVar,shDerefOpError,shStringSpecial,shSkipInitWS,shIdWhiteSpace,shDerefTextError,shPattern,shSetIdentifier
107 syn region shExpr transparent matchgroup=shOperator start="\[" skip=+\\\\\|\\$+ end="\]" contains=ALLBUT,@shTestList
108 syn region shExpr transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=ALLBUT,@shExprList1
109 if exists("b:is_kornshell")
110 syn region shDblBrace transparent matchgroup=shOperator start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=ALLBUT,@shTestList
112 syn match shTestOpr contained "[!=]\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>"
115 syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=ALLBUT,@shLoopList
116 syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<fi\>" contains=ALLBUT,@shLoopList
117 syn region shFor matchgroup=shStatement start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=ALLBUT,@shLoopList
120 syn region shCaseEsac matchgroup=shConditional start="\<case\>" matchgroup=shConditional end="\<esac\>" contains=@shCaseEsacList
121 syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment
122 syn region shCase contained skipwhite skipnl matchgroup=shConditional start="[^$()]\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=ALLBUT,@shCaseList nextgroup=shCase,shCaseStart,shCaseBar,shComment
123 syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase
124 syn match shCaseBar contained "[^|)]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar
126 syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=ALLBUT,@shExprList2
127 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=ALLBUT,@shSubShList
131 syn match shOperator "[!&;|]"
132 syn match shOperator "\[\[[^:]\|]]"
133 syn match shCharClass "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
134 syn match shOperator "!\==" skipwhite nextgroup=shPattern
135 syn match shPattern "\<\S\+" contained contains=shSinglequote,shDoublequote,shDeref
136 syn match shWrapLineOperator "\\$"
137 syn region shCommandSub start="`" skip="\\`" end="`" contains=ALLBUT,@shCommandSubList1
139 " $(..) is not supported by sh (Bourne shell). However, apparently
140 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
141 " (ie. Posix compliant shell). /bin/ksh should work for those
142 " systems too, however, so the following syntax will flag $(..) as
143 " an Error under /bin/sh. By consensus of vimdev'ers!
144 if exists("b:is_kornshell") || exists("b:is_bash")
145 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" end=")" contains=ALLBUT,@shCommandSubList2
146 syn region shArithmetic matchgroup=shArithRegion start="\$((" end="))" contains=ALLBUT,@shCommandSubList2
147 syn match shSkipInitWS contained "^\s\+"
149 syn region shCommandSub matchgroup=Error start="$(" end=")" contains=ALLBUT,@shCommandSubList2
152 if exists("b:is_bash")
153 syn keyword bashSpecialVariables contained BASH HISTCONTROL LANG OPTERR PWD
154 syn keyword bashSpecialVariables contained BASH_ENV HISTFILE LC_ALL OPTIND RANDOM
155 syn keyword bashSpecialVariables contained BASH_VERSINFO HISTFILESIZE LC_COLLATE OSTYPE REPLY
156 syn keyword bashSpecialVariables contained BASH_VERSION HISTIGNORE LC_MESSAGES PATH SECONDS
157 syn keyword bashSpecialVariables contained CDPATH HISTSIZE LINENO PIPESTATUS SHELLOPTS
158 syn keyword bashSpecialVariables contained DIRSTACK HOME MACHTYPE PPID SHLVL
159 syn keyword bashSpecialVariables contained EUID HOSTFILE MAIL PROMPT_COMMAND TIMEFORMAT
160 syn keyword bashSpecialVariables contained FCEDIT HOSTNAME MAILCHECK PS1 TIMEOUT
161 syn keyword bashSpecialVariables contained FIGNORE HOSTTYPE MAILPATH PS2 UID
162 syn keyword bashSpecialVariables contained GLOBIGNORE IFS OLDPWD PS3 auto_resume
163 syn keyword bashSpecialVariables contained GROUPS IGNOREEOF OPTARG PS4 histchars
164 syn keyword bashSpecialVariables contained HISTCMD INPUTRC
165 syn keyword bashStatement chmod fgrep install rm sort
166 syn keyword bashStatement clear find less rmdir strip
167 syn keyword bashStatement du gnufind ls rpm tail
168 syn keyword bashStatement egrep gnugrep mkdir sed touch
169 syn keyword bashStatement expr grep mv sleep complete
170 syn keyword bashAdminStatement daemon killproc reload start stop
171 syn keyword bashAdminStatement killall nice restart status
174 if exists("b:is_kornshell")
175 syn keyword kshSpecialVariables contained CDPATH HISTFILE MAILCHECK PPID RANDOM
176 syn keyword kshSpecialVariables contained COLUMNS HISTSIZE MAILPATH PS1 REPLY
177 syn keyword kshSpecialVariables contained EDITOR HOME OLDPWD PS2 SECONDS
178 syn keyword kshSpecialVariables contained ENV IFS OPTARG PS3 SHELL
179 syn keyword kshSpecialVariables contained ERRNO LINENO OPTIND PS4 TMOUT
180 syn keyword kshSpecialVariables contained FCEDIT LINES PATH PWD VISUAL
181 syn keyword kshSpecialVariables contained FPATH MAIL
182 syn keyword kshStatement cat expr less printenv strip
183 syn keyword kshStatement chmod fgrep ls rm stty
184 syn keyword kshStatement clear find mkdir rmdir tail
185 syn keyword kshStatement cp grep mv sed touch
186 syn keyword kshStatement du install nice sort tput
187 syn keyword kshStatement egrep killall
190 syn match shSource "^\.\s"
191 syn match shSource "\s\.\s"
192 syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=ALLBUT,@shColonList
196 syn keyword shTodo contained TODO
197 syn cluster shCommentGroup contains=shTodo
198 syn match shComment "#.*$" contains=@shCommentGroup
200 " String and Character constants
201 "===============================
202 syn match shNumber "-\=\<\d\+\>"
203 syn match shSpecial contained "\\\d\d\d\|\\[abcfnrtv]"
204 syn region shSinglequote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
205 syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
206 syn match shStringSpecial contained "[^[:print:]]"
207 syn match shSpecial "\\[\\\"\'`$]"
209 " File redirection highlighted as operators
210 "==========================================
211 syn match shRedir "\d\=>\(&[-0-9]\)\="
212 syn match shRedir "\d\=>>-\="
213 syn match shRedir "\d\=<\(&[-0-9]\)\="
214 syn match shRedir "\d<<-\="
216 " Shell Input Redirection (Here Documents)
218 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$"
219 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^\t*END[a-zA-Z_0-9]*$"
220 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$"
221 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\t*EOF$"
222 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$"
223 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\t*\.$"
225 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\z(\h\w*\)\**" matchgroup=shRedir end="^\z1$"
226 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\z(\h\w*\)\**" matchgroup=shRedir end="^\t*\z1$"
231 syn match shVariable "\<\h\w*="me=e-1 nextgroup=shSetIdentifier
232 syn match shIdWhiteSpace contained "\s"
233 syn match shSetIdentifier contained "=" nextgroup=shString,shPattern
234 if exists("b:is_bash")
235 syn region shSetList matchgroup=shStatement start="\<\(declare\|typeset\|local\|export\|set\|unset\)\>[^/]"me=e-1 end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
236 elseif exists("b:is_kornshell")
237 syn region shSetList matchgroup=shStatement start="\<\(typeset\|set\|export\|unset\)\>[^/]"me=e-1 end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
239 syn region shSetList matchgroup=shStatement start="\<\(set\|export\|unset\)\>[^/]"me=e-1 end="$" matchgroup=shOperator end="[;&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
242 " The [^/] in the start pattern is a kludge to avoid bad
243 " highlighting with cd /usr/local/lib...
244 syn region shFunction transparent matchgroup=shFunctionName start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=ALLBUT,@shFunctionList
245 syn region shDeref oneline start="\${" end="}" contains=shDeref,shDerefVar
246 syn match shDeref "\$\h\w*\>"
247 syn match shPosnParm "\$[-#@*$?!0-9]"
248 syn match shDerefVar contained "\d\+\>" nextgroup=shDerefOp,shDerefError,shDerefOpError,shExpr
249 syn match shDerefVar contained "\h\w*\>" nextgroup=shDerefOp,shDerefError,shDerefOpError,shExpr
250 if exists("b:is_bash")
251 syn match shDerefVar contained "[-@*?!]" nextgroup=shDerefOp,shDerefError,shDerefOpError,shExpr
253 syn match shDerefVar contained "[-#@*?!]" nextgroup=shDerefOp,shDerefError,shDerefOpError,shExpr
255 syn match shDerefVar contained "\$[^{(]"me=s+1 nextgroup=shDerefOp,shDerefError,shDerefOpError,shExpr
256 syn match shDerefOpError contained "[^:}[]"
257 syn match shDerefOp contained ":\=[-=?+]" nextgroup=shDerefText
258 syn region shDerefText contained start="[^{}]" end="}"me=e-1 contains=shDeref,shCommandSub,shDoubleQuote,shSingleQuote,shDerefTextError
259 syn match shDerefTextError contained "^."
260 syn match shDerefError contained "\s.\{-}}"me=e-1
261 syn region shDerefText contained start="{" end="}" contains=shDeref,shCommandSub
263 if exists("b:is_kornshell") || exists("b:is_bash")
264 syn match shDerefVar contained "#\(\d\+\|\h\w*\)" nextgroup=shDerefOp,shDerefError,shDerefOpError,shExpr
265 syn match shDerefOp contained "##\|%%\|[#%]" nextgroup=shDerefText
268 " A bunch of useful sh keywords
269 syn keyword shStatement break eval newgrp return ulimit
270 syn keyword shStatement cd exec pwd shift umask
271 syn keyword shStatement chdir exit read test wait
272 syn keyword shStatement continue kill readonly trap
273 syn keyword shConditional elif else then while
275 if exists("b:is_kornshell") || exists("b:is_bash")
276 syn keyword shFunction function
277 syn keyword shRepeat select until
278 syn keyword shStatement alias fg integer printf times
279 syn keyword shStatement autoload functions jobs r true
280 syn keyword shStatement bg getopts let stop type
281 syn keyword shStatement false hash nohup suspend unalias
282 syn keyword shStatement fc history print time whence
284 if exists("b:is_bash")
285 syn keyword shStatement bind disown help popd shopt
286 syn keyword shStatement builtin enable logout pushd source
287 syn keyword shStatement dirs
289 syn keyword shStatement login newgrp
295 if !exists("sh_minlines")
296 let sh_minlines = 200
298 if !exists("sh_maxlines")
299 let sh_maxlines = 2 * sh_minlines
301 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
302 syn sync match shDoSync grouphere shDo "\<do\>"
303 syn sync match shDoSync groupthere shDo "\<done\>"
304 syn sync match shIfSync grouphere shIf "\<if\>"
305 syn sync match shIfSync groupthere shIf "\<fi\>"
306 syn sync match shForSync grouphere shFor "\<for\>"
307 syn sync match shForSync groupthere shFor "\<in\>"
308 syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
309 syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
311 " The default highlighting.
312 hi def link shArithRegion shShellVariables
313 hi def link shCaseBar shConditional
314 hi def link shCaseIn shConditional
315 hi def link shCaseStart shConditional
316 hi def link shCmdSubRegion shShellVariables
317 hi def link shColon shStatement
318 hi def link shDeref shShellVariables
319 hi def link shDerefOp shOperator
320 hi def link shDerefVar shShellVariables
321 hi def link shDoubleQuote shString
322 hi def link shEcho shString
323 hi def link shEmbeddedEcho shString
324 hi def link shHereDoc shString
325 hi def link shOption shCommandSub
326 hi def link shPattern shString
327 hi def link shPosnParm shShellVariables
328 hi def link shRedir shOperator
329 hi def link shSinglequote shString
330 hi def link shSource shOperator
331 hi def link shStringSpecial shSpecial
332 hi def link shSubShRegion shOperator
333 hi def link shTestOpr shConditional
334 hi def link shVariable shSetList
335 hi def link shWrapLineOperator shOperator
337 if exists("b:is_bash")
338 hi def link bashAdminStatement shStatement
339 hi def link bashSpecialVariables shShellVariables
340 hi def link bashStatement shStatement
342 if exists("b:is_kornshell")
343 hi def link kshSpecialVariables shShellVariables
344 hi def link kshStatement shStatement
347 hi def link shCaseError Error
348 hi def link shCurlyError Error
349 hi def link shDerefError Error
350 hi def link shDerefOpError Error
351 hi def link shDerefTextError Error
352 hi def link shDoError Error
353 hi def link shEsacError Error
354 hi def link shIfError Error
355 hi def link shInError Error
356 hi def link shParenError Error
357 hi def link shTestError Error
358 if exists("b:is_kornshell")
359 hi def link shDTestError Error
362 hi def link shArithmetic Special
363 hi def link shCharClass Identifier
364 hi def link shCommandSub Special
365 hi def link shComment Comment
366 hi def link shConditional Conditional
367 hi def link shExprRegion Delimiter
368 hi def link shFunction Function
369 hi def link shFunctionName Function
370 hi def link shNumber Number
371 hi def link shOperator Operator
372 hi def link shRepeat Repeat
373 hi def link shSetList Identifier
374 hi def link shShellVariables PreProc
375 hi def link shSpecial Special
376 hi def link shStatement Statement
377 hi def link shString String
378 hi def link shTodo Todo
382 if exists("b:is_bash")
383 let b:current_syntax = "bash"
384 elseif exists("b:is_kornshell")
385 let b:current_syntax = "ksh"
387 let b:current_syntax = "sh"