2 " Language: shell (sh) Korn shell (ksh) bash (sh)
3 " Maintainer: Dr. Charles E. Campbell, Jr. <NdrOchipS@PcampbellAfamily.Mbiz>
4 " Previous Maintainer: Lennart Schultz <Lennart.Schultz@ecmwf.int>
5 " Last Change: Dec 12, 2006
7 " URL: http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
9 " Using the following VIM variables: {{{1
10 " g:is_bash if none of the previous three variables are
11 " defined, then if g:is_bash is set enhance with
12 " bash syntax highlighting
13 " g:is_kornshell if neither b:is_kornshell or b:is_bash is
14 " defined, then if g:is_kornshell is set
15 " enhance with kornshell/POSIX syntax highlighting
16 " g:is_posix this variable is the same as g:is_kornshell
17 " g:sh_fold_enabled if non-zero, syntax folding is enabled
18 " g:sh_minlines sets up syn sync minlines (dflt: 200)
19 " g:sh_maxlines sets up syn sync maxlines (dflt: 2x sh_minlines)
21 " This file includes many ideas from Éric Brunet (eric.brunet@ens.fr)
23 " For version 5.x: Clear all syntax items {{{1
24 " For version 6.x: Quit when a syntax file was already loaded
27 elseif exists("b:current_syntax")
31 " handling /bin/sh with is_kornshell/is_sh {{{1
32 " b:is_sh is set when "#! /bin/sh" is found;
33 " However, it often is just a masquerade by bash (typically Linux)
34 " or kornshell (typically workstations with Posix "sh").
35 " So, when the user sets "is_bash" or "is_kornshell",
36 " a b:is_sh is converted into b:is_bash/b:is_kornshell,
38 if !exists("b:is_kornshell") && !exists("b:is_bash")
39 if exists("g:is_posix") && !exists("g:is_kornshell")
40 let g:is_kornshell= g:is_posix
42 if exists("g:is_kornshell")
47 elseif exists("g:is_bash")
57 " set up default g:sh_fold_enabled {{{1
58 if !exists("g:sh_fold_enabled")
59 let g:sh_fold_enabled= 0
60 elseif g:sh_fold_enabled != 0 && !has("folding")
61 let g:sh_fold_enabled= 0
62 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
64 if g:sh_fold_enabled && &fdm == "manual"
68 " sh syntax is case sensitive {{{1
71 " Clusters: contains=@... clusters {{{1
72 "==================================
73 syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq
74 syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
75 syn cluster shColonList contains=@shCaseList
76 syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq
77 syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
78 syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
79 syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
80 syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError
81 syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq
82 syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
83 syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
84 syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shFunctionStart,shCtrlSeq
85 if exists("b:is_kornshell") || exists("b:is_bash")
86 syn cluster shFunctionList add=shDblBrace,shDblParen
88 syn cluster shHereBeginList contains=@shCommandSubList
89 syn cluster shHereList contains=shBeginHere,shHerePayload
90 syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
91 syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq
92 syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest
93 syn cluster shSubShList contains=@shCaseList,shOperator
94 syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
99 " This one is needed INSIDE a CommandSub, so that `echo bla` be correct
100 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
101 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
103 " This must be after the strings, so that bla \" be correct
104 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,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shDoubleQuote,shCharClass,shCtrlSeq
108 if exists("b:is_kornshell") || exists("b:is_bash")
109 syn match shStatement "\<alias\>"
110 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
111 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
116 syn match shDoError "\<done\>"
117 syn match shIfError "\<fi\>"
118 syn match shInError "\<in\>"
119 syn match shCaseError ";;"
120 syn match shEsacError "\<esac\>"
121 syn match shCurlyError "}"
122 syn match shParenError ")"
123 if exists("b:is_kornshell")
124 syn match shDTestError "]]"
126 syn match shTestError "]"
128 " Options Interceptor: {{{1
129 " ====================
130 syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
131 syn match shOption "\s--[^ \t$`'"|]\+"ms=s+1
133 " File Redirection Highlighted As Operators: {{{1
134 "===========================================
135 syn match shRedir "\d\=>\(&[-0-9]\)\="
136 syn match shRedir "\d\=>>-\="
137 syn match shRedir "\d\=<\(&[-0-9]\)\="
138 syn match shRedir "\d<<-\="
142 syn match shOperator "<<\|>>" contained
143 syn match shOperator "[!&;|]"
144 syn match shOperator "\[[[^:]\|\]]"
145 syn match shOperator "!\==" skipwhite nextgroup=shPattern
146 syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
150 syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2
151 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList
155 "syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
156 syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
157 syn region shTest transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
158 syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
159 syn match shTestOpr contained '=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
160 syn match shTestPattern contained '\w\+'
161 syn match shTestDoubleQuote contained '"[^"]*"'
162 syn match shTestSingleQuote contained '\\.'
163 syn match shTestSingleQuote contained "'[^']*'"
164 if exists("b:is_kornshell") || exists("b:is_bash")
165 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList
166 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList
169 " Character Class In Range: {{{1
170 " =========================
171 syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
173 " Loops: do, if, while, until {{{1
176 syn region shDo fold transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
177 syn region shIf fold transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
178 syn region shFor fold matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
180 syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
181 syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
182 syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
184 if exists("b:is_kornshell") || exists("b:is_bash")
185 syn cluster shCaseList add=shRepeat
186 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
187 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
188 syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
190 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2 contains=@shLoopList
191 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2 contains=@shLoopList
193 syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
194 syn match shComma contained ","
196 " Case: case...esac {{{1
198 syn match shCaseBar contained skipwhite "[^|"`'()]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
199 syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
200 syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\([^#$()'" \t]\|\\.\)\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
202 syn region shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
204 syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
206 syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
207 if exists("b:is_bash")
208 syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained
210 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
212 syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
213 syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
214 syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
218 syn match shWrapLineOperator "\\$"
219 syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
221 " $() and $(()): {{{1
222 " $(..) is not supported by sh (Bourne shell). However, apparently
223 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
224 " (ie. Posix compliant shell). /bin/ksh should work for those
225 " systems too, however, so the following syntax will flag $(..) as
226 " an Error under /bin/sh. By consensus of vimdev'ers!
227 if exists("b:is_kornshell") || exists("b:is_bash")
228 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
229 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
230 syn match shSkipInitWS contained "^\s\+"
232 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
235 if exists("b:is_bash")
236 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
237 syn cluster shCaseList add=bashAdminStatement,bashStatement
238 syn keyword bashSpecialVariables contained BASH BASH_ENV BASH_VERSINFO BASH_VERSION CDPATH DIRSTACK EUID FCEDIT FIGNORE GLOBIGNORE GROUPS HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_MESSAGES LINENO MACHTYPE MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELLOPTS SHLVL TIMEFORMAT TIMEOUT UID auto_resume histchars
239 syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep install less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch
240 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
243 if exists("b:is_kornshell")
244 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
245 syn cluster shCaseList add=kshStatement
246 syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV ERRNO FCEDIT FPATH HISTFILE HISTSIZE HOME IFS LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL TMOUT VISUAL
247 syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep install killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail touch tput
250 syn match shSource "^\.\s"
251 syn match shSource "\s\.\s"
252 syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
254 " String And Character Constants: {{{1
255 "================================
256 syn match shNumber "-\=\<\d\+\>#\="
257 syn match shCtrlSeq "\\\d\d\d\|\\[abcfnrtv0]" contained
258 if exists("b:is_bash")
259 syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
261 if exists("b:is_bash")
262 syn region shExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial
264 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial
266 syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial,@Spell
267 syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell
268 syn match shStringSpecial "[^[:print:]]" contained
269 syn match shStringSpecial "\%(\\\\\)*\\[\\"'`$()#]"
270 syn match shSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
271 syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
275 syn cluster shCommentGroup contains=shTodo,@Spell
276 syn keyword shTodo contained COMBAK FIXME TODO XXX
277 syn match shComment "^\s*\zs#.*$" contains=@shCommentGroup
278 syn match shComment "#.*$" contains=@shCommentGroup
280 " Here Documents: {{{1
281 " =========================================
283 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
284 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^\s*END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
285 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList
286 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList
287 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList
288 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList
290 elseif g:sh_fold_enabled
291 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
292 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
293 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
294 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
295 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
296 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
297 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
298 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
299 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
300 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
301 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
302 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
303 syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
306 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
307 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
308 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
309 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
310 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
311 syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
312 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
313 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
314 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
315 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
316 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
317 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
318 syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
323 if exists("b:is_bash")
324 syn match shRedir "<<<"
329 syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier
330 syn match shIdWhiteSpace contained "\s"
331 syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
332 if exists("b:is_bash")
333 syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
334 syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="\\ze[|)]" matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
335 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)\>"
336 elseif exists("b:is_kornshell")
337 syn region shSetList matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
338 syn region shSetList matchgroup=shSet start="\<set\>\ze[^/]" end="$\|\ze[})]" matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
339 syn match shSet "\<\(typeset\|set\|export\|unset\)\>"
341 syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]" matchgroup=shOperator end="\ze[|);&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
342 syn match shStatement "\<\(set\|export\|unset\)\>"
346 syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
347 " COMBAK -- look at bash09. function foo() (line#35) is folding 38 lines. Not being terminated properly
348 "syn match shFunctionStart "{" contained
350 syn region shFunctionOne transparent fold start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart
351 syn region shFunctionTwo transparent fold start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart
353 syn region shFunctionOne transparent start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList
354 syn region shFunctionTwo transparent start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained
357 " Parameter Dereferencing: {{{1
358 " ========================
359 syn match shDerefSimple "\$\%(\h\w*\|\d\)"
360 syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
361 syn match shDerefWordError "[^}$[]" contained
362 syn match shDerefSimple "\$[-#*@!?]"
363 syn match shDerefSimple "\$\$"
364 if exists("b:is_bash") || exists("b:is_kornshell")
365 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
368 " bash: ${!prefix*} and ${#parameter}: {{{1
369 " ====================================
370 if exists("b:is_bash")
371 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
372 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
375 syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
376 syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
377 syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
379 " sh ksh bash : ${var[... ]...} array reference: {{{1
380 syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
382 " Special ${parameter OPERATOR word} handling: {{{1
383 " sh ksh bash : ${parameter:-word} word is default value
384 " sh ksh bash : ${parameter:=word} assign word as default value
385 " sh ksh bash : ${parameter:?word} display word if parameter is null
386 " sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
387 " ksh bash : ${parameter#pattern} remove small left pattern
388 " ksh bash : ${parameter##pattern} remove large left pattern
389 " ksh bash : ${parameter%pattern} remove small right pattern
390 " ksh bash : ${parameter%%pattern} remove large right pattern
391 syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
392 syn match shDerefOpError contained ":[[:punct:]]"
393 syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
394 syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
395 if exists("b:is_bash") || exists("b:is_kornshell")
396 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
397 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
398 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
399 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
400 syn match shDerefEscape contained '\%(\\\\\)*\\.'
402 syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
403 syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
404 syn match shDerefString contained "\\["']"
406 if exists("b:is_bash")
407 " bash : ${parameter:offset}
408 " bash : ${parameter:offset:length}
409 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
410 syn match shDerefPOL contained ":[^}]\+" contains=@shCommandSubList
412 " bash : ${parameter//pattern/string}
413 " bash : ${parameter//pattern}
414 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
415 syn region shDerefPPSleft contained start='.' skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
416 syn region shDerefPPSright contained start='.' end='\ze}' contains=@shCommandSubList
419 " Useful sh Keywords: {{{1
420 " ===================
421 syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
422 syn keyword shConditional contained elif else then
423 syn keyword shCondError elif else then
425 " Useful ksh Keywords: {{{1
426 " ====================
427 if exists("b:is_kornshell") || exists("b:is_bash")
428 syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup print printf r stop suspend time times true type unalias whence
430 " Useful bash Keywords: {{{1
431 " =====================
432 if exists("b:is_bash")
433 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
435 syn keyword shStatement login newgrp
439 " Synchronization: {{{1
441 if !exists("sh_minlines")
442 let sh_minlines = 200
444 if !exists("sh_maxlines")
445 let sh_maxlines = 2 * sh_minlines
447 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
448 syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
449 syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
450 syn sync match shDoSync grouphere shDo "\<do\>"
451 syn sync match shDoSync groupthere shDo "\<done\>"
452 syn sync match shForSync grouphere shFor "\<for\>"
453 syn sync match shForSync groupthere shFor "\<in\>"
454 syn sync match shIfSync grouphere shIf "\<if\>"
455 syn sync match shIfSync groupthere shIf "\<fi\>"
456 syn sync match shUntilSync grouphere shRepeat "\<until\>"
457 syn sync match shWhileSync grouphere shRepeat "\<while\>"
459 " Default Highlighting: {{{1
460 " =====================
461 hi def link shArithRegion shShellVariables
462 hi def link shBeginHere shRedir
463 hi def link shCaseBar shConditional
464 hi def link shCaseCommandSub shCommandSub
465 hi def link shCaseDoubleQuote shDoubleQuote
466 hi def link shCaseIn shConditional
467 hi def link shCaseSingleQuote shSingleQuote
468 hi def link shCaseStart shConditional
469 hi def link shCmdSubRegion shShellVariables
470 hi def link shColon shStatement
471 hi def link shDerefOp shOperator
472 hi def link shDerefPOL shDerefOp
473 hi def link shDerefPPS shDerefOp
474 hi def link shDeref shShellVariables
475 hi def link shDerefSimple shDeref
476 hi def link shDerefSpecial shDeref
477 hi def link shDerefString shDoubleQuote
478 hi def link shDerefVar shDeref
479 hi def link shDoubleQuote shString
480 hi def link shEcho shString
481 hi def link shEmbeddedEcho shString
482 hi def link shExSingleQuote shSingleQuote
483 hi def link shFunctionStart Delimiter
484 hi def link shHereDoc shString
485 hi def link shHerePayload shHereDoc
486 hi def link shLoop shStatement
487 hi def link shOption shCommandSub
488 hi def link shPattern shString
489 hi def link shPosnParm shShellVariables
490 hi def link shRange shOperator
491 hi def link shRedir shOperator
492 hi def link shSingleQuote shString
493 hi def link shSource shOperator
494 hi def link shStringSpecial shSpecial
495 hi def link shSubShRegion shOperator
496 hi def link shTestOpr shConditional
497 hi def link shTestPattern shString
498 hi def link shTestDoubleQuote shString
499 hi def link shTestSingleQuote shString
500 hi def link shVariable shSetList
501 hi def link shWrapLineOperator shOperator
503 if exists("b:is_bash")
504 hi def link bashAdminStatement shStatement
505 hi def link bashSpecialVariables shShellVariables
506 hi def link bashStatement shStatement
507 hi def link shFunctionParen Delimiter
508 hi def link shFunctionDelim Delimiter
510 if exists("b:is_kornshell")
511 hi def link kshSpecialVariables shShellVariables
512 hi def link kshStatement shStatement
513 hi def link shFunctionParen Delimiter
516 hi def link shCaseError Error
517 hi def link shCondError Error
518 hi def link shCurlyError Error
519 hi def link shDerefError Error
520 hi def link shDerefOpError Error
521 hi def link shDerefWordError Error
522 hi def link shDoError Error
523 hi def link shEsacError Error
524 hi def link shIfError Error
525 hi def link shInError Error
526 hi def link shParenError Error
527 hi def link shTestError Error
528 if exists("b:is_kornshell")
529 hi def link shDTestError Error
532 hi def link shArithmetic Special
533 hi def link shCharClass Identifier
534 hi def link shSnglCase Statement
535 hi def link shCommandSub Special
536 hi def link shComment Comment
537 hi def link shConditional Conditional
538 hi def link shCtrlSeq Special
539 hi def link shExprRegion Delimiter
540 hi def link shFunctionKey Function
541 hi def link shFunctionName Function
542 hi def link shNumber Number
543 hi def link shOperator Operator
544 hi def link shRepeat Repeat
545 hi def link shSet Statement
546 hi def link shSetList Identifier
547 hi def link shShellVariables PreProc
548 hi def link shSpecial Special
549 hi def link shStatement Statement
550 hi def link shString String
551 hi def link shTodo Todo
552 hi def link shAlias Identifier
554 " Set Current Syntax: {{{1
555 " ===================
556 if exists("b:is_bash")
557 let b:current_syntax = "bash"
558 elseif exists("b:is_kornshell")
559 let b:current_syntax = "ksh"
561 let b:current_syntax = "sh"
564 " vim: ts=16 fdm=marker