xref: /vim-8.2.3635/runtime/syntax/sh.vim (revision 96f45c0b)
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:		Jun 16, 2019
6" Version:		188
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
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
133syn cluster shDblQuoteList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
134syn cluster shDerefList	contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
135syn cluster shDerefVarList	contains=shDerefOff,shDerefOp,shDerefVarArray,shDerefOpError
136syn cluster shEchoList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
137syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
138syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest
139syn cluster shFunctionList	contains=@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
140if exists("b:is_kornshell") || exists("b:is_bash")
141 syn cluster shFunctionList	add=shRepeat
142 syn cluster shFunctionList	add=shDblBrace,shDblParen
143endif
144syn cluster shHereBeginList	contains=@shCommandSubList
145syn cluster shHereList	contains=shBeginHere,shHerePayload
146syn cluster shHereListDQ	contains=shBeginHere,@shDblQuoteList,shHerePayload
147syn cluster shIdList	contains=shCommandSub,shCommandSubBQ,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
148syn cluster shIfList	contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
149syn cluster shLoopList	contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shForPP,shIf,shOption,shSet,shTest,shTestOpr,shTouch
150syn cluster shPPSRightList	contains=shComment,shDeref,shDerefSimple,shEscape,shPosnParm
151syn cluster shSubShList	contains=@shCommandSubList,shCommandSubBQ,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
152syn cluster shTestList	contains=shArithmetic,shCharClass,shCommandSub,shCommandSubBQ,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
153syn cluster shNoZSList	contains=shSpecialNoZS
154syn cluster shForList	contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shArithmetic
155
156" Echo: {{{1
157" ====
158" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
159syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=@shEchoList skipwhite nextgroup=shQuickComment
160syn region shEcho 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=@shEchoList skipwhite nextgroup=shQuickComment
161syn match  shEchoQuote contained	'\%(\\\\\)*\\["`'()]'
162
163" This must be after the strings, so that ... \" will be correct
164syn 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
165
166" Alias: {{{1
167" =====
168if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
169 syn match shStatement "\<alias\>"
170 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+\)\@="  skip="\\$" end="\>\|`"
171 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+=\)\@=" skip="\\$" end="="
172
173 " Touch: {{{1
174 " =====
175 syn match shTouch	'\<touch\>[^;#]*'	skipwhite nextgroup=shComment contains=shTouchCmd,shDoubleQuote,shSingleQuote,shDeref,shDerefSimple
176 syn match shTouchCmd	'\<touch\>'		contained
177endif
178
179" Error Codes: {{{1
180" ============
181if !exists("g:sh_no_error")
182 syn match   shDoError "\<done\>"
183 syn match   shIfError "\<fi\>"
184 syn match   shInError "\<in\>"
185 syn match   shCaseError ";;"
186 syn match   shEsacError "\<esac\>"
187 syn match   shCurlyError "}"
188 syn match   shParenError ")"
189 syn match   shOK	'\.\(done\|fi\|in\|esac\)'
190 if exists("b:is_kornshell") || exists("b:is_bash")
191  syn match     shDTestError "]]"
192 endif
193 syn match     shTestError "]"
194endif
195
196" Options: {{{1
197" ====================
198syn match   shOption	"\s\zs[-+][-_a-zA-Z#@]\+"
199syn match   shOption	"\s\zs--[^ \t$`'"|);]\+"
200
201" File Redirection Highlighted As Operators: {{{1
202"===========================================
203syn match      shRedir	"\d\=>\(&[-0-9]\)\="
204syn match      shRedir	"\d\=>>-\="
205syn match      shRedir	"\d\=<\(&[-0-9]\)\="
206syn match      shRedir	"\d<<-\="
207
208" Operators: {{{1
209" ==========
210syn match   shOperator	"<<\|>>"		contained
211syn match   shOperator	"[!&;|]"		contained
212syn match   shOperator	"\[[[^:]\|\]]"		contained
213syn match   shOperator	"[-=/*+%]\=="		skipwhite nextgroup=shPattern
214syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shExSingleQuote,shSingleQuote,shExDoubleQuote,shDoubleQuote,shDeref
215
216" Subshells: {{{1
217" ==========
218syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"		contains=@shExprList2 nextgroup=shSpecialNxt
219syn region shSubSh transparent matchgroup=shSubShRegion start="[^(]\zs(" end=")"	contains=@shSubShList nextgroup=shSpecialNxt
220
221" Tests: {{{1
222"=======
223syn region shExpr	matchgroup=shRange start="\[" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
224syn region shTest	transparent matchgroup=shStatement start="\<test\s" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
225syn region shNoQuote	start='\S'	skip='\%(\\\\\)*\\.'	end='\ze\s' end="\ze['"]"	contained contains=shDerefSimple,shDeref
226syn match  shAstQuote	contained	'\*\ze"'	nextgroup=shString
227syn match  shTestOpr	contained	'[^-+/%]\zs=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
228syn match  shTestOpr	contained	"<=\|>=\|!=\|==\|=\~\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
229syn match  shTestPattern	contained	'\w\+'
230syn region shTestDoubleQuote	contained	start='\%(\%(\\\\\)*\\\)\@<!"' skip=+\\\\\|\\"+ end='"'	contains=shDeref,shDerefSimple,shDerefSpecial
231syn match  shTestSingleQuote	contained	'\\.'	nextgroup=shTestSingleQuote
232syn match  shTestSingleQuote	contained	"'[^']*'"
233if exists("b:is_kornshell") || exists("b:is_bash")
234 syn region  shDblBrace matchgroup=Delimiter start="\[\["	skip=+\%(\\\\\)*\\$+ end="\]\]"	contains=@shTestList,shAstQuote,shNoQuote,shComment
235 syn region  shDblParen matchgroup=Delimiter start="(("	skip=+\%(\\\\\)*\\$+ end="))"	contains=@shTestList,shComment
236endif
237
238" Character Class In Range: {{{1
239" =========================
240syn match   shCharClass	contained	"\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
241
242" Loops: do, if, while, until {{{1
243" ======
244ShFoldIfDoFor syn region shDo	transparent	matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>"			contains=@shLoopList
245ShFoldIfDoFor syn region shIf	transparent	matchgroup=shConditional start="\<if\_s" matchgroup=shConditional skip=+-fi\>+ end="\<;\_s*then\>" end="\<fi\>"	contains=@shIfList
246ShFoldIfDoFor syn region shFor		matchgroup=shLoop start="\<for\ze\_s\s*\%(((\)\@!" end="\<in\>" end="\<do\>"me=e-2			contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
247ShFoldIfDoFor syn region shForPP	matchgroup=shLoop start='\<for\>\_s*((' end='))' contains=@shForList
248
249if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
250 syn cluster shCaseList	add=shRepeat
251 syn cluster shFunctionList	add=shRepeat
252 syn region shRepeat   matchgroup=shLoop   start="\<while\_s" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen,shDblBrace
253 syn region shRepeat   matchgroup=shLoop   start="\<until\_s" end="\<do\>"me=e-2	contains=@shLoopList,shDblParen,shDblBrace
254 if !exists("b:is_posix")
255  syn region shCaseEsac matchgroup=shConditional start="\<select\s" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
256 endif
257else
258 syn region shRepeat   matchgroup=shLoop   start="\<while\_s" end="\<do\>"me=e-2		contains=@shLoopList
259 syn region shRepeat   matchgroup=shLoop   start="\<until\_s" end="\<do\>"me=e-2		contains=@shLoopList
260endif
261syn region shCurlyIn   contained	matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
262syn match  shComma     contained	","
263
264" Case: case...esac {{{1
265" ====
266syn match shCaseBar	contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|"		nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
267syn match shCaseStart	contained skipwhite skipnl "("			nextgroup=shCase,shCaseBar
268syn match shCaseLabel	contained skipwhite	"\%(\\.\|[-a-zA-Z0-9_*.]\)\+"	contains=shCharClass
269if exists("b:is_bash")
270 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
271else
272 ShFoldIfDoFor syn region	shCase	contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end="esac"me=s-1		contains=@shCaseList	nextgroup=shCaseStart,shCase,shComment
273endif
274ShFoldIfDoFor syn region	shCaseEsac	matchgroup=shConditional start="\<case\>" end="\<esac\>"	contains=@shCaseEsacList
275
276syn keyword shCaseIn	contained skipwhite skipnl in			nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
277if exists("b:is_bash")
278 syn region  shCaseExSingleQuote	matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
279elseif !exists("g:sh_no_error")
280 syn region  shCaseExSingleQuote	matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
281endif
282syn region  shCaseSingleQuote	matchgroup=shQuote start=+'+ end=+'+		contains=shStringSpecial		skipwhite skipnl nextgroup=shCaseBar	contained
283syn region  shCaseDoubleQuote	matchgroup=shQuote start=+"+ skip=+\\\\\|\\.+ end=+"+	contains=@shDblQuoteList,shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
284syn region  shCaseCommandSub	start=+`+ skip=+\\\\\|\\.+ end=+`+		contains=@shCommandSubList		skipwhite skipnl nextgroup=shCaseBar	contained
285if exists("b:is_bash")
286 syn region  shCaseRange	matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+\]+	contained	contains=shCharClass
287 syn match   shCharClass	'\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|or\|xdigit\):\]'			contained
288else
289 syn region  shCaseRange	matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+\]+	contained
290endif
291" Misc: {{{1
292"======
293syn match   shWrapLineOperator "\\$"
294syn region  shCommandSubBQ   	start="`" skip="\\\\\|\\." end="`"	contains=shBQComment,@shCommandSubList
295"see ksh13
296"syn match   shEscape	contained	'\%(^\)\@!\%(\\\\\)*\\.'	nextgroup=shSingleQuote,shDoubleQuote,shComment
297syn match   shEscape	contained	'\%(^\)\@!\%(\\\\\)*\\.'	nextgroup=shComment
298
299" $() and $(()): {{{1
300" $(..) is not supported by sh (Bourne shell).  However, apparently
301" some systems (HP?) have as their /bin/sh a (link to) Korn shell
302" (ie. Posix compliant shell).  /bin/ksh should work for those
303" systems too, however, so the following syntax will flag $(..) as
304" an Error under /bin/sh.  By consensus of vimdev'ers!
305if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
306 syn region shCommandSub matchgroup=shCmdSubRegion start="\$("  skip='\\\\\|\\.' end=")"  contains=@shCommandSubList
307 syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
308 syn region shArithmetic matchgroup=shArithRegion  start="\$\[" skip='\\\\\|\\.' end="\]" contains=@shArithList
309 syn match  shSkipInitWS contained	"^\s\+"
310elseif !exists("g:sh_no_error")
311 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
312endif
313syn region shCmdParenRegion matchgroup=shCmdSubRegion start="(\ze[^(]" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
314
315if exists("b:is_bash")
316 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
317 syn cluster shCaseList add=bashAdminStatement,bashStatement
318 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
319 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
320 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
321 syn keyword bashStatement	command compgen
322endif
323
324if exists("b:is_kornshell") || exists("b:is_posix")
325 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
326 syn cluster shCaseList add=kshStatement
327 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
328 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
329 syn keyword kshStatement command setgroups setsenv
330endif
331
332syn match   shSource	"^\.\s"
333syn match   shSource	"\s\.\s"
334"syn region  shColon	start="^\s*:" end="$" end="\s#"me=e-2 contains=@shColonList
335"syn region  shColon	start="^\s*\zs:" end="$" end="\s#"me=e-2
336if exists("b:is_kornshell") || exists("b:is_posix")
337 syn match   shColon	'^\s*\zs:'
338endif
339
340" String And Character Constants: {{{1
341"================================
342syn match   shNumber	"\<\d\+\>#\="
343syn match   shNumber	"\<-\=\.\=\d\+\>#\="
344syn match   shCtrlSeq	"\\\d\d\d\|\\[abcfnrtv0]"			contained
345if exists("b:is_bash")
346 syn match   shSpecial	"[^\\]\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]"	contained
347 syn match   shSpecial	"^\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]"	contained
348 syn region  shExSingleQuote	matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial,shSpecial		nextgroup=shSpecialNxt
349 syn region  shExDoubleQuote	matchgroup=shQuote start=+\$"+ skip=+\\\\\|\\.\|\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial,shSpecial	nextgroup=shSpecialNxt
350elseif !exists("g:sh_no_error")
351 syn region  shExSingleQuote	matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+	contains=shStringSpecial
352 syn region  shExDoubleQuote	matchGroup=Error start=+\$"+ skip=+\\\\\|\\.+ end=+"+	contains=shStringSpecial
353endif
354syn region  shSingleQuote	matchgroup=shQuote start=+'+ end=+'+		contains=@Spell	nextgroup=shSpecialStart,shSpecialSQ
355syn region  shDoubleQuote	matchgroup=shQuote start=+\%(\%(\\\\\)*\\\)\@<!"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial,@Spell	nextgroup=shSpecialStart
356syn region  shDoubleQuote	matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+		contained contains=@shDblQuoteList,shStringSpecial,@Spell	nextgroup=shSpecialStart
357syn match   shStringSpecial	"[^[:print:] \t]"			contained
358syn match   shStringSpecial	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"			nextgroup=shComment
359syn match   shSpecialSQ	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"		contained	nextgroup=shBkslshSnglQuote,@shNoZSList
360syn match   shSpecialDQ	"[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"		contained	nextgroup=shBkslshDblQuote,@shNoZSList
361syn match   shSpecialStart	"\%(\\\\\)*\\[\\"'`$()#]"			contained	nextgroup=shBkslshSnglQuote,shBkslshDblQuote,@shNoZSList
362syn match   shSpecial	"^\%(\\\\\)*\\[\\"'`$()#]"
363syn match   shSpecialNoZS	contained	"\%(\\\\\)*\\[\\"'`$()#]"
364syn match   shSpecialNxt	contained	"\\[\\"'`$()#]"
365syn region  shBkslshSnglQuote	contained	matchgroup=shQuote start=+'+ end=+'+	contains=@Spell	nextgroup=shSpecialStart
366syn region  shBkslshDblQuote	contained	matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial,@Spell	nextgroup=shSpecialStart
367
368" Comments: {{{1
369"==========
370syn cluster	shCommentGroup	contains=shTodo,@Spell
371if exists("b:is_bash")
372 syn match	shTodo	contained		"\<\%(COMBAK\|FIXME\|TODO\|XXX\)\ze:\=\>"
373else
374 syn keyword	shTodo	contained		COMBAK FIXME TODO XXX
375endif
376syn match	shComment		"^\s*\zs#.*$"	contains=@shCommentGroup
377syn match	shComment		"\s\zs#.*$"	contains=@shCommentGroup
378syn match	shComment	contained	"#.*$"	contains=@shCommentGroup
379syn match	shQuickComment	contained	"#.*$"
380syn match	shBQComment	contained	"#.\{-}\ze`"	contains=@shCommentGroup
381
382" Here Documents: {{{1
383" =========================================
384"  Note : shHereDoc0[137] only had shDblQuoteList contained
385ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc01 start="<<\s*\\\=\z([^ \t|>]\+\)"		matchgroup=shHereDoc01 end="^\z1\s*$"	contains=@shDblQuoteList
386ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc02 start="<<\s*\"\z([^"]\+\)\""		matchgroup=shHereDoc02 end="^\z1\s*$"
387ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc03 start="<<-\s*\z([^ \t|>]\+\)"		matchgroup=shHereDoc03 end="^\s*\z1\s*$"	contains=@shDblQuoteList
388ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc04 start="<<-\s*'\z([^']\+\)'"		matchgroup=shHereDoc04 end="^\s*\z1\s*$"
389ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc05 start="<<\s*'\z([^']\+\)'"		matchgroup=shHereDoc05 end="^\z1\s*$"
390ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*\"\z([^"]\+\)\""		matchgroup=shHereDoc06 end="^\s*\z1\s*$"
391ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc07 start="<<\s*\\\_$\_s*\z([^ \t'"|>]\+\)"	matchgroup=shHereDoc07 end="^\z1\s*$"
392ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc08 start="<<\s*\\\_$\_s*'\z([^\t|>]\+\)'"	matchgroup=shHereDoc08 end="^\z1\s*$"
393ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc09 start="<<\s*\\\_$\_s*\"\z([^\t|>]\+\)\""	matchgroup=shHereDoc09 end="^\z1\s*$"
394ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t|>]\+\)"	matchgroup=shHereDoc10 end="^\s*\z1\s*$"
395ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<-\s*\\\_$\_s*\\\z([^ \t|>]\+\)"	matchgroup=shHereDoc11 end="^\s*\z1\s*$"        contains=@shDblQuoteList
396ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*'\z([^']\+\)'"		matchgroup=shHereDoc12 end="^\s*\z1\s*$"
397ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<-\s*\\\_$\_s*\"\z([^"]\+\)\""	matchgroup=shHereDoc13 end="^\s*\z1\s*$"
398ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc14 start="<<\\\z([^ \t|>]\+\)"		matchgroup=shHereDoc14 end="^\z1\s*$"           contains=@shDblQuoteList
399ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc15 start="<<-\s*\\\z([^ \t|>]\+\)"		matchgroup=shHereDoc15 end="^\s*\z1\s*$"        contains=@shDblQuoteList
400ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc16 start="<<-\s*\\\z([^ \t|>]\+\)"		matchgroup=shHereDoc15 end="^\s*\z1\s*$"        contains=@shDblQuoteList
401
402" Here Strings: {{{1
403" =============
404" available for: bash; ksh (really should be ksh93 only) but not if its a posix
405if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_posix"))
406 syn match shHereString "<<<"	skipwhite	nextgroup=shCmdParenRegion
407endif
408
409" Identifiers: {{{1
410"=============
411syn match  shSetOption	"\s\zs[-+][a-zA-Z0-9]\+\>"	contained
412syn match  shVariable	"\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="	nextgroup=shVarAssign
413syn match  shVarAssign	"="		contained	nextgroup=shCmdParenRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
414syn match  shVar	contained	"\h\w*"
415syn region shAtExpr	contained	start="@(" end=")" contains=@shIdList
416if exists("b:is_bash")
417 syn match  shSet "^\s*set\ze\s\+$"
418 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
419 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
420elseif exists("b:is_kornshell") || exists("b:is_posix")
421 syn match  shSet "^\s*set\ze\s\+$"
422 syn region shSetList oneline matchgroup=shSet start="\<\(export\)\>\ze[/]\@!" end="$"		matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]"	contains=@shIdList
423 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
424else
425 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
426endif
427
428" Functions: {{{1
429if !exists("b:is_posix")
430 syn keyword shFunctionKey function	skipwhite skipnl nextgroup=shFunctionTwo
431endif
432
433if exists("b:is_bash")
434 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
435 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
436 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
437 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
438else
439 ShFoldFunctions syn region shFunctionOne	matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{"			end="}"	contains=@shFunctionList		 skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
440 ShFoldFunctions syn region shFunctionTwo	matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{"		end="}"	contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
441 ShFoldFunctions syn region shFunctionThree	matchgroup=shFunction start="^\s*\h\w*\s*()\_s*("			end=")"	contains=@shFunctionList		 skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
442 ShFoldFunctions syn region shFunctionFour	matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*("		end=")"	contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
443endif
444
445" Parameter Dereferencing: {{{1
446" ========================
447if !exists("g:sh_no_error")
448 syn match  shDerefWordError	"[^}$[~]"	contained
449endif
450syn match  shDerefSimple	"\$\%(\h\w*\|\d\)"	nextgroup=@shNoZSList
451syn region shDeref	matchgroup=PreProc start="\${" end="}"	contains=@shDerefList,shDerefVarArray
452syn match  shDerefSimple	"\$[-#*@!?]"	nextgroup=@shNoZSList
453syn match  shDerefSimple	"\$\$"	nextgroup=@shNoZSList
454syn match  shDerefSimple	"\${\d}"	nextgroup=@shNoZSList
455if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
456 syn region shDeref	matchgroup=PreProc start="\${##\=" end="}"	contains=@shDerefList	nextgroup=@shSpecialNoZS
457 syn region shDeref	matchgroup=PreProc start="\${\$\$" end="}"	contains=@shDerefList	nextgroup=@shSpecialNoZS
458endif
459
460" ksh: ${!var[*]} array index list syntax: {{{1
461" ========================================
462if exists("b:is_kornshell") || exists("b:is_posix")
463 syn region shDeref	matchgroup=PreProc start="\${!" end="}"	contains=@shDerefVarArray
464endif
465
466" bash: ${!prefix*} and ${#parameter}: {{{1
467" ====================================
468if exists("b:is_bash")
469 syn region shDeref	matchgroup=PreProc start="\${!" end="\*\=}"	contains=@shDerefList,shDerefOff
470 syn match  shDerefVar	contained	"{\@<=!\h\w*"		nextgroup=@shDerefVarList
471endif
472if exists("b:is_kornshell")
473 syn match  shDerefVar	contained	"{\@<=!\h\w*[[:alnum:]_.]*"	nextgroup=@shDerefVarList
474endif
475
476syn match  shDerefSpecial	contained	"{\@<=[-*@?0]"		nextgroup=shDerefOp,shDerefOpError
477syn match  shDerefSpecial	contained	"\({[#!]\)\@<=[[:alnum:]*@_]\+"	nextgroup=@shDerefVarList,shDerefOp
478syn match  shDerefVar	contained	"{\@<=\h\w*"		nextgroup=@shDerefVarList
479syn match  shDerefVar	contained	'\d'                            nextgroup=@shDerefVarList
480if exists("b:is_kornshell") || exists("b:is_posix")
481  syn match  shDerefVar	contained	"{\@<=\h\w*[[:alnum:]_.]*"	nextgroup=@shDerefVarList
482endif
483
484" sh ksh bash : ${var[... ]...}  array reference: {{{1
485syn region  shDerefVarArray   contained	matchgroup=shDeref start="\[" end="]"	contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
486
487" Special ${parameter OPERATOR word} handling: {{{1
488" sh ksh bash : ${parameter:-word}    word is default value
489" sh ksh bash : ${parameter:=word}    assign word as default value
490" sh ksh bash : ${parameter:?word}    display word if parameter is null
491" sh ksh bash : ${parameter:+word}    use word if parameter is not null, otherwise nothing
492"    ksh bash : ${parameter#pattern}  remove small left  pattern
493"    ksh bash : ${parameter##pattern} remove large left  pattern
494"    ksh bash : ${parameter%pattern}  remove small right pattern
495"    ksh bash : ${parameter%%pattern} remove large right pattern
496"        bash : ${parameter^pattern}  Case modification
497"        bash : ${parameter^^pattern} Case modification
498"        bash : ${parameter,pattern}  Case modification
499"        bash : ${parameter,,pattern} Case modification
500syn cluster shDerefPatternList	contains=shDerefPattern,shDerefString
501if !exists("g:sh_no_error")
502 syn match shDerefOpError	contained	":[[:punct:]]"
503endif
504syn match  shDerefOp	contained	":\=[-=?]"	nextgroup=@shDerefPatternList
505syn match  shDerefOp	contained	":\=+"	nextgroup=@shDerefPatternList
506if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
507 syn match  shDerefOp	contained	"#\{1,2}"		nextgroup=@shDerefPatternList
508 syn match  shDerefOp	contained	"%\{1,2}"		nextgroup=@shDerefPatternList
509 syn match  shDerefPattern	contained	"[^{}]\+"		contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
510 syn region shDerefPattern	contained	start="{" end="}"	contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
511 syn match  shDerefEscape	contained	'\%(\\\\\)*\\.'
512endif
513if exists("b:is_bash")
514 syn match  shDerefOp	contained	"[,^]\{1,2}"	nextgroup=@shDerefPatternList
515endif
516syn region shDerefString	contained	matchgroup=shDerefDelim start=+\%(\\\)\@<!'+ end=+'+	contains=shStringSpecial
517syn region shDerefString	contained	matchgroup=shDerefDelim start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+	contains=@shDblQuoteList,shStringSpecial
518syn match  shDerefString	contained	"\\["']"	nextgroup=shDerefPattern
519
520if exists("b:is_bash")
521 " bash : ${parameter:offset}
522 " bash : ${parameter:offset:length}
523 syn region shDerefOff	contained	start=':[^-=?+]' end='\ze:'	end='\ze}'	contains=shDeref,shDerefSimple,shDerefEscape	nextgroup=shDerefLen,shDeref,shDerefSimple
524 syn region shDerefOff	contained	start=':\s-'	end='\ze:'	end='\ze}'	contains=shDeref,shDerefSimple,shDerefEscape	nextgroup=shDerefLen,shDeref,shDerefSimple
525 syn match  shDerefLen	contained	":[^}]\+"	contains=shDeref,shDerefSimple,shArithmetic
526
527 " bash : ${parameter//pattern/string}
528 " bash : ${parameter//pattern}
529 syn match  shDerefPPS	contained	'/\{1,2}'	nextgroup=shDerefPPSleft
530 syn region shDerefPPSleft	contained	start='.'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}'	nextgroup=shDerefPPSright	contains=@shCommandSubList
531 syn region shDerefPPSright	contained	start='.'	skip=@\%(\\\\\)\+@		end='\ze}'				contains=@shPPSRightList
532
533 " bash : ${parameter/#substring/replacement}
534 syn match  shDerefPSR	contained	'/#'	nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
535 syn region shDerefPSRleft	contained	start='[^"']'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}'	nextgroup=shDerefPSRright
536 syn region shDerefPSRright	contained	start='.'	skip=@\%(\\\\\)\+@		end='\ze}'
537endif
538
539" Arithmetic Parenthesized Expressions: {{{1
540"syn region shParen matchgroup=shArithRegion start='[^$]\zs(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
541syn region shParen matchgroup=shArithRegion start='\$\@!(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
542
543" Additional sh Keywords: {{{1
544" ===================
545syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
546syn keyword shConditional contained elif else then
547if !exists("g:sh_no_error")
548 syn keyword shCondError elif else then
549endif
550
551" Additional ksh Keywords and Aliases: {{{1
552" ===================================
553if exists("b:is_kornshell") || exists("b:is_posix")
554 syn keyword shStatement bg builtin disown enum export false fg getconf getopts hist jobs let printf sleep true unalias whence
555 syn keyword shStatement typeset skipwhite nextgroup=shSetOption
556 syn keyword shStatement autoload compound fc float functions hash history integer nameref nohup r redirect source stop suspend times type
557 if exists("b:is_posix")
558  syn keyword shStatement command
559 else
560  syn keyword shStatement time
561 endif
562
563" Additional bash Keywords: {{{1
564" =====================
565elseif exists("b:is_bash")
566 syn keyword shStatement bg builtin disown export false fg getopts jobs let printf sleep true unalias
567 syn keyword shStatement typeset nextgroup=shSetOption
568 syn keyword shStatement fc hash history source suspend times type
569 syn keyword shStatement bind builtin caller compopt declare dirs disown enable export help logout mapfile popd pushd readarray shopt source typeset
570else
571 syn keyword shStatement login newgrp
572endif
573
574" Synchronization: {{{1
575" ================
576if !exists("g:sh_minlines")
577 let s:sh_minlines = 200
578else
579 let s:sh_minlines= g:sh_minlines
580endif
581if !exists("g:sh_maxlines")
582 let s:sh_maxlines = 2*s:sh_minlines
583 if s:sh_maxlines < 25
584  let s:sh_maxlines= 25
585 endif
586else
587 let s:sh_maxlines= g:sh_maxlines
588endif
589exec "syn sync minlines=" . s:sh_minlines . " maxlines=" . s:sh_maxlines
590syn sync match shCaseEsacSync	grouphere	shCaseEsac	"\<case\>"
591syn sync match shCaseEsacSync	groupthere	shCaseEsac	"\<esac\>"
592syn sync match shDoSync	grouphere	shDo	"\<do\>"
593syn sync match shDoSync	groupthere	shDo	"\<done\>"
594syn sync match shForSync	grouphere	shFor	"\<for\>"
595syn sync match shForSync	groupthere	shFor	"\<in\>"
596syn sync match shIfSync	grouphere	shIf	"\<if\>"
597syn sync match shIfSync	groupthere	shIf	"\<fi\>"
598syn sync match shUntilSync	grouphere	shRepeat	"\<until\>"
599syn sync match shWhileSync	grouphere	shRepeat	"\<while\>"
600
601" Default Highlighting: {{{1
602" =====================
603if !exists("skip_sh_syntax_inits")
604 hi def link shArithRegion	shShellVariables
605 hi def link shAstQuote	shDoubleQuote
606 hi def link shAtExpr	shSetList
607 hi def link shBkslshSnglQuote	shSingleQuote
608 hi def link shBkslshDblQuote	shDOubleQuote
609 hi def link shBeginHere	shRedir
610 hi def link shCaseBar	shConditional
611 hi def link shCaseCommandSub	shCommandSub
612 hi def link shCaseDoubleQuote	shDoubleQuote
613 hi def link shCaseIn	shConditional
614 hi def link shQuote	shOperator
615 hi def link shCaseSingleQuote	shSingleQuote
616 hi def link shCaseStart	shConditional
617 hi def link shCmdSubRegion	shShellVariables
618 hi def link shColon	shComment
619 hi def link shDerefOp	shOperator
620 hi def link shDerefPOL	shDerefOp
621 hi def link shDerefPPS	shDerefOp
622 hi def link shDerefPSR	shDerefOp
623 hi def link shDeref	shShellVariables
624 hi def link shDerefDelim	shOperator
625 hi def link shDerefSimple	shDeref
626 hi def link shDerefSpecial	shDeref
627 hi def link shDerefString	shDoubleQuote
628 hi def link shDerefVar	shDeref
629 hi def link shDoubleQuote	shString
630 hi def link shEcho	shString
631 hi def link shEchoDelim	shOperator
632 hi def link shEchoQuote	shString
633 hi def link shForPP	shLoop
634 hi def link shFunction	Function
635 hi def link shEmbeddedEcho	shString
636 hi def link shEscape	shCommandSub
637 hi def link shExDoubleQuote	shDoubleQuote
638 hi def link shExSingleQuote	shSingleQuote
639 hi def link shHereDoc	shString
640 hi def link shHereString	shRedir
641 hi def link shHerePayload	shHereDoc
642 hi def link shLoop	shStatement
643 hi def link shSpecialNxt	shSpecial
644 hi def link shNoQuote	shDoubleQuote
645 hi def link shOption	shCommandSub
646 hi def link shPattern	shString
647 hi def link shParen	shArithmetic
648 hi def link shPosnParm	shShellVariables
649 hi def link shQuickComment	shComment
650 hi def link shBQComment	shComment
651 hi def link shRange	shOperator
652 hi def link shRedir	shOperator
653 hi def link shSetListDelim	shOperator
654 hi def link shSetOption	shOption
655 hi def link shSingleQuote	shString
656 hi def link shSource	shOperator
657 hi def link shStringSpecial	shSpecial
658 hi def link shSpecialStart	shSpecial
659 hi def link shSubShRegion	shOperator
660 hi def link shTestOpr	shConditional
661 hi def link shTestPattern	shString
662 hi def link shTestDoubleQuote	shString
663 hi def link shTestSingleQuote	shString
664 hi def link shTouchCmd	shStatement
665 hi def link shVariable	shSetList
666 hi def link shWrapLineOperator	shOperator
667
668 if exists("b:is_bash")
669   hi def link bashAdminStatement	shStatement
670   hi def link bashSpecialVariables	shShellVariables
671   hi def link bashStatement		shStatement
672   hi def link shCharClass		shSpecial
673   hi def link shDerefOff		shDerefOp
674   hi def link shDerefLen		shDerefOff
675 endif
676 if exists("b:is_kornshell") || exists("b:is_posix")
677   hi def link kshSpecialVariables	shShellVariables
678   hi def link kshStatement		shStatement
679 endif
680
681 if !exists("g:sh_no_error")
682  hi def link shCaseError		Error
683  hi def link shCondError		Error
684  hi def link shCurlyError		Error
685  hi def link shDerefOpError		Error
686  hi def link shDerefWordError		Error
687  hi def link shDoError		Error
688  hi def link shEsacError		Error
689  hi def link shIfError		Error
690  hi def link shInError		Error
691  hi def link shParenError		Error
692  hi def link shTestError		Error
693  if exists("b:is_kornshell") || exists("b:is_posix")
694    hi def link shDTestError		Error
695  endif
696 endif
697
698 hi def link shArithmetic		Special
699 hi def link shCharClass		Identifier
700 hi def link shSnglCase		Statement
701 hi def link shCommandSub		Special
702 hi def link shCommandSubBQ		shCommandSub
703 hi def link shComment		Comment
704 hi def link shConditional		Conditional
705 hi def link shCtrlSeq		Special
706 hi def link shExprRegion		Delimiter
707 hi def link shFunctionKey		Function
708 hi def link shFunctionName		Function
709 hi def link shNumber		Number
710 hi def link shOperator		Operator
711 hi def link shRepeat		Repeat
712 hi def link shSet		Statement
713 hi def link shSetList		Identifier
714 hi def link shShellVariables		PreProc
715 hi def link shSpecial		Special
716 hi def link shSpecialDQ		Special
717 hi def link shSpecialSQ		Special
718 hi def link shSpecialNoZS		shSpecial
719 hi def link shStatement		Statement
720 hi def link shString		String
721 hi def link shTodo		Todo
722 hi def link shAlias		Identifier
723 hi def link shHereDoc01		shRedir
724 hi def link shHereDoc02		shRedir
725 hi def link shHereDoc03		shRedir
726 hi def link shHereDoc04		shRedir
727 hi def link shHereDoc05		shRedir
728 hi def link shHereDoc06		shRedir
729 hi def link shHereDoc07		shRedir
730 hi def link shHereDoc08		shRedir
731 hi def link shHereDoc09		shRedir
732 hi def link shHereDoc10		shRedir
733 hi def link shHereDoc11		shRedir
734 hi def link shHereDoc12		shRedir
735 hi def link shHereDoc13		shRedir
736 hi def link shHereDoc14		shRedir
737 hi def link shHereDoc15		shRedir
738endif
739
740" Delete shell folding commands {{{1
741" =============================
742delc ShFoldFunctions
743delc ShFoldHereDoc
744delc ShFoldIfDoFor
745
746" Set Current Syntax: {{{1
747" ===================
748if exists("b:is_bash")
749 let b:current_syntax = "bash"
750elseif exists("b:is_kornshell")
751 let b:current_syntax = "ksh"
752elseif exists("b:is_posix")
753 let b:current_syntax = "posix"
754else
755 let b:current_syntax = "sh"
756endif
757
758" vim: ts=16 fdm=marker
759