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: Jul 11, 2008
7 " URL: http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
8 " For options and settings, please use: :help ft-sh-syntax
9 " This file includes many ideas from Éric Brunet (eric.brunet@ens.fr)
11 " For version 5.x: Clear all syntax items {{{1
12 " For version 6.x: Quit when a syntax file was already loaded
15 elseif exists("b:current_syntax")
19 " handling /bin/sh with is_kornshell/is_sh {{{1
20 " b:is_sh is set when "#! /bin/sh" is found;
21 " However, it often is just a masquerade by bash (typically Linux)
22 " or kornshell (typically workstations with Posix "sh").
23 " So, when the user sets "is_bash" or "is_kornshell",
24 " a b:is_sh is converted into b:is_bash/b:is_kornshell,
26 if !exists("b:is_kornshell") && !exists("b:is_bash")
27 if exists("g:is_posix") && !exists("g:is_kornshell")
28 let g:is_kornshell= g:is_posix
30 if exists("g:is_kornshell")
35 elseif exists("g:is_bash")
45 " set up default g:sh_fold_enabled {{{1
46 if !exists("g:sh_fold_enabled")
47 let g:sh_fold_enabled= 0
48 elseif g:sh_fold_enabled != 0 && !has("folding")
49 let g:sh_fold_enabled= 0
50 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
52 if !exists("s:sh_fold_functions")
53 let s:sh_fold_functions = 1
55 if !exists("s:sh_fold_heredoc")
56 let s:sh_fold_heredoc = 2
58 if !exists("s:sh_fold_ifdofor")
59 let s:sh_fold_ifdofor = 4
61 if g:sh_fold_enabled && &fdm == "manual"
65 " sh syntax is case sensitive {{{1
68 " Clusters: contains=@... clusters {{{1
69 "==================================
70 syn cluster shErrorList contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError
71 if exists("b:is_kornshell")
72 syn cluster ErrorList add=shDTestError
74 syn cluster shArithParenList contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen
75 syn cluster shArithList contains=@shArithParenList,shParenError
76 syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial
77 syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
78 syn cluster shColonList contains=@shCaseList
79 syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq,shSpecial
80 syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
81 syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
82 syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
83 syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError
84 syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
85 syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
86 syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
87 syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
88 if exists("b:is_kornshell") || exists("b:is_bash")
89 syn cluster shFunctionList add=shRepeat
90 syn cluster shFunctionList add=shDblBrace,shDblParen
92 syn cluster shHereBeginList contains=@shCommandSubList
93 syn cluster shHereList contains=shBeginHere,shHerePayload
94 syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
95 syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shSetOption,shDeref,shDerefSimple,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial
96 syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest,@shErrorList,shSet
97 syn cluster shSubShList contains=@shCaseList,shOperator
98 syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
103 " This one is needed INSIDE a CommandSub, so that `echo bla` be correct
104 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 skipwhite nextgroup=shQuickComment
105 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 skipwhite nextgroup=shQuickComment
106 syn match shEchoQuote contained '\%(\\\\\)*\\["`']'
108 " This must be after the strings, so that ... \" will be correct
109 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
113 if exists("b:is_kornshell") || exists("b:is_bash")
114 syn match shStatement "\<alias\>"
115 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
116 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
121 syn match shDoError "\<done\>"
122 syn match shIfError "\<fi\>"
123 syn match shInError "\<in\>"
124 syn match shCaseError ";;"
125 syn match shEsacError "\<esac\>"
126 syn match shCurlyError "}"
127 syn match shParenError ")"
128 if exists("b:is_kornshell")
129 syn match shDTestError "]]"
131 syn match shTestError "]"
134 " ====================
135 syn match shOption "\s\zs[-+][a-zA-Z0-9]\+\>"
136 syn match shOption "\s\zs--[^ \t$`'"|]\+"
138 " File Redirection Highlighted As Operators: {{{1
139 "===========================================
140 syn match shRedir "\d\=>\(&[-0-9]\)\="
141 syn match shRedir "\d\=>>-\="
142 syn match shRedir "\d\=<\(&[-0-9]\)\="
143 syn match shRedir "\d<<-\="
147 syn match shOperator "<<\|>>" contained
148 syn match shOperator "[!&;|]" contained
149 syn match shOperator "\[[[^:]\|\]]" contained
150 syn match shOperator "!\==" skipwhite nextgroup=shPattern
151 syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
155 syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2
156 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList
160 "syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
161 syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
162 syn region shTest transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
163 syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
164 syn match shTestOpr contained '=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
165 syn match shTestPattern contained '\w\+'
166 syn match shTestDoubleQuote contained '"[^"]*"'
167 syn match shTestSingleQuote contained '\\.'
168 syn match shTestSingleQuote contained "'[^']*'"
169 if exists("b:is_kornshell") || exists("b:is_bash")
170 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList
171 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList
174 " Character Class In Range: {{{1
175 " =========================
176 syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
178 " Loops: do, if, while, until {{{1
180 if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
181 syn region shDo fold transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
182 syn region shIf fold transparent matchgroup=shConditional start="\<if\_s" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
183 syn region shFor fold matchgroup=shLoop start="\<for\_s" end="\<in\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
185 syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
186 syn region shIf transparent matchgroup=shConditional start="\<if\_s" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
187 syn region shFor matchgroup=shLoop start="\<for\_s" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
189 if exists("b:is_kornshell") || exists("b:is_bash")
190 syn cluster shCaseList add=shRepeat
191 syn cluster shFunctionList add=shRepeat
192 syn region shRepeat matchgroup=shLoop start="\<while\_s" end="\<in\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
193 syn region shRepeat matchgroup=shLoop start="\<until\_s" end="\<in\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
194 syn region shCaseEsac matchgroup=shConditional start="\<select\s" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
196 syn region shRepeat matchgroup=shLoop start="\<while\_s" end="\<do\>"me=e-2 contains=@shLoopList
197 syn region shRepeat matchgroup=shLoop start="\<until\_s" end="\<do\>"me=e-2 contains=@shLoopList
199 syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
200 syn match shComma contained ","
202 " Case: case...esac {{{1
204 syn match shCaseBar contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|" nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
205 syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
206 syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
207 if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
208 syn region shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
210 syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
212 syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
213 if exists("b:is_bash")
214 syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained
216 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
218 syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
219 syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
220 syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
224 syn match shWrapLineOperator "\\$"
225 syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
226 syn match shEscape contained '\\.'
228 " $() and $(()): {{{1
229 " $(..) is not supported by sh (Bourne shell). However, apparently
230 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
231 " (ie. Posix compliant shell). /bin/ksh should work for those
232 " systems too, however, so the following syntax will flag $(..) as
233 " an Error under /bin/sh. By consensus of vimdev'ers!
234 if exists("b:is_kornshell") || exists("b:is_bash")
235 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
236 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
237 syn match shSkipInitWS contained "^\s\+"
239 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
242 if exists("b:is_bash")
243 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
244 syn cluster shCaseList add=bashAdminStatement,bashStatement
245 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
246 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
247 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
250 if exists("b:is_kornshell")
251 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
252 syn cluster shCaseList add=kshStatement
253 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
254 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
257 syn match shSource "^\.\s"
258 syn match shSource "\s\.\s"
259 syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
261 " String And Character Constants: {{{1
262 "================================
263 syn match shNumber "-\=\<\d\+\>#\="
264 syn match shCtrlSeq "\\\d\d\d\|\\[abcfnrtv0]" contained
265 if exists("b:is_bash")
266 syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
268 if exists("b:is_bash")
269 syn region shExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial
271 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial
273 syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial,@Spell
274 syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell
275 syn match shStringSpecial "[^[:print:] \t]" contained
276 syn match shStringSpecial "\%(\\\\\)*\\[\\"'`$()#]"
277 syn match shSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
278 syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
282 syn cluster shCommentGroup contains=shTodo,@Spell
283 syn keyword shTodo contained COMBAK FIXME TODO XXX
284 syn match shComment "^\s*\zs#.*$" contains=@shCommentGroup
285 syn match shComment "\s\zs#.*$" contains=@shCommentGroup
286 syn match shQuickComment contained "#.*$"
288 " Here Documents: {{{1
289 " =========================================
291 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
292 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
293 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList
294 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList
295 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList
296 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList
298 elseif (g:sh_fold_enabled % (s:sh_fold_heredoc * 2))/s:sh_fold_heredoc
299 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
300 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
301 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
302 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
303 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
304 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
305 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
306 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
307 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
308 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
309 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
310 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
311 syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
314 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
315 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
316 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
317 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
318 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
319 syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
320 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
321 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
322 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
323 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
324 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
325 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
326 syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
331 if exists("b:is_bash")
332 syn match shRedir "<<<"
337 syn match shSetOption "\s\zs[-+][a-zA-Z0-9]\+\>" contained
338 syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier
339 syn match shSetIdentifier "=" contained nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
340 if exists("b:is_bash")
341 syn region shSetList oneline matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze#\|=" contains=@shIdList
342 syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="\ze[;|)]\|$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
343 elseif exists("b:is_kornshell")
344 syn region shSetList oneline matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
345 syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
347 syn region shSetList oneline matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
351 if !exists("g:is_posix")
352 syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
355 if exists("b:is_bash")
356 if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
357 syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
358 syn region shFunctionTwo fold matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
360 syn region shFunctionOne matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{" end="}" contains=@shFunctionList
361 syn region shFunctionTwo matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained
364 if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
365 syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
366 syn region shFunctionTwo fold matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
368 syn region shFunctionOne matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}" contains=@shFunctionList
369 syn region shFunctionTwo matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained
373 " Parameter Dereferencing: {{{1
374 " ========================
375 syn match shDerefSimple "\$\%(\h\w*\|\d\)"
376 syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
377 syn match shDerefWordError "[^}$[]" contained
378 syn match shDerefSimple "\$[-#*@!?]"
379 syn match shDerefSimple "\$\$"
380 if exists("b:is_bash") || exists("b:is_kornshell")
381 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
382 syn region shDeref matchgroup=PreProc start="\${\$\$" end="}" contains=@shDerefList
385 " bash: ${!prefix*} and ${#parameter}: {{{1
386 " ====================================
387 if exists("b:is_bash")
388 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
389 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
392 syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
393 syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
394 syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
396 " sh ksh bash : ${var[... ]...} array reference: {{{1
397 syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
399 " Special ${parameter OPERATOR word} handling: {{{1
400 " sh ksh bash : ${parameter:-word} word is default value
401 " sh ksh bash : ${parameter:=word} assign word as default value
402 " sh ksh bash : ${parameter:?word} display word if parameter is null
403 " sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
404 " ksh bash : ${parameter#pattern} remove small left pattern
405 " ksh bash : ${parameter##pattern} remove large left pattern
406 " ksh bash : ${parameter%pattern} remove small right pattern
407 " ksh bash : ${parameter%%pattern} remove large right pattern
408 syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
409 syn match shDerefOpError contained ":[[:punct:]]"
410 syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
411 syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
412 if exists("b:is_bash") || exists("b:is_kornshell")
413 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
414 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
415 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
416 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
417 syn match shDerefEscape contained '\%(\\\\\)*\\.'
419 syn region shDerefString contained matchgroup=shOperator start=+\%(\\\)\@<!'+ end=+'+ contains=shStringSpecial
420 syn region shDerefString contained matchgroup=shOperator start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
421 syn match shDerefString contained "\\["']" nextgroup=shDerefPattern
423 if exists("b:is_bash")
424 " bash : ${parameter:offset}
425 " bash : ${parameter:offset:length}
426 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
427 syn match shDerefPOL contained ":[^}]\+" contains=@shCommandSubList
429 " bash : ${parameter//pattern/string}
430 " bash : ${parameter//pattern}
431 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
432 syn region shDerefPPSleft contained start='.' skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
433 syn region shDerefPPSright contained start='.' end='\ze}' contains=@shCommandSubList
436 " Arithmetic Parenthesized Expressions: {{{1
437 syn region shParen matchgroup=shArithRegion start='(\ze[^(]' end=')' contains=@shArithParenList
439 " Useful sh Keywords: {{{1
440 " ===================
441 syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
442 syn keyword shConditional contained elif else then
443 syn keyword shCondError elif else then
445 " Useful ksh Keywords: {{{1
446 " ====================
447 if exists("b:is_kornshell") || exists("b:is_bash")
448 syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup print printf r stop suspend times true type unalias whence
449 if exists("g:is_posix")
450 syn keyword shStatement command
452 syn keyword shStatement time
455 " Useful bash Keywords: {{{1
456 " =====================
457 if exists("b:is_bash")
458 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
460 syn keyword shStatement login newgrp
464 " Synchronization: {{{1
466 if !exists("sh_minlines")
467 let sh_minlines = 200
469 if !exists("sh_maxlines")
470 let sh_maxlines = 2 * sh_minlines
472 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
473 syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
474 syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
475 syn sync match shDoSync grouphere shDo "\<do\>"
476 syn sync match shDoSync groupthere shDo "\<done\>"
477 syn sync match shForSync grouphere shFor "\<for\>"
478 syn sync match shForSync groupthere shFor "\<in\>"
479 syn sync match shIfSync grouphere shIf "\<if\>"
480 syn sync match shIfSync groupthere shIf "\<fi\>"
481 syn sync match shUntilSync grouphere shRepeat "\<until\>"
482 syn sync match shWhileSync grouphere shRepeat "\<while\>"
484 " Default Highlighting: {{{1
485 " =====================
486 hi def link shArithRegion shShellVariables
487 hi def link shBeginHere shRedir
488 hi def link shCaseBar shConditional
489 hi def link shCaseCommandSub shCommandSub
490 hi def link shCaseDoubleQuote shDoubleQuote
491 hi def link shCaseIn shConditional
492 hi def link shCaseSingleQuote shSingleQuote
493 hi def link shCaseStart shConditional
494 hi def link shCmdSubRegion shShellVariables
495 hi def link shColon shStatement
496 hi def link shDerefOp shOperator
497 hi def link shDerefPOL shDerefOp
498 hi def link shDerefPPS shDerefOp
499 hi def link shDeref shShellVariables
500 hi def link shDerefSimple shDeref
501 hi def link shDerefSpecial shDeref
502 hi def link shDerefString shDoubleQuote
503 hi def link shDerefVar shDeref
504 hi def link shDoubleQuote shString
505 hi def link shEcho shString
506 hi def link shEchoQuote shString
507 hi def link shEmbeddedEcho shString
508 hi def link shEscape shCommandSub
509 hi def link shExSingleQuote shSingleQuote
510 hi def link shFunction Function
511 hi def link shHereDoc shString
512 hi def link shHerePayload shHereDoc
513 hi def link shLoop shStatement
514 hi def link shOption shCommandSub
515 hi def link shPattern shString
516 hi def link shParen shArithmetic
517 hi def link shPosnParm shShellVariables
518 hi def link shQuickComment shComment
519 hi def link shRange shOperator
520 hi def link shRedir shOperator
521 hi def link shSetOption shOption
522 hi def link shSingleQuote shString
523 hi def link shSource shOperator
524 hi def link shStringSpecial shSpecial
525 hi def link shSubShRegion shOperator
526 hi def link shTestOpr shConditional
527 hi def link shTestPattern shString
528 hi def link shTestDoubleQuote shString
529 hi def link shTestSingleQuote shString
530 hi def link shVariable shSetList
531 hi def link shWrapLineOperator shOperator
533 if exists("b:is_bash")
534 hi def link bashAdminStatement shStatement
535 hi def link bashSpecialVariables shShellVariables
536 hi def link bashStatement shStatement
537 hi def link shFunctionParen Delimiter
538 hi def link shFunctionDelim Delimiter
540 if exists("b:is_kornshell")
541 hi def link kshSpecialVariables shShellVariables
542 hi def link kshStatement shStatement
543 hi def link shFunctionParen Delimiter
546 hi def link shCaseError Error
547 hi def link shCondError Error
548 hi def link shCurlyError Error
549 hi def link shDerefError Error
550 hi def link shDerefOpError Error
551 hi def link shDerefWordError Error
552 hi def link shDoError Error
553 hi def link shEsacError Error
554 hi def link shIfError Error
555 hi def link shInError Error
556 hi def link shParenError Error
557 hi def link shTestError Error
558 if exists("b:is_kornshell")
559 hi def link shDTestError Error
562 hi def link shArithmetic Special
563 hi def link shCharClass Identifier
564 hi def link shSnglCase Statement
565 hi def link shCommandSub Special
566 hi def link shComment Comment
567 hi def link shConditional Conditional
568 hi def link shCtrlSeq Special
569 hi def link shExprRegion Delimiter
570 hi def link shFunctionKey Function
571 hi def link shFunctionName Function
572 hi def link shNumber Number
573 hi def link shOperator Operator
574 hi def link shRepeat Repeat
575 hi def link shSet Statement
576 hi def link shSetList Identifier
577 hi def link shShellVariables PreProc
578 hi def link shSpecial Special
579 hi def link shStatement Statement
580 hi def link shString String
581 hi def link shTodo Todo
582 hi def link shAlias Identifier
584 " Set Current Syntax: {{{1
585 " ===================
586 if exists("b:is_bash")
587 let b:current_syntax = "bash"
588 elseif exists("b:is_kornshell")
589 let b:current_syntax = "ksh"
591 let b:current_syntax = "sh"
594 " vim: ts=16 fdm=marker