Merge branch 'vim-with-runtime' into feat/quickfix-title
[vim_extended.git] / runtime / syntax / sh.vim
blob2b1269fc07be96ee26be602563ce511ec788eca4
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 12, 2010
6 " Version:              111
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  setlocal 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,shOK
71 if exists("b:is_kornshell")
72  syn cluster ErrorList add=shDTestError
73 endif
74 syn cluster shArithParenList    contains=shArithmetic,shCaseEsac,shDeref,shDerefSimple,shEcho,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement
75 syn cluster shArithList contains=@shArithParenList,shParenError
76 syn cluster shCaseEsacList      contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
77 syn cluster shCaseList  contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
78 syn cluster shColonList contains=@shCaseList
79 syn cluster shCommandSubList    contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq,shSpecial
80 syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
81 syn cluster shDblQuoteList      contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
82 syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
83 syn cluster shDerefVarList      contains=shDerefOp,shDerefVarArray,shDerefOpError
84 syn cluster shEchoList  contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
85 syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
86 syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
87 syn cluster shFunctionList      contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
88 if exists("b:is_kornshell") || exists("b:is_bash")
89  syn cluster shFunctionList     add=shRepeat
90  syn cluster shFunctionList     add=shDblBrace,shDblParen
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=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
98 syn cluster shTestList  contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
100 " Echo: {{{1
101 " ====
102 " This one is needed INSIDE a CommandSub, so that `echo bla` be correct
103 syn region shEcho matchgroup=shStatement start="\<echo\>"  skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=@shEchoList skipwhite nextgroup=shQuickComment
104 syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=@shEchoList skipwhite nextgroup=shQuickComment
105 syn match  shEchoQuote contained        '\%(\\\\\)*\\["`'()]'
107 " This must be after the strings, so that ... \" will be correct
108 syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shDoubleQuote,shCharClass,shCtrlSeq
110 " Alias: {{{1
111 " =====
112 if exists("b:is_kornshell") || exists("b:is_bash")
113  syn match shStatement "\<alias\>"
114  syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
115  syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
116 endif
118 " Error Codes: {{{1
119 " ============
120 syn match   shDoError "\<done\>"
121 syn match   shIfError "\<fi\>"
122 syn match   shInError "\<in\>"
123 syn match   shCaseError ";;"
124 syn match   shEsacError "\<esac\>"
125 syn match   shCurlyError "}"
126 syn match   shParenError ")"
127 syn match   shOK        '\.\(done\|fi\|in\|esac\)'
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 nextgroup=shMoreSpecial
156 syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")"       contains=@shSubShList nextgroup=shMoreSpecial
158 " Tests: {{{1
159 "=======
160 syn region shExpr       matchgroup=shRange start="\[" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
161 syn region shTest       transparent matchgroup=shStatement start="\<test\s" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
162 syn match  shTestOpr    contained       "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
163 syn match  shTestOpr    contained       '=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
164 syn match  shTestPattern        contained       '\w\+'
165 syn match  shTestDoubleQuote    contained       '"[^"]*"'
166 syn match  shTestSingleQuote    contained       '\\.'
167 syn match  shTestSingleQuote    contained       "'[^']*'"
168 if exists("b:is_kornshell") || exists("b:is_bash")
169  syn region  shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]"   contains=@shTestList
170  syn region  shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))"       contains=@shTestList
171 endif
173 " Character Class In Range: {{{1
174 " =========================
175 syn match   shCharClass contained       "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
177 " Loops: do, if, while, until {{{1
178 " ======
179 if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
180  syn region shDo        fold transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
181  syn region shIf        fold transparent matchgroup=shConditional start="\<if\_s" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"   contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
182  syn region shFor       fold matchgroup=shLoop start="\<for\_s" end="\<in\_s" end="\<do\>"me=e-2        contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
183 else
184  syn region shDo        transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
185  syn region shIf        transparent matchgroup=shConditional start="\<if\_s" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"   contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
186  syn region shFor       matchgroup=shLoop start="\<for\_s" end="\<in\>" end="\<do\>"me=e-2      contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
187 endif
188 if exists("b:is_kornshell") || exists("b:is_bash")
189  syn cluster shCaseList add=shRepeat
190  syn cluster shFunctionList     add=shRepeat
191  syn region shRepeat   matchgroup=shLoop   start="\<while\_s" end="\<in\_s" end="\<do\>"me=e-2  contains=@shLoopList,shDblParen,shDblBrace
192  syn region shRepeat   matchgroup=shLoop   start="\<until\_s" end="\<in\_s" end="\<do\>"me=e-2  contains=@shLoopList,shDblParen,shDblBrace
193  syn region shCaseEsac matchgroup=shConditional start="\<select\s" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
194 else
195  syn region shRepeat   matchgroup=shLoop   start="\<while\_s" end="\<do\>"me=e-2                contains=@shLoopList
196  syn region shRepeat   matchgroup=shLoop   start="\<until\_s" end="\<do\>"me=e-2                contains=@shLoopList
197 endif
198 syn region shCurlyIn   contained        matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
199 syn match  shComma     contained        ","
201 " Case: case...esac {{{1
202 " ====
203 syn match   shCaseBar   contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|"         nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
204 syn match   shCaseStart contained skipwhite skipnl "("                  nextgroup=shCase,shCaseBar
205 if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
206  syn region  shCase     fold contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
207  syn region  shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>"   contains=@shCaseEsacList
208 else
209  syn region  shCase     contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
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
221 syn region  shCaseRange matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+]+     contained
223 " Misc: {{{1
224 "======
225 syn match   shWrapLineOperator "\\$"
226 syn region  shCommandSub   start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
227 syn match   shEscape    contained       '\\.'
229 " $() and $(()): {{{1
230 " $(..) is not supported by sh (Bourne shell).  However, apparently
231 " some systems (HP?) have as their /bin/sh a (link to) Korn shell
232 " (ie. Posix compliant shell).  /bin/ksh should work for those
233 " systems too, however, so the following syntax will flag $(..) as
234 " an Error under /bin/sh.  By consensus of vimdev'ers!
235 if exists("b:is_kornshell") || exists("b:is_bash")
236  syn region shCommandSub matchgroup=shCmdSubRegion start="\$("  skip='\\\\\|\\.' end=")"  contains=@shCommandSubList
237  syn region shArithmetic matchgroup=shArithRegion  start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
238  syn match  shSkipInitWS contained      "^\s\+"
239 else
240  syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
241 endif
243 if exists("b:is_bash")
244  syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
245  syn cluster shCaseList add=bashAdminStatement,bashStatement
246  syn keyword bashSpecialVariables contained BASH BASH_ENV BASH_VERSINFO BASH_VERSION CDPATH DIRSTACK EUID FCEDIT FIGNORE GLOBIGNORE GROUPS HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_MESSAGES LINENO MACHTYPE MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELLOPTS SHLVL TIMEFORMAT TIMEOUT UID auto_resume histchars
247  syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep install less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch
248  syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
249 endif
251 if exists("b:is_kornshell")
252  syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
253  syn cluster shCaseList add=kshStatement
254  syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV ERRNO FCEDIT FPATH HISTFILE HISTSIZE HOME IFS LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL TMOUT VISUAL
255  syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep install killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail touch tput
256 endif
258 syn match   shSource    "^\.\s"
259 syn match   shSource    "\s\.\s"
260 "syn region  shColon    start="^\s*:" end="$" end="\s#"me=e-2 contains=@shColonList
261 syn region  shColon     start="^\s*\zs:" end="$" end="\s#"me=e-2
263 " String And Character Constants: {{{1
264 "================================
265 syn match   shNumber    "-\=\<\d\+\>#\="
266 syn match   shCtrlSeq   "\\\d\d\d\|\\[abcfnrtv0]"               contained
267 if exists("b:is_bash")
268  syn match   shSpecial  "\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]"      contained
269 endif
270 if exists("b:is_bash")
271  syn region  shExSingleQuote    matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+      contains=shStringSpecial,shSpecial
272 else
273  syn region  shExSingleQuote    matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+   contains=shStringSpecial
274 endif
275 syn region  shSingleQuote       matchgroup=shOperator start=+'+ end=+'+         contains=@Spell
276 syn region  shDoubleQuote       matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+      contains=@shDblQuoteList,shStringSpecial,@Spell
277 syn match   shStringSpecial     "[^[:print:] \t]"       contained
278 syn match   shStringSpecial     "\%(\\\\\)*\\[\\"'`$()#]"
279 syn match   shSpecial   "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]" nextgroup=shMoreSpecial
280 syn match   shSpecial   "^\%(\\\\\)*\\[\\"'`$()#]"
281 syn match   shMoreSpecial       "\%(\\\\\)*\\[\\"'`$()#]" nextgroup=shMoreSpecial contained
283 " Comments: {{{1
284 "==========
285 syn cluster     shCommentGroup  contains=shTodo,@Spell
286 syn keyword     shTodo  contained               COMBAK FIXME TODO XXX
287 syn match       shComment               "^\s*\zs#.*$"   contains=@shCommentGroup
288 syn match       shComment               "\s\zs#.*$"     contains=@shCommentGroup
289 syn match       shQuickComment  contained       "#.*$"
291 " Here Documents: {{{1
292 " =========================================
293 if version < 600
294  syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**"  matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
295  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
296  syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir      end="^EOF$"     contains=@shDblQuoteList
297  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir     end="^\s*EOF$"  contains=@shDblQuoteList
298  syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**"  matchgroup=shRedir      end="^\.$"      contains=@shDblQuoteList
299  syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir      end="^\s*\.$"   contains=@shDblQuoteList
301 elseif (g:sh_fold_enabled % (s:sh_fold_heredoc * 2))/s:sh_fold_heredoc
302  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)"             matchgroup=shRedir end="^\z1\s*$"       contains=@shDblQuoteList
303  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\""         matchgroup=shRedir end="^\z1\s*$"
304  syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'"           matchgroup=shRedir end="^\z1\s*$"
305  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)"            matchgroup=shRedir end="^\s*\z1\s*$"    contains=@shDblQuoteList
306  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\""                matchgroup=shRedir end="^\s*\z1\s*$"
307  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'"          matchgroup=shRedir end="^\s*\z1\s*$"
308  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)"            matchgroup=shRedir end="^\z1\s*$"
309  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\""        matchgroup=shRedir end="^\z1\s*$"
310  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'"         matchgroup=shRedir end="^\s*\z1\s*$"
311  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)"           matchgroup=shRedir end="^\s*\z1\s*$"
312  syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\""       matchgroup=shRedir end="^\s*\z1\s*$"
313  syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'"          matchgroup=shRedir end="^\z1\s*$"
314  syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)"              matchgroup=shRedir end="^\z1\s*$"
316 else
317  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)"      matchgroup=shRedir end="^\z1\s*$"    contains=@shDblQuoteList
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*$" contains=@shDblQuoteList
320  syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'"       matchgroup=shRedir end="^\s*\z1\s*$"
321  syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'"        matchgroup=shRedir end="^\z1\s*$"
322  syn region shHereDoc matchgroup=shRedir start="<<-\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="^\s*\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="<<\s*\\\_$\_s*'\z(\S*\)'"       matchgroup=shRedir end="^\z1\s*$"
327  syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\""     matchgroup=shRedir end="^\z1\s*$"
328  syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\""    matchgroup=shRedir end="^\s*\z1\s*$"
329  syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)"           matchgroup=shRedir end="^\z1\s*$"
330 endif
332 " Here Strings: {{{1
333 " =============
334 if exists("b:is_bash")
335  syn match shRedir "<<<"
336 endif
338 " Identifiers: {{{1
339 "=============
340 syn match  shSetOption  "\s\zs[-+][a-zA-Z0-9]\+\>"      contained
341 syn match  shVariable   "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze="     nextgroup=shSetIdentifier
342 syn match  shSetIdentifier      "="             contained       nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
343 if exists("b:is_bash")
344  syn region shSetList oneline matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$"    matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|=" contains=@shIdList
345  syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="\ze[;|)]\|$"                 matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
346 elseif exists("b:is_kornshell")
347  syn region shSetList oneline matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$"            matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
348  syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="$"                           matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
349 else
350  syn region shSetList oneline matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$"                matchgroup=shOperator end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
351 endif
353 " Functions: {{{1
354 if !exists("g:is_posix")
355  syn keyword shFunctionKey function     skipwhite skipnl nextgroup=shFunctionTwo
356 endif
358 if exists("b:is_bash")
359  if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
360   syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{" end="}"    contains=@shFunctionList                        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
361   syn region shFunctionTwo fold matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
362  else
363   syn region shFunctionOne      matchgroup=shFunction start="^\s*\h[-a-zA-Z_0-9]*\s*()\_s*{"    end="}" contains=@shFunctionList
364   syn region shFunctionTwo      matchgroup=shFunction start="\h[-a-zA-Z_0-9]*\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained
365  endif
366 else
367  if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
368   syn region shFunctionOne fold matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}"       contains=@shFunctionList                        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
369   syn region shFunctionTwo fold matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{"    end="}" contains=shFunctionKey,@shFunctionList contained        skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
370  else
371   syn region shFunctionOne      matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{"       end="}" contains=@shFunctionList
372   syn region shFunctionTwo      matchgroup=shFunction start="\h\w*\s*\%(()\)\=\_s*{"    end="}" contains=shFunctionKey,@shFunctionList contained
373  endif
374 endif
376 " Parameter Dereferencing: {{{1
377 " ========================
378 syn match  shDerefSimple        "\$\%(\h\w*\|\d\)"
379 syn region shDeref      matchgroup=PreProc start="\${" end="}"  contains=@shDerefList,shDerefVarArray
380 syn match  shDerefWordError     "[^}$[]"        contained
381 syn match  shDerefSimple        "\$[-#*@!?]"
382 syn match  shDerefSimple        "\$\$"
383 if exists("b:is_bash") || exists("b:is_kornshell")
384  syn region shDeref     matchgroup=PreProc start="\${##\=" end="}"      contains=@shDerefList
385  syn region shDeref     matchgroup=PreProc start="\${\$\$" end="}"      contains=@shDerefList
386 endif
388 " bash: ${!prefix*} and ${#parameter}: {{{1
389 " ====================================
390 if exists("b:is_bash")
391  syn region shDeref     matchgroup=PreProc start="\${!" end="\*\=}"     contains=@shDerefList,shDerefOp
392  syn match  shDerefVar  contained       "{\@<=!\w\+"            nextgroup=@shDerefVarList
393 endif
395 syn match  shDerefSpecial       contained       "{\@<=[-*@?0]"          nextgroup=shDerefOp,shDerefOpError
396 syn match  shDerefSpecial       contained       "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
397 syn match  shDerefVar   contained       "{\@<=\w\+"             nextgroup=@shDerefVarList
399 " sh ksh bash : ${var[... ]...}  array reference: {{{1
400 syn region  shDerefVarArray   contained matchgroup=shDeref start="\[" end="]"   contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
402 " Special ${parameter OPERATOR word} handling: {{{1
403 " sh ksh bash : ${parameter:-word}    word is default value
404 " sh ksh bash : ${parameter:=word}    assign word as default value
405 " sh ksh bash : ${parameter:?word}    display word if parameter is null
406 " sh ksh bash : ${parameter:+word}    use word if parameter is not null, otherwise nothing
407 "    ksh bash : ${parameter#pattern}  remove small left  pattern
408 "    ksh bash : ${parameter##pattern} remove large left  pattern
409 "    ksh bash : ${parameter%pattern}  remove small right pattern
410 "    ksh bash : ${parameter%%pattern} remove large right pattern
411 syn cluster shDerefPatternList  contains=shDerefPattern,shDerefString
412 syn match shDerefOpError        contained       ":[[:punct:]]"
413 syn match  shDerefOp    contained       ":\=[-=?]"      nextgroup=@shDerefPatternList
414 syn match  shDerefOp    contained       ":\=+"  nextgroup=@shDerefPatternList
415 if exists("b:is_bash") || exists("b:is_kornshell")
416  syn match  shDerefOp   contained       "#\{1,2}"       nextgroup=@shDerefPatternList
417  syn match  shDerefOp   contained       "%\{1,2}"       nextgroup=@shDerefPatternList
418  syn match  shDerefPattern      contained       "[^{}]\+"       contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
419  syn region shDerefPattern      contained       start="{" end="}"       contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
420  syn match  shDerefEscape       contained       '\%(\\\\\)*\\.'
421 endif
422 syn region shDerefString        contained       matchgroup=shOperator start=+\%(\\\)\@<!'+ end=+'+              contains=shStringSpecial
423 syn region shDerefString        contained       matchgroup=shOperator start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+   contains=@shDblQuoteList,shStringSpecial
424 syn match  shDerefString        contained       "\\["']"        nextgroup=shDerefPattern
426 if exists("b:is_bash")
427  " bash : ${parameter:offset}
428  " bash : ${parameter:offset:length}
429  syn region shDerefOp   contained       start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
430  syn match  shDerefPOL  contained       ":[^}]\+"       contains=@shCommandSubList
432  " bash : ${parameter//pattern/string}
433  " bash : ${parameter//pattern}
434  syn match  shDerefPPS  contained       '/\{1,2}'       nextgroup=shDerefPPSleft
435  syn region shDerefPPSleft      contained       start='.'       skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
436  syn region shDerefPPSright     contained       start='.'       end='\ze}'      contains=@shCommandSubList
437 endif
439 " Arithmetic Parenthesized Expressions: {{{1
440 syn region shParen matchgroup=shArithRegion start='(\ze[^(]' end=')' contains=@shArithParenList
442 " Useful sh Keywords: {{{1
443 " ===================
444 syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
445 syn keyword shConditional contained elif else then
446 syn keyword shCondError elif else then
448 " Useful ksh Keywords: {{{1
449 " ====================
450 if exists("b:is_kornshell") || exists("b:is_bash")
451  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
452  if exists("g:is_posix")
453   syn keyword shStatement command
454  else
455   syn keyword shStatement time
456  endif
458 " Useful bash Keywords: {{{1
459 " =====================
460  if exists("b:is_bash")
461   syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
462  else
463   syn keyword shStatement login newgrp
464  endif
465 endif
467 " Synchronization: {{{1
468 " ================
469 if !exists("sh_minlines")
470   let sh_minlines = 200
471 endif
472 if !exists("sh_maxlines")
473   let sh_maxlines = 2 * sh_minlines
474 endif
475 exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
476 syn sync match shCaseEsacSync   grouphere       shCaseEsac      "\<case\>"
477 syn sync match shCaseEsacSync   groupthere      shCaseEsac      "\<esac\>"
478 syn sync match shDoSync grouphere       shDo    "\<do\>"
479 syn sync match shDoSync groupthere      shDo    "\<done\>"
480 syn sync match shForSync        grouphere       shFor   "\<for\>"
481 syn sync match shForSync        groupthere      shFor   "\<in\>"
482 syn sync match shIfSync grouphere       shIf    "\<if\>"
483 syn sync match shIfSync groupthere      shIf    "\<fi\>"
484 syn sync match shUntilSync      grouphere       shRepeat        "\<until\>"
485 syn sync match shWhileSync      grouphere       shRepeat        "\<while\>"
487 " Default Highlighting: {{{1
488 " =====================
489 hi def link shArithRegion       shShellVariables
490 hi def link shBeginHere shRedir
491 hi def link shCaseBar   shConditional
492 hi def link shCaseCommandSub    shCommandSub
493 hi def link shCaseDoubleQuote   shDoubleQuote
494 hi def link shCaseIn    shConditional
495 hi def link shCaseSingleQuote   shSingleQuote
496 hi def link shCaseStart shConditional
497 hi def link shCmdSubRegion      shShellVariables
498 hi def link shColon     shComment
499 hi def link shDerefOp   shOperator
500 hi def link shDerefPOL  shDerefOp
501 hi def link shDerefPPS  shDerefOp
502 hi def link shDeref     shShellVariables
503 hi def link shDerefSimple       shDeref
504 hi def link shDerefSpecial      shDeref
505 hi def link shDerefString       shDoubleQuote
506 hi def link shDerefVar  shDeref
507 hi def link shDoubleQuote       shString
508 hi def link shEcho      shString
509 hi def link shEchoQuote shString
510 hi def link shEmbeddedEcho      shString
511 hi def link shEscape    shCommandSub
512 hi def link shExSingleQuote     shSingleQuote
513 hi def link shFunction  Function
514 hi def link shHereDoc   shString
515 hi def link shHerePayload       shHereDoc
516 hi def link shLoop      shStatement
517 hi def link shMoreSpecial       shSpecial
518 hi def link shOption    shCommandSub
519 hi def link shPattern   shString
520 hi def link shParen     shArithmetic
521 hi def link shPosnParm  shShellVariables
522 hi def link shQuickComment      shComment
523 hi def link shRange     shOperator
524 hi def link shRedir     shOperator
525 hi def link shSetOption shOption
526 hi def link shSingleQuote       shString
527 hi def link shSource    shOperator
528 hi def link shStringSpecial     shSpecial
529 hi def link shSubShRegion       shOperator
530 hi def link shTestOpr   shConditional
531 hi def link shTestPattern       shString
532 hi def link shTestDoubleQuote   shString
533 hi def link shTestSingleQuote   shString
534 hi def link shVariable  shSetList
535 hi def link shWrapLineOperator  shOperator
537 if exists("b:is_bash")
538   hi def link bashAdminStatement        shStatement
539   hi def link bashSpecialVariables      shShellVariables
540   hi def link bashStatement             shStatement
541   hi def link shFunctionParen           Delimiter
542   hi def link shFunctionDelim           Delimiter
543 endif
544 if exists("b:is_kornshell")
545   hi def link kshSpecialVariables       shShellVariables
546   hi def link kshStatement              shStatement
547   hi def link shFunctionParen           Delimiter
548 endif
550 hi def link shCaseError         Error
551 hi def link shCondError         Error
552 hi def link shCurlyError                Error
553 hi def link shDerefError                Error
554 hi def link shDerefOpError              Error
555 hi def link shDerefWordError            Error
556 hi def link shDoError           Error
557 hi def link shEsacError         Error
558 hi def link shIfError           Error
559 hi def link shInError           Error
560 hi def link shParenError                Error
561 hi def link shTestError         Error
562 if exists("b:is_kornshell")
563   hi def link shDTestError              Error
564 endif
566 hi def link shArithmetic                Special
567 hi def link shCharClass         Identifier
568 hi def link shSnglCase          Statement
569 hi def link shCommandSub                Special
570 hi def link shComment           Comment
571 hi def link shConditional               Conditional
572 hi def link shCtrlSeq           Special
573 hi def link shExprRegion                Delimiter
574 hi def link shFunctionKey               Function
575 hi def link shFunctionName              Function
576 hi def link shNumber            Number
577 hi def link shOperator          Operator
578 hi def link shRepeat            Repeat
579 hi def link shSet               Statement
580 hi def link shSetList           Identifier
581 hi def link shShellVariables            PreProc
582 hi def link shSpecial           Special
583 hi def link shStatement         Statement
584 hi def link shString            String
585 hi def link shTodo              Todo
586 hi def link shAlias             Identifier
588 " Set Current Syntax: {{{1
589 " ===================
590 if exists("b:is_bash")
591  let b:current_syntax = "bash"
592 elseif exists("b:is_kornshell")
593  let b:current_syntax = "ksh"
594 else
595  let b:current_syntax = "sh"
596 endif
598 " vim: ts=16 fdm=marker