blob: 83b8a592df7a8e17cf53db1efaff126e6d615526 [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 Moolenaar383f9bc2005-01-19 22:18:32 +00005" Last Change: Dec 28, 2004
6" Version: 71
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
Bram Moolenaar383f9bc2005-01-19 22:18:32 +000069syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest
Bram Moolenaar071d4272004-06-13 20:20:40 +000070syn 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
Bram Moolenaar383f9bc2005-01-19 22:18:32 +000075syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
Bram Moolenaar071d4272004-06-13 20:20:40 +000076syn 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
Bram Moolenaar383f9bc2005-01-19 22:18:32 +000081syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest
Bram Moolenaar071d4272004-06-13 20:20:40 +000082syn cluster shSubShList contains=@shCaseList
Bram Moolenaar383f9bc2005-01-19 22:18:32 +000083syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shSingleQuote,shSpecial,shTestOpr,shTest
Bram Moolenaar071d4272004-06-13 20:20:40 +000084
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
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000138syn region shTest transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000139syn 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
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000288 syn match shHerePayload "^.*$" contained skipnl nextgroup=shHerePayload contains=@shDblQuoteList
289 syn match shBeginLine ".*$" contained skipnl nextgroup=shHerePayload contains=@shCommandSubList
290 syn match shBeginHere "<<-\=\s*\S\+" contained nextgroup=shBeginLine
Bram Moolenaar071d4272004-06-13 20:20:40 +0000291 else
292 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1$" contains=@shDblQuoteList
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$" contains=@shDblQuoteList
295 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
296 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
297 syn region shHereDoc matchgroup=shRedir start="<<-\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="^\s*\z1$"
300 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
301 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
302 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
303 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
304 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000305endif
306
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000307" Here Strings: {{{1
308" =============
309if exists("b:is_bash")
310 syn match shRedir "<<<"
311endif
312
313" Identifiers: {{{1
314"=============
Bram Moolenaar071d4272004-06-13 20:20:40 +0000315syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier
316syn match shIdWhiteSpace contained "\s"
317syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote
318if exists("b:is_bash")
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000319 syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList
320 syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="\\ze[|)]" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000321 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)$"
322elseif exists("b:is_kornshell")
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000323 syn region shSetList matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
324 syn region shSetList matchgroup=shSet start="\<set\>\ze[^/]" end="$\|\ze[})]" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000325 syn match shSet "\<\(typeset\|set\|export\|unset\)$"
326else
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000327 syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]" matchgroup=shOperator end="[;&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000328 syn match shStatement "\<\(set\|export\|unset\)$"
329endif
330
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000331" Functions: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000332" handles functions which start: Function () {
333" Apparently Bourne shell accepts functions too,
334" even though it isn't documented by my man pages
335" for it.
336syn cluster shCommandSubList add=bkshFunction
337if g:sh_fold_enabled
338 syn region bkshFunctionBody transparent fold matchgroup=Delimiter start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=bkshFunction,bkshFunctionDelim,@shFunctionList
339else
340 syn region bkshFunctionBody transparent matchgroup=Delimiter start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=bkshFunction,bkshFunctionDelim,@shFunctionList
341endif
342syn match bkshFunction "^\s*\<\h\w*\>\s*()" skipwhite skipnl contains=bkshFunctionParen
343syn match bkshFunctionParen "[()]" contained
344syn match bkshFunctionDelim "[{}]" contained
345
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000346" Parameter Dereferencing: {{{1
347" ========================
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000348syn match shDerefSimple "\$\%(\h\w*\|\d\)"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000349syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
350syn match shDerefWordError "[^}$[]" contained
351syn match shDerefSimple "\$[-#*@!?]"
352syn match shDerefSimple "\$\$"
353if exists("b:is_bash") || exists("b:is_kornshell")
354 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
355endif
356
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000357" bash: ${!prefix*} and ${#parameter}: {{{1
358" ====================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000359if exists("b:is_bash")
360 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
361 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
362endif
363
364syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
365syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
366syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
367
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000368" sh ksh bash : ${var[... ]...} array reference: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000369syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
370
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000371" Special ${parameter OPERATOR word} handling: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000372" sh ksh bash : ${parameter:-word} word is default value
373" sh ksh bash : ${parameter:=word} assign word as default value
374" sh ksh bash : ${parameter:?word} display word if parameter is null
375" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
376" ksh bash : ${parameter#pattern} remove small left pattern
377" ksh bash : ${parameter##pattern} remove large left pattern
378" ksh bash : ${parameter%pattern} remove small right pattern
379" ksh bash : ${parameter%%pattern} remove large right pattern
380syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
381syn match shDerefOpError contained ":[[:punct:]]"
382syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
383syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
384if exists("b:is_bash") || exists("b:is_kornshell")
385 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
386 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
387 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub nextgroup=shDerefPattern
388 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
389endif
390syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
391syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
392syn match shDerefString contained "\\["']"
393
394" bash : ${parameter:offset}
395" bash : ${parameter:offset:length}
396" bash : ${parameter//pattern/string}
397" bash : ${parameter//pattern}
398if exists("b:is_bash")
399 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
400 syn match shDerefPOL contained ":[^}]\{1,}" contains=@shCommandSubList
401 syn match shDerefOp contained "/\{1,2}" nextgroup=shDerefPat
402 syn match shDerefPat contained "[^/}]\{1,}" nextgroup=shDerefPatStringOp
403 syn match shDerefPatStringOp contained "/" nextgroup=shDerefPatString
404 syn match shDerefPatString contained "[^}]\{1,}"
405endif
406
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000407" Useful sh Keywords: {{{1
408" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000409syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
410syn keyword shConditional contained elif else then
411syn keyword shCondError elif else then
412
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000413" Useful ksh Keywords: {{{1
414" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000415if exists("b:is_kornshell") || exists("b:is_bash")
416 syn keyword shFunction function
417 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
418
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000419" Useful bash Keywords: {{{1
420" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000421 if exists("b:is_bash")
422 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
423 else
424 syn keyword shStatement login newgrp
425 endif
426endif
427
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000428" Synchronization: {{{1
429" ================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000430if !exists("sh_minlines")
431 let sh_minlines = 200
432endif
433if !exists("sh_maxlines")
434 let sh_maxlines = 2 * sh_minlines
435endif
436exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
437syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
438syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
439syn sync match shDoSync grouphere shDo "\<do\>"
440syn sync match shDoSync groupthere shDo "\<done\>"
441syn sync match shForSync grouphere shFor "\<for\>"
442syn sync match shForSync groupthere shFor "\<in\>"
443syn sync match shIfSync grouphere shIf "\<if\>"
444syn sync match shIfSync groupthere shIf "\<fi\>"
445syn sync match shUntilSync grouphere shRepeat "\<until\>"
446syn sync match shWhileSync grouphere shRepeat "\<while\>"
447
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000448" Default Highlighting: {{{1
449" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000450hi def link shArithRegion shShellVariables
451hi def link shCaseBar shConditional
452hi def link shCaseIn shConditional
453hi def link shCaseCommandSub shCommandSub
454hi def link shCaseDoubleQuote shDoubleQuote
455hi def link shCaseSingleQuote shSingleQuote
456hi def link shCaseStart shConditional
457hi def link shCmdSubRegion shShellVariables
458hi def link shColon shStatement
459
460hi def link shDeref shShellVariables
461hi def link shDerefOp shOperator
462
463hi def link shDerefVar shDeref
464hi def link shDerefPOL shDerefOp
465hi def link shDerefPatString shDerefPattern
466hi def link shDerefPatStringOp shDerefOp
467hi def link shDerefSimple shDeref
468hi def link shDerefSpecial shDeref
469hi def link shDerefString shDoubleQuote
470hi def link shHerePayload shHereDoc
471hi def link shBeginHere shRedir
472
473hi def link shDoubleQuote shString
474hi def link shEcho shString
475hi def link shEmbeddedEcho shString
476hi def link shHereDoc shString
477hi def link shLoop shStatement
478hi def link shOption shCommandSub
479hi def link shPattern shString
480hi def link shPosnParm shShellVariables
481hi def link shRange shOperator
482hi def link shRedir shOperator
483hi def link shSingleQuote shString
484hi def link shSource shOperator
485hi def link shStringSpecial shSpecial
486hi def link shSubShRegion shOperator
487hi def link shTestOpr shConditional
488hi def link shVariable shSetList
489hi def link shWrapLineOperator shOperator
490
491if exists("b:is_bash")
492 hi def link bashAdminStatement shStatement
493 hi def link bashSpecialVariables shShellVariables
494 hi def link bashStatement shStatement
495 hi def link bkshFunction Function
496 hi def link bkshFunctionParen Delimiter
497 hi def link bkshFunctionDelim Delimiter
498endif
499if exists("b:is_kornshell")
500 hi def link kshSpecialVariables shShellVariables
501 hi def link kshStatement shStatement
502 hi def link bkshFunction Function
503 hi def link bkshFunctionParen Delimiter
504endif
505
506hi def link shCaseError Error
507hi def link shCondError Error
508hi def link shCurlyError Error
509hi def link shDerefError Error
510hi def link shDerefOpError Error
511hi def link shDerefWordError Error
512hi def link shDoError Error
513hi def link shEsacError Error
514hi def link shIfError Error
515hi def link shInError Error
516hi def link shParenError Error
517hi def link shTestError Error
518if exists("b:is_kornshell")
519 hi def link shDTestError Error
520endif
521
522hi def link shArithmetic Special
523hi def link shCharClass Identifier
524hi def link shSnglCase Statement
525hi def link shCommandSub Special
526hi def link shComment Comment
527hi def link shConditional Conditional
528hi def link shExprRegion Delimiter
529hi def link shFunction Function
530hi def link shFunctionName Function
531hi def link shNumber Number
532hi def link shOperator Operator
533hi def link shRepeat Repeat
534hi def link shSet Statement
535hi def link shSetList Identifier
536hi def link shShellVariables PreProc
537hi def link shSpecial Special
538hi def link shStatement Statement
539hi def link shString String
540hi def link shTodo Todo
541hi def link shAlias Identifier
542
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000543" Set Current Syntax: {{{1
544" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000545if exists("b:is_bash")
546 let b:current_syntax = "bash"
547elseif exists("b:is_kornshell")
548 let b:current_syntax = "ksh"
549else
550 let b:current_syntax = "sh"
551endif
552
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000553" vim: ts=16 fdm=marker