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: Sep 01, 2009
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,shOK
71 if exists("b:is_kornshell")
72 syn cluster ErrorList add=shDTestError
74 syn cluster shArithParenList contains=shArithmetic,shDeref,shDerefSimple,shEcho,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement
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,shExpr
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,shOption,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=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,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="\s#"me=e-2 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="\s#"me=e-2 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="\s#"me=e-2 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 syn match shOK '\.\(done\|fi\|in\|esac\)'
129 if exists("b:is_kornshell")
130 syn match shDTestError "]]"
132 syn match shTestError "]"
135 " ====================
136 syn match shOption "\s\zs[-+][a-zA-Z0-9]\+\>"
137 syn match shOption "\s\zs--[^ \t$`'"|]\+"
139 " File Redirection Highlighted As Operators: {{{1
140 "===========================================
141 syn match shRedir "\d\=>\(&[-0-9]\)\="
142 syn match shRedir "\d\=>>-\="
143 syn match shRedir "\d\=<\(&[-0-9]\)\="
144 syn match shRedir "\d<<-\="
148 syn match shOperator "<<\|>>" contained
149 syn match shOperator "[!&;|]" contained
150 syn match shOperator "\[[[^:]\|\]]" contained
151 syn match shOperator "!\==" skipwhite nextgroup=shPattern
152 syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
156 syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 nextgroup=shMoreSpecial
157 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList nextgroup=shMoreSpecial
161 syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList,shSpecial
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 if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
207 syn region shCase fold contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
208 syn region shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
210 syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
211 syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
213 syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
214 if exists("b:is_bash")
215 syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained
217 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
219 syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
220 syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
221 syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
225 syn match shWrapLineOperator "\\$"
226 syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
227 syn match shEscape contained '\\.'
229 " $() and $(()): {{{1
230 " $(..) is not supported by sh (Bourne shell). However, apparently
231 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
232 " (ie. Posix compliant shell). /bin/ksh should work for those
233 " systems too, however, so the following syntax will flag $(..) as
234 " an Error under /bin/sh. By consensus of vimdev'ers!
235 if exists("b:is_kornshell") || exists("b:is_bash")
236 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
237 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
238 syn match shSkipInitWS contained "^\s\+"
240 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
243 if exists("b:is_bash")
244 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
245 syn cluster shCaseList add=bashAdminStatement,bashStatement
246 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
247 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
248 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
251 if exists("b:is_kornshell")
252 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
253 syn cluster shCaseList add=kshStatement
254 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
255 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
258 syn match shSource "^\.\s"
259 syn match shSource "\s\.\s"
260 syn region shColon start="^\s*:" end="$\|" end="\s#"me=e-2 contains=@shColonList
262 " String And Character Constants: {{{1
263 "================================
264 syn match shNumber "-\=\<\d\+\>#\="
265 syn match shCtrlSeq "\\\d\d\d\|\\[abcfnrtv0]" contained
266 if exists("b:is_bash")
267 syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
269 if exists("b:is_bash")
270 syn region shExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial
272 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial
274 syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial,@Spell
275 syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell
276 syn match shStringSpecial "[^[:print:] \t]" contained
277 syn match shStringSpecial "\%(\\\\\)*\\[\\"'`$()#]"
278 syn match shSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]" nextgroup=shMoreSpecial
279 syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
280 syn match shMoreSpecial "\%(\\\\\)*\\[\\"'`$()#]" nextgroup=shMoreSpecial contained
284 syn cluster shCommentGroup contains=shTodo,@Spell
285 syn keyword shTodo contained COMBAK FIXME TODO XXX
286 syn match shComment "^\s*\zs#.*$" contains=@shCommentGroup
287 syn match shComment "\s\zs#.*$" contains=@shCommentGroup
288 syn match shQuickComment contained "#.*$"
290 " Here Documents: {{{1
291 " =========================================
293 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
294 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
295 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList
296 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList
297 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList
298 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList
300 elseif (g:sh_fold_enabled % (s:sh_fold_heredoc * 2))/s:sh_fold_heredoc
301 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
302 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
303 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
304 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
305 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
306 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
307 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
308 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\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="^\s*\z1\s*$"
311 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
312 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
313 syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
316 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
317 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
318 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
319 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
320 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
321 syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
322 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
323 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
324 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
325 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
326 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
327 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
328 syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
333 if exists("b:is_bash")
334 syn match shRedir "<<<"
339 syn match shSetOption "\s\zs[-+][a-zA-Z0-9]\+\>" contained
340 syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier
341 syn match shSetIdentifier "=" contained nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
342 if exists("b:is_bash")
343 syn region shSetList oneline matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|=" contains=@shIdList
344 syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="\ze[;|)]\|$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
345 elseif exists("b:is_kornshell")
346 syn region shSetList oneline matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
347 syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
349 syn region shSetList oneline matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
353 if !exists("g:is_posix")
354 syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
357 if exists("b:is_bash")
358 if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
359 syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
360 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
362 syn region shFunctionOne matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{" end="}" contains=@shFunctionList
363 syn region shFunctionTwo matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained
366 if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
367 syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
368 syn region shFunctionTwo fold matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
370 syn region shFunctionOne matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}" contains=@shFunctionList
371 syn region shFunctionTwo matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained
375 " Parameter Dereferencing: {{{1
376 " ========================
377 syn match shDerefSimple "\$\%(\h\w*\|\d\)"
378 syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
379 syn match shDerefWordError "[^}$[]" contained
380 syn match shDerefSimple "\$[-#*@!?]"
381 syn match shDerefSimple "\$\$"
382 if exists("b:is_bash") || exists("b:is_kornshell")
383 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
384 syn region shDeref matchgroup=PreProc start="\${\$\$" end="}" contains=@shDerefList
387 " bash: ${!prefix*} and ${#parameter}: {{{1
388 " ====================================
389 if exists("b:is_bash")
390 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
391 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
394 syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
395 syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
396 syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
398 " sh ksh bash : ${var[... ]...} array reference: {{{1
399 syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
401 " Special ${parameter OPERATOR word} handling: {{{1
402 " sh ksh bash : ${parameter:-word} word is default value
403 " sh ksh bash : ${parameter:=word} assign word as default value
404 " sh ksh bash : ${parameter:?word} display word if parameter is null
405 " sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
406 " ksh bash : ${parameter#pattern} remove small left pattern
407 " ksh bash : ${parameter##pattern} remove large left pattern
408 " ksh bash : ${parameter%pattern} remove small right pattern
409 " ksh bash : ${parameter%%pattern} remove large right pattern
410 syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
411 syn match shDerefOpError contained ":[[:punct:]]"
412 syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
413 syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
414 if exists("b:is_bash") || exists("b:is_kornshell")
415 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
416 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
417 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
418 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
419 syn match shDerefEscape contained '\%(\\\\\)*\\.'
421 syn region shDerefString contained matchgroup=shOperator start=+\%(\\\)\@<!'+ end=+'+ contains=shStringSpecial
422 syn region shDerefString contained matchgroup=shOperator start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
423 syn match shDerefString contained "\\["']" nextgroup=shDerefPattern
425 if exists("b:is_bash")
426 " bash : ${parameter:offset}
427 " bash : ${parameter:offset:length}
428 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
429 syn match shDerefPOL contained ":[^}]\+" contains=@shCommandSubList
431 " bash : ${parameter//pattern/string}
432 " bash : ${parameter//pattern}
433 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
434 syn region shDerefPPSleft contained start='.' skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
435 syn region shDerefPPSright contained start='.' end='\ze}' contains=@shCommandSubList
438 " Arithmetic Parenthesized Expressions: {{{1
439 syn region shParen matchgroup=shArithRegion start='(\ze[^(]' end=')' contains=@shArithParenList
441 " Useful sh Keywords: {{{1
442 " ===================
443 syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
444 syn keyword shConditional contained elif else then
445 syn keyword shCondError elif else then
447 " Useful ksh Keywords: {{{1
448 " ====================
449 if exists("b:is_kornshell") || exists("b:is_bash")
450 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
451 if exists("g:is_posix")
452 syn keyword shStatement command
454 syn keyword shStatement time
457 " Useful bash Keywords: {{{1
458 " =====================
459 if exists("b:is_bash")
460 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
462 syn keyword shStatement login newgrp
466 " Synchronization: {{{1
468 if !exists("sh_minlines")
469 let sh_minlines = 200
471 if !exists("sh_maxlines")
472 let sh_maxlines = 2 * sh_minlines
474 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
475 syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
476 syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
477 syn sync match shDoSync grouphere shDo "\<do\>"
478 syn sync match shDoSync groupthere shDo "\<done\>"
479 syn sync match shForSync grouphere shFor "\<for\>"
480 syn sync match shForSync groupthere shFor "\<in\>"
481 syn sync match shIfSync grouphere shIf "\<if\>"
482 syn sync match shIfSync groupthere shIf "\<fi\>"
483 syn sync match shUntilSync grouphere shRepeat "\<until\>"
484 syn sync match shWhileSync grouphere shRepeat "\<while\>"
486 " Default Highlighting: {{{1
487 " =====================
488 hi def link shArithRegion shShellVariables
489 hi def link shBeginHere shRedir
490 hi def link shCaseBar shConditional
491 hi def link shCaseCommandSub shCommandSub
492 hi def link shCaseDoubleQuote shDoubleQuote
493 hi def link shCaseIn shConditional
494 hi def link shCaseSingleQuote shSingleQuote
495 hi def link shCaseStart shConditional
496 hi def link shCmdSubRegion shShellVariables
497 hi def link shColon shStatement
498 hi def link shDerefOp shOperator
499 hi def link shDerefPOL shDerefOp
500 hi def link shDerefPPS shDerefOp
501 hi def link shDeref shShellVariables
502 hi def link shDerefSimple shDeref
503 hi def link shDerefSpecial shDeref
504 hi def link shDerefString shDoubleQuote
505 hi def link shDerefVar shDeref
506 hi def link shDoubleQuote shString
507 hi def link shEcho shString
508 hi def link shEchoQuote shString
509 hi def link shEmbeddedEcho shString
510 hi def link shEscape shCommandSub
511 hi def link shExSingleQuote shSingleQuote
512 hi def link shFunction Function
513 hi def link shHereDoc shString
514 hi def link shHerePayload shHereDoc
515 hi def link shLoop shStatement
516 hi def link shMoreSpecial shSpecial
517 hi def link shOption shCommandSub
518 hi def link shPattern shString
519 hi def link shParen shArithmetic
520 hi def link shPosnParm shShellVariables
521 hi def link shQuickComment shComment
522 hi def link shRange shOperator
523 hi def link shRedir shOperator
524 hi def link shSetOption shOption
525 hi def link shSingleQuote shString
526 hi def link shSource shOperator
527 hi def link shStringSpecial shSpecial
528 hi def link shSubShRegion shOperator
529 hi def link shTestOpr shConditional
530 hi def link shTestPattern shString
531 hi def link shTestDoubleQuote shString
532 hi def link shTestSingleQuote shString
533 hi def link shVariable shSetList
534 hi def link shWrapLineOperator shOperator
536 if exists("b:is_bash")
537 hi def link bashAdminStatement shStatement
538 hi def link bashSpecialVariables shShellVariables
539 hi def link bashStatement shStatement
540 hi def link shFunctionParen Delimiter
541 hi def link shFunctionDelim Delimiter
543 if exists("b:is_kornshell")
544 hi def link kshSpecialVariables shShellVariables
545 hi def link kshStatement shStatement
546 hi def link shFunctionParen Delimiter
549 hi def link shCaseError Error
550 hi def link shCondError Error
551 hi def link shCurlyError Error
552 hi def link shDerefError Error
553 hi def link shDerefOpError Error
554 hi def link shDerefWordError Error
555 hi def link shDoError Error
556 hi def link shEsacError Error
557 hi def link shIfError Error
558 hi def link shInError Error
559 hi def link shParenError Error
560 hi def link shTestError Error
561 if exists("b:is_kornshell")
562 hi def link shDTestError Error
565 hi def link shArithmetic Special
566 hi def link shCharClass Identifier
567 hi def link shSnglCase Statement
568 hi def link shCommandSub Special
569 hi def link shComment Comment
570 hi def link shConditional Conditional
571 hi def link shCtrlSeq Special
572 hi def link shExprRegion Delimiter
573 hi def link shFunctionKey Function
574 hi def link shFunctionName Function
575 hi def link shNumber Number
576 hi def link shOperator Operator
577 hi def link shRepeat Repeat
578 hi def link shSet Statement
579 hi def link shSetList Identifier
580 hi def link shShellVariables PreProc
581 hi def link shSpecial Special
582 hi def link shStatement Statement
583 hi def link shString String
584 hi def link shTodo Todo
585 hi def link shAlias Identifier
587 " Set Current Syntax: {{{1
588 " ===================
589 if exists("b:is_bash")
590 let b:current_syntax = "bash"
591 elseif exists("b:is_kornshell")
592 let b:current_syntax = "ksh"
594 let b:current_syntax = "sh"
597 " vim: ts=16 fdm=marker