blob: 4add7921f3878e69e65c779dc739d554b44e9e75 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim syntax file
2" Language: shell (sh) Korn shell (ksh) bash (sh)
Christian Brabandtf9ca1392024-02-19 20:37:11 +01003" Maintainer: This runtime file is looking for a new maintainer.
4" Previous Maintainers: Charles E. Campbell
5" Lennart Schultz <Lennart.Schultz@ecmwf.int>
dkearns1bdc9432024-03-05 05:14:08 +11006" Last Change: 2024 Mar 04 by Vim Project
Aliaksei Budavei48fa3192024-12-30 10:23:50 +01007" 2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> (improved bracket expressions, #15941)
Christian Brabandt3159b642025-01-06 18:50:15 +01008" 2025 Jan 06 add $PS0 to bashSpecialVariables (#16394)
Eisuke Kawashima54cb5142025-01-18 10:11:28 +01009" 2025 Jan 18 add bash coproc, remove duplicate syn keywords (#16467)
Mohamed Akram51a06ec2025-03-21 17:52:08 +010010" 2025 Mar 21 update shell capability detection (#16939)
Doug Kearns6099db92025-04-03 21:13:39 +020011" 2025 Apr 03 command substitution opening paren at EOL (#17026)
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020012" 2025 Apr 10 improve shell detection (#17084)
Doug Kearnsf57c0652025-04-30 20:04:28 +020013" 2025 Apr 29 match escaped chars in test operands (#17221)
Doug Kearnsfe228672025-05-05 20:10:11 +020014" 2025 May 06 improve single-quote string matching in parameter expansions
Bram Moolenaar71badf92023-04-22 22:40:14 +010015" Version: 208
Christian Brabandtf9ca1392024-02-19 20:37:11 +010016" Former URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
Bram Moolenaare2719092015-01-10 15:09:25 +010017" For options and settings, please use: :help ft-sh-syntax
Bram Moolenaar23515b42020-11-29 14:36:24 +010018" This file includes many ideas from Eric Brunet (eric.brunet@ens.fr) and heredoc fixes from Felipe Contreras
Bram Moolenaar071d4272004-06-13 20:20:40 +000019
Bram Moolenaarf37506f2016-08-31 22:22:10 +020020" quit when a syntax file was already loaded {{{1
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020021if exists("b:current_syntax")
Bram Moolenaar071d4272004-06-13 20:20:40 +000022 finish
23endif
24
Mohamed Akram51a06ec2025-03-21 17:52:08 +010025" Ensure this is set unless we find another shell
26let b:is_sh = 1
27
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +020028" If the shell script itself specifies which shell to use, use it
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020029let s:shebang = getline(1)
30
31if s:shebang =~ '^#!.\{-2,}\<ksh\>'
Bram Moolenaar91c49372016-05-08 09:50:29 +020032 let b:is_kornshell = 1
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020033elseif s:shebang =~ '^#!.\{-2,}\<bash\>'
Bram Moolenaar91c49372016-05-08 09:50:29 +020034 let b:is_bash = 1
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020035elseif s:shebang =~ '^#!.\{-2,}\<dash\>'
Bram Moolenaard58a3bf2020-09-28 21:48:16 +020036 let b:is_dash = 1
Bram Moolenaard4755bb2004-09-02 19:12:26 +000037" handling /bin/sh with is_kornshell/is_sh {{{1
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +020038" b:is_sh will be set when "#! /bin/sh" is found;
Bram Moolenaar071d4272004-06-13 20:20:40 +000039" However, it often is just a masquerade by bash (typically Linux)
40" or kornshell (typically workstations with Posix "sh").
Mohamed Akram51a06ec2025-03-21 17:52:08 +010041" So, when the user sets "g:is_kornshell", "g:is_bash",
42" "g:is_posix" or "g:is_dash", a b:is_sh is converted into
43" b:is_kornshell/b:is_bash/b:is_posix/b:is_dash, respectively.
44elseif !exists("b:is_kornshell") && !exists("b:is_bash") && !exists("b:is_posix") && !exists("b:is_dash")
45 if exists("g:is_kornshell")
46 let b:is_kornshell= 1
47 elseif exists("g:is_bash")
48 let b:is_bash= 1
49 elseif exists("g:is_dash")
50 let b:is_dash= 1
51 elseif exists("g:is_posix")
52 let b:is_posix= 1
53 elseif exists("g:is_sh")
54 let b:is_sh= 1
55 else
56 " user did not specify which shell to use, and
57 " the script itself does not specify which shell to use. FYI: /bin/sh is ambiguous.
58 " Assuming /bin/sh is executable, and if its a link, find out what it links to.
59 let s:shell = ""
60 if executable("/bin/sh")
61 let s:shell = resolve("/bin/sh")
62 elseif executable("/usr/bin/sh")
63 let s:shell = resolve("/usr/bin/sh")
Bram Moolenaar7fc904b2006-04-13 20:37:35 +000064 endif
Mohamed Akram51a06ec2025-03-21 17:52:08 +010065 if s:shell =~ '\<ksh\>'
66 let b:is_kornshell= 1
67 elseif s:shell =~ '\<bash\>'
68 let b:is_bash = 1
69 elseif s:shell =~ '\<dash\>'
70 let b:is_dash = 1
Bram Moolenaar071d4272004-06-13 20:20:40 +000071 else
Mohamed Akram51a06ec2025-03-21 17:52:08 +010072 let b:is_posix = 1
Bram Moolenaar071d4272004-06-13 20:20:40 +000073 endif
Mohamed Akram51a06ec2025-03-21 17:52:08 +010074 unlet s:shell
75 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000076endif
77
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020078unlet s:shebang
79
Bram Moolenaard58a3bf2020-09-28 21:48:16 +020080" if b:is_dash, set b:is_posix too
81if exists("b:is_dash")
82 let b:is_posix= 1
83endif
84
Mohamed Akram51a06ec2025-03-21 17:52:08 +010085if exists("b:is_kornshell") || exists("b:is_bash")
86 if exists("b:is_sh")
87 unlet b:is_sh
88 endif
89endif
90
Bram Moolenaarcd71fa32005-03-11 22:46:48 +000091" set up default g:sh_fold_enabled {{{1
Bram Moolenaarb4ff5182015-11-10 21:15:48 +010092" ================================
Bram Moolenaar071d4272004-06-13 20:20:40 +000093if !exists("g:sh_fold_enabled")
94 let g:sh_fold_enabled= 0
Bram Moolenaar293ee4d2004-12-09 21:34:53 +000095elseif g:sh_fold_enabled != 0 && !has("folding")
96 let g:sh_fold_enabled= 0
Bram Moolenaarcd71fa32005-03-11 22:46:48 +000097 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
98endif
Bram Moolenaar86b48162022-12-06 18:20:10 +000099let s:sh_fold_functions= and(g:sh_fold_enabled,1)
100let s:sh_fold_heredoc = and(g:sh_fold_enabled,2)
101let s:sh_fold_ifdofor = and(g:sh_fold_enabled,4)
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000102if g:sh_fold_enabled && &fdm == "manual"
Bram Moolenaar97d62492012-11-15 21:28:22 +0100103 " Given that the user provided g:sh_fold_enabled
104 " AND g:sh_fold_enabled is manual (usual default)
105 " implies a desire for syntax-based folding
106 setl fdm=syntax
Bram Moolenaar071d4272004-06-13 20:20:40 +0000107endif
108
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200109" set up the syntax-highlighting for iskeyword
Bram Moolenaar723dd942019-04-04 13:11:03 +0200110if (v:version == 704 && has("patch-7.4.1142")) || v:version > 704
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200111 if !exists("g:sh_syntax_isk") || (exists("g:sh_syntax_isk") && g:sh_syntax_isk)
112 if exists("b:is_bash")
113 exe "syn iskeyword ".&iskeyword.",-,:"
114 else
115 exe "syn iskeyword ".&iskeyword.",-"
116 endif
Bram Moolenaar91c49372016-05-08 09:50:29 +0200117 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +0100118endif
119
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100120" Set up folding commands for shell {{{1
121" =================================
Bram Moolenaar86b48162022-12-06 18:20:10 +0000122sil! delc ShFoldFunctions
123sil! delc ShFoldHereDoc
124sil! delc ShFoldIfDoFor
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100125if s:sh_fold_functions
126 com! -nargs=* ShFoldFunctions <args> fold
127else
128 com! -nargs=* ShFoldFunctions <args>
129endif
130if s:sh_fold_heredoc
131 com! -nargs=* ShFoldHereDoc <args> fold
132else
133 com! -nargs=* ShFoldHereDoc <args>
134endif
135if s:sh_fold_ifdofor
136 com! -nargs=* ShFoldIfDoFor <args> fold
137else
138 com! -nargs=* ShFoldIfDoFor <args>
139endif
140
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100141" Generate bracket expression items {{{1
142" =================================
143" Note that the following function can be invoked as many times as necessary
144" provided that these constraints hold for the passed dictionary argument:
145" - every time a unique group-name value is assigned to the "itemGroup" key;
146" - only ONCE either the "extraArgs" key is not entered or it is entered and
147" its value does not have "contained" among other optional arguments (":help
148" :syn-arguments").
149fun! s:GenerateBracketExpressionItems(dict) abort
150 let itemGroup = a:dict.itemGroup
151 let bracketGroup = a:dict.bracketGroup
152 let invGroup = itemGroup . 'Inv'
153 let skipLeftBracketGroup = itemGroup . 'SkipLeftBracket'
154 let skipRightBracketGroup = itemGroup . 'SkipRightBracket'
155 let extraArgs = has_key(a:dict, 'extraArgs') ? a:dict.extraArgs : ''
156
157 " Make the leading "[!^]" stand out in a NON-matching expression.
158 exec 'syn match ' . invGroup . ' contained "\[\@<=[!^]"'
159
160 " Set up indirections for unbalanced-bracket highlighting.
161 exec 'syn region ' . skipRightBracketGroup . ' contained matchgroup=' . bracketGroup . ' start="\[\%([!^]\=\\\=\]\)\@=" matchgroup=shCollSymb end="\[\.[^]]\{-}\][^]]\{-}\.\]" matchgroup=' . itemGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . invGroup
162 exec 'syn region ' . skipLeftBracketGroup . ' contained matchgroup=' . bracketGroup . ' start="\[\%([!^]\=\\\=\]\)\@=" skip="[!^]\=\\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\%(\[[:.=]\@!\)\@=" matchgroup=' . itemGroup . ' end="\[[:.=]\@!" contains=@shBracketExprList,shDoubleQuote,' . invGroup
163
164 " Look for a general matching expression.
165 exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' start="\[\S\@=" end="\]" contains=@shBracketExprList,shDoubleQuote ' . extraArgs
166 " Look for a general NON-matching expression.
167 exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' start="\[[!^]\@=" end="\]" contains=@shBracketExprList,shDoubleQuote,' . invGroup . ' ' . extraArgs
168
169 " Accommodate unbalanced brackets in bracket expressions. The supported
170 " syntax for a plain "]" can be: "[]ws]" and "[^]ws]"; or, "[ws[.xs]ys.]zs]"
171 " and "[^ws[.xs]ys.]zs]"; see §9.3.5 RE Bracket Expression (in XBD).
172 exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\\=\]" matchgroup=' . bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . skipRightBracketGroup . ' ' . extraArgs
173 " Strive to handle "[]...[]" etc.
174 exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\[[:.=]\@!" matchgroup=' . bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . skipLeftBracketGroup . ' ' . extraArgs
175
176 if !exists("g:skip_sh_syntax_inits")
177 exec 'hi def link ' . skipLeftBracketGroup . ' ' . itemGroup
178 exec 'hi def link ' . skipRightBracketGroup . ' ' . itemGroup
179 exec 'hi def link ' . invGroup . ' Underlined'
180 endif
181endfun
182
183call s:GenerateBracketExpressionItems({'itemGroup': 'shBracketExpr', 'bracketGroup': 'shBracketExprDelim'})
184
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000185" sh syntax is case sensitive {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000186syn case match
187
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000188" Clusters: contains=@... clusters {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000189"==================================
Bram Moolenaar5c736222010-01-06 20:54:52 +0100190syn cluster shErrorList contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError,shOK
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200191if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000192 syn cluster ErrorList add=shDTestError
193endif
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100194syn cluster shArithParenList contains=shArithmetic,shArithParen,shCaseEsac,shComment,shDeref,shDerefVarArray,shDo,shDerefSimple,shEcho,shEscape,shExpr,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
Bram Moolenaarc236c162008-07-13 17:41:49 +0000195syn cluster shArithList contains=@shArithParenList,shParenError
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100196syn cluster shBracketExprList contains=shCharClassOther,shCharClass,shCollSymb,shEqClass
Bram Moolenaard2855f52018-07-31 22:23:58 +0200197syn cluster shCaseEsacList contains=shCaseStart,shCaseLabel,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800198syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shComment,shDblBrace,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
Bram Moolenaar23515b42020-11-29 14:36:24 +0100199if exists("b:is_kornshell") || exists("b:is_bash")
Lucien Grondin1858e2b2023-11-02 20:33:56 +0100200 syn cluster shCaseList add=shForPP,shDblParen
Bram Moolenaar23515b42020-11-29 14:36:24 +0100201endif
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100202syn cluster shCommandSubList contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
Bram Moolenaar572cb562005-08-05 21:35:02 +0000203syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100204" COMBAK: removing shEscape from shDblQuoteList fails ksh04:43 -- Jun 09, 2022: I don't see the problem with ksh04, so am reinstating shEscape
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800205syn cluster shDblQuoteList contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
Bram Moolenaaracb4f222016-01-10 15:59:26 +0100206syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200207syn cluster shDerefVarList contains=shDerefOffset,shDerefOp,shDerefVarArray,shDerefOpError
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100208syn cluster shEchoList contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
209syn cluster shExprList1 contains=shBracketExpr,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000210syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100211syn cluster shFunctionList contains=shBracketExpr,@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
Bram Moolenaar7263a772007-05-10 17:35:54 +0000212if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaar23515b42020-11-29 14:36:24 +0100213 syn cluster shFunctionList add=shRepeat,shDblBrace,shDblParen,shForPP
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100214 syn cluster shDerefList add=shCommandSubList,shEchoDeref
Bram Moolenaar7263a772007-05-10 17:35:54 +0000215endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000216syn cluster shHereBeginList contains=@shCommandSubList
217syn cluster shHereList contains=shBeginHere,shHerePayload
218syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100219syn cluster shIdList contains=shArithmetic,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200220syn cluster shIfList contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
Bram Moolenaar23515b42020-11-29 14:36:24 +0100221syn cluster shLoopList contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shIf,shOption,shSet,shTest,shTestOpr,shTouch
222if exists("b:is_kornshell") || exists("b:is_bash")
Lucien Grondina390e982023-10-28 21:40:48 +0200223 syn cluster shLoopList add=shForPP,shDblParen
Bram Moolenaar23515b42020-11-29 14:36:24 +0100224endif
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100225syn cluster shPPSLeftList contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
Bram Moolenaardd60c362023-02-27 15:49:53 +0000226syn cluster shPPSRightList contains=shDeref,shDerefSimple,shEscape,shPosnParm
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100227syn cluster shSubShList contains=shBracketExpr,@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
228syn cluster shTestList contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100229syn cluster shNoZSList contains=shSpecialNoZS
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800230syn cluster shForList contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shArithmetic
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100231
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000232" Echo: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000233" ====
234" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800235if exists("b:is_kornshell")
236 syn region shEcho matchgroup=shStatement start="\<echo\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`}]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 end="\ze[ \t\n;]}" contains=@shEchoList skipwhite nextgroup=shQuickComment
237 syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`}]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 end="\ze[ \t\n;]}" contains=@shEchoList skipwhite nextgroup=shQuickComment
238else
239 syn region shEcho matchgroup=shStatement start="\<echo\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
240 syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|()`]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
241endif
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100242if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
243 syn region shEchoDeref contained matchgroup=shStatement start="\<echo\>" skip="\\$" matchgroup=shEchoDelim end="$" end="[<>;&|()`}]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
244 syn region shEchoDeref contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" end="[<>;&|()`}]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList skipwhite nextgroup=shQuickComment
245endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100246syn match shEchoQuote contained '\%(\\\\\)*\\["`'()]'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000247
Bram Moolenaarc236c162008-07-13 17:41:49 +0000248" This must be after the strings, so that ... \" will be correct
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100249syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=shBracketExpr,shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shExDoubleQuote,shDoubleQuote,shCtrlSeq
Bram Moolenaar071d4272004-06-13 20:20:40 +0000250
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000251" Alias: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000252" =====
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200253if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000254 syn match shStatement "\<alias\>"
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000255 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*\)\@=" skip="\\$" end="\>\|`"
256 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*=\)\@=" skip="\\$" end="="
257" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+\)\@=" skip="\\$" end="\>\|`"
258" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+=\)\@=" skip="\\$" end="="
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100259
260 " Touch: {{{1
261 " =====
Bram Moolenaar6d5ad4c2016-10-27 17:00:16 +0200262 syn match shTouch '\<touch\>[^;#]*' skipwhite nextgroup=shComment contains=shTouchCmd,shDoubleQuote,shSingleQuote,shDeref,shDerefSimple
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100263 syn match shTouchCmd '\<touch\>' contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000264endif
265
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000266" Error Codes: {{{1
267" ============
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100268if !exists("g:sh_no_error")
Bram Moolenaare2719092015-01-10 15:09:25 +0100269 syn match shDoError "\<done\>"
270 syn match shIfError "\<fi\>"
271 syn match shInError "\<in\>"
272 syn match shCaseError ";;"
273 syn match shEsacError "\<esac\>"
274 syn match shCurlyError "}"
275 syn match shParenError ")"
276 syn match shOK '\.\(done\|fi\|in\|esac\)'
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200277 if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaare2719092015-01-10 15:09:25 +0100278 syn match shDTestError "]]"
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100279 endif
Bram Moolenaare2719092015-01-10 15:09:25 +0100280 syn match shTestError "]"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000281endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000282
Bram Moolenaarc236c162008-07-13 17:41:49 +0000283" Options: {{{1
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000284" ====================
Bram Moolenaar7db8f6f2016-03-29 23:12:46 +0200285syn match shOption "\s\zs[-+][-_a-zA-Z#@]\+"
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100286syn match shOption "\s\zs--[^ \t$=`'"|);]\+"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000287
Bram Moolenaar7263a772007-05-10 17:35:54 +0000288" File Redirection Highlighted As Operators: {{{1
289"===========================================
290syn match shRedir "\d\=>\(&[-0-9]\)\="
291syn match shRedir "\d\=>>-\="
292syn match shRedir "\d\=<\(&[-0-9]\)\="
293syn match shRedir "\d<<-\="
294
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000295" Operators: {{{1
296" ==========
Bram Moolenaar7263a772007-05-10 17:35:54 +0000297syn match shOperator "<<\|>>" contained
Bram Moolenaarc236c162008-07-13 17:41:49 +0000298syn match shOperator "[!&;|]" contained
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200299syn match shOperator "[-=/*+%]\==" skipwhite nextgroup=shPattern
Bram Moolenaare90ee312010-08-05 22:08:47 +0200300syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shExDoubleQuote,shDoubleQuote,shDeref
Bram Moolenaar071d4272004-06-13 20:20:40 +0000301
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000302" Subshells: {{{1
303" ==========
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200304syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 nextgroup=shSpecialNxt
305syn region shSubSh transparent matchgroup=shSubShRegion start="[^(]\zs(" end=")" contains=@shSubShList nextgroup=shSpecialNxt
Bram Moolenaar071d4272004-06-13 20:20:40 +0000306
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000307" Tests: {{{1
308"=======
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100309syn region shExpr matchgroup=shRange start="\[\s\@=" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
Bram Moolenaar5c736222010-01-06 20:54:52 +0100310syn region shTest transparent matchgroup=shStatement start="\<test\s" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
Doug Kearnsf57c0652025-04-30 20:04:28 +0200311syn region shNoQuote start='\S' skip='\%(\\\\\)*\\.' end='\ze\s' end="\ze['"]" contained contains=shBracketExpr,shDerefSimple,shDeref,shEscape
Bram Moolenaar91c49372016-05-08 09:50:29 +0200312syn match shAstQuote contained '\*\ze"' nextgroup=shString
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200313syn match shTestOpr contained '[^-+/%]\zs=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100314syn match shTestOpr contained "<=\|>=\|!=\|==\|=\~\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
Bram Moolenaar9964e462007-05-05 17:54:07 +0000315syn match shTestPattern contained '\w\+'
Bram Moolenaar91c49372016-05-08 09:50:29 +0200316syn region shTestDoubleQuote contained start='\%(\%(\\\\\)*\\\)\@<!"' skip=+\\\\\|\\"+ end='"' contains=shDeref,shDerefSimple,shDerefSpecial
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100317syn match shTestSingleQuote contained '\\.' nextgroup=shTestSingleQuote
Bram Moolenaar9964e462007-05-05 17:54:07 +0000318syn match shTestSingleQuote contained "'[^']*'"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000319if exists("b:is_kornshell") || exists("b:is_bash")
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100320 syn region shDblBrace matchgroup=Delimiter start="\[\[\s\@=" skip=+\%(\\\\\)*\\$+ end="\]\]" contains=@shTestList,shAstQuote,shNoQuote,shComment
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100321 syn region shDblParen matchgroup=Delimiter start="((" skip=+\%(\\\\\)*\\$+ end="))" contains=@shTestList,shComment
Bram Moolenaar071d4272004-06-13 20:20:40 +0000322endif
323
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000324" Character Class In Range: {{{1
325" =========================
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100326syn match shCharClassOther contained "\[:\w\{-}:\]"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000327syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100328syn match shCollSymb contained "\[\..\{-}\.\]"
329syn match shEqClass contained "\[=.\{-}=\]"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000330
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000331" Loops: do, if, while, until {{{1
332" ======
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100333ShFoldIfDoFor syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
334ShFoldIfDoFor syn region shIf transparent matchgroup=shConditional start="\<if\_s" matchgroup=shConditional skip=+-fi\>+ end="\<;\_s*then\>" end="\<fi\>" contains=@shIfList
335ShFoldIfDoFor syn region shFor matchgroup=shLoop start="\<for\ze\_s\s*\%(((\)\@!" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn
Bram Moolenaar23515b42020-11-29 14:36:24 +0100336if exists("b:is_kornshell") || exists("b:is_bash")
337 ShFoldIfDoFor syn region shForPP matchgroup=shLoop start='\<for\>\_s*((' end='))' contains=@shForList
338endif
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100339
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200340if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000341 syn cluster shCaseList add=shRepeat
342 syn cluster shFunctionList add=shRepeat
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200343 syn region shRepeat matchgroup=shLoop start="\<while\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
344 syn region shRepeat matchgroup=shLoop start="\<until\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
345 if !exists("b:is_posix")
346 syn region shCaseEsac matchgroup=shConditional start="\<select\s" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
347 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000348else
Bram Moolenaarc236c162008-07-13 17:41:49 +0000349 syn region shRepeat matchgroup=shLoop start="\<while\_s" end="\<do\>"me=e-2 contains=@shLoopList
350 syn region shRepeat matchgroup=shLoop start="\<until\_s" end="\<do\>"me=e-2 contains=@shLoopList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000351endif
Bram Moolenaar572cb562005-08-05 21:35:02 +0000352syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
353syn match shComma contained ","
Bram Moolenaar071d4272004-06-13 20:20:40 +0000354
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000355" Case: case...esac {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000356" ====
Bram Moolenaard2855f52018-07-31 22:23:58 +0200357syn match shCaseBar contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|" nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
358syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100359syn match shCaseLabel contained skipwhite "\%(\\.\|[-a-zA-Z0-9_*.]\)\+" contains=shBracketExpr
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100360if exists("b:is_bash")
Bram Moolenaard2855f52018-07-31 22:23:58 +0200361 ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end=";&" end=";;&" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100362elseif exists("b:is_kornshell")
363 ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end=";&" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100364else
Bram Moolenaard2855f52018-07-31 22:23:58 +0200365 ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100366endif
Bram Moolenaard2855f52018-07-31 22:23:58 +0200367ShFoldIfDoFor syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100368
Bram Moolenaardf177f62005-02-22 08:39:57 +0000369syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100370if exists("b:is_bash") || exists("b:is_kornshell")
Bram Moolenaar4b22cdb2010-08-02 22:12:46 +0200371 syn region shCaseExSingleQuote matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100372elseif !exists("g:sh_no_error")
Bram Moolenaardf177f62005-02-22 08:39:57 +0000373 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
374endif
Bram Moolenaar4b22cdb2010-08-02 22:12:46 +0200375syn region shCaseSingleQuote matchgroup=shQuote start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
376syn region shCaseDoubleQuote matchgroup=shQuote start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000377syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100378call s:GenerateBracketExpressionItems({'itemGroup': 'shCaseRange', 'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'skip=+\\\\+ contained'})
Bram Moolenaar97d62492012-11-15 21:28:22 +0100379if exists("b:is_bash")
Bram Moolenaar97d62492012-11-15 21:28:22 +0100380 syn match shCharClass '\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|or\|xdigit\):\]' contained
Bram Moolenaar97d62492012-11-15 21:28:22 +0100381endif
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000382" Misc: {{{1
383"======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000384syn match shWrapLineOperator "\\$"
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200385syn region shCommandSubBQ start="`" skip="\\\\\|\\." end="`" contains=shBQComment,@shCommandSubList
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100386"COMBAK: see ksh13:50
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100387"syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shSingleQuote,shDoubleQuote,shComment
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100388"COMBAK: see sh11:27
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100389syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shComment
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100390"COMBAK: see ksh13:53
391"syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000393" $() and $(()): {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000394" $(..) is not supported by sh (Bourne shell). However, apparently
395" some systems (HP?) have as their /bin/sh a (link to) Korn shell
396" (ie. Posix compliant shell). /bin/ksh should work for those
397" systems too, however, so the following syntax will flag $(..) as
398" an Error under /bin/sh. By consensus of vimdev'ers!
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100399if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
Doug Kearns6099db92025-04-03 21:13:39 +0200400 syn region shCommandSub matchgroup=shCmdSubRegion start="\$((\@!" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800401 if exists("b:is_kornshell")
402 syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[ \t\n<]" skip='\\\\\|\\.' end="\zs[ \t\n;]}" contains=@shCommandSubList
403 syn region shValsub matchgroup=shCmdSubRegion start="\${|" skip='\\\\\|\\.' end="}" contains=@shCommandSubList
404 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +0000405 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
Bram Moolenaar61d35bd2012-03-28 20:51:51 +0200406 syn region shArithmetic matchgroup=shArithRegion start="\$\[" skip='\\\\\|\\.' end="\]" contains=@shArithList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000407 syn match shSkipInitWS contained "^\s\+"
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100408 syn region shArithParen matchgroup=shArithRegion contained start="(" end=")" contains=@shArithParenList
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100409elseif !exists("g:sh_no_error")
Bram Moolenaardf177f62005-02-22 08:39:57 +0000410 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411endif
dkearns1bdc9432024-03-05 05:14:08 +1100412syn region shCmdParenRegion matchgroup=shCmdSubRegion start="((\@!" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000413
414if exists("b:is_bash")
415 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
416 syn cluster shCaseList add=bashAdminStatement,bashStatement
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100417 syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING BASH_LINENO BASHOPTS BASHPID BASH_REMATCH BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION BASH_XTRACEFD CDPATH COLUMNS COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS COPROC COPROC_PID DIRSTACK EMACS ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNEST GLOBIGNORE GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LINENO LINES MACHTYPE MAIL MAILCHECK MAILPATH MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS POSIXLY_CORRECT PPID PROMPT_COMMAND PS0 PS1 PS2 PS3 PS4 PWD RANDOM READLINE_LINE READLINE_POINT REPLY SECONDS SHELL SHELLOPTS SHLVL TIMEFORMAT TIMEOUT TMPDIR UID
Bram Moolenaar5ed11532022-07-06 13:18:11 +0100418 syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep head less ls mkdir mv rm rmdir rpm sed sleep sort strip tail
Bram Moolenaar071d4272004-06-13 20:20:40 +0000419 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
Bram Moolenaar97d62492012-11-15 21:28:22 +0100420 syn keyword bashStatement command compgen
Bram Moolenaar071d4272004-06-13 20:20:40 +0000421endif
422
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200423if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000424 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
425 syn cluster shCaseList add=kshStatement
426 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
Bram Moolenaar5ed11532022-07-06 13:18:11 +0100427 syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep head killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail tput
Bram Moolenaar97d62492012-11-15 21:28:22 +0100428 syn keyword kshStatement command setgroups setsenv
Bram Moolenaar071d4272004-06-13 20:20:40 +0000429endif
430
431syn match shSource "^\.\s"
432syn match shSource "\s\.\s"
Bram Moolenaar5c736222010-01-06 20:54:52 +0100433"syn region shColon start="^\s*:" end="$" end="\s#"me=e-2 contains=@shColonList
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100434"syn region shColon start="^\s*\zs:" end="$" end="\s#"me=e-2
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200435if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaar91c49372016-05-08 09:50:29 +0200436 syn match shColon '^\s*\zs:'
437endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000438
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000439" String And Character Constants: {{{1
440"================================
Bram Moolenaar7db8f6f2016-03-29 23:12:46 +0200441syn match shNumber "\<\d\+\>#\="
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200442syn match shNumber "\<-\=\.\=\d\+\>#\="
Bram Moolenaar802a0d92016-06-26 16:17:58 +0200443syn match shCtrlSeq "\\\d\d\d\|\\[abcfnrtv0]" contained
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100444if exists("b:is_bash") || exists("b:is_kornshell")
Bram Moolenaar802a0d92016-06-26 16:17:58 +0200445 syn match shSpecial "[^\\]\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]" contained
446 syn match shSpecial "^\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]" contained
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200447 syn region shExSingleQuote matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial nextgroup=shSpecialNxt
448 syn region shExDoubleQuote matchgroup=shQuote start=+\$"+ skip=+\\\\\|\\.\|\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,shSpecial nextgroup=shSpecialNxt
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100449elseif !exists("g:sh_no_error")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000450 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial
Bram Moolenaare90ee312010-08-05 22:08:47 +0200451 syn region shExDoubleQuote matchGroup=Error start=+\$"+ skip=+\\\\\|\\.+ end=+"+ contains=shStringSpecial
Bram Moolenaardf177f62005-02-22 08:39:57 +0000452endif
Bram Moolenaard2855f52018-07-31 22:23:58 +0200453syn region shSingleQuote matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart,shSpecialSQ
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200454syn region shDoubleQuote matchgroup=shQuote start=+\%(\%(\\\\\)*\\\)\@<!"+ skip=+\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
Bram Moolenaar802a0d92016-06-26 16:17:58 +0200455syn match shStringSpecial "[^[:print:] \t]" contained
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200456syn match shStringSpecial "[^\\]\zs\%(\\\\\)*\(\\[\\"'`$()#]\)\+" nextgroup=shComment
457syn match shSpecialSQ "[^\\]\zs\%(\\\\\)*\(\\[\\"'`$()#]\)\+" contained nextgroup=shBkslshSnglQuote,@shNoZSList
458syn match shSpecialDQ "[^\\]\zs\%(\\\\\)*\(\\[\\"'`$()#]\)\+" contained nextgroup=shBkslshDblQuote,@shNoZSList
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200459syn match shSpecialStart "\%(\\\\\)*\\[\\"'`$()#]" contained nextgroup=shBkslshSnglQuote,shBkslshDblQuote,@shNoZSList
Bram Moolenaar60cce2f2015-10-13 23:21:27 +0200460syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100461syn match shSpecialNoZS contained "\%(\\\\\)*\\[\\"'`$()#]"
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200462syn match shSpecialNxt contained "\\[\\"'`$()#]"
Bram Moolenaar47e13952020-05-12 22:49:12 +0200463"syn region shBkslshSnglQuote contained matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart
464"syn region shBkslshDblQuote contained matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
Bram Moolenaar071d4272004-06-13 20:20:40 +0000465
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000466" Comments: {{{1
467"==========
Bram Moolenaar5c736222010-01-06 20:54:52 +0100468syn cluster shCommentGroup contains=shTodo,@Spell
Bram Moolenaar6d5ad4c2016-10-27 17:00:16 +0200469if exists("b:is_bash")
470 syn match shTodo contained "\<\%(COMBAK\|FIXME\|TODO\|XXX\)\ze:\=\>"
471else
472 syn keyword shTodo contained COMBAK FIXME TODO XXX
473endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100474syn match shComment "^\s*\zs#.*$" contains=@shCommentGroup
475syn match shComment "\s\zs#.*$" contains=@shCommentGroup
Bram Moolenaar97d62492012-11-15 21:28:22 +0100476syn match shComment contained "#.*$" contains=@shCommentGroup
Bram Moolenaar113cb512021-11-07 20:27:04 +0000477syn match shQuickComment contained "#.*$" contains=@shCommentGroup
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200478syn match shBQComment contained "#.\{-}\ze`" contains=@shCommentGroup
Bram Moolenaar071d4272004-06-13 20:20:40 +0000479
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000480" Here Documents: {{{1
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200481" (modified by Felipe Contreras)
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000482" =========================================
Bram Moolenaar86b48162022-12-06 18:20:10 +0000483ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc01 start="<<\s*\z([^ \t|>]\+\)" matchgroup=shHereDoc01 end="^\z1$" contains=@shDblQuoteList
Bram Moolenaar71badf92023-04-22 22:40:14 +0100484ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc02 start="<<-\s*\z([^ \t|>]\+\)" matchgroup=shHereDoc02 end="^\t*\z1$" contains=@shDblQuoteList
Bram Moolenaar86b48162022-12-06 18:20:10 +0000485ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc03 start="<<\s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc03 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100486ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc04 start="<<-\s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc04 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000487ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc05 start="<<\s*'\z([^']\+\)'" matchgroup=shHereDoc05 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100488ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*'\z([^']\+\)'" matchgroup=shHereDoc06 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000489ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc07 start="<<\s*\"\z([^"]\+\)\"" matchgroup=shHereDoc07 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100490ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc08 start="<<-\s*\"\z([^"]\+\)\"" matchgroup=shHereDoc08 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000491ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc09 start="<<\s*\\\_$\_s*\z([^ \t|>]\+\)" matchgroup=shHereDoc09 end="^\z1$" contains=@shDblQuoteList
Bram Moolenaar71badf92023-04-22 22:40:14 +0100492ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t|>]\+\)" matchgroup=shHereDoc10 end="^\t*\z1$" contains=@shDblQuoteList
Bram Moolenaar86b48162022-12-06 18:20:10 +0000493ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<\s*\\\_$\_s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc11 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100494ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc12 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000495ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<\s*\\\_$\_s*'\z([^']\+\)'" matchgroup=shHereDoc13 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100496ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc14 start="<<-\s*\\\_$\_s*'\z([^']\+\)'" matchgroup=shHereDoc14 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000497ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc15 start="<<\s*\\\_$\_s*\"\z([^"]\+\)\"" matchgroup=shHereDoc15 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100498ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc16 start="<<-\s*\\\_$\_s*\"\z([^"]\+\)\"" matchgroup=shHereDoc16 end="^\t*\z1$"
Bram Moolenaar23515b42020-11-29 14:36:24 +0100499
Bram Moolenaar071d4272004-06-13 20:20:40 +0000500
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000501" Here Strings: {{{1
502" =============
Bram Moolenaar6d5ad4c2016-10-27 17:00:16 +0200503" available for: bash; ksh (really should be ksh93 only) but not if its a posix
Bram Moolenaar690afe12017-01-28 18:34:47 +0100504if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_posix"))
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200505 syn match shHereString "<<<" skipwhite nextgroup=shCmdParenRegion
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000506endif
507
508" Identifiers: {{{1
509"=============
Bram Moolenaarc236c162008-07-13 17:41:49 +0000510syn match shSetOption "\s\zs[-+][a-zA-Z0-9]\+\>" contained
Bram Moolenaar23515b42020-11-29 14:36:24 +0100511syn match shVariable "\<\h\w*\ze=" nextgroup=shVarAssign
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100512if exists("b:is_bash")
513 " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
514 syn region shArrayValue contained start="\[\%(..\{-}\]=\)\@=" end="\]=\@=" contains=@shArrayValueList nextgroup=shVarAssign
515 syn cluster shArrayValueList contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,bashSpecialVariables,shParenError
516endif
517if exists("b:is_bash") || exists("b:is_kornshell")
518 syn match shVariable "\<\h\w*\%(\[..\{-}\]\)\=\ze\%([|^&*/%+-]\|[<^]<\|[>^]>\)\==" contains=shDerefVarArray nextgroup=shVarAssign
519 syn match shVarAssign contained "\%([|^&*/%+-]\|[<^]<\|[>^]>\)\==" nextgroup=shArrayRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
520 syn region shArrayRegion contained matchgroup=shShellVariables start="(" skip='\\\\\|\\.' end=")" contains=@shArrayValueList,shArrayValue,shComment
521else
522 syn match shVarAssign contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
523endif
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100524syn match shVar contained "\h\w*"
Bram Moolenaarbc488a72013-07-05 21:01:22 +0200525syn region shAtExpr contained start="@(" end=")" contains=@shIdList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000526if exists("b:is_bash")
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100527 syn match shSet "^\s*set\ze\s\+$"
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100528 syn region shSetList oneline matchgroup=shSet start="\<\%(declare\|local\|export\)\>\ze[/a-zA-Z_]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|=" contains=@shIdList
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100529 syn region shSetList oneline matchgroup=shSet start="\<\%(set\|unset\)\>[/a-zA-Z_]\@!" end="\ze[;|#)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+=" contains=@shIdList nextgroup=shComment
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200530elseif exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100531 syn match shSet "^\s*set\ze\s\+$"
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200532 if exists("b:is_dash")
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100533 syn region shSetList oneline matchgroup=shSet start="\<\%(local\)\>\ze[/]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200534 endif
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100535 syn region shSetList oneline matchgroup=shSet start="\<\(export\)\>\ze[/]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100536 syn region shSetList oneline matchgroup=shSet start="\<\%(set\|unset\>\)\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList nextgroup=shComment
Bram Moolenaar071d4272004-06-13 20:20:40 +0000537else
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100538 syn region shSetList oneline matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000539endif
540
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100541" KornShell namespace: {{{1
542if exists("b:is_kornshell")
543 syn keyword shFunctionKey namespace skipwhite skipnl nextgroup=shFunctionTwo
544endif
545
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000546" Functions: {{{1
Bram Moolenaar690afe12017-01-28 18:34:47 +0100547if !exists("b:is_posix")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000548 syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
549endif
550
551if exists("b:is_bash")
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100552 syn keyword shFunctionKey coproc
Bram Moolenaar91c49372016-05-08 09:50:29 +0200553 ShFoldFunctions syn region shFunctionOne matchgroup=shFunction start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
554 ShFoldFunctions syn region shFunctionTwo matchgroup=shFunction start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
555 ShFoldFunctions syn region shFunctionThree matchgroup=shFunction start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*(" end=")" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
556 ShFoldFunctions syn region shFunctionFour matchgroup=shFunction start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*)" end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
Bram Moolenaar071d4272004-06-13 20:20:40 +0000557else
Bram Moolenaar91c49372016-05-08 09:50:29 +0200558 ShFoldFunctions syn region shFunctionOne matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
559 ShFoldFunctions syn region shFunctionTwo matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
560 ShFoldFunctions syn region shFunctionThree matchgroup=shFunction start="^\s*\h\w*\s*()\_s*(" end=")" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
561 ShFoldFunctions syn region shFunctionFour matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*(" end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
Bram Moolenaar071d4272004-06-13 20:20:40 +0000562endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000563
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000564" Parameter Dereferencing: {{{1
565" ========================
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000566" Note: sh04 failure with following line
567"if !exists("g:sh_no_error") && !(exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix"))
568if !exists("g:sh_no_error")
Bram Moolenaar91c49372016-05-08 09:50:29 +0200569 syn match shDerefWordError "[^}$[~]" contained
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100570endif
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100571syn match shDerefSimple "\$\%(\h\w*\|\d\)" nextgroup=@shNoZSList
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800572if exists("b:is_kornshell")
573 syn region shDeref matchgroup=PreProc start="\${\ze[^ \t\n<|]" end="}" contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
574else
575 syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
576endif
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100577syn match shDerefSimple "\$[-#*@!?]" nextgroup=@shNoZSList
578syn match shDerefSimple "\$\$" nextgroup=@shNoZSList
Bram Moolenaar47e13952020-05-12 22:49:12 +0200579syn match shDerefSimple "\${\d}" nextgroup=@shNoZSList nextgroup=shSpecialStart
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200580if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaar47e13952020-05-12 22:49:12 +0200581 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList nextgroup=@shSpecialNoZS,shSpecialStart
582 syn region shDeref matchgroup=PreProc start="\${\$\$" end="}" contains=@shDerefList nextgroup=@shSpecialNoZS,shSpecialStart
Bram Moolenaar071d4272004-06-13 20:20:40 +0000583endif
584
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100585" ksh: ${.sh.*} variables: {{{1
586" ========================================
587if exists("b:is_kornshell")
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100588 syn match shDerefVar contained "\.\+" nextgroup=@shDerefVarList
589endif
590
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100591" ksh: ${!var[*]} array index list syntax: {{{1
592" ========================================
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200593if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100594 syn region shDeref matchgroup=PreProc start="\${!" end="}" contains=@shDerefVarArray
595endif
596
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000597" bash: ${!prefix*} and ${#parameter}: {{{1
598" ====================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000599if exists("b:is_bash")
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200600 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOffset
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200601 syn match shDerefVar contained "{\@<=!\h\w*" nextgroup=@shDerefVarList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000602endif
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100603if exists("b:is_kornshell")
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200604 syn match shDerefVar contained "{\@<=!\h\w*[[:alnum:]_.]*" nextgroup=@shDerefVarList
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100605endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000606
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200607syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOffset,shDerefOpError
Bram Moolenaar071d4272004-06-13 20:20:40 +0000608syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200609syn match shDerefVar contained "{\@<=\h\w*" nextgroup=@shDerefVarList
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200610syn match shDerefVar contained '\d' nextgroup=@shDerefVarList
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200611if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200612 syn match shDerefVar contained "{\@<=\h\w*[[:alnum:]_.]*" nextgroup=@shDerefVarList
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100613endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000614
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000615" sh ksh bash : ${var[... ]...} array reference: {{{1
Lucien Grondince3b0132023-11-04 09:41:37 +0100616syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError,shDerefOffset
Bram Moolenaar071d4272004-06-13 20:20:40 +0000617
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000618" Special ${parameter OPERATOR word} handling: {{{1
Bram Moolenaare2719092015-01-10 15:09:25 +0100619" sh ksh bash : ${parameter:-word} word is default value
620" sh ksh bash : ${parameter:=word} assign word as default value
621" sh ksh bash : ${parameter:?word} display word if parameter is null
622" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
623" ksh bash : ${parameter#pattern} remove small left pattern
624" ksh bash : ${parameter##pattern} remove large left pattern
625" ksh bash : ${parameter%pattern} remove small right pattern
626" ksh bash : ${parameter%%pattern} remove large right pattern
627" bash : ${parameter^pattern} Case modification
628" bash : ${parameter^^pattern} Case modification
629" bash : ${parameter,pattern} Case modification
630" bash : ${parameter,,pattern} Case modification
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200631" bash : ${@:start:qty} display command line arguments from start to start+qty-1 (inferred)
Bram Moolenaardd60c362023-02-27 15:49:53 +0000632" bash : ${parameter@operator} transforms parameter (operator∈[uULqEPARa])
Bram Moolenaar071d4272004-06-13 20:20:40 +0000633syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100634if !exists("g:sh_no_error")
635 syn match shDerefOpError contained ":[[:punct:]]"
636endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000637syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
638syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200639if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200640 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
641 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100642 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern skipnl
Bram Moolenaar071d4272004-06-13 20:20:40 +0000643 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100644 " Match parametric bracket expressions with a leading whitespace character.
645 syn region shDerefPattern contained matchgroup=shBracketExprDelim start="\[" end="\]" contains=@shBracketExprList,shDoubleQuote nextgroup=shDerefPattern
646 call s:GenerateBracketExpressionItems({'itemGroup': 'shDerefPattern', 'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'contained nextgroup=shDerefPattern'})
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000647 syn match shDerefEscape contained '\%(\\\\\)*\\.'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000648endif
Bram Moolenaard960d762011-09-21 19:22:10 +0200649if exists("b:is_bash")
650 syn match shDerefOp contained "[,^]\{1,2}" nextgroup=@shDerefPatternList
Bram Moolenaardd60c362023-02-27 15:49:53 +0000651 syn match shDerefOp contained "@[uULQEPAKa]"
Bram Moolenaard960d762011-09-21 19:22:10 +0200652endif
Doug Kearnsfe228672025-05-05 20:10:11 +0200653syn region shDerefString contained matchgroup=shDerefDelim start=+\%(\\\)\@<!'+ end=+'+
Bram Moolenaar4b22cdb2010-08-02 22:12:46 +0200654syn region shDerefString contained matchgroup=shDerefDelim start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
Bram Moolenaarc236c162008-07-13 17:41:49 +0000655syn match shDerefString contained "\\["']" nextgroup=shDerefPattern
Bram Moolenaar071d4272004-06-13 20:20:40 +0000656
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200657if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
658 " bash ksh posix : ${parameter:offset}
659 " bash ksh posix : ${parameter:offset:length}
660 syn region shDerefOffset contained start=':[^-=?+]' end='\ze:' end='\ze}' contains=shDeref,shDerefSimple,shDerefEscape nextgroup=shDerefLen,shDeref,shDerefSimple
661 syn region shDerefOffset contained start=':\s-' end='\ze:' end='\ze}' contains=shDeref,shDerefSimple,shDerefEscape nextgroup=shDerefLen,shDeref,shDerefSimple
Bram Moolenaard2855f52018-07-31 22:23:58 +0200662 syn match shDerefLen contained ":[^}]\+" contains=shDeref,shDerefSimple,shArithmetic
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200663endif
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000664
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200665if exists("b:is_bash")
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100666 " bash : ${parameter/pattern/string}
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000667 " bash : ${parameter//pattern/string}
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000668 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200669 syn region shDerefPPSleft contained start='.' skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp end='/' end='\ze}' end='"' nextgroup=shDerefPPSright contains=@shPPSLeftList
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100670 syn region shDerefPPSright contained start='.' skip=@\%(\\\\\)\+@ end='\ze}' contains=@shPPSRightList
Bram Moolenaaracb4f222016-01-10 15:59:26 +0100671
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100672 " bash : ${parameter/#pattern/string}
673 " bash : ${parameter/%pattern/string}
674 syn match shDerefPSR contained '/[#%]' nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
675 syn region shDerefPSRleft contained start='[^"']' skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPSRright contains=shBracketExpr
Bram Moolenaaracb4f222016-01-10 15:59:26 +0100676 syn region shDerefPSRright contained start='.' skip=@\%(\\\\\)\+@ end='\ze}'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000677endif
678
Bram Moolenaarc236c162008-07-13 17:41:49 +0000679" Arithmetic Parenthesized Expressions: {{{1
Bram Moolenaarbc488a72013-07-05 21:01:22 +0200680"syn region shParen matchgroup=shArithRegion start='[^$]\zs(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
681syn region shParen matchgroup=shArithRegion start='\$\@!(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
Bram Moolenaarc236c162008-07-13 17:41:49 +0000682
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200683" Additional sh Keywords: {{{1
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000684" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000685syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
686syn keyword shConditional contained elif else then
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100687if !exists("g:sh_no_error")
688 syn keyword shCondError elif else then
689endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000690
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200691" Additional ksh Keywords and Aliases: {{{1
692" ===================================
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100693if exists("b:is_kornshell") || exists("b:is_posix")
694 syn keyword shStatement bg builtin disown enum export false fg getconf getopts hist jobs let printf sleep true unalias whence
695 syn keyword shStatement typeset skipwhite nextgroup=shSetOption
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200696 syn keyword shStatement autoload compound fc float functions hash history integer nameref nohup r redirect source stop suspend times type
Bram Moolenaar690afe12017-01-28 18:34:47 +0100697 if exists("b:is_posix")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000698 syn keyword shStatement command
699 else
700 syn keyword shStatement time
701 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000702
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200703" Additional bash Keywords: {{{1
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000704" =====================
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100705elseif exists("b:is_bash")
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100706 syn keyword shStatement bg builtin disown export false fg getopts jobs let printf true unalias
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100707 syn keyword shStatement typeset nextgroup=shSetOption
708 syn keyword shStatement fc hash history source suspend times type
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100709 syn keyword shStatement bind caller compopt declare dirs enable help logout local mapfile popd pushd readarray shopt typeset
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100710else
711 syn keyword shStatement login newgrp
Bram Moolenaar071d4272004-06-13 20:20:40 +0000712endif
713
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000714" Synchronization: {{{1
715" ================
Bram Moolenaar03413f42016-04-12 21:07:15 +0200716if !exists("g:sh_minlines")
717 let s:sh_minlines = 200
718else
719 let s:sh_minlines= g:sh_minlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000720endif
Bram Moolenaar03413f42016-04-12 21:07:15 +0200721if !exists("g:sh_maxlines")
722 let s:sh_maxlines = 2*s:sh_minlines
723 if s:sh_maxlines < 25
724 let s:sh_maxlines= 25
725 endif
726else
727 let s:sh_maxlines= g:sh_maxlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000728endif
Bram Moolenaar03413f42016-04-12 21:07:15 +0200729exec "syn sync minlines=" . s:sh_minlines . " maxlines=" . s:sh_maxlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000730syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
731syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
732syn sync match shDoSync grouphere shDo "\<do\>"
733syn sync match shDoSync groupthere shDo "\<done\>"
734syn sync match shForSync grouphere shFor "\<for\>"
735syn sync match shForSync groupthere shFor "\<in\>"
736syn sync match shIfSync grouphere shIf "\<if\>"
737syn sync match shIfSync groupthere shIf "\<fi\>"
738syn sync match shUntilSync grouphere shRepeat "\<until\>"
739syn sync match shWhileSync grouphere shRepeat "\<while\>"
740
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000741" Default Highlighting: {{{1
742" =====================
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200743if !exists("skip_sh_syntax_inits")
744 hi def link shArithRegion shShellVariables
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100745 hi def link shArrayValue shDeref
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200746 hi def link shAstQuote shDoubleQuote
747 hi def link shAtExpr shSetList
Bram Moolenaard2855f52018-07-31 22:23:58 +0200748 hi def link shBkslshSnglQuote shSingleQuote
749 hi def link shBkslshDblQuote shDOubleQuote
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200750 hi def link shBeginHere shRedir
751 hi def link shCaseBar shConditional
752 hi def link shCaseCommandSub shCommandSub
753 hi def link shCaseDoubleQuote shDoubleQuote
754 hi def link shCaseIn shConditional
755 hi def link shQuote shOperator
756 hi def link shCaseSingleQuote shSingleQuote
757 hi def link shCaseStart shConditional
758 hi def link shCmdSubRegion shShellVariables
759 hi def link shColon shComment
760 hi def link shDerefOp shOperator
761 hi def link shDerefPOL shDerefOp
762 hi def link shDerefPPS shDerefOp
763 hi def link shDerefPSR shDerefOp
764 hi def link shDeref shShellVariables
765 hi def link shDerefDelim shOperator
766 hi def link shDerefSimple shDeref
767 hi def link shDerefSpecial shDeref
768 hi def link shDerefString shDoubleQuote
769 hi def link shDerefVar shDeref
770 hi def link shDoubleQuote shString
771 hi def link shEcho shString
772 hi def link shEchoDelim shOperator
773 hi def link shEchoQuote shString
774 hi def link shForPP shLoop
775 hi def link shFunction Function
776 hi def link shEmbeddedEcho shString
777 hi def link shEscape shCommandSub
778 hi def link shExDoubleQuote shDoubleQuote
779 hi def link shExSingleQuote shSingleQuote
780 hi def link shHereDoc shString
781 hi def link shHereString shRedir
782 hi def link shHerePayload shHereDoc
783 hi def link shLoop shStatement
784 hi def link shSpecialNxt shSpecial
785 hi def link shNoQuote shDoubleQuote
786 hi def link shOption shCommandSub
787 hi def link shPattern shString
788 hi def link shParen shArithmetic
789 hi def link shPosnParm shShellVariables
790 hi def link shQuickComment shComment
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200791 hi def link shBQComment shComment
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200792 hi def link shRange shOperator
793 hi def link shRedir shOperator
794 hi def link shSetListDelim shOperator
795 hi def link shSetOption shOption
796 hi def link shSingleQuote shString
797 hi def link shSource shOperator
798 hi def link shStringSpecial shSpecial
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200799 hi def link shSpecialStart shSpecial
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200800 hi def link shSubShRegion shOperator
801 hi def link shTestOpr shConditional
802 hi def link shTestPattern shString
803 hi def link shTestDoubleQuote shString
804 hi def link shTestSingleQuote shString
805 hi def link shTouchCmd shStatement
806 hi def link shVariable shSetList
807 hi def link shWrapLineOperator shOperator
Bram Moolenaar071d4272004-06-13 20:20:40 +0000808
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200809 if exists("b:is_bash")
810 hi def link bashAdminStatement shStatement
811 hi def link bashSpecialVariables shShellVariables
812 hi def link bashStatement shStatement
813 hi def link shCharClass shSpecial
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200814 hi def link shDerefOffset shDerefOp
815 hi def link shDerefLen shDerefOffset
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100816 endif
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200817 if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200818 hi def link kshSpecialVariables shShellVariables
819 hi def link kshStatement shStatement
820 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000821
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200822 if !exists("g:sh_no_error")
823 hi def link shCaseError Error
824 hi def link shCondError Error
825 hi def link shCurlyError Error
826 hi def link shDerefOpError Error
827 hi def link shDerefWordError Error
828 hi def link shDoError Error
829 hi def link shEsacError Error
830 hi def link shIfError Error
831 hi def link shInError Error
832 hi def link shParenError Error
833 hi def link shTestError Error
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200834 if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200835 hi def link shDTestError Error
836 endif
837 endif
838
839 hi def link shArithmetic Special
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100840 hi def link shBracketExprDelim Delimiter
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200841 hi def link shCharClass Identifier
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100842 hi def link shCollSymb shCharClass
843 hi def link shEqClass shCharClass
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200844 hi def link shSnglCase Statement
845 hi def link shCommandSub Special
Bram Moolenaard2855f52018-07-31 22:23:58 +0200846 hi def link shCommandSubBQ shCommandSub
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800847 hi def link shSubshare shCommandSub
848 hi def link shValsub shCommandSub
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200849 hi def link shComment Comment
850 hi def link shConditional Conditional
851 hi def link shCtrlSeq Special
852 hi def link shExprRegion Delimiter
853 hi def link shFunctionKey Function
854 hi def link shFunctionName Function
855 hi def link shNumber Number
856 hi def link shOperator Operator
857 hi def link shRepeat Repeat
858 hi def link shSet Statement
859 hi def link shSetList Identifier
860 hi def link shShellVariables PreProc
861 hi def link shSpecial Special
Bram Moolenaard2855f52018-07-31 22:23:58 +0200862 hi def link shSpecialDQ Special
863 hi def link shSpecialSQ Special
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100864 hi def link shSpecialNoZS shSpecial
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200865 hi def link shStatement Statement
866 hi def link shString String
867 hi def link shTodo Todo
868 hi def link shAlias Identifier
869 hi def link shHereDoc01 shRedir
870 hi def link shHereDoc02 shRedir
871 hi def link shHereDoc03 shRedir
872 hi def link shHereDoc04 shRedir
873 hi def link shHereDoc05 shRedir
874 hi def link shHereDoc06 shRedir
875 hi def link shHereDoc07 shRedir
876 hi def link shHereDoc08 shRedir
877 hi def link shHereDoc09 shRedir
878 hi def link shHereDoc10 shRedir
879 hi def link shHereDoc11 shRedir
880 hi def link shHereDoc12 shRedir
881 hi def link shHereDoc13 shRedir
882 hi def link shHereDoc14 shRedir
883 hi def link shHereDoc15 shRedir
Bram Moolenaar23515b42020-11-29 14:36:24 +0100884 hi def link shHereDoc16 shRedir
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200885endif
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100886
887" Delete shell folding commands {{{1
888" =============================
889delc ShFoldFunctions
890delc ShFoldHereDoc
891delc ShFoldIfDoFor
Bram Moolenaar071d4272004-06-13 20:20:40 +0000892
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100893" Delete the bracket expression function {{{1
894" ======================================
895delfun s:GenerateBracketExpressionItems
896
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000897" Set Current Syntax: {{{1
898" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000899if exists("b:is_bash")
900 let b:current_syntax = "bash"
901elseif exists("b:is_kornshell")
902 let b:current_syntax = "ksh"
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200903elseif exists("b:is_posix")
904 let b:current_syntax = "posix"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000905else
906 let b:current_syntax = "sh"
907endif
908
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000909" vim: ts=16 fdm=marker