xref: /vim-8.2.3635/runtime/syntax/sh.vim (revision 2d2970ea)
1" Vim syntax file
2" Language:		shell (sh) Korn shell (ksh) bash (sh)
3" Maintainer:		Charles E. Campbell <[email protected]>
4" Previous Maintainer:	Lennart Schultz <[email protected]>
5" Last Change:		Apr 14, 2020
6" Version:		190
7" URL:		http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
8" For options and settings, please use:      :help ft-sh-syntax
9" This file includes many ideas from Eric Brunet ([email protected])
10
11" quit when a syntax file was already loaded {{{1
12if exists("b:current_syntax")
13  finish
14endif
15
16" trying to answer the question: which shell is /bin/sh, really?
17" If the user has not specified any of g:is_kornshell, g:is_bash, g:is_posix, g:is_sh, then guess.
18if getline(1) =~ '\<ksh$'
19 let b:is_kornshell = 1
20elseif getline(1) =~ '\<bash$'
21 let b:is_bash      = 1
22elseif getline(1) =~ '\<dash$'
23 let b:is_posix     = 1
24elseif !exists("g:is_kornshell") && !exists("g:is_bash") && !exists("g:is_posix") && !exists("g:is_sh")
25 let s:shell = ""
26 if executable("/bin/sh")
27  let s:shell = resolve("/bin/sh")
28 elseif executable("/usr/bin/sh")
29  let s:shell = resolve("/usr/bin/sh")
30 endif
31 if     s:shell =~ 'ksh$'
32  let b:is_kornshell= 1
33 elseif s:shell =~ 'bash$'
34  let b:is_bash = 1
35 elseif s:shell =~ 'dash$'
36  let b:is_posix = 1
37 endif
38 unlet s:shell
39endif
40
41" handling /bin/sh with is_kornshell/is_sh {{{1
42" b:is_sh is set when "#! /bin/sh" is found;
43" However, it often is just a masquerade by bash (typically Linux)
44" or kornshell (typically workstations with Posix "sh").
45" So, when the user sets "g:is_bash", "g:is_kornshell",
46" or "g:is_posix", a b:is_sh is converted into b:is_bash/b:is_kornshell,
47" respectively.
48if !exists("b:is_kornshell") && !exists("b:is_bash")
49  if exists("g:is_posix") && !exists("g:is_kornshell")
50   let g:is_kornshell= g:is_posix
51  endif
52  if exists("g:is_kornshell")
53    let b:is_kornshell= 1
54    if exists("b:is_sh")
55      unlet b:is_sh
56    endif
57  elseif exists("g:is_bash")
58    let b:is_bash= 1
59    if exists("b:is_sh")
60      unlet b:is_sh
61    endif
62  else
63    let b:is_sh= 1
64  endif
65endif
66
67" set up default g:sh_fold_enabled {{{1
68" ================================
69if !exists("g:sh_fold_enabled")
70 let g:sh_fold_enabled= 0
71elseif g:sh_fold_enabled != 0 && !has("folding")
72 let g:sh_fold_enabled= 0
73 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
74endif
75if !exists("s:sh_fold_functions")
76 let s:sh_fold_functions= and(g:sh_fold_enabled,1)
77endif
78if !exists("s:sh_fold_heredoc")
79 let s:sh_fold_heredoc  = and(g:sh_fold_enabled,2)
80endif
81if !exists("s:sh_fold_ifdofor")
82 let s:sh_fold_ifdofor  = and(g:sh_fold_enabled,4)
83endif
84if g:sh_fold_enabled && &fdm == "manual"
85 " Given that	the	user provided g:sh_fold_enabled
86 " 	AND	g:sh_fold_enabled is manual (usual default)
87 " 	implies	a desire for syntax-based folding
88 setl fdm=syntax
89endif
90
91" set up the syntax-highlighting iskeyword
92if (v:version == 704 && has("patch-7.4.1142")) || v:version > 704
93 if exists("b:is_bash")
94  exe "syn iskeyword ".&iskeyword.",-,:"
95 else
96  exe "syn iskeyword ".&iskeyword.",-"
97 endif
98endif
99
100" Set up folding commands for shell {{{1
101" =================================
102if s:sh_fold_functions
103 com! -nargs=* ShFoldFunctions <args> fold
104else
105 com! -nargs=* ShFoldFunctions <args>
106endif
107if s:sh_fold_heredoc
108 com! -nargs=* ShFoldHereDoc <args> fold
109else
110 com! -nargs=* ShFoldHereDoc <args>
111endif
112if s:sh_fold_ifdofor
113 com! -nargs=* ShFoldIfDoFor <args> fold
114else
115 com! -nargs=* ShFoldIfDoFor <args>
116endif
117
118" sh syntax is case sensitive {{{1
119syn case match
120
121" Clusters: contains=@... clusters {{{1
122"==================================
123syn cluster shErrorList	contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError,shOK
124if exists("b:is_kornshell") || exists("b:is_bash")
125 syn cluster ErrorList add=shDTestError
126endif
127syn cluster shArithParenList	contains=shArithmetic,shCaseEsac,shComment,shDeref,shDo,shDerefSimple,shEcho,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
128syn cluster shArithList	contains=@shArithParenList,shParenError
129syn cluster shCaseEsacList	contains=shCaseStart,shCaseLabel,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
130syn cluster shCaseList	contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSubBQ,shComment,shDo,shEcho,shExpr,shFor,shForPP,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
131syn cluster shCommandSubList	contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
132syn cluster shCurlyList	contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
133" COMBAK: removing shEscape fromshDblQuoteList fails ksh04:43
134syn cluster shDblQuoteList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shDeref,shDerefSimple,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
135syn cluster shDerefList	contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
136syn cluster shDerefVarList	contains=shDerefOff,shDerefOp,shDerefVarArray,shDerefOpError
137syn cluster shEchoList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
138syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
139syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest
140syn cluster shFunctionList	contains=@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
141if exists("b:is_kornshell") || exists("b:is_bash")
142 syn cluster shFunctionList	add=shRepeat
143 syn cluster shFunctionList	add=shDblBrace,shDblParen
144endif
145syn cluster shHereBeginList	contains=@shCommandSubList
146syn cluster shHereList	contains=shBeginHere,shHerePayload
147syn cluster shHereListDQ	contains=shBeginHere,@shDblQuoteList,shHerePayload
148syn cluster shIdList	contains=shCommandSub,shCommandSubBQ,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
149syn cluster shIfList	contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
150syn cluster shLoopList	contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shForPP,shIf,shOption,shSet,shTest,shTestOpr,shTouch
151syn cluster shPPSLeftList	contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
152syn cluster shPPSRightList	contains=shComment,shDeref,shDerefSimple,shEscape,shPosnParm
153syn cluster shSubShList	contains=@shCommandSubList,shCommandSubBQ,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
154syn cluster shTestList	contains=shArithmetic,shCharClass,shCommandSub,shCommandSubBQ,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
155syn cluster shNoZSList	contains=shSpecialNoZS
156syn cluster shForList	contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shArithmetic
157
158" Echo: {{{1
159" ====
160" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
161syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
162syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
163syn match  shEchoQuote contained	'\%(\\\\\)*\\["`'()]'
164
165" This must be after the strings, so that ... \" will be correct
166syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim 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,shExDoubleQuote,shDoubleQuote,shCharClass,shCtrlSeq
167
168" Alias: {{{1
169" =====
170if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
171 syn match shStatement "\<alias\>"
172 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+\)\@="  skip="\\$" end="\>\|`"
173 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+=\)\@=" skip="\\$" end="="
174
175 " Touch: {{{1
176 " =====
177 syn match shTouch	'\<touch\>[^;#]*'	skipwhite nextgroup=shComment contains=shTouchCmd,shDoubleQuote,shSingleQuote,shDeref,shDerefSimple
178 syn match shTouchCmd	'\<touch\>'		contained
179endif
180
181" Error Codes: {{{1
182" ============
183if !exists("g:sh_no_error")
184 syn match   shDoError "\<done\>"
185 syn match   shIfError "\<fi\>"
186 syn match   shInError "\<in\>"
187 syn match   shCaseError ";;"
188 syn match   shEsacError "\<esac\>"
189 syn match   shCurlyError "}"
190 syn match   shParenError ")"
191 syn match   shOK	'\.\(done\|fi\|in\|esac\)'
192 if exists("b:is_kornshell") || exists("b:is_bash")
193  syn match     shDTestError "]]"
194 endif
195 syn match     shTestError "]"
196endif
197
198" Options: {{{1
199" ====================
200syn match   shOption	"\s\zs[-+][-_a-zA-Z#@]\+"
201syn match   shOption	"\s\zs--[^ \t$=`'"|);]\+"
202
203" File Redirection Highlighted As Operators: {{{1
204"===========================================
205syn match      shRedir	"\d\=>\(&[-0-9]\)\="
206syn match      shRedir	"\d\=>>-\="
207syn match      shRedir	"\d\=<\(&[-0-9]\)\="
208syn match      shRedir	"\d<<-\="
209
210" Operators: {{{1
211" ==========
212syn match   shOperator	"<<\|>>"		contained
213syn match   shOperator	"[!&;|]"		contained
214syn match   shOperator	"\[[[^:]\|\]]"		contained
215syn match   shOperator	"[-=/*+%]\=="		skipwhite nextgroup=shPattern
216syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shExSingleQuote,shSingleQuote,shExDoubleQuote,shDoubleQuote,shDeref
217
218" Subshells: {{{1
219" ==========
220syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"		contains=@shExprList2 nextgroup=shSpecialNxt
221syn region shSubSh transparent matchgroup=shSubShRegion start="[^(]\zs(" end=")"	contains=@shSubShList nextgroup=shSpecialNxt
222
223" Tests: {{{1
224"=======
225syn region shExpr	matchgroup=shRange start="\[" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
226syn region shTest	transparent matchgroup=shStatement start="\<test\s" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
227syn region shNoQuote	start='\S'	skip='\%(\\\\\)*\\.'	end='\ze\s' end="\ze['"]"	contained contains=shDerefSimple,shDeref
228syn match  shAstQuote	contained	'\*\ze"'	nextgroup=shString
229syn match  shTestOpr	contained	'[^-+/%]\zs=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
230syn match  shTestOpr	contained	"<=\|>=\|!=\|==\|=\~\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
231syn match  shTestPattern	contained	'\w\+'
232syn region shTestDoubleQuote	contained	start='\%(\%(\\\\\)*\\\)\@<!"' skip=+\\\\\|\\"+ end='"'	contains=shDeref,shDerefSimple,shDerefSpecial
233syn match  shTestSingleQuote	contained	'\\.'	nextgroup=shTestSingleQuote
234syn match  shTestSingleQuote	contained	"'[^']*'"
235if exists("b:is_kornshell") || exists("b:is_bash")
236 syn region  shDblBrace matchgroup=Delimiter start="\[\["	skip=+\%(\\\\\)*\\$+ end="\]\]"	contains=@shTestList,shAstQuote,shNoQuote,shComment
237 syn region  shDblParen matchgroup=Delimiter start="(("	skip=+\%(\\\\\)*\\$+ end="))"	contains=@shTestList,shComment
238endif
239
240" Character Class In Range: {{{1
241" =========================
242syn match   shCharClass	contained	"\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
243
244" Loops: do, if, while, until {{{1
245" ======
246ShFoldIfDoFor syn region shDo	transparent	matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>"			contains=@shLoopList
247ShFoldIfDoFor syn region shIf	transparent	matchgroup=shConditional start="\<if\_s" matchgroup=shConditional skip=+-fi\>+ end="\<;\_s*then\>" end="\<fi\>"	contains=@shIfList
248ShFoldIfDoFor syn region shFor		matchgroup=shLoop start="\<for\ze\_s\s*\%(((\)\@!" end="\<in\>" end="\<do\>"me=e-2			contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
249ShFoldIfDoFor syn region shForPP	matchgroup=shLoop start='\<for\>\_s*((' end='))' contains=@shForList
250
251if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
252 syn cluster shCaseList	add=shRepeat
253 syn cluster shFunctionList	add=shRepeat
254 syn region shRepeat   matchgroup=shLoop   start="\<while\_s" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen,shDblBrace
255 syn region shRepeat   matchgroup=shLoop   start="\<until\_s" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen,shDblBrace
256 if !exists("b:is_posix")
257  syn region shCaseEsac matchgroup=shConditional start="\<select\s" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
258 endif
259else
260 syn region shRepeat   matchgroup=shLoop   start="\<while\_s" end="\<do\>"me=e-2		contains=@shLoopList
261 syn region shRepeat   matchgroup=shLoop   start="\<until\_s" end="\<do\>"me=e-2		contains=@shLoopList
262endif
263syn region shCurlyIn   contained	matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
264syn match  shComma     contained	","
265
266" Case: case...esac {{{1
267" ====
268syn match shCaseBar	contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|"		nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
269syn match shCaseStart	contained skipwhite skipnl "("			nextgroup=shCase,shCaseBar
270syn match shCaseLabel	contained skipwhite	"\%(\\.\|[-a-zA-Z0-9_*.]\)\+"	contains=shCharClass
271if exists("b:is_bash")
272 ShFoldIfDoFor syn region	shCase	contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end=";&" end=";;&" end="esac"me=s-1	contains=@shCaseList	nextgroup=shCaseStart,shCase,shComment
273else
274 ShFoldIfDoFor syn region	shCase	contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end="esac"me=s-1		contains=@shCaseList	nextgroup=shCaseStart,shCase,shComment
275endif
276ShFoldIfDoFor syn region	shCaseEsac	matchgroup=shConditional start="\<case\>" end="\<esac\>"	contains=@shCaseEsacList
277
278syn keyword shCaseIn	contained skipwhite skipnl in			nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
279if exists("b:is_bash")
280 syn region  shCaseExSingleQuote	matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
281elseif !exists("g:sh_no_error")
282 syn region  shCaseExSingleQuote	matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
283endif
284syn region  shCaseSingleQuote	matchgroup=shQuote start=+'+ end=+'+		contains=shStringSpecial		skipwhite skipnl nextgroup=shCaseBar	contained
285syn region  shCaseDoubleQuote	matchgroup=shQuote start=+"+ skip=+\\\\\|\\.+ end=+"+	contains=@shDblQuoteList,shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
286syn region  shCaseCommandSub	start=+`+ skip=+\\\\\|\\.+ end=+`+		contains=@shCommandSubList		skipwhite skipnl nextgroup=shCaseBar	contained
287if exists("b:is_bash")
288 syn region  shCaseRange	matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+\]+	contained	contains=shCharClass
289 syn match   shCharClass	'\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|or\|xdigit\):\]'			contained
290else
291 syn region  shCaseRange	matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+\]+	contained
292endif
293" Misc: {{{1
294"======
295syn match   shWrapLineOperator "\\$"
296syn region  shCommandSubBQ   	start="`" skip="\\\\\|\\." end="`"	contains=shBQComment,@shCommandSubList
297"COMBAK: see ksh13:50
298"syn match   shEscape	contained	'\%(^\)\@!\%(\\\\\)*\\.'	nextgroup=shSingleQuote,shDoubleQuote,shComment
299"COMBAK: see sh11:27
300syn match   shEscape	contained	'\%(^\)\@!\%(\\\\\)*\\.'	nextgroup=shComment
301"COMBAK: see ksh13:53
302"syn match   shEscape	contained	'\%(^\)\@!\%(\\\\\)*\\.'
303
304" $() and $(()): {{{1
305" $(..) is not supported by sh (Bourne shell).  However, apparently
306" some systems (HP?) have as their /bin/sh a (link to) Korn shell
307" (ie. Posix compliant shell).  /bin/ksh should work for those
308" systems too, however, so the following syntax will flag $(..) as
309" an Error under /bin/sh.  By consensus of vimdev'ers!
310if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
311 syn region shCommandSub matchgroup=shCmdSubRegion start="\$("  skip='\\\\\|\\.' end=")"  contains=@shCommandSubList
312 syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
313 syn region shArithmetic matchgroup=shArithRegion  start="\$\[" skip='\\\\\|\\.' end="\]" contains=@shArithList
314 syn match  shSkipInitWS contained	"^\s\+"
315elseif !exists("g:sh_no_error")
316 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
317endif
318syn region shCmdParenRegion matchgroup=shCmdSubRegion start="(\ze[^(]" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
319
320if exists("b:is_bash")
321 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
322 syn cluster shCaseList add=bashAdminStatement,bashStatement
323 syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES BASH_ALIASES BASH_ARGC BASH_ARGC BASH_ARGV BASH_ARGV BASH_CMDS BASH_CMDS BASH_COMMAND BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING BASH_EXECUTION_STRING BASH_LINENO BASH_LINENO BASHOPTS BASHOPTS BASHPID BASHPID BASH_REMATCH BASH_REMATCH BASH_SOURCE BASH_SOURCE BASH_SUBSHELL BASH_SUBSHELL BASH_VERSINFO BASH_VERSION BASH_XTRACEFD BASH_XTRACEFD CDPATH COLUMNS COLUMNS COMP_CWORD COMP_CWORD COMP_KEY COMP_KEY COMP_LINE COMP_LINE COMP_POINT COMP_POINT COMPREPLY COMPREPLY COMP_TYPE COMP_TYPE COMP_WORDBREAKS COMP_WORDBREAKS COMP_WORDS COMP_WORDS COPROC COPROC DIRSTACK EMACS EMACS ENV ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNAME FUNCNEST FUNCNEST GLOBIGNORE GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HISTTIMEFORMAT HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_CTYPE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_NUMERIC LINENO LINES LINES MACHTYPE MAIL MAILCHECK MAILPATH MAPFILE MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS POSIXLY_CORRECT POSIXLY_CORRECT PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM READLINE_LINE READLINE_LINE READLINE_POINT READLINE_POINT REPLY SECONDS SHELL SHELL SHELLOPTS SHLVL TIMEFORMAT TIMEOUT TMPDIR TMPDIR UID
324 syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep less ls mkdir mv rm rmdir rpm sed sleep sort strip tail
325 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
326 syn keyword bashStatement	command compgen
327endif
328
329if exists("b:is_kornshell") || exists("b:is_posix")
330 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
331 syn cluster shCaseList add=kshStatement
332 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
333 syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail tput
334 syn keyword kshStatement command setgroups setsenv
335endif
336
337syn match   shSource	"^\.\s"
338syn match   shSource	"\s\.\s"
339"syn region  shColon	start="^\s*:" end="$" end="\s#"me=e-2 contains=@shColonList
340"syn region  shColon	start="^\s*\zs:" end="$" end="\s#"me=e-2
341if exists("b:is_kornshell") || exists("b:is_posix")
342 syn match   shColon	'^\s*\zs:'
343endif
344
345" String And Character Constants: {{{1
346"================================
347syn match   shNumber	"\<\d\+\>#\="
348syn match   shNumber	"\<-\=\.\=\d\+\>#\="
349syn match   shCtrlSeq	"\\\d\d\d\|\\[abcfnrtv0]"			contained
350if exists("b:is_bash")
351 syn match   shSpecial	"[^\\]\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]"	contained
352 syn match   shSpecial	"^\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]"	contained
353 syn region  shExSingleQuote	matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial		nextgroup=shSpecialNxt
354 syn region  shExDoubleQuote	matchgroup=shQuote start=+\$"+ skip=+\\\\\|\\.\|\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial,shSpecial	nextgroup=shSpecialNxt
355elseif !exists("g:sh_no_error")
356 syn region  shExSingleQuote	matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial
357 syn region  shExDoubleQuote	matchGroup=Error start=+\$"+ skip=+\\\\\|\\.+ end=+"+	contains=shStringSpecial
358endif
359syn region  shSingleQuote	matchgroup=shQuote start=+'+ end=+'+		contains=@Spell	nextgroup=shSpecialStart,shSpecialSQ
360syn region  shDoubleQuote	matchgroup=shQuote start=+\%(\%(\\\\\)*\\\)\@<!"+ skip=+\\.+ end=+"+	contains=@shDblQuoteList,shStringSpecial,@Spell	nextgroup=shSpecialStart
361syn region  shDoubleQuote	matchgroup=shQuote start=+"+ matchgroup=shSpecial skip=+\\"+ end=+"+		contained	contains=@shDblQuoteList,shStringSpecial,@Spell	nextgroup=shSpecialStart
362syn match   shStringSpecial	"[^[:print:] \t]"			contained
363syn match   shStringSpecial	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"			nextgroup=shComment
364syn match   shSpecialSQ	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"		contained	nextgroup=shBkslshSnglQuote,@shNoZSList
365syn match   shSpecialDQ	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"		contained	nextgroup=shBkslshDblQuote,@shNoZSList
366syn match   shSpecialStart	"\%(\\\\\)*\\[\\"'`$()#]"			contained	nextgroup=shBkslshSnglQuote,shBkslshDblQuote,@shNoZSList
367syn match   shSpecial	"^\%(\\\\\)*\\[\\"'`$()#]"
368syn match   shSpecialNoZS	contained	"\%(\\\\\)*\\[\\"'`$()#]"
369syn match   shSpecialNxt	contained	"\\[\\"'`$()#]"
370"syn region  shBkslshSnglQuote	contained	matchgroup=shQuote start=+'+ end=+'+	contains=@Spell	nextgroup=shSpecialStart
371"syn region  shBkslshDblQuote	contained	matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial,@Spell	nextgroup=shSpecialStart
372
373" Comments: {{{1
374"==========
375syn cluster	shCommentGroup	contains=shTodo,@Spell
376if exists("b:is_bash")
377 syn match	shTodo	contained		"\<\%(COMBAK\|FIXME\|TODO\|XXX\)\ze:\=\>"
378else
379 syn keyword	shTodo	contained		COMBAK FIXME TODO XXX
380endif
381syn match	shComment		"^\s*\zs#.*$"	contains=@shCommentGroup
382syn match	shComment		"\s\zs#.*$"	contains=@shCommentGroup
383syn match	shComment	contained	"#.*$"	contains=@shCommentGroup
384syn match	shQuickComment	contained	"#.*$"
385syn match	shBQComment	contained	"#.\{-}\ze`"	contains=@shCommentGroup
386
387" Here Documents: {{{1
388" =========================================
389"  Note : shHereDoc0[137] only had shDblQuoteList contained
390ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc01 start="<<\s*\\\=\z([^ \t|>]\+\)"		matchgroup=shHereDoc01 end="^\z1\s*$"	contains=@shDblQuoteList
391ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc02 start="<<\s*\"\z([^"]\+\)\""		matchgroup=shHereDoc02 end="^\z1\s*$"
392ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc03 start="<<-\s*\z([^ \t|>]\+\)"		matchgroup=shHereDoc03 end="^\s*\z1\s*$"	contains=@shDblQuoteList
393ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc04 start="<<-\s*'\z([^']\+\)'"		matchgroup=shHereDoc04 end="^\s*\z1\s*$"
394ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc05 start="<<\s*'\z([^']\+\)'"		matchgroup=shHereDoc05 end="^\z1\s*$"
395ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*\"\z([^"]\+\)\""		matchgroup=shHereDoc06 end="^\s*\z1\s*$"
396ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc07 start="<<\s*\\\_$\_s*\z([^ \t'"|>]\+\)"	matchgroup=shHereDoc07 end="^\z1\s*$"
397ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc08 start="<<\s*\\\_$\_s*'\z([^\t|>]\+\)'"	matchgroup=shHereDoc08 end="^\z1\s*$"
398ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc09 start="<<\s*\\\_$\_s*\"\z([^\t|>]\+\)\""	matchgroup=shHereDoc09 end="^\z1\s*$"
399ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t|>]\+\)"	matchgroup=shHereDoc10 end="^\s*\z1\s*$"
400ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<-\s*\\\_$\_s*\\\z([^ \t|>]\+\)"	matchgroup=shHereDoc11 end="^\s*\z1\s*$"        contains=@shDblQuoteList
401ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*'\z([^']\+\)'"		matchgroup=shHereDoc12 end="^\s*\z1\s*$"
402ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<-\s*\\\_$\_s*\"\z([^"]\+\)\""	matchgroup=shHereDoc13 end="^\s*\z1\s*$"
403ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc14 start="<<\\\z([^ \t|>]\+\)"		matchgroup=shHereDoc14 end="^\z1\s*$"           contains=@shDblQuoteList
404ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc15 start="<<-\s*\\\z([^ \t|>]\+\)"		matchgroup=shHereDoc15 end="^\s*\z1\s*$"        contains=@shDblQuoteList
405ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc16 start="<<-\s*\\\z([^ \t|>]\+\)"		matchgroup=shHereDoc15 end="^\s*\z1\s*$"        contains=@shDblQuoteList
406
407" Here Strings: {{{1
408" =============
409" available for: bash; ksh (really should be ksh93 only) but not if its a posix
410if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_posix"))
411 syn match shHereString "<<<"	skipwhite	nextgroup=shCmdParenRegion
412endif
413
414" Identifiers: {{{1
415"=============
416syn match  shSetOption	"\s\zs[-+][a-zA-Z0-9]\+\>"	contained
417syn match  shVariable	"\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="	nextgroup=shVarAssign
418syn match  shVarAssign	"="		contained	nextgroup=shCmdParenRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
419syn match  shVar	contained	"\h\w*"
420syn region shAtExpr	contained	start="@(" end=")" contains=@shIdList
421if exists("b:is_bash")
422 syn match  shSet "^\s*set\ze\s\+$"
423 syn region shSetList oneline matchgroup=shSet start="\<\%(declare\|local\|export\)\>\ze[/a-zA-Z_]\@!" end="$"	matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|="	contains=@shIdList
424 syn region shSetList oneline matchgroup=shSet start="\<\%(set\|unset\)\>[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"		matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+="	contains=@shIdList nextgroup=shComment
425elseif exists("b:is_kornshell") || exists("b:is_posix")
426 syn match  shSet "^\s*set\ze\s\+$"
427 syn region shSetList oneline matchgroup=shSet start="\<\(export\)\>\ze[/]\@!" end="$"		matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"	contains=@shIdList
428 syn region shSetList oneline matchgroup=shSet start="\<\%(set\|unset\>\)\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"		matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"	contains=@shIdList nextgroup=shComment
429else
430 syn region shSetList oneline matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$"	matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"	contains=@shIdList
431endif
432
433" Functions: {{{1
434if !exists("b:is_posix")
435 syn keyword shFunctionKey function	skipwhite skipnl nextgroup=shFunctionTwo
436endif
437
438if exists("b:is_bash")
439 ShFoldFunctions syn region shFunctionOne	matchgroup=shFunction start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*{"		end="}"	contains=@shFunctionList		 skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
440 ShFoldFunctions syn region shFunctionTwo	matchgroup=shFunction start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*{"	end="}"	contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
441 ShFoldFunctions syn region shFunctionThree	matchgroup=shFunction start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*("		end=")"	contains=@shFunctionList		 skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
442 ShFoldFunctions syn region shFunctionFour	matchgroup=shFunction start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*)"	end=")"	contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
443else
444 ShFoldFunctions syn region shFunctionOne	matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{"			end="}"	contains=@shFunctionList		 skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
445 ShFoldFunctions syn region shFunctionTwo	matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{"		end="}"	contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
446 ShFoldFunctions syn region shFunctionThree	matchgroup=shFunction start="^\s*\h\w*\s*()\_s*("			end=")"	contains=@shFunctionList		 skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
447 ShFoldFunctions syn region shFunctionFour	matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*("		end=")"	contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
448endif
449
450" Parameter Dereferencing: {{{1
451" ========================
452if !exists("g:sh_no_error")
453 syn match  shDerefWordError	"[^}$[~]"	contained
454endif
455syn match  shDerefSimple	"\$\%(\h\w*\|\d\)"	nextgroup=@shNoZSList
456syn region shDeref	matchgroup=PreProc start="\${" end="}"	contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
457syn match  shDerefSimple	"\$[-#*@!?]"	nextgroup=@shNoZSList
458syn match  shDerefSimple	"\$\$"	nextgroup=@shNoZSList
459syn match  shDerefSimple	"\${\d}"	nextgroup=@shNoZSList	nextgroup=shSpecialStart
460if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
461 syn region shDeref	matchgroup=PreProc start="\${##\=" end="}"	contains=@shDerefList	nextgroup=@shSpecialNoZS,shSpecialStart
462 syn region shDeref	matchgroup=PreProc start="\${\$\$" end="}"	contains=@shDerefList	nextgroup=@shSpecialNoZS,shSpecialStart
463endif
464
465" ksh: ${!var[*]} array index list syntax: {{{1
466" ========================================
467if exists("b:is_kornshell") || exists("b:is_posix")
468 syn region shDeref	matchgroup=PreProc start="\${!" end="}"	contains=@shDerefVarArray
469endif
470
471" bash: ${!prefix*} and ${#parameter}: {{{1
472" ====================================
473if exists("b:is_bash")
474 syn region shDeref	matchgroup=PreProc start="\${!" end="\*\=}"	contains=@shDerefList,shDerefOff
475 syn match  shDerefVar	contained	"{\@<=!\h\w*"		nextgroup=@shDerefVarList
476endif
477if exists("b:is_kornshell")
478 syn match  shDerefVar	contained	"{\@<=!\h\w*[[:alnum:]_.]*"	nextgroup=@shDerefVarList
479endif
480
481syn match  shDerefSpecial	contained	"{\@<=[-*@?0]"		nextgroup=shDerefOp,shDerefOpError
482syn match  shDerefSpecial	contained	"\({[#!]\)\@<=[[:alnum:]*@_]\+"	nextgroup=@shDerefVarList,shDerefOp
483syn match  shDerefVar	contained	"{\@<=\h\w*"		nextgroup=@shDerefVarList
484syn match  shDerefVar	contained	'\d'                            nextgroup=@shDerefVarList
485if exists("b:is_kornshell") || exists("b:is_posix")
486  syn match  shDerefVar	contained	"{\@<=\h\w*[[:alnum:]_.]*"	nextgroup=@shDerefVarList
487endif
488
489" sh ksh bash : ${var[... ]...}  array reference: {{{1
490syn region  shDerefVarArray   contained	matchgroup=shDeref start="\[" end="]"	contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
491
492" Special ${parameter OPERATOR word} handling: {{{1
493" sh ksh bash : ${parameter:-word}    word is default value
494" sh ksh bash : ${parameter:=word}    assign word as default value
495" sh ksh bash : ${parameter:?word}    display word if parameter is null
496" sh ksh bash : ${parameter:+word}    use word if parameter is not null, otherwise nothing
497"    ksh bash : ${parameter#pattern}  remove small left  pattern
498"    ksh bash : ${parameter##pattern} remove large left  pattern
499"    ksh bash : ${parameter%pattern}  remove small right pattern
500"    ksh bash : ${parameter%%pattern} remove large right pattern
501"        bash : ${parameter^pattern}  Case modification
502"        bash : ${parameter^^pattern} Case modification
503"        bash : ${parameter,pattern}  Case modification
504"        bash : ${parameter,,pattern} Case modification
505syn cluster shDerefPatternList	contains=shDerefPattern,shDerefString
506if !exists("g:sh_no_error")
507 syn match shDerefOpError	contained	":[[:punct:]]"
508endif
509syn match  shDerefOp	contained	":\=[-=?]"	nextgroup=@shDerefPatternList
510syn match  shDerefOp	contained	":\=+"	nextgroup=@shDerefPatternList
511if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
512 syn match  shDerefOp	contained	"#\{1,2}"		nextgroup=@shDerefPatternList
513 syn match  shDerefOp	contained	"%\{1,2}"		nextgroup=@shDerefPatternList
514 syn match  shDerefPattern	contained	"[^{}]\+"		contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
515 syn region shDerefPattern	contained	start="{" end="}"	contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
516 syn match  shDerefEscape	contained	'\%(\\\\\)*\\.'
517endif
518if exists("b:is_bash")
519 syn match  shDerefOp	contained	"[,^]\{1,2}"	nextgroup=@shDerefPatternList
520endif
521syn region shDerefString	contained	matchgroup=shDerefDelim start=+\%(\\\)\@<!'+ end=+'+	contains=shStringSpecial
522syn region shDerefString	contained	matchgroup=shDerefDelim start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial
523syn match  shDerefString	contained	"\\["']"	nextgroup=shDerefPattern
524
525if exists("b:is_bash")
526 " bash : ${parameter:offset}
527 " bash : ${parameter:offset:length}
528 syn region shDerefOff	contained	start=':[^-=?+]' end='\ze:'	end='\ze}'	contains=shDeref,shDerefSimple,shDerefEscape	nextgroup=shDerefLen,shDeref,shDerefSimple
529 syn region shDerefOff	contained	start=':\s-'	end='\ze:'	end='\ze}'	contains=shDeref,shDerefSimple,shDerefEscape	nextgroup=shDerefLen,shDeref,shDerefSimple
530 syn match  shDerefLen	contained	":[^}]\+"	contains=shDeref,shDerefSimple,shArithmetic
531
532 " bash : ${parameter//pattern/string}
533 " bash : ${parameter//pattern}
534 syn match  shDerefPPS	contained	'/\{1,2}'	nextgroup=shDerefPPSleft
535 syn region shDerefPPSleft	contained	start='.'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}'	nextgroup=shDerefPPSright	contains=@shPPSLeftList
536 syn region shDerefPPSright	contained	start='.'	skip=@\%(\\\\\)\+@		end='\ze}'				contains=@shPPSRightList
537
538 " bash : ${parameter/#substring/replacement}
539 syn match  shDerefPSR	contained	'/#'	nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
540 syn region shDerefPSRleft	contained	start='[^"']'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}'	nextgroup=shDerefPSRright
541 syn region shDerefPSRright	contained	start='.'	skip=@\%(\\\\\)\+@		end='\ze}'
542endif
543
544" Arithmetic Parenthesized Expressions: {{{1
545"syn region shParen matchgroup=shArithRegion start='[^$]\zs(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
546syn region shParen matchgroup=shArithRegion start='\$\@!(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
547
548" Additional sh Keywords: {{{1
549" ===================
550syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
551syn keyword shConditional contained elif else then
552if !exists("g:sh_no_error")
553 syn keyword shCondError elif else then
554endif
555
556" Additional ksh Keywords and Aliases: {{{1
557" ===================================
558if exists("b:is_kornshell") || exists("b:is_posix")
559 syn keyword shStatement bg builtin disown enum export false fg getconf getopts hist jobs let printf sleep true unalias whence
560 syn keyword shStatement typeset skipwhite nextgroup=shSetOption
561 syn keyword shStatement autoload compound fc float functions hash history integer nameref nohup r redirect source stop suspend times type
562 if exists("b:is_posix")
563  syn keyword shStatement command
564 else
565  syn keyword shStatement time
566 endif
567
568" Additional bash Keywords: {{{1
569" =====================
570elseif exists("b:is_bash")
571 syn keyword shStatement bg builtin disown export false fg getopts jobs let printf sleep true unalias
572 syn keyword shStatement typeset nextgroup=shSetOption
573 syn keyword shStatement fc hash history source suspend times type
574 syn keyword shStatement bind builtin caller compopt declare dirs disown enable export help logout mapfile popd pushd readarray shopt source typeset
575else
576 syn keyword shStatement login newgrp
577endif
578
579" Synchronization: {{{1
580" ================
581if !exists("g:sh_minlines")
582 let s:sh_minlines = 200
583else
584 let s:sh_minlines= g:sh_minlines
585endif
586if !exists("g:sh_maxlines")
587 let s:sh_maxlines = 2*s:sh_minlines
588 if s:sh_maxlines < 25
589  let s:sh_maxlines= 25
590 endif
591else
592 let s:sh_maxlines= g:sh_maxlines
593endif
594exec "syn sync minlines=" . s:sh_minlines . " maxlines=" . s:sh_maxlines
595syn sync match shCaseEsacSync	grouphere	shCaseEsac	"\<case\>"
596syn sync match shCaseEsacSync	groupthere	shCaseEsac	"\<esac\>"
597syn sync match shDoSync	grouphere	shDo	"\<do\>"
598syn sync match shDoSync	groupthere	shDo	"\<done\>"
599syn sync match shForSync	grouphere	shFor	"\<for\>"
600syn sync match shForSync	groupthere	shFor	"\<in\>"
601syn sync match shIfSync	grouphere	shIf	"\<if\>"
602syn sync match shIfSync	groupthere	shIf	"\<fi\>"
603syn sync match shUntilSync	grouphere	shRepeat	"\<until\>"
604syn sync match shWhileSync	grouphere	shRepeat	"\<while\>"
605
606" Default Highlighting: {{{1
607" =====================
608if !exists("skip_sh_syntax_inits")
609 hi def link shArithRegion	shShellVariables
610 hi def link shAstQuote	shDoubleQuote
611 hi def link shAtExpr	shSetList
612 hi def link shBkslshSnglQuote	shSingleQuote
613 hi def link shBkslshDblQuote	shDOubleQuote
614 hi def link shBeginHere	shRedir
615 hi def link shCaseBar	shConditional
616 hi def link shCaseCommandSub	shCommandSub
617 hi def link shCaseDoubleQuote	shDoubleQuote
618 hi def link shCaseIn	shConditional
619 hi def link shQuote	shOperator
620 hi def link shCaseSingleQuote	shSingleQuote
621 hi def link shCaseStart	shConditional
622 hi def link shCmdSubRegion	shShellVariables
623 hi def link shColon	shComment
624 hi def link shDerefOp	shOperator
625 hi def link shDerefPOL	shDerefOp
626 hi def link shDerefPPS	shDerefOp
627 hi def link shDerefPSR	shDerefOp
628 hi def link shDeref	shShellVariables
629 hi def link shDerefDelim	shOperator
630 hi def link shDerefSimple	shDeref
631 hi def link shDerefSpecial	shDeref
632 hi def link shDerefString	shDoubleQuote
633 hi def link shDerefVar	shDeref
634 hi def link shDoubleQuote	shString
635 hi def link shEcho	shString
636 hi def link shEchoDelim	shOperator
637 hi def link shEchoQuote	shString
638 hi def link shForPP	shLoop
639 hi def link shFunction	Function
640 hi def link shEmbeddedEcho	shString
641 hi def link shEscape	shCommandSub
642 hi def link shExDoubleQuote	shDoubleQuote
643 hi def link shExSingleQuote	shSingleQuote
644 hi def link shHereDoc	shString
645 hi def link shHereString	shRedir
646 hi def link shHerePayload	shHereDoc
647 hi def link shLoop	shStatement
648 hi def link shSpecialNxt	shSpecial
649 hi def link shNoQuote	shDoubleQuote
650 hi def link shOption	shCommandSub
651 hi def link shPattern	shString
652 hi def link shParen	shArithmetic
653 hi def link shPosnParm	shShellVariables
654 hi def link shQuickComment	shComment
655 hi def link shBQComment	shComment
656 hi def link shRange	shOperator
657 hi def link shRedir	shOperator
658 hi def link shSetListDelim	shOperator
659 hi def link shSetOption	shOption
660 hi def link shSingleQuote	shString
661 hi def link shSource	shOperator
662 hi def link shStringSpecial	shSpecial
663 hi def link shSpecialStart	shSpecial
664 hi def link shSubShRegion	shOperator
665 hi def link shTestOpr	shConditional
666 hi def link shTestPattern	shString
667 hi def link shTestDoubleQuote	shString
668 hi def link shTestSingleQuote	shString
669 hi def link shTouchCmd	shStatement
670 hi def link shVariable	shSetList
671 hi def link shWrapLineOperator	shOperator
672
673 if exists("b:is_bash")
674   hi def link bashAdminStatement	shStatement
675   hi def link bashSpecialVariables	shShellVariables
676   hi def link bashStatement		shStatement
677   hi def link shCharClass		shSpecial
678   hi def link shDerefOff		shDerefOp
679   hi def link shDerefLen		shDerefOff
680 endif
681 if exists("b:is_kornshell") || exists("b:is_posix")
682   hi def link kshSpecialVariables	shShellVariables
683   hi def link kshStatement		shStatement
684 endif
685
686 if !exists("g:sh_no_error")
687  hi def link shCaseError		Error
688  hi def link shCondError		Error
689  hi def link shCurlyError		Error
690  hi def link shDerefOpError		Error
691  hi def link shDerefWordError		Error
692  hi def link shDoError		Error
693  hi def link shEsacError		Error
694  hi def link shIfError		Error
695  hi def link shInError		Error
696  hi def link shParenError		Error
697  hi def link shTestError		Error
698  if exists("b:is_kornshell") || exists("b:is_posix")
699    hi def link shDTestError		Error
700  endif
701 endif
702
703 hi def link shArithmetic		Special
704 hi def link shCharClass		Identifier
705 hi def link shSnglCase		Statement
706 hi def link shCommandSub		Special
707 hi def link shCommandSubBQ		shCommandSub
708 hi def link shComment		Comment
709 hi def link shConditional		Conditional
710 hi def link shCtrlSeq		Special
711 hi def link shExprRegion		Delimiter
712 hi def link shFunctionKey		Function
713 hi def link shFunctionName		Function
714 hi def link shNumber		Number
715 hi def link shOperator		Operator
716 hi def link shRepeat		Repeat
717 hi def link shSet		Statement
718 hi def link shSetList		Identifier
719 hi def link shShellVariables		PreProc
720 hi def link shSpecial		Special
721 hi def link shSpecialDQ		Special
722 hi def link shSpecialSQ		Special
723 hi def link shSpecialNoZS		shSpecial
724 hi def link shStatement		Statement
725 hi def link shString		String
726 hi def link shTodo		Todo
727 hi def link shAlias		Identifier
728 hi def link shHereDoc01		shRedir
729 hi def link shHereDoc02		shRedir
730 hi def link shHereDoc03		shRedir
731 hi def link shHereDoc04		shRedir
732 hi def link shHereDoc05		shRedir
733 hi def link shHereDoc06		shRedir
734 hi def link shHereDoc07		shRedir
735 hi def link shHereDoc08		shRedir
736 hi def link shHereDoc09		shRedir
737 hi def link shHereDoc10		shRedir
738 hi def link shHereDoc11		shRedir
739 hi def link shHereDoc12		shRedir
740 hi def link shHereDoc13		shRedir
741 hi def link shHereDoc14		shRedir
742 hi def link shHereDoc15		shRedir
743endif
744
745" Delete shell folding commands {{{1
746" =============================
747delc ShFoldFunctions
748delc ShFoldHereDoc
749delc ShFoldIfDoFor
750
751" Set Current Syntax: {{{1
752" ===================
753if exists("b:is_bash")
754 let b:current_syntax = "bash"
755elseif exists("b:is_kornshell")
756 let b:current_syntax = "ksh"
757elseif exists("b:is_posix")
758 let b:current_syntax = "posix"
759else
760 let b:current_syntax = "sh"
761endif
762
763" vim: ts=16 fdm=marker
764