blob: 27ff7757bb4db51832de69001891b09af85f7520 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" 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>
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00005" Last Change: Oct 17, 2004
6" Version: 70
Bram Moolenaar071d4272004-06-13 20:20:40 +00007" URL: http://www.erols.com/astronaut/vim/index.html#vimlinks_syntax
8"
Bram Moolenaard4755bb2004-09-02 19:12:26 +00009" Using the following VIM variables: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000010" b:is_kornshell if defined, enhance with kornshell syntax
11" b:is_bash if defined, enhance with bash syntax
12" is_kornshell if neither b:is_kornshell or b:is_bash is
13" defined, then if is_kornshell is set
14" b:is_kornshell is default
15" is_bash if none of the previous three variables are
16" defined, then if is_bash is set b:is_bash is default
17" g:sh_fold_enabled if non-zero, syntax folding is enabled
18" sh_minlines sets up syn sync minlines (default: 200)
19" sh_maxlines sets up syn sync maxlines (default: twice sh_minlines)
20"
21" This file includes many ideas from Éric Brunet (eric.brunet@ens.fr)
22
Bram Moolenaard4755bb2004-09-02 19:12:26 +000023" For version 5.x: Clear all syntax items {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000024" For version 6.x: Quit when a syntax file was already loaded
25if version < 600
26 syntax clear
27elseif exists("b:current_syntax")
28 finish
29endif
30
Bram Moolenaard4755bb2004-09-02 19:12:26 +000031" handling /bin/sh with is_kornshell/is_sh {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000032" 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.
38if !exists("b:is_kornshell") && !exists("b:is_bash")
39 if exists("is_kornshell")
40 let b:is_kornshell= 1
41 if exists("b:is_sh")
42 unlet b:is_sh
43 endif
44 elseif exists("is_bash")
45 let b:is_bash= 1
46 if exists("b:is_sh")
47 unlet b:is_sh
48 endif
49 else
50 let b:is_sh= 1
51 endif
52endif
53
54if !exists("g:sh_fold_enabled")
55 let g:sh_fold_enabled= 0
Bram Moolenaar293ee4d2004-12-09 21:34:53 +000056elseif g:sh_fold_enabled != 0 && !has("folding")
57 let g:sh_fold_enabled= 0
58 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; re-compile vim for +fold support"
Bram Moolenaar071d4272004-06-13 20:20:40 +000059endif
60
61" sh syntax is case sensitive
62syn case match
63
Bram Moolenaard4755bb2004-09-02 19:12:26 +000064" Clusters: contains=@... clusters {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000065"==================================
66syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseSingleQuote,shCaseDoubleQuote,shSpecial
67syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,bkshFunction,shSpecial
68syn cluster shColonList contains=@shCaseList
69syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias
70syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shSpecial,shPosnParm
71syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError
72syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError
73syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shSingleQuote,shDoubleQuote,shSpecial
74syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple
75syn cluster shExprList2 contains=@shExprList1,@shCaseList
76syn cluster shFunctionList contains=@shCaseList,shOperator
77syn cluster shHereBeginList contains=@shCommandSubList
78syn cluster shHereList contains=shBeginHere,shHerePayload
79syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
80syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shSingleQuote,shDoubleQuote,shExpr
81syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac
82syn cluster shSubShList contains=@shCaseList
83syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shSingleQuote,shSpecial,shTestOpr
84
85
Bram Moolenaard4755bb2004-09-02 19:12:26 +000086" Echo: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000087" ====
88" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
89syn 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
90syn 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
91
92" This must be after the strings, so that bla \" be correct
93syn 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,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass
94
Bram Moolenaard4755bb2004-09-02 19:12:26 +000095" Alias: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000096" =====
97if exists("b:is_kornshell") || exists("b:is_bash")
98 syn match shStatement "\<alias\>"
99 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
100 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
101endif
102
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000103" Error Codes: {{{1
104" ============
Bram Moolenaar071d4272004-06-13 20:20:40 +0000105syn match shDoError "\<done\>"
106syn match shIfError "\<fi\>"
107syn match shInError "\<in\>"
108syn match shCaseError ";;"
109syn match shEsacError "\<esac\>"
110syn match shCurlyError "}"
111syn match shParenError ")"
112if exists("b:is_kornshell")
113 syn match shDTestError "]]"
114endif
115syn match shTestError "]"
116
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000117" Options Interceptor: {{{1
118" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000119syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
120syn match shOption "\s--\S\+"ms=s+1
121
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000122" Operators: {{{1
123" ==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000124syn match shOperator "[!&;|]"
125syn match shOperator "\[[[^:]\|\]]"
126syn match shOperator "!\==" skipwhite nextgroup=shPattern
127syn match shPattern "\<\S\+\())\)\@=" contained contains=shSingleQuote,shDoubleQuote,shDeref
128
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000129" Subshells: {{{1
130" ==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000131syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2
132syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList
133
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000134" Tests: {{{1
135"=======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000136"syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
137syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
138syn region shExpr transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
139syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!=<>]"
140if exists("b:is_kornshell") || exists("b:is_bash")
141 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList
142 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList
143endif
144
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000145" Character Class In Range: {{{1
146" =========================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000147syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
148
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000149" Loops: do, if, while, until {{{1
150" ======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000151syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
152syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen
153syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen
154if exists("b:is_kornshell") || exists("b:is_bash")
155 syn cluster shCaseList add=shRepeat
156 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
157 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
158 syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
159else
160 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2 contains=@shLoopList
161 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2 contains=@shLoopList
162endif
163
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000164" Case: case...esac {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000165" ====
166syn match shCaseBar contained skipwhite "[^|"`'()]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseSingleQuote,shCaseDoubleQuote
167syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
168syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="[^$()]\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,,shComment
169syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
170syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseSingleQuote,shCaseDoubleQuote
171syn region shCaseSingleQuote matchgroup=shOperator start=+'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
172syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
173syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
174
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000175" Misc: {{{1
176"======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000177syn match shWrapLineOperator "\\$"
178syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
179
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000180" $() and $(()): {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000181" $(..) is not supported by sh (Bourne shell). However, apparently
182" some systems (HP?) have as their /bin/sh a (link to) Korn shell
183" (ie. Posix compliant shell). /bin/ksh should work for those
184" systems too, however, so the following syntax will flag $(..) as
185" an Error under /bin/sh. By consensus of vimdev'ers!
186if exists("b:is_kornshell") || exists("b:is_bash")
187 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
188 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
189 syn match shSkipInitWS contained "^\s\+"
190else
191 syn region shCommandSub matchgroup=Error start="$(" end=")" contains=@shCommandSubList
192endif
193
194if exists("b:is_bash")
195 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
196 syn cluster shCaseList add=bashAdminStatement,bashStatement
197 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
198 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
199 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
200endif
201
202if exists("b:is_kornshell")
203 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
204 syn cluster shCaseList add=kshStatement
205 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
206 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
207endif
208
209syn match shSource "^\.\s"
210syn match shSource "\s\.\s"
211syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
212
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000213" String And Character Constants: {{{1
214"================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000215syn match shNumber "-\=\<\d\+\>"
216syn match shSpecial "\\\d\d\d\|\\[abcfnrtv0]" contained
217syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
218syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
219syn match shStringSpecial "[^[:print:]]" contained
220syn match shSpecial "\\[\\\"\'`$()#]"
221
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000222" Comments: {{{1
223"==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000224syn cluster shCommentGroup contains=shTodo,@Spell
225syn keyword shTodo contained TODO
226syn match shComment "#.*$" contains=@shCommentGroup
227
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000228" File Redirection Highlighted As Operators: {{{1
229"===========================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000230syn match shRedir "\d\=>\(&[-0-9]\)\="
231syn match shRedir "\d\=>>-\="
232syn match shRedir "\d\=<\(&[-0-9]\)\="
233syn match shRedir "\d<<-\="
234
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000235" Here Documents: {{{1
236" =========================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000237if version < 600
238 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
239 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
240 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList
241 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList
242 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList
243 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList
244
245elseif g:sh_fold_enabled
246
247 if v:version > 602 || (v:version == 602 && has("patch219"))
248 syn region shHereDoc fold start="\(<<\s*\\\=\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereListDQ keepend
249 syn region shHereDoc fold start="\(<<\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
250 syn region shHereDoc fold start="\(<<\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
251 syn region shHereDoc fold start="\(<<\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
252 syn region shHereDoc fold start="\(<<\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
253 syn region shHereDoc fold start="\(<<\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereList keepend
254 syn region shHereDoc fold start="\(<<-\s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
255 syn region shHereDoc fold start="\(<<-\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereListDQ keepend
256 syn region shHereDoc fold start="\(<<-\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereList keepend
257 syn region shHereDoc fold start="\(<<-\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
258 syn region shHereDoc fold start="\(<<-\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
259 syn region shHereDoc fold start="\(<<-\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
260 else
261 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1$" contains=@shDblQuoteList
262 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
263 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
264 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$" contains=@shDblQuoteList
265 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
266 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
267 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1$"
268 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
269 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
270 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$"
271 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
272 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
273 endif
274else
275 if v:version > 602 || (v:version == 602 && has("patch219"))
276 syn region shHereDoc start="\(<<\s*\\\=\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereList keepend
277 syn region shHereDoc start="\(<<\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereListDQ keepend
278 syn region shHereDoc start="\(<<\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
279 syn region shHereDoc start="\(<<\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
280 syn region shHereDoc start="\(<<\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
281 syn region shHereDoc start="\(<<\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereList keepend
282 syn region shHereDoc start="\(<<-\s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
283 syn region shHereDoc start="\(<<-\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereListDQ keepend
284 syn region shHereDoc start="\(<<-\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereList keepend
285 syn region shHereDoc start="\(<<-\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
286 syn region shHereDoc start="\(<<-\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
287 syn region shHereDoc start="\(<<-\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
288 else
289 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1$" contains=@shDblQuoteList
290 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
291 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$" contains=@shDblQuoteList
292 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
293 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
294 syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
295 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1$"
296 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$"
297 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
298 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
299 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
300 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
301 endif
302 if v:version > 602 || (v:version == 602 && has("patch219"))
303 syn match shHerePayload "^.*$" contained skipnl nextgroup=shHerePayload contains=@shDblQuoteList
304 syn match shBeginLine ".*$" contained skipnl nextgroup=shHerePayload contains=@shCommandSubList
305 syn match shBeginHere "<<-\=\s*\S\+" contained nextgroup=shBeginLine
306 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000307endif
308
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000309" Here Strings: {{{1
310" =============
311if exists("b:is_bash")
312 syn match shRedir "<<<"
313endif
314
315" Identifiers: {{{1
316"=============
Bram Moolenaar071d4272004-06-13 20:20:40 +0000317syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier
318syn match shIdWhiteSpace contained "\s"
319syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote
320if exists("b:is_bash")
321 syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>[^/]"me=e-1 end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
322 syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="[|)]"me=e-1 matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
323 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)$"
324elseif exists("b:is_kornshell")
325 syn region shSetList matchgroup=shSet start="\<\(typeset\|export\|unset\)\>[^/]"me=e-1 end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
326 syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
327 syn match shSet "\<\(typeset\|set\|export\|unset\)$"
328else
329 syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>[^/]"me=e-1 end="$" end="[)|]"me=e-1 matchgroup=shOperator end="[;&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
330 syn match shStatement "\<\(set\|export\|unset\)$"
331endif
332
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000333" Functions: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000334" handles functions which start: Function () {
335" Apparently Bourne shell accepts functions too,
336" even though it isn't documented by my man pages
337" for it.
338syn cluster shCommandSubList add=bkshFunction
339if g:sh_fold_enabled
340 syn region bkshFunctionBody transparent fold matchgroup=Delimiter start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=bkshFunction,bkshFunctionDelim,@shFunctionList
341else
342 syn region bkshFunctionBody transparent matchgroup=Delimiter start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=bkshFunction,bkshFunctionDelim,@shFunctionList
343endif
344syn match bkshFunction "^\s*\<\h\w*\>\s*()" skipwhite skipnl contains=bkshFunctionParen
345syn match bkshFunctionParen "[()]" contained
346syn match bkshFunctionDelim "[{}]" contained
347
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000348" Parameter Dereferencing: {{{1
349" ========================
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000350syn match shDerefSimple "\$\%(\h\w*\|\d\)"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000351syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
352syn match shDerefWordError "[^}$[]" contained
353syn match shDerefSimple "\$[-#*@!?]"
354syn match shDerefSimple "\$\$"
355if exists("b:is_bash") || exists("b:is_kornshell")
356 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
357endif
358
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000359" bash: ${!prefix*} and ${#parameter}: {{{1
360" ====================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000361if exists("b:is_bash")
362 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
363 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
364endif
365
366syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
367syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
368syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
369
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000370" sh ksh bash : ${var[... ]...} array reference: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000371syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
372
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000373" Special ${parameter OPERATOR word} handling: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000374" sh ksh bash : ${parameter:-word} word is default value
375" sh ksh bash : ${parameter:=word} assign word as default value
376" sh ksh bash : ${parameter:?word} display word if parameter is null
377" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
378" ksh bash : ${parameter#pattern} remove small left pattern
379" ksh bash : ${parameter##pattern} remove large left pattern
380" ksh bash : ${parameter%pattern} remove small right pattern
381" ksh bash : ${parameter%%pattern} remove large right pattern
382syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
383syn match shDerefOpError contained ":[[:punct:]]"
384syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
385syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
386if exists("b:is_bash") || exists("b:is_kornshell")
387 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
388 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
389 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub nextgroup=shDerefPattern
390 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
391endif
392syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
393syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
394syn match shDerefString contained "\\["']"
395
396" bash : ${parameter:offset}
397" bash : ${parameter:offset:length}
398" bash : ${parameter//pattern/string}
399" bash : ${parameter//pattern}
400if exists("b:is_bash")
401 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
402 syn match shDerefPOL contained ":[^}]\{1,}" contains=@shCommandSubList
403 syn match shDerefOp contained "/\{1,2}" nextgroup=shDerefPat
404 syn match shDerefPat contained "[^/}]\{1,}" nextgroup=shDerefPatStringOp
405 syn match shDerefPatStringOp contained "/" nextgroup=shDerefPatString
406 syn match shDerefPatString contained "[^}]\{1,}"
407endif
408
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000409" Useful sh Keywords: {{{1
410" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
412syn keyword shConditional contained elif else then
413syn keyword shCondError elif else then
414
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000415" Useful ksh Keywords: {{{1
416" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000417if exists("b:is_kornshell") || exists("b:is_bash")
418 syn keyword shFunction function
419 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
420
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000421" Useful bash Keywords: {{{1
422" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000423 if exists("b:is_bash")
424 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
425 else
426 syn keyword shStatement login newgrp
427 endif
428endif
429
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000430" Synchronization: {{{1
431" ================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000432if !exists("sh_minlines")
433 let sh_minlines = 200
434endif
435if !exists("sh_maxlines")
436 let sh_maxlines = 2 * sh_minlines
437endif
438exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
439syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
440syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
441syn sync match shDoSync grouphere shDo "\<do\>"
442syn sync match shDoSync groupthere shDo "\<done\>"
443syn sync match shForSync grouphere shFor "\<for\>"
444syn sync match shForSync groupthere shFor "\<in\>"
445syn sync match shIfSync grouphere shIf "\<if\>"
446syn sync match shIfSync groupthere shIf "\<fi\>"
447syn sync match shUntilSync grouphere shRepeat "\<until\>"
448syn sync match shWhileSync grouphere shRepeat "\<while\>"
449
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000450" Default Highlighting: {{{1
451" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000452hi def link shArithRegion shShellVariables
453hi def link shCaseBar shConditional
454hi def link shCaseIn shConditional
455hi def link shCaseCommandSub shCommandSub
456hi def link shCaseDoubleQuote shDoubleQuote
457hi def link shCaseSingleQuote shSingleQuote
458hi def link shCaseStart shConditional
459hi def link shCmdSubRegion shShellVariables
460hi def link shColon shStatement
461
462hi def link shDeref shShellVariables
463hi def link shDerefOp shOperator
464
465hi def link shDerefVar shDeref
466hi def link shDerefPOL shDerefOp
467hi def link shDerefPatString shDerefPattern
468hi def link shDerefPatStringOp shDerefOp
469hi def link shDerefSimple shDeref
470hi def link shDerefSpecial shDeref
471hi def link shDerefString shDoubleQuote
472hi def link shHerePayload shHereDoc
473hi def link shBeginHere shRedir
474
475hi def link shDoubleQuote shString
476hi def link shEcho shString
477hi def link shEmbeddedEcho shString
478hi def link shHereDoc shString
479hi def link shLoop shStatement
480hi def link shOption shCommandSub
481hi def link shPattern shString
482hi def link shPosnParm shShellVariables
483hi def link shRange shOperator
484hi def link shRedir shOperator
485hi def link shSingleQuote shString
486hi def link shSource shOperator
487hi def link shStringSpecial shSpecial
488hi def link shSubShRegion shOperator
489hi def link shTestOpr shConditional
490hi def link shVariable shSetList
491hi def link shWrapLineOperator shOperator
492
493if exists("b:is_bash")
494 hi def link bashAdminStatement shStatement
495 hi def link bashSpecialVariables shShellVariables
496 hi def link bashStatement shStatement
497 hi def link bkshFunction Function
498 hi def link bkshFunctionParen Delimiter
499 hi def link bkshFunctionDelim Delimiter
500endif
501if exists("b:is_kornshell")
502 hi def link kshSpecialVariables shShellVariables
503 hi def link kshStatement shStatement
504 hi def link bkshFunction Function
505 hi def link bkshFunctionParen Delimiter
506endif
507
508hi def link shCaseError Error
509hi def link shCondError Error
510hi def link shCurlyError Error
511hi def link shDerefError Error
512hi def link shDerefOpError Error
513hi def link shDerefWordError Error
514hi def link shDoError Error
515hi def link shEsacError Error
516hi def link shIfError Error
517hi def link shInError Error
518hi def link shParenError Error
519hi def link shTestError Error
520if exists("b:is_kornshell")
521 hi def link shDTestError Error
522endif
523
524hi def link shArithmetic Special
525hi def link shCharClass Identifier
526hi def link shSnglCase Statement
527hi def link shCommandSub Special
528hi def link shComment Comment
529hi def link shConditional Conditional
530hi def link shExprRegion Delimiter
531hi def link shFunction Function
532hi def link shFunctionName Function
533hi def link shNumber Number
534hi def link shOperator Operator
535hi def link shRepeat Repeat
536hi def link shSet Statement
537hi def link shSetList Identifier
538hi def link shShellVariables PreProc
539hi def link shSpecial Special
540hi def link shStatement Statement
541hi def link shString String
542hi def link shTodo Todo
543hi def link shAlias Identifier
544
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000545" Set Current Syntax: {{{1
546" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000547if exists("b:is_bash")
548 let b:current_syntax = "bash"
549elseif exists("b:is_kornshell")
550 let b:current_syntax = "ksh"
551else
552 let b:current_syntax = "sh"
553endif
554
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000555" vim: ts=16 fdm=marker