vim: update release.sh to vim 7.3
[msysgit/mtrensch.git] / share / vim / vim72 / syntax / sh.vim
blob5fa8d938fde6a439ad3af32c5fb9369c85bdabc5
1 " Vim syntax file
2 " Language:             shell (sh) Korn shell (ksh) bash (sh)
3 " Maintainer:           Dr. Charles E. Campbell, Jr.  <NdrOchipS@PcampbellAfamily.Mbiz>
4 " Previous Maintainer:  Lennart Schultz <Lennart.Schultz@ecmwf.int>
5 " Last Change:          Jul 11, 2008
6 " Version:              102
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
13 if version < 600
14   syntax clear
15 elseif exists("b:current_syntax")
16   finish
17 endif
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,
25 " respectively.
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
29   endif
30   if exists("g:is_kornshell")
31     let b:is_kornshell= 1
32     if exists("b:is_sh")
33       unlet b:is_sh
34     endif
35   elseif exists("g:is_bash")
36     let b:is_bash= 1
37     if exists("b:is_sh")
38       unlet b:is_sh
39     endif
40   else
41     let b:is_sh= 1
42   endif
43 endif
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"
51 endif
52 if !exists("s:sh_fold_functions")
53  let s:sh_fold_functions = 1
54 endif
55 if !exists("s:sh_fold_heredoc")
56  let s:sh_fold_heredoc   = 2
57 endif
58 if !exists("s:sh_fold_ifdofor")
59  let s:sh_fold_ifdofor   = 4
60 endif
61 if g:sh_fold_enabled && &fdm == "manual"
62  set fdm=syntax
63 endif
65 " sh syntax is case sensitive {{{1
66 syn case match
68 " Clusters: contains=@... clusters {{{1
69 "==================================
70 syn cluster shErrorList contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError
71 if exists("b:is_kornshell")
72  syn cluster ErrorList add=shDTestError
73 endif
74 syn cluster shArithParenList    contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen
75 syn cluster shArithList contains=@shArithParenList,shParenError
76 syn cluster shCaseEsacList      contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial
77 syn cluster shCaseList  contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
78 syn cluster shColonList contains=@shCaseList
79 syn cluster shCommandSubList    contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq,shSpecial
80 syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
81 syn cluster shDblQuoteList      contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
82 syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
83 syn cluster shDerefVarList      contains=shDerefOp,shDerefVarArray,shDerefOpError
84 syn cluster shEchoList  contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
85 syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
86 syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
87 syn cluster shFunctionList      contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
88 if exists("b:is_kornshell") || exists("b:is_bash")
89  syn cluster shFunctionList     add=shRepeat
90  syn cluster shFunctionList     add=shDblBrace,shDblParen
91 endif
92 syn cluster shHereBeginList     contains=@shCommandSubList
93 syn cluster shHereList  contains=shBeginHere,shHerePayload
94 syn cluster shHereListDQ        contains=shBeginHere,@shDblQuoteList,shHerePayload
95 syn cluster shIdList    contains=shCommandSub,shWrapLineOperator,shSetOption,shDeref,shDerefSimple,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial
96 syn cluster shLoopList  contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest,@shErrorList,shSet
97 syn cluster shSubShList contains=@shCaseList,shOperator
98 syn cluster shTestList  contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
101 " Echo: {{{1
102 " ====
103 " This one is needed INSIDE a CommandSub, so that `echo bla` be correct
104 syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
105 syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
106 syn match  shEchoQuote contained        '\%(\\\\\)*\\["`']'
108 " This must be after the strings, so that ... \" will be correct
109 syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shDoubleQuote,shCharClass,shCtrlSeq
111 " Alias: {{{1
112 " =====
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="="
117 endif
119 " Error Codes: {{{1
120 " ============
121 syn match   shDoError "\<done\>"
122 syn match   shIfError "\<fi\>"
123 syn match   shInError "\<in\>"
124 syn match   shCaseError ";;"
125 syn match   shEsacError "\<esac\>"
126 syn match   shCurlyError "}"
127 syn match   shParenError ")"
128 if exists("b:is_kornshell")
129  syn match     shDTestError "]]"
130 endif
131 syn match     shTestError "]"
133 " Options: {{{1
134 " ====================
135 syn match   shOption    "\s\zs[-+][a-zA-Z0-9]\+\>"
136 syn match   shOption    "\s\zs--[^ \t$`'"|]\+"
138 " File Redirection Highlighted As Operators: {{{1
139 "===========================================
140 syn match      shRedir  "\d\=>\(&[-0-9]\)\="
141 syn match      shRedir  "\d\=>>-\="
142 syn match      shRedir  "\d\=<\(&[-0-9]\)\="
143 syn match      shRedir  "\d<<-\="
145 " Operators: {{{1
146 " ==========
147 syn match   shOperator  "<<\|>>"                contained
148 syn match   shOperator  "[!&;|]"                contained
149 syn match   shOperator  "\[[[^:]\|\]]"          contained
150 syn match   shOperator  "!\=="          skipwhite nextgroup=shPattern
151 syn match   shPattern   "\<\S\+\())\)\@="       contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
153 " Subshells: {{{1
154 " ==========
155 syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"       contains=@shExprList2
156 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")"       contains=@shSubShList
158 " Tests: {{{1
159 "=======
160 "syn region  shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
161 syn region shExpr       matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
162 syn region shTest       transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
163 syn match  shTestOpr    contained       "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
164 syn match  shTestOpr    contained       '=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
165 syn match  shTestPattern        contained       '\w\+'
166 syn match  shTestDoubleQuote    contained       '"[^"]*"'
167 syn match  shTestSingleQuote    contained       '\\.'
168 syn match  shTestSingleQuote    contained       "'[^']*'"
169 if exists("b:is_kornshell") || exists("b:is_bash")
170  syn region  shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]"   contains=@shTestList
171  syn region  shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))"       contains=@shTestList
172 endif
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
179 " ======
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
184 else
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
188 endif
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
195 else
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
198 endif
199 syn region shCurlyIn   contained        matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
200 syn match  shComma     contained        ","
202 " Case: case...esac {{{1
203 " ====
204 syn match   shCaseBar   contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|"         nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
205 syn match   shCaseStart contained skipwhite skipnl "("                  nextgroup=shCase,shCaseBar
206 syn region  shCase      contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
207 if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
208  syn region  shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>"   contains=@shCaseEsacList
209 else
210  syn region  shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>"        contains=@shCaseEsacList
211 endif
212 syn keyword shCaseIn    contained skipwhite skipnl in                   nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
213 if exists("b:is_bash")
214  syn region  shCaseExSingleQuote        matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+      contains=shStringSpecial,shSpecial      skipwhite skipnl nextgroup=shCaseBar    contained
215 else
216  syn region  shCaseExSingleQuote        matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+   contains=shStringSpecial        skipwhite skipnl nextgroup=shCaseBar    contained
217 endif
218 syn region  shCaseSingleQuote   matchgroup=shOperator start=+'+ end=+'+         contains=shStringSpecial                skipwhite skipnl nextgroup=shCaseBar    contained
219 syn region  shCaseDoubleQuote   matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+        contains=@shDblQuoteList,shStringSpecial        skipwhite skipnl nextgroup=shCaseBar    contained
220 syn region  shCaseCommandSub    start=+`+ skip=+\\\\\|\\.+ end=+`+              contains=@shCommandSubList              skipwhite skipnl nextgroup=shCaseBar    contained
222 " Misc: {{{1
223 "======
224 syn match   shWrapLineOperator "\\$"
225 syn region  shCommandSub   start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
226 syn match   shEscape    contained       '\\.'
228 " $() and $(()): {{{1
229 " $(..) is not supported by sh (Bourne shell).  However, apparently
230 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
231 " (ie. Posix compliant shell).  /bin/ksh should work for those
232 " systems too, however, so the following syntax will flag $(..) as
233 " an Error under /bin/sh.  By consensus of vimdev'ers!
234 if exists("b:is_kornshell") || exists("b:is_bash")
235  syn region shCommandSub matchgroup=shCmdSubRegion start="\$("  skip='\\\\\|\\.' end=")"  contains=@shCommandSubList
236  syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
237  syn match  shSkipInitWS contained      "^\s\+"
238 else
239  syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
240 endif
242 if exists("b:is_bash")
243  syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
244  syn cluster shCaseList add=bashAdminStatement,bashStatement
245  syn keyword bashSpecialVariables contained BASH BASH_ENV BASH_VERSINFO BASH_VERSION CDPATH DIRSTACK EUID FCEDIT FIGNORE GLOBIGNORE GROUPS HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_MESSAGES LINENO MACHTYPE MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELLOPTS SHLVL TIMEFORMAT TIMEOUT UID auto_resume histchars
246  syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep install less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch
247  syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
248 endif
250 if exists("b:is_kornshell")
251  syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
252  syn cluster shCaseList add=kshStatement
253  syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV ERRNO FCEDIT FPATH HISTFILE HISTSIZE HOME IFS LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL TMOUT VISUAL
254  syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep install killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail touch tput
255 endif
257 syn match   shSource    "^\.\s"
258 syn match   shSource    "\s\.\s"
259 syn region  shColon     start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
261 " String And Character Constants: {{{1
262 "================================
263 syn match   shNumber    "-\=\<\d\+\>#\="
264 syn match   shCtrlSeq   "\\\d\d\d\|\\[abcfnrtv0]"               contained
265 if exists("b:is_bash")
266  syn match   shSpecial  "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
267 endif
268 if exists("b:is_bash")
269  syn region  shExSingleQuote    matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+      contains=shStringSpecial,shSpecial
270 else
271  syn region  shExSingleQuote    matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+   contains=shStringSpecial
272 endif
273 syn region  shSingleQuote       matchgroup=shOperator start=+'+ end=+'+         contains=shStringSpecial,@Spell
274 syn region  shDoubleQuote       matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+      contains=@shDblQuoteList,shStringSpecial,@Spell
275 syn match   shStringSpecial     "[^[:print:] \t]"       contained
276 syn match   shStringSpecial     "\%(\\\\\)*\\[\\"'`$()#]"
277 syn match   shSpecial   "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
278 syn match   shSpecial   "^\%(\\\\\)*\\[\\"'`$()#]"
280 " Comments: {{{1
281 "==========
282 syn cluster    shCommentGroup   contains=shTodo,@Spell
283 syn keyword    shTodo   contained       COMBAK FIXME TODO XXX
284 syn match      shComment        "^\s*\zs#.*$"   contains=@shCommentGroup
285 syn match      shComment        "\s\zs#.*$"     contains=@shCommentGroup
286 syn match      shQuickComment   contained       "#.*$"
288 " Here Documents: {{{1
289 " =========================================
290 if version < 600
291  syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**"  matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
292  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^\s*END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
293  syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir      end="^EOF$"     contains=@shDblQuoteList
294  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir     end="^\s*EOF$"  contains=@shDblQuoteList
295  syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**"  matchgroup=shRedir      end="^\.$"      contains=@shDblQuoteList
296  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir      end="^\s*\.$"   contains=@shDblQuoteList
298 elseif (g:sh_fold_enabled % (s:sh_fold_heredoc * 2))/s:sh_fold_heredoc
299  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)"             matchgroup=shRedir end="^\z1\s*$"       contains=@shDblQuoteList
300  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\""         matchgroup=shRedir end="^\z1\s*$"
301  syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'"           matchgroup=shRedir end="^\z1\s*$"
302  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)"            matchgroup=shRedir end="^\s*\z1\s*$"    contains=@shDblQuoteList
303  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\""                matchgroup=shRedir end="^\s*\z1\s*$"
304  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'"          matchgroup=shRedir end="^\s*\z1\s*$"
305  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)"            matchgroup=shRedir end="^\z1\s*$"
306  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\""        matchgroup=shRedir end="^\z1\s*$"
307  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'"         matchgroup=shRedir end="^\s*\z1\s*$"
308  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)"           matchgroup=shRedir end="^\s*\z1\s*$"
309  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\""       matchgroup=shRedir end="^\s*\z1\s*$"
310  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'"          matchgroup=shRedir end="^\z1\s*$"
311  syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)"              matchgroup=shRedir end="^\z1\s*$"
313 else
314  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)"      matchgroup=shRedir end="^\z1\s*$"    contains=@shDblQuoteList
315  syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\""      matchgroup=shRedir end="^\z1\s*$"
316  syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)"         matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
317  syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'"       matchgroup=shRedir end="^\s*\z1\s*$"
318  syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'"        matchgroup=shRedir end="^\z1\s*$"
319  syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\""     matchgroup=shRedir end="^\s*\z1\s*$"
320  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
321  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)"        matchgroup=shRedir end="^\s*\z1\s*$"
322  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'"      matchgroup=shRedir end="^\s*\z1\s*$"
323  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'"       matchgroup=shRedir end="^\z1\s*$"
324  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\""     matchgroup=shRedir end="^\z1\s*$"
325  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\""    matchgroup=shRedir end="^\s*\z1\s*$"
326  syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)"           matchgroup=shRedir end="^\z1\s*$"
327 endif
329 " Here Strings: {{{1
330 " =============
331 if exists("b:is_bash")
332  syn match shRedir "<<<"
333 endif
335 " Identifiers: {{{1
336 "=============
337 syn match  shSetOption  "\s\zs[-+][a-zA-Z0-9]\+\>"      contained
338 syn match  shVariable   "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="     nextgroup=shSetIdentifier
339 syn match  shSetIdentifier      "="             contained       nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
340 if exists("b:is_bash")
341  syn region shSetList oneline matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$"    matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze#\|=" contains=@shIdList
342  syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="\ze[;|)]\|$"                 matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
343 elseif exists("b:is_kornshell")
344  syn region shSetList oneline matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$"            matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
345  syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="$"                           matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
346 else
347  syn region shSetList oneline matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$"                matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze[#=]" contains=@shIdList
348 endif
350 " Functions: {{{1
351 if !exists("g:is_posix")
352  syn keyword shFunctionKey function     skipwhite skipnl nextgroup=shFunctionTwo
353 endif
355 if exists("b:is_bash")
356  if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
357   syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{" end="}"    contains=@shFunctionList                        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
358   syn region shFunctionTwo fold matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
359  else
360   syn region shFunctionOne      matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{"    end="}" contains=@shFunctionList
361   syn region shFunctionTwo      matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained
362  endif
363 else
364  if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
365   syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}"       contains=@shFunctionList                        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
366   syn region shFunctionTwo fold matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{"    end="}" contains=shFunctionKey,@shFunctionList contained        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
367  else
368   syn region shFunctionOne      matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{"       end="}" contains=@shFunctionList
369   syn region shFunctionTwo      matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{"    end="}" contains=shFunctionKey,@shFunctionList contained
370  endif
371 endif
373 " Parameter Dereferencing: {{{1
374 " ========================
375 syn match  shDerefSimple        "\$\%(\h\w*\|\d\)"
376 syn region shDeref      matchgroup=PreProc start="\${" end="}"  contains=@shDerefList,shDerefVarArray
377 syn match  shDerefWordError     "[^}$[]"        contained
378 syn match  shDerefSimple        "\$[-#*@!?]"
379 syn match  shDerefSimple        "\$\$"
380 if exists("b:is_bash") || exists("b:is_kornshell")
381  syn region shDeref     matchgroup=PreProc start="\${##\=" end="}"      contains=@shDerefList
382  syn region shDeref     matchgroup=PreProc start="\${\$\$" end="}"      contains=@shDerefList
383 endif
385 " bash: ${!prefix*} and ${#parameter}: {{{1
386 " ====================================
387 if exists("b:is_bash")
388  syn region shDeref     matchgroup=PreProc start="\${!" end="\*\=}"     contains=@shDerefList,shDerefOp
389  syn match  shDerefVar  contained       "{\@<=!\w\+"            nextgroup=@shDerefVarList
390 endif
392 syn match  shDerefSpecial       contained       "{\@<=[-*@?0]"          nextgroup=shDerefOp,shDerefOpError
393 syn match  shDerefSpecial       contained       "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
394 syn match  shDerefVar   contained       "{\@<=\w\+"             nextgroup=@shDerefVarList
396 " sh ksh bash : ${var[... ]...}  array reference: {{{1
397 syn region  shDerefVarArray   contained matchgroup=shDeref start="\[" end="]"   contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
399 " Special ${parameter OPERATOR word} handling: {{{1
400 " sh ksh bash : ${parameter:-word}    word is default value
401 " sh ksh bash : ${parameter:=word}    assign word as default value
402 " sh ksh bash : ${parameter:?word}    display word if parameter is null
403 " sh ksh bash : ${parameter:+word}    use word if parameter is not null, otherwise nothing
404 "    ksh bash : ${parameter#pattern}  remove small left  pattern
405 "    ksh bash : ${parameter##pattern} remove large left  pattern
406 "    ksh bash : ${parameter%pattern}  remove small right pattern
407 "    ksh bash : ${parameter%%pattern} remove large right pattern
408 syn cluster shDerefPatternList  contains=shDerefPattern,shDerefString
409 syn match shDerefOpError        contained       ":[[:punct:]]"
410 syn match  shDerefOp    contained       ":\=[-=?]"      nextgroup=@shDerefPatternList
411 syn match  shDerefOp    contained       ":\=+"  nextgroup=@shDerefPatternList
412 if exists("b:is_bash") || exists("b:is_kornshell")
413  syn match  shDerefOp   contained       "#\{1,2}"       nextgroup=@shDerefPatternList
414  syn match  shDerefOp   contained       "%\{1,2}"       nextgroup=@shDerefPatternList
415  syn match  shDerefPattern      contained       "[^{}]\+"       contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
416  syn region shDerefPattern      contained       start="{" end="}"       contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
417  syn match  shDerefEscape       contained       '\%(\\\\\)*\\.'
418 endif
419 syn region shDerefString        contained       matchgroup=shOperator start=+\%(\\\)\@<!'+ end=+'+              contains=shStringSpecial
420 syn region shDerefString        contained       matchgroup=shOperator start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+   contains=@shDblQuoteList,shStringSpecial
421 syn match  shDerefString        contained       "\\["']"        nextgroup=shDerefPattern
423 if exists("b:is_bash")
424  " bash : ${parameter:offset}
425  " bash : ${parameter:offset:length}
426  syn region shDerefOp   contained       start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
427  syn match  shDerefPOL  contained       ":[^}]\+"       contains=@shCommandSubList
429  " bash : ${parameter//pattern/string}
430  " bash : ${parameter//pattern}
431  syn match  shDerefPPS  contained       '/\{1,2}'       nextgroup=shDerefPPSleft
432  syn region shDerefPPSleft      contained       start='.'       skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
433  syn region shDerefPPSright     contained       start='.'       end='\ze}'      contains=@shCommandSubList
434 endif
436 " Arithmetic Parenthesized Expressions: {{{1
437 syn region shParen matchgroup=shArithRegion start='(\ze[^(]' end=')' contains=@shArithParenList
439 " Useful sh Keywords: {{{1
440 " ===================
441 syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
442 syn keyword shConditional contained elif else then
443 syn keyword shCondError elif else then
445 " Useful ksh Keywords: {{{1
446 " ====================
447 if exists("b:is_kornshell") || exists("b:is_bash")
448  syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup print printf r stop suspend times true type unalias whence
449  if exists("g:is_posix")
450   syn keyword shStatement command
451  else
452   syn keyword shStatement time
453  endif
455 " Useful bash Keywords: {{{1
456 " =====================
457  if exists("b:is_bash")
458   syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
459  else
460   syn keyword shStatement login newgrp
461  endif
462 endif
464 " Synchronization: {{{1
465 " ================
466 if !exists("sh_minlines")
467   let sh_minlines = 200
468 endif
469 if !exists("sh_maxlines")
470   let sh_maxlines = 2 * sh_minlines
471 endif
472 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
473 syn sync match shCaseEsacSync   grouphere       shCaseEsac      "\<case\>"
474 syn sync match shCaseEsacSync   groupthere      shCaseEsac      "\<esac\>"
475 syn sync match shDoSync grouphere       shDo    "\<do\>"
476 syn sync match shDoSync groupthere      shDo    "\<done\>"
477 syn sync match shForSync        grouphere       shFor   "\<for\>"
478 syn sync match shForSync        groupthere      shFor   "\<in\>"
479 syn sync match shIfSync grouphere       shIf    "\<if\>"
480 syn sync match shIfSync groupthere      shIf    "\<fi\>"
481 syn sync match shUntilSync      grouphere       shRepeat        "\<until\>"
482 syn sync match shWhileSync      grouphere       shRepeat        "\<while\>"
484 " Default Highlighting: {{{1
485 " =====================
486 hi def link shArithRegion       shShellVariables
487 hi def link shBeginHere shRedir
488 hi def link shCaseBar   shConditional
489 hi def link shCaseCommandSub    shCommandSub
490 hi def link shCaseDoubleQuote   shDoubleQuote
491 hi def link shCaseIn    shConditional
492 hi def link shCaseSingleQuote   shSingleQuote
493 hi def link shCaseStart shConditional
494 hi def link shCmdSubRegion      shShellVariables
495 hi def link shColon     shStatement
496 hi def link shDerefOp   shOperator
497 hi def link shDerefPOL  shDerefOp
498 hi def link shDerefPPS  shDerefOp
499 hi def link shDeref     shShellVariables
500 hi def link shDerefSimple       shDeref
501 hi def link shDerefSpecial      shDeref
502 hi def link shDerefString       shDoubleQuote
503 hi def link shDerefVar  shDeref
504 hi def link shDoubleQuote       shString
505 hi def link shEcho      shString
506 hi def link shEchoQuote shString
507 hi def link shEmbeddedEcho      shString
508 hi def link shEscape    shCommandSub
509 hi def link shExSingleQuote     shSingleQuote
510 hi def link shFunction  Function
511 hi def link shHereDoc   shString
512 hi def link shHerePayload       shHereDoc
513 hi def link shLoop      shStatement
514 hi def link shOption    shCommandSub
515 hi def link shPattern   shString
516 hi def link shParen     shArithmetic
517 hi def link shPosnParm  shShellVariables
518 hi def link shQuickComment      shComment
519 hi def link shRange     shOperator
520 hi def link shRedir     shOperator
521 hi def link shSetOption shOption
522 hi def link shSingleQuote       shString
523 hi def link shSource    shOperator
524 hi def link shStringSpecial     shSpecial
525 hi def link shSubShRegion       shOperator
526 hi def link shTestOpr   shConditional
527 hi def link shTestPattern       shString
528 hi def link shTestDoubleQuote   shString
529 hi def link shTestSingleQuote   shString
530 hi def link shVariable  shSetList
531 hi def link shWrapLineOperator  shOperator
533 if exists("b:is_bash")
534   hi def link bashAdminStatement        shStatement
535   hi def link bashSpecialVariables      shShellVariables
536   hi def link bashStatement             shStatement
537   hi def link shFunctionParen           Delimiter
538   hi def link shFunctionDelim           Delimiter
539 endif
540 if exists("b:is_kornshell")
541   hi def link kshSpecialVariables       shShellVariables
542   hi def link kshStatement              shStatement
543   hi def link shFunctionParen           Delimiter
544 endif
546 hi def link shCaseError         Error
547 hi def link shCondError         Error
548 hi def link shCurlyError                Error
549 hi def link shDerefError                Error
550 hi def link shDerefOpError              Error
551 hi def link shDerefWordError            Error
552 hi def link shDoError           Error
553 hi def link shEsacError         Error
554 hi def link shIfError           Error
555 hi def link shInError           Error
556 hi def link shParenError                Error
557 hi def link shTestError         Error
558 if exists("b:is_kornshell")
559   hi def link shDTestError              Error
560 endif
562 hi def link shArithmetic                Special
563 hi def link shCharClass         Identifier
564 hi def link shSnglCase          Statement
565 hi def link shCommandSub                Special
566 hi def link shComment           Comment
567 hi def link shConditional               Conditional
568 hi def link shCtrlSeq           Special
569 hi def link shExprRegion                Delimiter
570 hi def link shFunctionKey               Function
571 hi def link shFunctionName              Function
572 hi def link shNumber            Number
573 hi def link shOperator          Operator
574 hi def link shRepeat            Repeat
575 hi def link shSet               Statement
576 hi def link shSetList           Identifier
577 hi def link shShellVariables            PreProc
578 hi def link shSpecial           Special
579 hi def link shStatement         Statement
580 hi def link shString            String
581 hi def link shTodo              Todo
582 hi def link shAlias             Identifier
584 " Set Current Syntax: {{{1
585 " ===================
586 if exists("b:is_bash")
587  let b:current_syntax = "bash"
588 elseif exists("b:is_kornshell")
589  let b:current_syntax = "ksh"
590 else
591  let b:current_syntax = "sh"
592 endif
594 " vim: ts=16 fdm=marker