Update runtime files
[MacVim/KaoriYa.git] / runtime / syntax / sh.vim
blobbddfe1c7e49226c455ed76ba81f8a64d8ddad605
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:          Apr 24, 2008
6 " Version:              90
7 " URL:          http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
9 " Using the following VIM variables: {{{1
10 " g:is_bash             if none of the previous three variables are
11 "               defined, then if g:is_bash is set enhance with
12 "               bash syntax highlighting
13 " g:is_kornshell        if neither b:is_kornshell or b:is_bash is
14 "               defined, then if g:is_kornshell is set
15 "               enhance with kornshell/POSIX syntax highlighting
16 " g:is_posix                    this variable is the same as g:is_kornshell
17 " g:sh_fold_enabled     if non-zero, syntax folding is enabled
18 " g:sh_minlines         sets up syn sync minlines (dflt: 200)
19 " g:sh_maxlines         sets up syn sync maxlines (dflt: 2x sh_minlines)
21 " This file includes many ideas from Éric Brunet (eric.brunet@ens.fr)
23 " For version 5.x: Clear all syntax items {{{1
24 " For version 6.x: Quit when a syntax file was already loaded
25 if version < 600
26   syntax clear
27 elseif exists("b:current_syntax")
28   finish
29 endif
31 " handling /bin/sh with is_kornshell/is_sh {{{1
32 " b:is_sh is set when "#! /bin/sh" is found;
33 " However, it often is just a masquerade by bash (typically Linux)
34 " or kornshell (typically workstations with Posix "sh").
35 " So, when the user sets "is_bash" or "is_kornshell",
36 " a b:is_sh is converted into b:is_bash/b:is_kornshell,
37 " respectively.
38 if !exists("b:is_kornshell") && !exists("b:is_bash")
39   if exists("g:is_posix") && !exists("g:is_kornshell")
40    let g:is_kornshell= g:is_posix
41   endif
42   if exists("g:is_kornshell")
43     let b:is_kornshell= 1
44     if exists("b:is_sh")
45       unlet b:is_sh
46     endif
47   elseif exists("g:is_bash")
48     let b:is_bash= 1
49     if exists("b:is_sh")
50       unlet b:is_sh
51     endif
52   else
53     let b:is_sh= 1
54   endif
55 endif
57 " set up default g:sh_fold_enabled {{{1
58 if !exists("g:sh_fold_enabled")
59  let g:sh_fold_enabled= 0
60 elseif g:sh_fold_enabled != 0 && !has("folding")
61  let g:sh_fold_enabled= 0
62  echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
63 endif
64 if g:sh_fold_enabled && &fdm == "manual"
65  set fdm=syntax
66 endif
68 " sh syntax is case sensitive {{{1
69 syn case match
71 " Clusters: contains=@... clusters {{{1
72 "==================================
73 syn cluster shCaseEsacList      contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq
74 syn cluster shCaseList  contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
75 syn cluster shColonList contains=@shCaseList
76 syn cluster shCommandSubList    contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq
77 syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
78 syn cluster shDblQuoteList      contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
79 syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
80 syn cluster shDerefVarList      contains=shDerefOp,shDerefVarArray,shDerefOpError
81 syn cluster shEchoList  contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq
82 syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
83 syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
84 syn cluster shFunctionList      contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shFunctionStart,shCtrlSeq
85 if exists("b:is_kornshell") || exists("b:is_bash")
86  syn cluster shFunctionList     add=shDblBrace,shDblParen
87 endif
88 syn cluster shHereBeginList     contains=@shCommandSubList
89 syn cluster shHereList  contains=shBeginHere,shHerePayload
90 syn cluster shHereListDQ        contains=shBeginHere,@shDblQuoteList,shHerePayload
91 syn cluster shIdList    contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq
92 syn cluster shLoopList  contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest
93 syn cluster shSubShList contains=@shCaseList,shOperator
94 syn cluster shTestList  contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
97 " Echo: {{{1
98 " ====
99 " This one is needed INSIDE a CommandSub, so that `echo bla` be correct
100 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
101 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
103 " This must be after the strings, so that bla \" be correct
104 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
106 " Alias: {{{1
107 " =====
108 if exists("b:is_kornshell") || exists("b:is_bash")
109  syn match shStatement "\<alias\>"
110  syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
111  syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
112 endif
114 " Error Codes: {{{1
115 " ============
116 syn match   shDoError "\<done\>"
117 syn match   shIfError "\<fi\>"
118 syn match   shInError "\<in\>"
119 syn match   shCaseError ";;"
120 syn match   shEsacError "\<esac\>"
121 syn match   shCurlyError "}"
122 syn match   shParenError ")"
123 if exists("b:is_kornshell")
124  syn match     shDTestError "]]"
125 endif
126 syn match     shTestError "]"
128 " Options Interceptor: {{{1
129 " ====================
130 syn match   shOption  "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
131 syn match   shOption  "\s--[^ \t$`'"|]\+"ms=s+1
133 " File Redirection Highlighted As Operators: {{{1
134 "===========================================
135 syn match      shRedir  "\d\=>\(&[-0-9]\)\="
136 syn match      shRedir  "\d\=>>-\="
137 syn match      shRedir  "\d\=<\(&[-0-9]\)\="
138 syn match      shRedir  "\d<<-\="
140 " Operators: {{{1
141 " ==========
142 syn match   shOperator  "<<\|>>"                contained
143 syn match   shOperator  "[!&;|]"
144 syn match   shOperator  "\[[[^:]\|\]]"
145 syn match   shOperator  "!\=="          skipwhite nextgroup=shPattern
146 syn match   shPattern   "\<\S\+\())\)\@="       contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
148 " Subshells: {{{1
149 " ==========
150 syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"       contains=@shExprList2
151 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")"       contains=@shSubShList
153 " Tests: {{{1
154 "=======
155 "syn region  shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
156 syn region shExpr       matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
157 syn region shTest       transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
158 syn match  shTestOpr    contained       "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
159 syn match  shTestOpr    contained       '=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
160 syn match  shTestPattern        contained       '\w\+'
161 syn match  shTestDoubleQuote    contained       '"[^"]*"'
162 syn match  shTestSingleQuote    contained       '\\.'
163 syn match  shTestSingleQuote    contained       "'[^']*'"
164 if exists("b:is_kornshell") || exists("b:is_bash")
165  syn region  shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]"   contains=@shTestList
166  syn region  shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))"       contains=@shTestList
167 endif
169 " Character Class In Range: {{{1
170 " =========================
171 syn match   shCharClass contained       "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
173 " Loops: do, if, while, until {{{1
174 " ======
175 if g:sh_fold_enabled
176  syn region shDo        fold transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
177  syn region shIf        fold transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"   contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
178  syn region shFor       fold matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2  contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
179 else
180  syn region shDo        transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
181  syn region shIf        transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"   contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
182  syn region shFor       matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2       contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
183 endif
184 if exists("b:is_kornshell") || exists("b:is_bash")
185  syn cluster shCaseList add=shRepeat
186  syn region shRepeat   matchgroup=shLoop   start="\<while\>" end="\<in\>" end="\<do\>"me=e-2    contains=@shLoopList,shDblParen,shDblBrace
187  syn region shRepeat   matchgroup=shLoop   start="\<until\>" end="\<in\>" end="\<do\>"me=e-2    contains=@shLoopList,shDblParen,shDblBrace
188  syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
189 else
190  syn region shRepeat   matchgroup=shLoop   start="\<while\>" end="\<do\>"me=e-2         contains=@shLoopList
191  syn region shRepeat   matchgroup=shLoop   start="\<until\>" end="\<do\>"me=e-2         contains=@shLoopList
192 endif
193 syn region shCurlyIn   contained        matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
194 syn match  shComma     contained        ","
196 " Case: case...esac {{{1
197 " ====
198 syn match   shCaseBar   contained skipwhite "[^|"`'()]\{-}|"hs=e                nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
199 syn match   shCaseStart contained skipwhite skipnl "("                  nextgroup=shCase,shCaseBar
200 syn region  shCase      contained skipwhite skipnl matchgroup=shSnglCase start="\([^#$()'" \t]\|\\.\)\{-})"ms=s,hs=e  end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
201 if g:sh_fold_enabled
202  syn region  shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>"   contains=@shCaseEsacList
203 else
204  syn region  shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>"        contains=@shCaseEsacList
205 endif
206 syn keyword shCaseIn    contained skipwhite skipnl in                   nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
207 if exists("b:is_bash")
208  syn region  shCaseExSingleQuote        matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+      contains=shStringSpecial,shSpecial      skipwhite skipnl nextgroup=shCaseBar    contained
209  syn region  shCaseExDoubleQuote        matchgroup=shOperator start=+\$"+ skip=+\\\\\|\\.+ end=+"+      contains=shStringSpecial,shSpecial,shCommandSub,shDeref skipwhite skipnl nextgroup=shCaseBar    contained
210 else
211  syn region  shCaseExSingleQuote        matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+   contains=shStringSpecial        skipwhite skipnl nextgroup=shCaseBar    contained
212 endif
213 syn region  shCaseSingleQuote   matchgroup=shOperator start=+'+ end=+'+         contains=shStringSpecial                skipwhite skipnl nextgroup=shCaseBar    contained
214 syn region  shCaseDoubleQuote   matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+        contains=@shDblQuoteList,shStringSpecial        skipwhite skipnl nextgroup=shCaseBar    contained
215 syn region  shCaseCommandSub    start=+`+ skip=+\\\\\|\\.+ end=+`+              contains=@shCommandSubList              skipwhite skipnl nextgroup=shCaseBar    contained
217 " Misc: {{{1
218 "======
219 syn match   shWrapLineOperator "\\$"
220 syn region  shCommandSub   start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
222 " $() and $(()): {{{1
223 " $(..) is not supported by sh (Bourne shell).  However, apparently
224 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
225 " (ie. Posix compliant shell).  /bin/ksh should work for those
226 " systems too, however, so the following syntax will flag $(..) as
227 " an Error under /bin/sh.  By consensus of vimdev'ers!
228 if exists("b:is_kornshell") || exists("b:is_bash")
229  syn region shCommandSub matchgroup=shCmdSubRegion start="\$("  skip='\\\\\|\\.' end=")"  contains=@shCommandSubList
230  syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
231  syn match  shSkipInitWS contained      "^\s\+"
232 else
233  syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
234 endif
236 if exists("b:is_bash")
237  syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
238  syn cluster shCaseList add=bashAdminStatement,bashStatement
239  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
240  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
241  syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
242 endif
244 if exists("b:is_kornshell")
245  syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
246  syn cluster shCaseList add=kshStatement
247  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
248  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
249 endif
251 syn match   shSource    "^\.\s"
252 syn match   shSource    "\s\.\s"
253 syn region  shColon     start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
255 " String And Character Constants: {{{1
256 "================================
257 syn match   shNumber    "-\=\<\d\+\>#\="
258 syn match   shCtrlSeq   "\\\d\d\d\|\\[abcfnrtv0]"               contained
259 if exists("b:is_bash")
260  syn match   shSpecial  "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
261 endif
262 if exists("b:is_bash")
263  syn region  shExSingleQuote    matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+      contains=shStringSpecial,shSpecial
264  syn region  shExDoubleQuote    matchgroup=shOperator start=+\$"+ skip=+\\\\\|\\.+ end=+"+      contains=shStringSpecial,shSpecial,shCommandSub,shDeref
265 else
266  syn region  shExSingleQuote    matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+   contains=shStringSpecial
267 endif
268 syn region  shSingleQuote       matchgroup=shOperator start=+'+ end=+'+         contains=shStringSpecial,@Spell
269 syn region  shDoubleQuote       matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+      contains=@shDblQuoteList,shStringSpecial,@Spell
270 syn match   shStringSpecial     "[^[:print:]]"  contained
271 syn match   shStringSpecial     "\%(\\\\\)*\\[\\"'`$()#]"
272 syn match   shSpecial   "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
273 syn match   shSpecial   "^\%(\\\\\)*\\[\\"'`$()#]"
275 " Comments: {{{1
276 "==========
277 syn cluster    shCommentGroup   contains=shTodo,@Spell
278 syn keyword    shTodo   contained       COMBAK FIXME TODO XXX
279 syn match      shComment        "^\s*\zs#.*$"   contains=@shCommentGroup
280 syn match      shComment        "#.*$"  contains=@shCommentGroup
282 " Here Documents: {{{1
283 " =========================================
284 if version < 600
285  syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**"  matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
286  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
287  syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir      end="^EOF$"     contains=@shDblQuoteList
288  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir     end="^\s*EOF$"  contains=@shDblQuoteList
289  syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**"  matchgroup=shRedir      end="^\.$"      contains=@shDblQuoteList
290  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir      end="^\s*\.$"   contains=@shDblQuoteList
292 elseif g:sh_fold_enabled
293  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)"             matchgroup=shRedir end="^\z1\s*$"       contains=@shDblQuoteList
294  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\""         matchgroup=shRedir end="^\z1\s*$"
295  syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'"           matchgroup=shRedir end="^\z1\s*$"
296  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)"            matchgroup=shRedir end="^\s*\z1\s*$"    contains=@shDblQuoteList
297  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\""                matchgroup=shRedir end="^\s*\z1\s*$"
298  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'"          matchgroup=shRedir end="^\s*\z1\s*$"
299  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)"            matchgroup=shRedir end="^\z1\s*$"
300  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\""        matchgroup=shRedir end="^\z1\s*$"
301  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'"         matchgroup=shRedir end="^\s*\z1\s*$"
302  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)"           matchgroup=shRedir end="^\s*\z1\s*$"
303  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\""       matchgroup=shRedir end="^\s*\z1\s*$"
304  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'"          matchgroup=shRedir end="^\z1\s*$"
305  syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)"              matchgroup=shRedir end="^\z1\s*$"
307 else
308  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)"      matchgroup=shRedir end="^\z1\s*$"    contains=@shDblQuoteList
309  syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\""      matchgroup=shRedir end="^\z1\s*$"
310  syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)"         matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
311  syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'"       matchgroup=shRedir end="^\s*\z1\s*$"
312  syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'"        matchgroup=shRedir end="^\z1\s*$"
313  syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\""     matchgroup=shRedir end="^\s*\z1\s*$"
314  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
315  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)"        matchgroup=shRedir end="^\s*\z1\s*$"
316  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'"      matchgroup=shRedir end="^\s*\z1\s*$"
317  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'"       matchgroup=shRedir end="^\z1\s*$"
318  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\""     matchgroup=shRedir end="^\z1\s*$"
319  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\""    matchgroup=shRedir end="^\s*\z1\s*$"
320  syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)"           matchgroup=shRedir end="^\z1\s*$"
321 endif
323 " Here Strings: {{{1
324 " =============
325 if exists("b:is_bash")
326  syn match shRedir "<<<"
327 endif
329 " Identifiers: {{{1
330 "=============
331 syn match  shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="       nextgroup=shSetIdentifier
332 syn match  shIdWhiteSpace  contained    "\s"
333 syn match  shSetIdentifier contained    "="     nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
334 if exists("b:is_bash")
335   syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$"   matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
336   syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="\\ze[|)]"                matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
337   syn match  shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)\>"
338 elseif exists("b:is_kornshell")
339   syn region shSetList matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$"           matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
340   syn region shSetList matchgroup=shSet start="\<set\>\ze[^/]" end="$\|\ze[})]"                 matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
341   syn match  shSet "\<\(typeset\|set\|export\|unset\)\>"
342 else
343   syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]"      matchgroup=shOperator end="\ze[|);&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
344   syn match  shStatement "\<\(set\|export\|unset\)\>"
345 endif
347 " Functions: {{{1
348 syn keyword shFunctionKey function      skipwhite skipnl nextgroup=shFunctionTwo
349 " COMBAK -- look at bash09.  function foo() (line#35) is folding 38 lines.  Not being terminated properly
350 "syn match   shFunctionStart    "{"     contained
351 if g:sh_fold_enabled
352  syn region shFunctionOne transparent fold      start="^\s*\h\w*\s*()\_s*\ze{"    matchgroup=shFunctionStart end="}"    contains=@shFunctionList                        skipwhite skipnl nextgroup=shFunctionStart
353  syn region shFunctionTwo transparent fold      start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}"    contains=shFunctionKey,@shFunctionList contained        skipwhite skipnl nextgroup=shFunctionStart
354 else
355  syn region shFunctionOne transparent   start="^\s*\h\w*\s*()\_s*\ze{"    matchgroup=shFunctionStart end="}"    contains=@shFunctionList
356  syn region shFunctionTwo transparent   start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}"    contains=shFunctionKey,@shFunctionList contained
357 endif
359 " Parameter Dereferencing: {{{1
360 " ========================
361 syn match  shDerefSimple        "\$\%(\h\w*\|\d\)"
362 syn region shDeref      matchgroup=PreProc start="\${" end="}"  contains=@shDerefList,shDerefVarArray
363 syn match  shDerefWordError     "[^}$[]"        contained
364 syn match  shDerefSimple        "\$[-#*@!?]"
365 syn match  shDerefSimple        "\$\$"
366 if exists("b:is_bash") || exists("b:is_kornshell")
367  syn region shDeref     matchgroup=PreProc start="\${##\=" end="}"      contains=@shDerefList
368 endif
370 " bash: ${!prefix*} and ${#parameter}: {{{1
371 " ====================================
372 if exists("b:is_bash")
373  syn region shDeref     matchgroup=PreProc start="\${!" end="\*\=}"     contains=@shDerefList,shDerefOp
374  syn match  shDerefVar  contained       "{\@<=!\w\+"            nextgroup=@shDerefVarList
375 endif
377 syn match  shDerefSpecial       contained       "{\@<=[-*@?0]"          nextgroup=shDerefOp,shDerefOpError
378 syn match  shDerefSpecial       contained       "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
379 syn match  shDerefVar   contained       "{\@<=\w\+"             nextgroup=@shDerefVarList
381 " sh ksh bash : ${var[... ]...}  array reference: {{{1
382 syn region  shDerefVarArray   contained matchgroup=shDeref start="\[" end="]"   contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
384 " Special ${parameter OPERATOR word} handling: {{{1
385 " sh ksh bash : ${parameter:-word}    word is default value
386 " sh ksh bash : ${parameter:=word}    assign word as default value
387 " sh ksh bash : ${parameter:?word}    display word if parameter is null
388 " sh ksh bash : ${parameter:+word}    use word if parameter is not null, otherwise nothing
389 "    ksh bash : ${parameter#pattern}  remove small left  pattern
390 "    ksh bash : ${parameter##pattern} remove large left  pattern
391 "    ksh bash : ${parameter%pattern}  remove small right pattern
392 "    ksh bash : ${parameter%%pattern} remove large right pattern
393 syn cluster shDerefPatternList  contains=shDerefPattern,shDerefString
394 syn match shDerefOpError        contained       ":[[:punct:]]"
395 syn match  shDerefOp    contained       ":\=[-=?]"      nextgroup=@shDerefPatternList
396 syn match  shDerefOp    contained       ":\=+"  nextgroup=@shDerefPatternList
397 if exists("b:is_bash") || exists("b:is_kornshell")
398  syn match  shDerefOp   contained       "#\{1,2}"       nextgroup=@shDerefPatternList
399  syn match  shDerefOp   contained       "%\{1,2}"       nextgroup=@shDerefPatternList
400  syn match  shDerefPattern      contained       "[^{}]\+"       contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
401  syn region shDerefPattern      contained       start="{" end="}"       contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
402  syn match  shDerefEscape       contained       '\%(\\\\\)*\\.'
403 endif
404 syn region shDerefString        contained       matchgroup=shOperator start=+'+ end=+'+         contains=shStringSpecial
405 syn region shDerefString        contained       matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+      contains=@shDblQuoteList,shStringSpecial
406 syn match  shDerefString        contained       "\\["']"
408 if exists("b:is_bash")
409  " bash : ${parameter:offset}
410  " bash : ${parameter:offset:length}
411  syn region shDerefOp   contained       start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
412  syn match  shDerefPOL  contained       ":[^}]\+"       contains=@shCommandSubList
414  " bash : ${parameter//pattern/string}
415  " bash : ${parameter//pattern}
416  syn match  shDerefPPS  contained       '/\{1,2}'       nextgroup=shDerefPPSleft
417  syn region shDerefPPSleft      contained       start='.'       skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
418  syn region shDerefPPSright     contained       start='.'       end='\ze}'      contains=@shCommandSubList
419 endif
421 " Useful sh Keywords: {{{1
422 " ===================
423 syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
424 syn keyword shConditional contained elif else then
425 syn keyword shCondError elif else then
427 " Useful ksh Keywords: {{{1
428 " ====================
429 if exists("b:is_kornshell") || exists("b:is_bash")
430  syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup print printf r stop suspend time times true type unalias whence
432 " Useful bash Keywords: {{{1
433 " =====================
434  if exists("b:is_bash")
435   syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
436  else
437   syn keyword shStatement login newgrp
438  endif
439 endif
441 " Synchronization: {{{1
442 " ================
443 if !exists("sh_minlines")
444   let sh_minlines = 200
445 endif
446 if !exists("sh_maxlines")
447   let sh_maxlines = 2 * sh_minlines
448 endif
449 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
450 syn sync match shCaseEsacSync   grouphere       shCaseEsac      "\<case\>"
451 syn sync match shCaseEsacSync   groupthere      shCaseEsac      "\<esac\>"
452 syn sync match shDoSync grouphere       shDo    "\<do\>"
453 syn sync match shDoSync groupthere      shDo    "\<done\>"
454 syn sync match shForSync        grouphere       shFor   "\<for\>"
455 syn sync match shForSync        groupthere      shFor   "\<in\>"
456 syn sync match shIfSync grouphere       shIf    "\<if\>"
457 syn sync match shIfSync groupthere      shIf    "\<fi\>"
458 syn sync match shUntilSync      grouphere       shRepeat        "\<until\>"
459 syn sync match shWhileSync      grouphere       shRepeat        "\<while\>"
461 " Default Highlighting: {{{1
462 " =====================
463 hi def link shArithRegion       shShellVariables
464 hi def link shBeginHere shRedir
465 hi def link shCaseBar   shConditional
466 hi def link shCaseCommandSub    shCommandSub
467 hi def link shCaseDoubleQuote   shDoubleQuote
468 hi def link shCaseIn    shConditional
469 hi def link shCaseSingleQuote   shSingleQuote
470 hi def link shCaseDoubleQuote   shSingleQuote
471 hi def link shCaseStart shConditional
472 hi def link shCmdSubRegion      shShellVariables
473 hi def link shColon     shStatement
474 hi def link shDerefOp   shOperator
475 hi def link shDerefPOL  shDerefOp
476 hi def link shDerefPPS  shDerefOp
477 hi def link shDeref     shShellVariables
478 hi def link shDerefSimple       shDeref
479 hi def link shDerefSpecial      shDeref
480 hi def link shDerefString       shDoubleQuote
481 hi def link shDerefVar  shDeref
482 hi def link shDoubleQuote       shString
483 hi def link shEcho      shString
484 hi def link shEmbeddedEcho      shString
485 hi def link shExSingleQuote     shSingleQuote
486 hi def link shExDoubleQuote     shSingleQuote
487 hi def link shFunctionStart     Delimiter
488 hi def link shHereDoc   shString
489 hi def link shHerePayload       shHereDoc
490 hi def link shLoop      shStatement
491 hi def link shOption    shCommandSub
492 hi def link shPattern   shString
493 hi def link shPosnParm  shShellVariables
494 hi def link shRange     shOperator
495 hi def link shRedir     shOperator
496 hi def link shSingleQuote       shString
497 hi def link shSource    shOperator
498 hi def link shStringSpecial     shSpecial
499 hi def link shSubShRegion       shOperator
500 hi def link shTestOpr   shConditional
501 hi def link shTestPattern       shString
502 hi def link shTestDoubleQuote   shString
503 hi def link shTestSingleQuote   shString
504 hi def link shVariable  shSetList
505 hi def link shWrapLineOperator  shOperator
507 if exists("b:is_bash")
508   hi def link bashAdminStatement        shStatement
509   hi def link bashSpecialVariables      shShellVariables
510   hi def link bashStatement             shStatement
511   hi def link shFunctionParen           Delimiter
512   hi def link shFunctionDelim           Delimiter
513 endif
514 if exists("b:is_kornshell")
515   hi def link kshSpecialVariables       shShellVariables
516   hi def link kshStatement              shStatement
517   hi def link shFunctionParen           Delimiter
518 endif
520 hi def link shCaseError         Error
521 hi def link shCondError         Error
522 hi def link shCurlyError                Error
523 hi def link shDerefError                Error
524 hi def link shDerefOpError              Error
525 hi def link shDerefWordError            Error
526 hi def link shDoError           Error
527 hi def link shEsacError         Error
528 hi def link shIfError           Error
529 hi def link shInError           Error
530 hi def link shParenError                Error
531 hi def link shTestError         Error
532 if exists("b:is_kornshell")
533   hi def link shDTestError              Error
534 endif
536 hi def link shArithmetic                Special
537 hi def link shCharClass         Identifier
538 hi def link shSnglCase          Statement
539 hi def link shCommandSub                Special
540 hi def link shComment           Comment
541 hi def link shConditional               Conditional
542 hi def link shCtrlSeq           Special
543 hi def link shExprRegion                Delimiter
544 hi def link shFunctionKey               Function
545 hi def link shFunctionName              Function
546 hi def link shNumber            Number
547 hi def link shOperator          Operator
548 hi def link shRepeat            Repeat
549 hi def link shSet               Statement
550 hi def link shSetList           Identifier
551 hi def link shShellVariables            PreProc
552 hi def link shSpecial           Special
553 hi def link shStatement         Statement
554 hi def link shString            String
555 hi def link shTodo              Todo
556 hi def link shAlias             Identifier
558 " Set Current Syntax: {{{1
559 " ===================
560 if exists("b:is_bash")
561  let b:current_syntax = "bash"
562 elseif exists("b:is_kornshell")
563  let b:current_syntax = "ksh"
564 else
565  let b:current_syntax = "sh"
566 endif
568 " vim: ts=16 fdm=marker