blob: 8e20b9881018bcc19ae08dd4ae7c0495f75361a7 [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 Moolenaar8dff8182006-04-06 20:18:50 +00005" Last Change: Apr 06, 2006
6" Version: 82
Bram Moolenaarcafda4f2005-09-06 19:25:11 +00007" URL: http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
Bram Moolenaar071d4272004-06-13 20:20:40 +00008"
Bram Moolenaard4755bb2004-09-02 19:12:26 +00009" Using the following VIM variables: {{{1
Bram Moolenaara5792f52005-11-23 21:25:05 +000010" b:is_kornshell if defined, enhance with kornshell/POSIX syntax
Bram Moolenaar071d4272004-06-13 20:20:40 +000011" b:is_bash if defined, enhance with bash syntax
Bram Moolenaara5792f52005-11-23 21:25:05 +000012" g:is_kornshell if neither b:is_kornshell or b:is_bash is
13" defined, then if g:is_kornshell is set
14" enhance with kornshell/POSIX syntax highlighting
15" g:is_bash if none of the previous three variables are
16" defined, then if g:is_bash is set enhance with
17" bash syntax highlighting
Bram Moolenaar071d4272004-06-13 20:20:40 +000018" g:sh_fold_enabled if non-zero, syntax folding is enabled
Bram Moolenaara5792f52005-11-23 21:25:05 +000019" g:sh_minlines sets up syn sync minlines (dflt: 200)
20" g:sh_maxlines sets up syn sync maxlines (dflt: 2x sh_minlines)
Bram Moolenaar071d4272004-06-13 20:20:40 +000021"
22" This file includes many ideas from Éric Brunet (eric.brunet@ens.fr)
23
Bram Moolenaard4755bb2004-09-02 19:12:26 +000024" For version 5.x: Clear all syntax items {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000025" For version 6.x: Quit when a syntax file was already loaded
26if version < 600
27 syntax clear
28elseif exists("b:current_syntax")
29 finish
30endif
31
Bram Moolenaard4755bb2004-09-02 19:12:26 +000032" handling /bin/sh with is_kornshell/is_sh {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000033" b:is_sh is set when "#! /bin/sh" is found;
34" However, it often is just a masquerade by bash (typically Linux)
35" or kornshell (typically workstations with Posix "sh").
36" So, when the user sets "is_bash" or "is_kornshell",
37" a b:is_sh is converted into b:is_bash/b:is_kornshell,
38" respectively.
39if !exists("b:is_kornshell") && !exists("b:is_bash")
40 if exists("is_kornshell")
41 let b:is_kornshell= 1
42 if exists("b:is_sh")
43 unlet b:is_sh
44 endif
45 elseif exists("is_bash")
46 let b:is_bash= 1
47 if exists("b:is_sh")
48 unlet b:is_sh
49 endif
50 else
51 let b:is_sh= 1
52 endif
53endif
54
Bram Moolenaarcd71fa32005-03-11 22:46:48 +000055" set up default g:sh_fold_enabled {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000056if !exists("g:sh_fold_enabled")
57 let g:sh_fold_enabled= 0
Bram Moolenaar293ee4d2004-12-09 21:34:53 +000058elseif g:sh_fold_enabled != 0 && !has("folding")
59 let g:sh_fold_enabled= 0
Bram Moolenaarcd71fa32005-03-11 22:46:48 +000060 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
61endif
62if g:sh_fold_enabled && &fdm == "manual"
63 set fdm=syntax
Bram Moolenaar071d4272004-06-13 20:20:40 +000064endif
65
Bram Moolenaarcd71fa32005-03-11 22:46:48 +000066" sh syntax is case sensitive {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000067syn case match
68
Bram Moolenaard4755bb2004-09-02 19:12:26 +000069" Clusters: contains=@... clusters {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000070"==================================
Bram Moolenaardf177f62005-02-22 08:39:57 +000071syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shSpecial
Bram Moolenaarcd71fa32005-03-11 22:46:48 +000072syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shSpecial
Bram Moolenaar071d4272004-06-13 20:20:40 +000073syn cluster shColonList contains=@shCaseList
Bram Moolenaardf177f62005-02-22 08:39:57 +000074syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest
Bram Moolenaar572cb562005-08-05 21:35:02 +000075syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
Bram Moolenaar071d4272004-06-13 20:20:40 +000076syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shSpecial,shPosnParm
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000077syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
Bram Moolenaar071d4272004-06-13 20:20:40 +000078syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError
Bram Moolenaardf177f62005-02-22 08:39:57 +000079syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial
80syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple
Bram Moolenaar383f9bc2005-01-19 22:18:32 +000081syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
Bram Moolenaar8dff8182006-04-06 20:18:50 +000082syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shSpecial,shOperator,shFunctionStart
Bram Moolenaar071d4272004-06-13 20:20:40 +000083syn cluster shHereBeginList contains=@shCommandSubList
84syn cluster shHereList contains=shBeginHere,shHerePayload
85syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
Bram Moolenaardf177f62005-02-22 08:39:57 +000086syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr
Bram Moolenaar383f9bc2005-01-19 22:18:32 +000087syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest
Bram Moolenaar071d4272004-06-13 20:20:40 +000088syn cluster shSubShList contains=@shCaseList
Bram Moolenaardf177f62005-02-22 08:39:57 +000089syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shSpecial,shTestOpr,shTest
Bram Moolenaar071d4272004-06-13 20:20:40 +000090
91
Bram Moolenaard4755bb2004-09-02 19:12:26 +000092" Echo: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000093" ====
94" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
95syn 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
96syn 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
97
98" This must be after the strings, so that bla \" be correct
Bram Moolenaardf177f62005-02-22 08:39:57 +000099syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass
Bram Moolenaar071d4272004-06-13 20:20:40 +0000100
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000101" Alias: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000102" =====
103if exists("b:is_kornshell") || exists("b:is_bash")
104 syn match shStatement "\<alias\>"
105 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`"
106 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="="
107endif
108
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000109" Error Codes: {{{1
110" ============
Bram Moolenaar071d4272004-06-13 20:20:40 +0000111syn match shDoError "\<done\>"
112syn match shIfError "\<fi\>"
113syn match shInError "\<in\>"
114syn match shCaseError ";;"
115syn match shEsacError "\<esac\>"
116syn match shCurlyError "}"
117syn match shParenError ")"
118if exists("b:is_kornshell")
119 syn match shDTestError "]]"
120endif
121syn match shTestError "]"
122
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000123" Options Interceptor: {{{1
124" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000125syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
Bram Moolenaare1438bb2006-03-01 22:01:55 +0000126syn match shOption "\s--[^ \t$`'"|]\+"ms=s+1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000127
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000128" Operators: {{{1
129" ==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000130syn match shOperator "[!&;|]"
131syn match shOperator "\[[[^:]\|\]]"
132syn match shOperator "!\==" skipwhite nextgroup=shPattern
Bram Moolenaardf177f62005-02-22 08:39:57 +0000133syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
Bram Moolenaar071d4272004-06-13 20:20:40 +0000134
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000135" Subshells: {{{1
136" ==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000137syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2
138syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList
139
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000140" Tests: {{{1
141"=======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000142"syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
143syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000144syn region shTest transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000145syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!=<>]"
146if exists("b:is_kornshell") || exists("b:is_bash")
147 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList
148 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList
149endif
150
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000151" Character Class In Range: {{{1
152" =========================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000153syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
154
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000155" Loops: do, if, while, until {{{1
156" ======
Bram Moolenaar8dff8182006-04-06 20:18:50 +0000157if g:sh_fold_enabled
158 syn region shDo fold transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
159 syn region shIf fold transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
160 syn region shFor fold matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
161else
162 syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
163 syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey
164 syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
165endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000166if exists("b:is_kornshell") || exists("b:is_bash")
167 syn cluster shCaseList add=shRepeat
168 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
169 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
170 syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
171else
172 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2 contains=@shLoopList
173 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2 contains=@shLoopList
174endif
Bram Moolenaar572cb562005-08-05 21:35:02 +0000175syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
176syn match shComma contained ","
Bram Moolenaar071d4272004-06-13 20:20:40 +0000177
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000178" Case: case...esac {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000179" ====
Bram Moolenaardf177f62005-02-22 08:39:57 +0000180syn match shCaseBar contained skipwhite "[^|"`'()]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
Bram Moolenaar071d4272004-06-13 20:20:40 +0000181syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000182syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="[^#$()'"]\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
Bram Moolenaar8dff8182006-04-06 20:18:50 +0000183if g:sh_fold_enabled
184 syn region shCaseEsac fold matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
185else
186 syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
187endif
Bram Moolenaardf177f62005-02-22 08:39:57 +0000188syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
189if exists("b:is_bash")
190 syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained
191else
192 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
193endif
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000194syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000195syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
196syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
197
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000198" Misc: {{{1
199"======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000200syn match shWrapLineOperator "\\$"
201syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
202
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000203" $() and $(()): {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000204" $(..) is not supported by sh (Bourne shell). However, apparently
205" some systems (HP?) have as their /bin/sh a (link to) Korn shell
206" (ie. Posix compliant shell). /bin/ksh should work for those
207" systems too, however, so the following syntax will flag $(..) as
208" an Error under /bin/sh. By consensus of vimdev'ers!
209if exists("b:is_kornshell") || exists("b:is_bash")
210 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
211 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList
212 syn match shSkipInitWS contained "^\s\+"
213else
Bram Moolenaardf177f62005-02-22 08:39:57 +0000214 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000215endif
216
217if exists("b:is_bash")
218 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
219 syn cluster shCaseList add=bashAdminStatement,bashStatement
220 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
221 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
222 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
223endif
224
225if exists("b:is_kornshell")
226 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
227 syn cluster shCaseList add=kshStatement
228 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
229 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
230endif
231
232syn match shSource "^\.\s"
233syn match shSource "\s\.\s"
234syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList
235
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000236" String And Character Constants: {{{1
237"================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238syn match shNumber "-\=\<\d\+\>"
Bram Moolenaardf177f62005-02-22 08:39:57 +0000239if exists("b:is_bash")
240 syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
241else
242 syn match shSpecial "\\\d\d\d\|\\[abcfnrtv0]" contained
243endif
244if exists("b:is_bash")
245 syn region shExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial
246else
247 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial
248endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000249syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
250syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
251syn match shStringSpecial "[^[:print:]]" contained
252syn match shSpecial "\\[\\\"\'`$()#]"
253
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000254" Comments: {{{1
255"==========
Bram Moolenaar071d4272004-06-13 20:20:40 +0000256syn cluster shCommentGroup contains=shTodo,@Spell
257syn keyword shTodo contained TODO
258syn match shComment "#.*$" contains=@shCommentGroup
259
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000260" File Redirection Highlighted As Operators: {{{1
261"===========================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000262syn match shRedir "\d\=>\(&[-0-9]\)\="
263syn match shRedir "\d\=>>-\="
264syn match shRedir "\d\=<\(&[-0-9]\)\="
265syn match shRedir "\d<<-\="
266
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000267" Here Documents: {{{1
268" =========================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000269if version < 600
270 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList
271 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
272 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList
273 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList
274 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList
275 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList
276
277elseif g:sh_fold_enabled
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000278 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
279 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
280 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
281 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
282 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
283 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
284 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
285 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
286 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
287 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
288 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
289 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000290
Bram Moolenaar071d4272004-06-13 20:20:40 +0000291else
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000292 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList
293 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
294 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList
295 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
296 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
297 syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
298 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$"
299 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$"
300 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$"
301 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$"
302 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
303 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
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"
Bram Moolenaardf177f62005-02-22 08:39:57 +0000316syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
Bram Moolenaar071d4272004-06-13 20:20:40 +0000317if exists("b:is_bash")
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000318 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
319 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 +0000320 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)$"
321elseif exists("b:is_kornshell")
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000322 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
323 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 +0000324 syn match shSet "\<\(typeset\|set\|export\|unset\)$"
325else
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000326 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 +0000327 syn match shStatement "\<\(set\|export\|unset\)$"
328endif
329
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000330" Functions: {{{1
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000331syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
Bram Moolenaar8dff8182006-04-06 20:18:50 +0000332syn match shFunctionStart "^\s*{" contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000333if g:sh_fold_enabled
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000334 syn region shFunctionOne transparent fold start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList
335 syn region shFunctionTwo transparent fold start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000336else
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000337 syn region shFunctionOne transparent start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList
338 syn region shFunctionTwo transparent start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000339endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000340
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000341" Parameter Dereferencing: {{{1
342" ========================
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000343syn match shDerefSimple "\$\%(\h\w*\|\d\)"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000344syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray
345syn match shDerefWordError "[^}$[]" contained
346syn match shDerefSimple "\$[-#*@!?]"
347syn match shDerefSimple "\$\$"
348if exists("b:is_bash") || exists("b:is_kornshell")
349 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList
350endif
351
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000352" bash: ${!prefix*} and ${#parameter}: {{{1
353" ====================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000354if exists("b:is_bash")
355 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp
356 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList
357endif
358
359syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError
360syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
361syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList
362
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000363" sh ksh bash : ${var[... ]...} array reference: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000364syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError
365
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000366" Special ${parameter OPERATOR word} handling: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000367" sh ksh bash : ${parameter:-word} word is default value
368" sh ksh bash : ${parameter:=word} assign word as default value
369" sh ksh bash : ${parameter:?word} display word if parameter is null
370" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
371" ksh bash : ${parameter#pattern} remove small left pattern
372" ksh bash : ${parameter##pattern} remove large left pattern
373" ksh bash : ${parameter%pattern} remove small right pattern
374" ksh bash : ${parameter%%pattern} remove large right pattern
375syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
376syn match shDerefOpError contained ":[[:punct:]]"
377syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
378syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
379if exists("b:is_bash") || exists("b:is_kornshell")
380 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
381 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000382 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
Bram Moolenaar071d4272004-06-13 20:20:40 +0000383 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000384 syn match shDerefEscape contained '\%(\\\\\)*\\.'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000385endif
386syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial
387syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
388syn match shDerefString contained "\\["']"
389
Bram Moolenaar071d4272004-06-13 20:20:40 +0000390if exists("b:is_bash")
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000391 " bash : ${parameter:offset}
392 " bash : ${parameter:offset:length}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000393 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000394 syn match shDerefPOL contained ":[^}]\+" contains=@shCommandSubList
395
396 " bash : ${parameter//pattern/string}
397 " bash : ${parameter//pattern}
398 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
Bram Moolenaara5792f52005-11-23 21:25:05 +0000399 syn region shDerefPPSleft contained start='.' skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPPSright contains=@shCommandSubList
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000400 syn region shDerefPPSright contained start='.' end='\ze}' contains=@shCommandSubList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000401endif
402
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000403" Useful sh Keywords: {{{1
404" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000405syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
406syn keyword shConditional contained elif else then
407syn keyword shCondError elif else then
408
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000409" Useful ksh Keywords: {{{1
410" ====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000412 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
413
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000414" Useful bash Keywords: {{{1
415" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000416 if exists("b:is_bash")
417 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source
418 else
419 syn keyword shStatement login newgrp
420 endif
421endif
422
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000423" Synchronization: {{{1
424" ================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000425if !exists("sh_minlines")
426 let sh_minlines = 200
427endif
428if !exists("sh_maxlines")
429 let sh_maxlines = 2 * sh_minlines
430endif
431exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
432syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
433syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
434syn sync match shDoSync grouphere shDo "\<do\>"
435syn sync match shDoSync groupthere shDo "\<done\>"
436syn sync match shForSync grouphere shFor "\<for\>"
437syn sync match shForSync groupthere shFor "\<in\>"
438syn sync match shIfSync grouphere shIf "\<if\>"
439syn sync match shIfSync groupthere shIf "\<fi\>"
440syn sync match shUntilSync grouphere shRepeat "\<until\>"
441syn sync match shWhileSync grouphere shRepeat "\<while\>"
442
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000443" Default Highlighting: {{{1
444" =====================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000445hi def link shArithRegion shShellVariables
Bram Moolenaardf177f62005-02-22 08:39:57 +0000446hi def link shBeginHere shRedir
Bram Moolenaar071d4272004-06-13 20:20:40 +0000447hi def link shCaseBar shConditional
Bram Moolenaar071d4272004-06-13 20:20:40 +0000448hi def link shCaseCommandSub shCommandSub
449hi def link shCaseDoubleQuote shDoubleQuote
Bram Moolenaardf177f62005-02-22 08:39:57 +0000450hi def link shCaseIn shConditional
Bram Moolenaar071d4272004-06-13 20:20:40 +0000451hi def link shCaseSingleQuote shSingleQuote
452hi def link shCaseStart shConditional
453hi def link shCmdSubRegion shShellVariables
454hi def link shColon shStatement
Bram Moolenaar071d4272004-06-13 20:20:40 +0000455hi def link shDerefOp shOperator
Bram Moolenaardf177f62005-02-22 08:39:57 +0000456hi def link shDerefPOL shDerefOp
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000457hi def link shDerefPPS shDerefOp
Bram Moolenaardf177f62005-02-22 08:39:57 +0000458hi def link shDeref shShellVariables
Bram Moolenaar071d4272004-06-13 20:20:40 +0000459hi def link shDerefSimple shDeref
460hi def link shDerefSpecial shDeref
461hi def link shDerefString shDoubleQuote
Bram Moolenaardf177f62005-02-22 08:39:57 +0000462hi def link shDerefVar shDeref
Bram Moolenaar071d4272004-06-13 20:20:40 +0000463hi def link shDoubleQuote shString
464hi def link shEcho shString
465hi def link shEmbeddedEcho shString
Bram Moolenaardf177f62005-02-22 08:39:57 +0000466hi def link shExSingleQuote shSingleQuote
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000467hi def link shFunctionStart Delimiter
Bram Moolenaar071d4272004-06-13 20:20:40 +0000468hi def link shHereDoc shString
Bram Moolenaardf177f62005-02-22 08:39:57 +0000469hi def link shHerePayload shHereDoc
Bram Moolenaar071d4272004-06-13 20:20:40 +0000470hi def link shLoop shStatement
471hi def link shOption shCommandSub
472hi def link shPattern shString
473hi def link shPosnParm shShellVariables
474hi def link shRange shOperator
475hi def link shRedir shOperator
476hi def link shSingleQuote shString
477hi def link shSource shOperator
478hi def link shStringSpecial shSpecial
479hi def link shSubShRegion shOperator
480hi def link shTestOpr shConditional
481hi def link shVariable shSetList
482hi def link shWrapLineOperator shOperator
483
484if exists("b:is_bash")
485 hi def link bashAdminStatement shStatement
486 hi def link bashSpecialVariables shShellVariables
487 hi def link bashStatement shStatement
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000488 hi def link shFunctionParen Delimiter
489 hi def link shFunctionDelim Delimiter
Bram Moolenaar071d4272004-06-13 20:20:40 +0000490endif
491if exists("b:is_kornshell")
492 hi def link kshSpecialVariables shShellVariables
493 hi def link kshStatement shStatement
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000494 hi def link shFunctionParen Delimiter
Bram Moolenaar071d4272004-06-13 20:20:40 +0000495endif
496
497hi def link shCaseError Error
498hi def link shCondError Error
499hi def link shCurlyError Error
500hi def link shDerefError Error
501hi def link shDerefOpError Error
502hi def link shDerefWordError Error
503hi def link shDoError Error
504hi def link shEsacError Error
505hi def link shIfError Error
506hi def link shInError Error
507hi def link shParenError Error
508hi def link shTestError Error
509if exists("b:is_kornshell")
510 hi def link shDTestError Error
511endif
512
513hi def link shArithmetic Special
514hi def link shCharClass Identifier
515hi def link shSnglCase Statement
516hi def link shCommandSub Special
517hi def link shComment Comment
518hi def link shConditional Conditional
519hi def link shExprRegion Delimiter
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000520hi def link shFunctionKey Function
Bram Moolenaar071d4272004-06-13 20:20:40 +0000521hi def link shFunctionName Function
522hi def link shNumber Number
523hi def link shOperator Operator
524hi def link shRepeat Repeat
525hi def link shSet Statement
526hi def link shSetList Identifier
527hi def link shShellVariables PreProc
528hi def link shSpecial Special
529hi def link shStatement Statement
530hi def link shString String
531hi def link shTodo Todo
532hi def link shAlias Identifier
533
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000534" Set Current Syntax: {{{1
535" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000536if exists("b:is_bash")
537 let b:current_syntax = "bash"
538elseif exists("b:is_kornshell")
539 let b:current_syntax = "ksh"
540else
541 let b:current_syntax = "sh"
542endif
543
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000544" vim: ts=16 fdm=marker