blob: f8624aec4c9f1787c2887f297e1c518fa0f77914 [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 Moolenaard4755bb2004-09-02 19:12:26 +00005" Last Change: Jul 26, 2004
6" Version: 69
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
56endif
57
58" sh syntax is case sensitive
59syn case match
60
Bram Moolenaard4755bb2004-09-02 19:12:26 +000061" Clusters: contains=@... clusters {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000062"==================================
63syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseSingleQuote,shCaseDoubleQuote,shSpecial
64syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,bkshFunction,shSpecial
65syn cluster shColonList contains=@shCaseList
66syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias
67syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shSpecial,shPosnParm
68syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError
69syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError
70syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shSingleQuote,shDoubleQuote,shSpecial
71syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple
72syn cluster shExprList2 contains=@shExprList1,@shCaseList
73syn cluster shFunctionList contains=@shCaseList,shOperator
74syn cluster shHereBeginList contains=@shCommandSubList
75syn cluster shHereList contains=shBeginHere,shHerePayload
76syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
77syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shSingleQuote,shDoubleQuote,shExpr
78syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac
79syn cluster shSubShList contains=@shCaseList
80syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shSingleQuote,shSpecial,shTestOpr
81
82
Bram Moolenaard4755bb2004-09-02 19:12:26 +000083" Echo: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000084" ====
85" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
86syn 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
87syn 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
88
89" This must be after the strings, so that bla \" be correct
90syn 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
91
Bram Moolenaard4755bb2004-09-02 19:12:26 +000092" Alias: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000093" =====
94if exists("b:is_kornshell") || exists("b:is_bash")
95 syn match shStatement "\<alias\>"
96 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
97 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
98endif
99
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000100" Error Codes: {{{1
101" ============
Bram Moolenaar071d4272004-06-13 20:20:40 +0000102syn match shDoError "\<done\>"
103syn match shIfError "\<fi\>"
104syn match shInError "\<in\>"
105syn match shCaseError ";;"
106syn match shEsacError "\<esac\>"
107syn match shCurlyError "}"
108syn match shParenError ")"
109if exists("b:is_kornshell")
110 syn match shDTestError "]]"
111endif
112syn match shTestError "]"
113
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000114" Options Interceptor: {{{1
115" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000116syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
117syn match shOption "\s--\S\+"ms=s+1
118
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000119" Operators: {{{1
120" ==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000121syn match shOperator "[!&;|]"
122syn match shOperator "\[[[^:]\|\]]"
123syn match shOperator "!\==" skipwhite nextgroup=shPattern
124syn match shPattern "\<\S\+\())\)\@=" contained contains=shSingleQuote,shDoubleQuote,shDeref
125
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000126" Subshells: {{{1
127" ==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2
129syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList
130
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000131" Tests: {{{1
132"=======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000133"syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
134syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
135syn region shExpr transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
136syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!=<>]"
137if exists("b:is_kornshell") || exists("b:is_bash")
138 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList
139 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList
140endif
141
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000142" Character Class In Range: {{{1
143" =========================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000144syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
145
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000146" Loops: do, if, while, until {{{1
147" ======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000148syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
149syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen
150syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen
151if exists("b:is_kornshell") || exists("b:is_bash")
152 syn cluster shCaseList add=shRepeat
153 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
154 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
155 syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
156else
157 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2 contains=@shLoopList
158 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2 contains=@shLoopList
159endif
160
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000161" Case: case...esac {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000162" ====
163syn match shCaseBar contained skipwhite "[^|"`'()]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseSingleQuote,shCaseDoubleQuote
164syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
165syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="[^$()]\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,,shComment
166syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
167syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseSingleQuote,shCaseDoubleQuote
168syn region shCaseSingleQuote matchgroup=shOperator start=+'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
169syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
170syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
171
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000172" Misc: {{{1
173"======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000174syn match shWrapLineOperator "\\$"
175syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
176
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000177" $() and $(()): {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000178" $(..) is not supported by sh (Bourne shell). However, apparently
179" some systems (HP?) have as their /bin/sh a (link to) Korn shell
180" (ie. Posix compliant shell). /bin/ksh should work for those
181" systems too, however, so the following syntax will flag $(..) as
182" an Error under /bin/sh. By consensus of vimdev'ers!
183if exists("b:is_kornshell") || exists("b:is_bash")
184 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
185 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
186 syn match shSkipInitWS contained "^\s\+"
187else
188 syn region shCommandSub matchgroup=Error start="$(" end=")" contains=@shCommandSubList
189endif
190
191if exists("b:is_bash")
192 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
193 syn cluster shCaseList add=bashAdminStatement,bashStatement
194 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
195 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
196 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
197endif
198
199if exists("b:is_kornshell")
200 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
201 syn cluster shCaseList add=kshStatement
202 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
203 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
204endif
205
206syn match shSource "^\.\s"
207syn match shSource "\s\.\s"
208syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
209
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000210" String And Character Constants: {{{1
211"================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000212syn match shNumber "-\=\<\d\+\>"
213syn match shSpecial "\\\d\d\d\|\\[abcfnrtv0]" contained
214syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
215syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
216syn match shStringSpecial "[^[:print:]]" contained
217syn match shSpecial "\\[\\\"\'`$()#]"
218
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000219" Comments: {{{1
220"==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000221syn cluster shCommentGroup contains=shTodo,@Spell
222syn keyword shTodo contained TODO
223syn match shComment "#.*$" contains=@shCommentGroup
224
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000225" File Redirection Highlighted As Operators: {{{1
226"===========================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000227syn match shRedir "\d\=>\(&[-0-9]\)\="
228syn match shRedir "\d\=>>-\="
229syn match shRedir "\d\=<\(&[-0-9]\)\="
230syn match shRedir "\d<<-\="
231
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000232" Here Documents: {{{1
233" =========================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000234if version < 600
235 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
236 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
237 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList
238 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList
239 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList
240 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList
241
242elseif g:sh_fold_enabled
243
244 if v:version > 602 || (v:version == 602 && has("patch219"))
245 syn region shHereDoc fold start="\(<<\s*\\\=\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereListDQ keepend
246 syn region shHereDoc fold start="\(<<\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
247 syn region shHereDoc fold start="\(<<\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
248 syn region shHereDoc fold start="\(<<\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
249 syn region shHereDoc fold start="\(<<\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
250 syn region shHereDoc fold start="\(<<\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereList keepend
251 syn region shHereDoc fold start="\(<<-\s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
252 syn region shHereDoc fold start="\(<<-\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereListDQ keepend
253 syn region shHereDoc fold start="\(<<-\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereList keepend
254 syn region shHereDoc fold start="\(<<-\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
255 syn region shHereDoc fold start="\(<<-\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
256 syn region shHereDoc fold start="\(<<-\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
257 else
258 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1$" contains=@shDblQuoteList
259 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
260 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
261 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$" contains=@shDblQuoteList
262 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
263 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
264 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1$"
265 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
266 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
267 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$"
268 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
269 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1$"
270 endif
271else
272 if v:version > 602 || (v:version == 602 && has("patch219"))
273 syn region shHereDoc start="\(<<\s*\\\=\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereList keepend
274 syn region shHereDoc start="\(<<\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereListDQ keepend
275 syn region shHereDoc start="\(<<\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
276 syn region shHereDoc start="\(<<\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
277 syn region shHereDoc start="\(<<\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\z1$"" contains=@shHereList keepend
278 syn region shHereDoc start="\(<<\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\z1$" contains=@shHereList keepend
279 syn region shHereDoc start="\(<<-\s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
280 syn region shHereDoc start="\(<<-\s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereListDQ keepend
281 syn region shHereDoc start="\(<<-\s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$"" contains=@shHereList keepend
282 syn region shHereDoc start="\(<<-\s*\\\_$\_s*'\z(\S*\)'\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
283 syn region shHereDoc start="\(<<-\s*\\\_$\_s*\z(\S*\)\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
284 syn region shHereDoc start="\(<<-\s*\\\_$\_s*\"\z(\S*\)\"\)\@=" matchgroup=shRedir end="^\s*\z1$" contains=@shHereList keepend
285 else
286 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1$" contains=@shDblQuoteList
287 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1$"
288 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$" contains=@shDblQuoteList
289 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1$"
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$"
292 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1$"
293 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1$"
294 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_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="^\z1$"
297 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1$"
298 endif
299 if v:version > 602 || (v:version == 602 && has("patch219"))
300 syn match shHerePayload "^.*$" contained skipnl nextgroup=shHerePayload contains=@shDblQuoteList
301 syn match shBeginLine ".*$" contained skipnl nextgroup=shHerePayload contains=@shCommandSubList
302 syn match shBeginHere "<<-\=\s*\S\+" contained nextgroup=shBeginLine
303 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000304endif
305
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000306" Here Strings: {{{1
307" =============
308if exists("b:is_bash")
309 syn match shRedir "<<<"
310endif
311
312" Identifiers: {{{1
313"=============
Bram Moolenaar071d4272004-06-13 20:20:40 +0000314syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier
315syn match shIdWhiteSpace contained "\s"
316syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote
317if exists("b:is_bash")
318 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
319 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
320 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)$"
321elseif exists("b:is_kornshell")
322 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
323 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
324 syn match shSet "\<\(typeset\|set\|export\|unset\)$"
325else
326 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
327 syn match shStatement "\<\(set\|export\|unset\)$"
328endif
329
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000330" Functions: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000331" handles functions which start: Function () {
332" Apparently Bourne shell accepts functions too,
333" even though it isn't documented by my man pages
334" for it.
335syn cluster shCommandSubList add=bkshFunction
336if g:sh_fold_enabled
337 syn region bkshFunctionBody transparent fold matchgroup=Delimiter start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=bkshFunction,bkshFunctionDelim,@shFunctionList
338else
339 syn region bkshFunctionBody transparent matchgroup=Delimiter start="^\s*\<\h\w*\>\s*()\s*{" end="}" contains=bkshFunction,bkshFunctionDelim,@shFunctionList
340endif
341syn match bkshFunction "^\s*\<\h\w*\>\s*()" skipwhite skipnl contains=bkshFunctionParen
342syn match bkshFunctionParen "[()]" contained
343syn match bkshFunctionDelim "[{}]" contained
344
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000345" Parameter Dereferencing: {{{1
346" ========================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000347syn match shDerefSimple "\$\w\+"
348syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
349syn match shDerefWordError "[^}$[]" contained
350syn match shDerefSimple "\$[-#*@!?]"
351syn match shDerefSimple "\$\$"
352if exists("b:is_bash") || exists("b:is_kornshell")
353 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
354endif
355
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000356" bash: ${!prefix*} and ${#parameter}: {{{1
357" ====================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000358if exists("b:is_bash")
359 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
360 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
361endif
362
363syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
364syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
365syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
366
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000367" sh ksh bash : ${var[... ]...} array reference: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000368syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
369
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000370" Special ${parameter OPERATOR word} handling: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000371" sh ksh bash : ${parameter:-word} word is default value
372" sh ksh bash : ${parameter:=word} assign word as default value
373" sh ksh bash : ${parameter:?word} display word if parameter is null
374" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
375" ksh bash : ${parameter#pattern} remove small left pattern
376" ksh bash : ${parameter##pattern} remove large left pattern
377" ksh bash : ${parameter%pattern} remove small right pattern
378" ksh bash : ${parameter%%pattern} remove large right pattern
379syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
380syn match shDerefOpError contained ":[[:punct:]]"
381syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
382syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
383if exists("b:is_bash") || exists("b:is_kornshell")
384 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
385 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
386 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub nextgroup=shDerefPattern
387 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
388endif
389syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
390syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
391syn match shDerefString contained "\\["']"
392
393" bash : ${parameter:offset}
394" bash : ${parameter:offset:length}
395" bash : ${parameter//pattern/string}
396" bash : ${parameter//pattern}
397if exists("b:is_bash")
398 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
399 syn match shDerefPOL contained ":[^}]\{1,}" contains=@shCommandSubList
400 syn match shDerefOp contained "/\{1,2}" nextgroup=shDerefPat
401 syn match shDerefPat contained "[^/}]\{1,}" nextgroup=shDerefPatStringOp
402 syn match shDerefPatStringOp contained "/" nextgroup=shDerefPatString
403 syn match shDerefPatString contained "[^}]\{1,}"
404endif
405
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000406" Useful sh Keywords: {{{1
407" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000408syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
409syn keyword shConditional contained elif else then
410syn keyword shCondError elif else then
411
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000412" Useful ksh Keywords: {{{1
413" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000414if exists("b:is_kornshell") || exists("b:is_bash")
415 syn keyword shFunction function
416 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
417
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000418" Useful bash Keywords: {{{1
419" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000420 if exists("b:is_bash")
421 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
422 else
423 syn keyword shStatement login newgrp
424 endif
425endif
426
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000427" Synchronization: {{{1
428" ================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000429if !exists("sh_minlines")
430 let sh_minlines = 200
431endif
432if !exists("sh_maxlines")
433 let sh_maxlines = 2 * sh_minlines
434endif
435exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
436syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
437syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
438syn sync match shDoSync grouphere shDo "\<do\>"
439syn sync match shDoSync groupthere shDo "\<done\>"
440syn sync match shForSync grouphere shFor "\<for\>"
441syn sync match shForSync groupthere shFor "\<in\>"
442syn sync match shIfSync grouphere shIf "\<if\>"
443syn sync match shIfSync groupthere shIf "\<fi\>"
444syn sync match shUntilSync grouphere shRepeat "\<until\>"
445syn sync match shWhileSync grouphere shRepeat "\<while\>"
446
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000447" Default Highlighting: {{{1
448" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000449hi def link shArithRegion shShellVariables
450hi def link shCaseBar shConditional
451hi def link shCaseIn shConditional
452hi def link shCaseCommandSub shCommandSub
453hi def link shCaseDoubleQuote shDoubleQuote
454hi def link shCaseSingleQuote shSingleQuote
455hi def link shCaseStart shConditional
456hi def link shCmdSubRegion shShellVariables
457hi def link shColon shStatement
458
459hi def link shDeref shShellVariables
460hi def link shDerefOp shOperator
461
462hi def link shDerefVar shDeref
463hi def link shDerefPOL shDerefOp
464hi def link shDerefPatString shDerefPattern
465hi def link shDerefPatStringOp shDerefOp
466hi def link shDerefSimple shDeref
467hi def link shDerefSpecial shDeref
468hi def link shDerefString shDoubleQuote
469hi def link shHerePayload shHereDoc
470hi def link shBeginHere shRedir
471
472hi def link shDoubleQuote shString
473hi def link shEcho shString
474hi def link shEmbeddedEcho shString
475hi def link shHereDoc shString
476hi def link shLoop shStatement
477hi def link shOption shCommandSub
478hi def link shPattern shString
479hi def link shPosnParm shShellVariables
480hi def link shRange shOperator
481hi def link shRedir shOperator
482hi def link shSingleQuote shString
483hi def link shSource shOperator
484hi def link shStringSpecial shSpecial
485hi def link shSubShRegion shOperator
486hi def link shTestOpr shConditional
487hi def link shVariable shSetList
488hi def link shWrapLineOperator shOperator
489
490if exists("b:is_bash")
491 hi def link bashAdminStatement shStatement
492 hi def link bashSpecialVariables shShellVariables
493 hi def link bashStatement shStatement
494 hi def link bkshFunction Function
495 hi def link bkshFunctionParen Delimiter
496 hi def link bkshFunctionDelim Delimiter
497endif
498if exists("b:is_kornshell")
499 hi def link kshSpecialVariables shShellVariables
500 hi def link kshStatement shStatement
501 hi def link bkshFunction Function
502 hi def link bkshFunctionParen Delimiter
503endif
504
505hi def link shCaseError Error
506hi def link shCondError Error
507hi def link shCurlyError Error
508hi def link shDerefError Error
509hi def link shDerefOpError Error
510hi def link shDerefWordError Error
511hi def link shDoError Error
512hi def link shEsacError Error
513hi def link shIfError Error
514hi def link shInError Error
515hi def link shParenError Error
516hi def link shTestError Error
517if exists("b:is_kornshell")
518 hi def link shDTestError Error
519endif
520
521hi def link shArithmetic Special
522hi def link shCharClass Identifier
523hi def link shSnglCase Statement
524hi def link shCommandSub Special
525hi def link shComment Comment
526hi def link shConditional Conditional
527hi def link shExprRegion Delimiter
528hi def link shFunction Function
529hi def link shFunctionName Function
530hi def link shNumber Number
531hi def link shOperator Operator
532hi def link shRepeat Repeat
533hi def link shSet Statement
534hi def link shSetList Identifier
535hi def link shShellVariables PreProc
536hi def link shSpecial Special
537hi def link shStatement Statement
538hi def link shString String
539hi def link shTodo Todo
540hi def link shAlias Identifier
541
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000542" Set Current Syntax: {{{1
543" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000544if exists("b:is_bash")
545 let b:current_syntax = "bash"
546elseif exists("b:is_kornshell")
547 let b:current_syntax = "ksh"
548else
549 let b:current_syntax = "sh"
550endif
551
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000552" vim: ts=16 fdm=marker