blob: 3e0a481fbd1e51ba9d3ce37ffef843ec77eb86c6 [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
Doug Kearns87947a92025-05-06 17:59:25 +020015" 2025 May 06 match KornShell compound arrays
Doug Kearns839b79e2025-05-10 20:57:10 +020016" 2025 May 10 improve wildcard character class lists
Johnothan Kingb0691b42025-05-21 21:21:14 +020017" 2025 May 21 improve supported KornShell features
hakkadaikon152a4502025-06-16 19:54:37 +020018" 2025 Jun 16 change how sh_fold_enabled is reset (#17557)
Bram Moolenaar71badf92023-04-22 22:40:14 +010019" Version: 208
Christian Brabandtf9ca1392024-02-19 20:37:11 +010020" Former URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
Bram Moolenaare2719092015-01-10 15:09:25 +010021" For options and settings, please use: :help ft-sh-syntax
Bram Moolenaar23515b42020-11-29 14:36:24 +010022" 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 +000023
Bram Moolenaarf37506f2016-08-31 22:22:10 +020024" quit when a syntax file was already loaded {{{1
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020025if exists("b:current_syntax")
Bram Moolenaar071d4272004-06-13 20:20:40 +000026 finish
27endif
28
Mohamed Akram51a06ec2025-03-21 17:52:08 +010029" Ensure this is set unless we find another shell
30let b:is_sh = 1
31
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +020032" If the shell script itself specifies which shell to use, use it
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020033let s:shebang = getline(1)
34
35if s:shebang =~ '^#!.\{-2,}\<ksh\>'
Johnothan Kingb0691b42025-05-21 21:21:14 +020036 " The binary is too ambiguous (i.e. '/bin/ksh' or some such).
Bram Moolenaar91c49372016-05-08 09:50:29 +020037 let b:is_kornshell = 1
Johnothan Kingb0691b42025-05-21 21:21:14 +020038 let b:generic_korn = 1
39elseif s:shebang =~ '^#!.\{-2,}\<ksh93u\+\>'
40 " ksh93u+ (or 93u-) release (still much too common to encounter)
41 let b:is_kornshell = 1
42 let b:is_ksh93u = 1
43elseif s:shebang =~ '^#!.\{-2,}\<ksh93v\>'
44 " ksh93v- alpha or beta
45 let b:is_kornshell = 1
46 let b:is_ksh93v = 1
47elseif s:shebang =~ '^#!.\{-2,}\<ksh93\>'
48 " Could be any ksh93 release
49 let b:is_kornshell = 1
50 let b:is_ksh93 = 1
51elseif s:shebang =~ '^#!.\{-2,}\<ksh2020\>'
52 let b:is_kornshell = 1
53 let b:is_ksh2020 = 1
54elseif s:shebang =~ '^#!.\{-2,}\<ksh88\>'
55 " The actual AT&T ksh88 and its feature set is assumed.
56 let b:is_kornshell = 1
57 let b:is_ksh88 = 1
58elseif s:shebang =~ '^#!.\{-2,}\<mksh\>'
59 " MirBSD Korn Shell
60 let b:is_kornshell = 1
61 let b:is_mksh = 1
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020062elseif s:shebang =~ '^#!.\{-2,}\<bash\>'
Bram Moolenaar91c49372016-05-08 09:50:29 +020063 let b:is_bash = 1
Aliaksei Budavei5c84d122025-04-10 21:52:14 +020064elseif s:shebang =~ '^#!.\{-2,}\<dash\>'
Bram Moolenaard58a3bf2020-09-28 21:48:16 +020065 let b:is_dash = 1
Bram Moolenaard4755bb2004-09-02 19:12:26 +000066" handling /bin/sh with is_kornshell/is_sh {{{1
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +020067" b:is_sh will be set when "#! /bin/sh" is found;
Bram Moolenaar071d4272004-06-13 20:20:40 +000068" However, it often is just a masquerade by bash (typically Linux)
69" or kornshell (typically workstations with Posix "sh").
Mohamed Akram51a06ec2025-03-21 17:52:08 +010070" So, when the user sets "g:is_kornshell", "g:is_bash",
71" "g:is_posix" or "g:is_dash", a b:is_sh is converted into
72" b:is_kornshell/b:is_bash/b:is_posix/b:is_dash, respectively.
73elseif !exists("b:is_kornshell") && !exists("b:is_bash") && !exists("b:is_posix") && !exists("b:is_dash")
74 if exists("g:is_kornshell")
75 let b:is_kornshell= 1
Johnothan Kingb0691b42025-05-21 21:21:14 +020076 let b:generic_korn = 1
Mohamed Akram51a06ec2025-03-21 17:52:08 +010077 elseif exists("g:is_bash")
78 let b:is_bash= 1
79 elseif exists("g:is_dash")
80 let b:is_dash= 1
81 elseif exists("g:is_posix")
82 let b:is_posix= 1
83 elseif exists("g:is_sh")
84 let b:is_sh= 1
85 else
86 " user did not specify which shell to use, and
87 " the script itself does not specify which shell to use. FYI: /bin/sh is ambiguous.
88 " Assuming /bin/sh is executable, and if its a link, find out what it links to.
89 let s:shell = ""
90 if executable("/bin/sh")
91 let s:shell = resolve("/bin/sh")
92 elseif executable("/usr/bin/sh")
93 let s:shell = resolve("/usr/bin/sh")
Bram Moolenaar7fc904b2006-04-13 20:37:35 +000094 endif
Johnothan Kingb0691b42025-05-21 21:21:14 +020095 if s:shell =~ '\<ksh\>'
96 " The binary is too ambiguous (i.e. '/bin/ksh' or some such).
97 let b:is_kornshell = 1
98 let b:generic_korn = 1
99 elseif s:shell =~ '\<ksh93u\+\>'
100 " ksh93u+ (or 93u-) release (still much too common to encounter)
101 let b:is_kornshell = 1
102 let b:is_ksh93u = 1
103 elseif s:shell =~ '\<ksh93v\>'
104 " ksh93v- alpha or beta
105 let b:is_kornshell = 1
106 let b:is_ksh93v = 1
107 elseif s:shell =~ '\<ksh93\>'
108 " Could be any ksh93 release
109 let b:is_kornshell = 1
110 let b:is_ksh93 = 1
111 elseif s:shebang =~ '\<ksh2020\>'
112 let b:is_kornshell = 1
113 let b:is_ksh2020 = 1
114 elseif s:shell =~ '\<ksh88\>'
115 " The actual AT&T ksh88 and its feature set is assumed.
116 let b:is_kornshell = 1
117 let b:is_ksh88 = 1
118 elseif s:shell =~ '\<mksh\>'
119 " MirBSD Korn Shell
120 let b:is_kornshell = 1
121 let b:is_mksh = 1
Mohamed Akram51a06ec2025-03-21 17:52:08 +0100122 elseif s:shell =~ '\<bash\>'
123 let b:is_bash = 1
124 elseif s:shell =~ '\<dash\>'
125 let b:is_dash = 1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000126 else
Mohamed Akram51a06ec2025-03-21 17:52:08 +0100127 let b:is_posix = 1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128 endif
Mohamed Akram51a06ec2025-03-21 17:52:08 +0100129 unlet s:shell
130 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000131endif
132
Aliaksei Budavei5c84d122025-04-10 21:52:14 +0200133unlet s:shebang
134
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200135" if b:is_dash, set b:is_posix too
136if exists("b:is_dash")
137 let b:is_posix= 1
138endif
139
Mohamed Akram51a06ec2025-03-21 17:52:08 +0100140if exists("b:is_kornshell") || exists("b:is_bash")
141 if exists("b:is_sh")
142 unlet b:is_sh
143 endif
144endif
145
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000146" set up default g:sh_fold_enabled {{{1
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100147" ================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000148if !exists("g:sh_fold_enabled")
149 let g:sh_fold_enabled= 0
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000150elseif g:sh_fold_enabled != 0 && !has("folding")
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000151 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support"
hakkadaikon152a4502025-06-16 19:54:37 +0200152 let g:sh_fold_enabled= 0
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000153endif
Bram Moolenaar86b48162022-12-06 18:20:10 +0000154let s:sh_fold_functions= and(g:sh_fold_enabled,1)
155let s:sh_fold_heredoc = and(g:sh_fold_enabled,2)
156let s:sh_fold_ifdofor = and(g:sh_fold_enabled,4)
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000157if g:sh_fold_enabled && &fdm == "manual"
Bram Moolenaar97d62492012-11-15 21:28:22 +0100158 " Given that the user provided g:sh_fold_enabled
159 " AND g:sh_fold_enabled is manual (usual default)
160 " implies a desire for syntax-based folding
161 setl fdm=syntax
Bram Moolenaar071d4272004-06-13 20:20:40 +0000162endif
163
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200164" set up the syntax-highlighting for iskeyword
Bram Moolenaar723dd942019-04-04 13:11:03 +0200165if (v:version == 704 && has("patch-7.4.1142")) || v:version > 704
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200166 if !exists("g:sh_syntax_isk") || (exists("g:sh_syntax_isk") && g:sh_syntax_isk)
167 if exists("b:is_bash")
168 exe "syn iskeyword ".&iskeyword.",-,:"
169 else
170 exe "syn iskeyword ".&iskeyword.",-"
171 endif
Bram Moolenaar91c49372016-05-08 09:50:29 +0200172 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +0100173endif
174
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100175" Set up folding commands for shell {{{1
176" =================================
Bram Moolenaar86b48162022-12-06 18:20:10 +0000177sil! delc ShFoldFunctions
178sil! delc ShFoldHereDoc
179sil! delc ShFoldIfDoFor
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100180if s:sh_fold_functions
181 com! -nargs=* ShFoldFunctions <args> fold
182else
183 com! -nargs=* ShFoldFunctions <args>
184endif
185if s:sh_fold_heredoc
186 com! -nargs=* ShFoldHereDoc <args> fold
187else
188 com! -nargs=* ShFoldHereDoc <args>
189endif
190if s:sh_fold_ifdofor
191 com! -nargs=* ShFoldIfDoFor <args> fold
192else
193 com! -nargs=* ShFoldIfDoFor <args>
194endif
195
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100196" Generate bracket expression items {{{1
197" =================================
198" Note that the following function can be invoked as many times as necessary
199" provided that these constraints hold for the passed dictionary argument:
200" - every time a unique group-name value is assigned to the "itemGroup" key;
201" - only ONCE either the "extraArgs" key is not entered or it is entered and
202" its value does not have "contained" among other optional arguments (":help
203" :syn-arguments").
204fun! s:GenerateBracketExpressionItems(dict) abort
205 let itemGroup = a:dict.itemGroup
206 let bracketGroup = a:dict.bracketGroup
207 let invGroup = itemGroup . 'Inv'
208 let skipLeftBracketGroup = itemGroup . 'SkipLeftBracket'
209 let skipRightBracketGroup = itemGroup . 'SkipRightBracket'
210 let extraArgs = has_key(a:dict, 'extraArgs') ? a:dict.extraArgs : ''
211
212 " Make the leading "[!^]" stand out in a NON-matching expression.
213 exec 'syn match ' . invGroup . ' contained "\[\@<=[!^]"'
214
215 " Set up indirections for unbalanced-bracket highlighting.
216 exec 'syn region ' . skipRightBracketGroup . ' contained matchgroup=' . bracketGroup . ' start="\[\%([!^]\=\\\=\]\)\@=" matchgroup=shCollSymb end="\[\.[^]]\{-}\][^]]\{-}\.\]" matchgroup=' . itemGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . invGroup
217 exec 'syn region ' . skipLeftBracketGroup . ' contained matchgroup=' . bracketGroup . ' start="\[\%([!^]\=\\\=\]\)\@=" skip="[!^]\=\\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\%(\[[:.=]\@!\)\@=" matchgroup=' . itemGroup . ' end="\[[:.=]\@!" contains=@shBracketExprList,shDoubleQuote,' . invGroup
218
219 " Look for a general matching expression.
220 exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' start="\[\S\@=" end="\]" contains=@shBracketExprList,shDoubleQuote ' . extraArgs
221 " Look for a general NON-matching expression.
222 exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' start="\[[!^]\@=" end="\]" contains=@shBracketExprList,shDoubleQuote,' . invGroup . ' ' . extraArgs
223
224 " Accommodate unbalanced brackets in bracket expressions. The supported
225 " syntax for a plain "]" can be: "[]ws]" and "[^]ws]"; or, "[ws[.xs]ys.]zs]"
226 " and "[^ws[.xs]ys.]zs]"; see §9.3.5 RE Bracket Expression (in XBD).
227 exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\\=\]" matchgroup=' . bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . skipRightBracketGroup . ' ' . extraArgs
228 " Strive to handle "[]...[]" etc.
229 exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\[[:.=]\@!" matchgroup=' . bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . skipLeftBracketGroup . ' ' . extraArgs
230
231 if !exists("g:skip_sh_syntax_inits")
232 exec 'hi def link ' . skipLeftBracketGroup . ' ' . itemGroup
233 exec 'hi def link ' . skipRightBracketGroup . ' ' . itemGroup
234 exec 'hi def link ' . invGroup . ' Underlined'
235 endif
236endfun
237
238call s:GenerateBracketExpressionItems({'itemGroup': 'shBracketExpr', 'bracketGroup': 'shBracketExprDelim'})
239
Bram Moolenaarcd71fa32005-03-11 22:46:48 +0000240" sh syntax is case sensitive {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000241syn case match
242
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000243" Clusters: contains=@... clusters {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000244"==================================
Bram Moolenaar5c736222010-01-06 20:54:52 +0100245syn cluster shErrorList contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError,shOK
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200246if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000247 syn cluster ErrorList add=shDTestError
248endif
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100249syn 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 +0000250syn cluster shArithList contains=@shArithParenList,shParenError
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100251syn cluster shBracketExprList contains=shCharClassOther,shCharClass,shCollSymb,shEqClass
Bram Moolenaard2855f52018-07-31 22:23:58 +0200252syn 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 -0800253syn 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 +0100254if exists("b:is_kornshell") || exists("b:is_bash")
Lucien Grondin1858e2b2023-11-02 20:33:56 +0100255 syn cluster shCaseList add=shForPP,shDblParen
Bram Moolenaar23515b42020-11-29 14:36:24 +0100256endif
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100257syn 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 +0000258syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100259" 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 -0800260syn cluster shDblQuoteList contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
Bram Moolenaaracb4f222016-01-10 15:59:26 +0100261syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200262syn cluster shDerefVarList contains=shDerefOffset,shDerefOp,shDerefVarArray,shDerefOpError
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100263syn cluster shEchoList contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
264syn cluster shExprList1 contains=shBracketExpr,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
Bram Moolenaar383f9bc2005-01-19 22:18:32 +0000265syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100266syn 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 +0000267if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaar23515b42020-11-29 14:36:24 +0100268 syn cluster shFunctionList add=shRepeat,shDblBrace,shDblParen,shForPP
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100269 syn cluster shDerefList add=shCommandSubList,shEchoDeref
Bram Moolenaar7263a772007-05-10 17:35:54 +0000270endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000271syn cluster shHereBeginList contains=@shCommandSubList
272syn cluster shHereList contains=shBeginHere,shHerePayload
273syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100274syn 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 +0200275syn cluster shIfList contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
Bram Moolenaar23515b42020-11-29 14:36:24 +0100276syn cluster shLoopList contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shIf,shOption,shSet,shTest,shTestOpr,shTouch
277if exists("b:is_kornshell") || exists("b:is_bash")
Lucien Grondina390e982023-10-28 21:40:48 +0200278 syn cluster shLoopList add=shForPP,shDblParen
Bram Moolenaar23515b42020-11-29 14:36:24 +0100279endif
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100280syn 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 +0000281syn cluster shPPSRightList contains=shDeref,shDerefSimple,shEscape,shPosnParm
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100282syn 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
283syn 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 +0100284syn cluster shNoZSList contains=shSpecialNoZS
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800285syn cluster shForList contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shArithmetic
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100286
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000287" Echo: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000288" ====
289" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
Johnothan Kingb0691b42025-05-21 21:21:14 +0200290if (exists("b:is_kornshell") && !exists("b:is_ksh88"))
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800291 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
292 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
293else
294 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
295 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
296endif
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100297if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
298 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
299 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
300endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100301syn match shEchoQuote contained '\%(\\\\\)*\\["`'()]'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000302
Bram Moolenaarc236c162008-07-13 17:41:49 +0000303" This must be after the strings, so that ... \" will be correct
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100304syn 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 +0000305
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000306" Alias: {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000307" =====
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200308if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000309 syn match shStatement "\<alias\>"
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000310 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*\)\@=" skip="\\$" end="\>\|`"
311 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*=\)\@=" skip="\\$" end="="
312" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+\)\@=" skip="\\$" end="\>\|`"
313" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+=\)\@=" skip="\\$" end="="
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100314
315 " Touch: {{{1
316 " =====
Bram Moolenaar6d5ad4c2016-10-27 17:00:16 +0200317 syn match shTouch '\<touch\>[^;#]*' skipwhite nextgroup=shComment contains=shTouchCmd,shDoubleQuote,shSingleQuote,shDeref,shDerefSimple
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100318 syn match shTouchCmd '\<touch\>' contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000319endif
320
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000321" Error Codes: {{{1
322" ============
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100323if !exists("g:sh_no_error")
Bram Moolenaare2719092015-01-10 15:09:25 +0100324 syn match shDoError "\<done\>"
325 syn match shIfError "\<fi\>"
326 syn match shInError "\<in\>"
327 syn match shCaseError ";;"
328 syn match shEsacError "\<esac\>"
329 syn match shCurlyError "}"
330 syn match shParenError ")"
331 syn match shOK '\.\(done\|fi\|in\|esac\)'
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200332 if exists("b:is_kornshell") || exists("b:is_bash")
Bram Moolenaare2719092015-01-10 15:09:25 +0100333 syn match shDTestError "]]"
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100334 endif
Bram Moolenaare2719092015-01-10 15:09:25 +0100335 syn match shTestError "]"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000336endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000337
Bram Moolenaarc236c162008-07-13 17:41:49 +0000338" Options: {{{1
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000339" ====================
Bram Moolenaar7db8f6f2016-03-29 23:12:46 +0200340syn match shOption "\s\zs[-+][-_a-zA-Z#@]\+"
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100341syn match shOption "\s\zs--[^ \t$=`'"|);]\+"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000342
Bram Moolenaar7263a772007-05-10 17:35:54 +0000343" File Redirection Highlighted As Operators: {{{1
344"===========================================
345syn match shRedir "\d\=>\(&[-0-9]\)\="
346syn match shRedir "\d\=>>-\="
347syn match shRedir "\d\=<\(&[-0-9]\)\="
348syn match shRedir "\d<<-\="
349
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000350" Operators: {{{1
351" ==========
Bram Moolenaar7263a772007-05-10 17:35:54 +0000352syn match shOperator "<<\|>>" contained
Bram Moolenaarc236c162008-07-13 17:41:49 +0000353syn match shOperator "[!&;|]" contained
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200354syn match shOperator "[-=/*+%]\==" skipwhite nextgroup=shPattern
Bram Moolenaare90ee312010-08-05 22:08:47 +0200355syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shExDoubleQuote,shDoubleQuote,shDeref
Bram Moolenaar071d4272004-06-13 20:20:40 +0000356
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000357" Subshells: {{{1
358" ==========
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200359syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 nextgroup=shSpecialNxt
360syn region shSubSh transparent matchgroup=shSubShRegion start="[^(]\zs(" end=")" contains=@shSubShList nextgroup=shSpecialNxt
Bram Moolenaar071d4272004-06-13 20:20:40 +0000361
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000362" Tests: {{{1
363"=======
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100364syn region shExpr matchgroup=shRange start="\[\s\@=" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
Bram Moolenaar5c736222010-01-06 20:54:52 +0100365syn 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 +0200366syn region shNoQuote start='\S' skip='\%(\\\\\)*\\.' end='\ze\s' end="\ze['"]" contained contains=shBracketExpr,shDerefSimple,shDeref,shEscape
Bram Moolenaar91c49372016-05-08 09:50:29 +0200367syn match shAstQuote contained '\*\ze"' nextgroup=shString
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200368syn match shTestOpr contained '[^-+/%]\zs=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100369syn match shTestOpr contained "<=\|>=\|!=\|==\|=\~\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
Bram Moolenaar9964e462007-05-05 17:54:07 +0000370syn match shTestPattern contained '\w\+'
Bram Moolenaar91c49372016-05-08 09:50:29 +0200371syn region shTestDoubleQuote contained start='\%(\%(\\\\\)*\\\)\@<!"' skip=+\\\\\|\\"+ end='"' contains=shDeref,shDerefSimple,shDerefSpecial
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100372syn match shTestSingleQuote contained '\\.' nextgroup=shTestSingleQuote
Bram Moolenaar9964e462007-05-05 17:54:07 +0000373syn match shTestSingleQuote contained "'[^']*'"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000374if exists("b:is_kornshell") || exists("b:is_bash")
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100375 syn region shDblBrace matchgroup=Delimiter start="\[\[\s\@=" skip=+\%(\\\\\)*\\$+ end="\]\]" contains=@shTestList,shAstQuote,shNoQuote,shComment
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100376 syn region shDblParen matchgroup=Delimiter start="((" skip=+\%(\\\\\)*\\$+ end="))" contains=@shTestList,shComment
Bram Moolenaar071d4272004-06-13 20:20:40 +0000377endif
378
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000379" Character Class In Range: {{{1
380" =========================
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100381syn match shCharClassOther contained "\[:\w\{-}:\]"
Doug Kearns839b79e2025-05-10 20:57:10 +0200382syn match shCharClass contained "\[:\%(alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|xdigit\):\]"
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100383syn match shCollSymb contained "\[\..\{-}\.\]"
384syn match shEqClass contained "\[=.\{-}=\]"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000385
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000386" Loops: do, if, while, until {{{1
387" ======
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100388ShFoldIfDoFor syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList
389ShFoldIfDoFor syn region shIf transparent matchgroup=shConditional start="\<if\_s" matchgroup=shConditional skip=+-fi\>+ end="\<;\_s*then\>" end="\<fi\>" contains=@shIfList
390ShFoldIfDoFor 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 +0100391if exists("b:is_kornshell") || exists("b:is_bash")
392 ShFoldIfDoFor syn region shForPP matchgroup=shLoop start='\<for\>\_s*((' end='))' contains=@shForList
393endif
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100394
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200395if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000396 syn cluster shCaseList add=shRepeat
397 syn cluster shFunctionList add=shRepeat
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200398 syn region shRepeat matchgroup=shLoop start="\<while\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
399 syn region shRepeat matchgroup=shLoop start="\<until\_s" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace
400 if !exists("b:is_posix")
401 syn region shCaseEsac matchgroup=shConditional start="\<select\s" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList
402 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000403else
Bram Moolenaarc236c162008-07-13 17:41:49 +0000404 syn region shRepeat matchgroup=shLoop start="\<while\_s" end="\<do\>"me=e-2 contains=@shLoopList
405 syn region shRepeat matchgroup=shLoop start="\<until\_s" end="\<do\>"me=e-2 contains=@shLoopList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000406endif
Bram Moolenaar572cb562005-08-05 21:35:02 +0000407syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}" contains=@shCurlyList
408syn match shComma contained ","
Bram Moolenaar071d4272004-06-13 20:20:40 +0000409
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000410" Case: case...esac {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411" ====
Bram Moolenaard2855f52018-07-31 22:23:58 +0200412syn match shCaseBar contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|" nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
413syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100414syn match shCaseLabel contained skipwhite "\%(\\.\|[-a-zA-Z0-9_*.]\)\+" contains=shBracketExpr
Johnothan Kingb0691b42025-05-21 21:21:14 +0200415if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88") && !exists("b:is_ksh93u") && !exists("b:is_ksh93v") && !exists("b:is_ksh2020"))
Bram Moolenaard2855f52018-07-31 22:23:58 +0200416 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 +0100417elseif exists("b:is_kornshell")
418 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 +0100419else
Bram Moolenaard2855f52018-07-31 22:23:58 +0200420 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 +0100421endif
Bram Moolenaard2855f52018-07-31 22:23:58 +0200422ShFoldIfDoFor syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100423
Bram Moolenaardf177f62005-02-22 08:39:57 +0000424syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
Johnothan Kingb0691b42025-05-21 21:21:14 +0200425if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88"))
Bram Moolenaar4b22cdb2010-08-02 22:12:46 +0200426 syn region shCaseExSingleQuote matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100427elseif !exists("g:sh_no_error")
Bram Moolenaardf177f62005-02-22 08:39:57 +0000428 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
429endif
Bram Moolenaar4b22cdb2010-08-02 22:12:46 +0200430syn region shCaseSingleQuote matchgroup=shQuote start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
431syn region shCaseDoubleQuote matchgroup=shQuote start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained
Bram Moolenaar071d4272004-06-13 20:20:40 +0000432syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100433call s:GenerateBracketExpressionItems({'itemGroup': 'shCaseRange', 'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'skip=+\\\\+ contained'})
Bram Moolenaar97d62492012-11-15 21:28:22 +0100434if exists("b:is_bash")
Doug Kearns839b79e2025-05-10 20:57:10 +0200435 syn match shCharClass "\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]" contained
436elseif exists("b:is_kornshell")
437 syn match shCharClass "\[:\%(alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]" contained
Bram Moolenaar97d62492012-11-15 21:28:22 +0100438endif
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000439" Misc: {{{1
440"======
Bram Moolenaar071d4272004-06-13 20:20:40 +0000441syn match shWrapLineOperator "\\$"
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200442syn region shCommandSubBQ start="`" skip="\\\\\|\\." end="`" contains=shBQComment,@shCommandSubList
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100443"COMBAK: see ksh13:50
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100444"syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shSingleQuote,shDoubleQuote,shComment
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100445"COMBAK: see sh11:27
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100446syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shComment
Bram Moolenaar1d9215b2020-01-25 13:27:42 +0100447"COMBAK: see ksh13:53
448"syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000449
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000450" $() and $(()): {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000451" $(..) is not supported by sh (Bourne shell). However, apparently
452" some systems (HP?) have as their /bin/sh a (link to) Korn shell
453" (ie. Posix compliant shell). /bin/ksh should work for those
454" systems too, however, so the following syntax will flag $(..) as
455" an Error under /bin/sh. By consensus of vimdev'ers!
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100456if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
Doug Kearns6099db92025-04-03 21:13:39 +0200457 syn region shCommandSub matchgroup=shCmdSubRegion start="\$((\@!" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800458 if exists("b:is_kornshell")
Johnothan Kingb0691b42025-05-21 21:21:14 +0200459 if !exists("b:is_ksh88")
460 if exists("b:is_mksh")
461 syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[ \t\n]" skip='\\\\\|\\.' end="\zs[ \t\n;]}" contains=@shCommandSubList
462 else
463 syn region shSubshare matchgroup=shCmdSubRegion start="\${\ze[ \t\n<]" skip='\\\\\|\\.' end="\zs[ \t\n;]}" contains=@shCommandSubList
464 endif
465 endif
466 if exists("b:is_mksh") || exists("b:generic_korn")
467 syn region shValsub matchgroup=shCmdSubRegion start="\${|" skip='\\\\\|\\.' end="}" contains=@shCommandSubList
468 endif
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800469 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +0000470 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shArithList
Bram Moolenaar61d35bd2012-03-28 20:51:51 +0200471 syn region shArithmetic matchgroup=shArithRegion start="\$\[" skip='\\\\\|\\.' end="\]" contains=@shArithList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000472 syn match shSkipInitWS contained "^\s\+"
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100473 syn region shArithParen matchgroup=shArithRegion contained start="(" end=")" contains=@shArithParenList
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100474elseif !exists("g:sh_no_error")
Bram Moolenaardf177f62005-02-22 08:39:57 +0000475 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000476endif
dkearns1bdc9432024-03-05 05:14:08 +1100477syn region shCmdParenRegion matchgroup=shCmdSubRegion start="((\@!" skip='\\\\\|\\.' end=")" contains=@shCommandSubList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000478
479if exists("b:is_bash")
480 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
481 syn cluster shCaseList add=bashAdminStatement,bashStatement
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100482 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
Johnothan Kingb0691b42025-05-21 21:21:14 +0200483 syn keyword bashStatement basename cat chgrp chmod chown cksum clear cmp comm command compgen complete cp cut date dirname du egrep expr fgrep find fmt fold getconf gnufind gnugrep grep head iconv id join less ln logname ls md5sum mkdir mkfifo mknod mktemp mv od paste pathchk readlink realpath rev rm rmdir rpm sed sha1sum sha224sum sha256sum sha384sum sha512sum sleep sort strip stty sum sync tail tee tr tty uname uniq wc which xargs xgrep
Bram Moolenaar071d4272004-06-13 20:20:40 +0000484 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop
485endif
486
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200487if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000488 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
489 syn cluster shCaseList add=kshStatement
Johnothan Kingb0691b42025-05-21 21:21:14 +0200490 syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV FCEDIT FIGNORE FPATH HISTCMD HISTEDIT HISTFILE HISTSIZE HOME IFS JOBMAX KSH_VERSION LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL SHLVL TMOUT VISUAL
491 syn keyword kshStatement basename cat chgrp chmod chown cksum clear cmp comm command cp cut date dirname du egrep expr fgrep find fmt fold grep head iconv id join killall less ln logname ls md5sum mkdir mknod mkfifo mktemp mv nice od paste pathchk printenv readlink realpath rev rm rmdir sed setgroups setsenv sha1sum sha224sum sha256sum sha384sum sha512sum sort strip stty sum sync tail tee tput tr tty uname uniq wc which xargs xgrep
492 if exists("b:is_ksh88")
493 syn keyword kshSpecialVariables contained ERRNO
494 elseif exists("b:is_mksh")
495 syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID
496 syn keyword kshStatement bind rename
497 elseif exists("b:is_ksh93v") || exists("b:is_ksh2020")
498 syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE
499 syn keyword kshStatement compgen complete
500 if exists("b:is_ksh93v")
501 syn keyword kshSpecialVariables contained VPATH CSWIDTH
502 syn keyword kshStatement vmstate alarm fds pids poll sha2sum
503 endif
504 elseif exists("b:is_ksh93u")
505 " ksh93u+
506 syn keyword kshSpecialVariables contained VPATH CSWIDTH
507 syn keyword kshStatement alarm fds pids vmstate
508 else
509 " 'ksh' is ambiguous; include everything
510 syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE VPATH SRANDOM CSWIDTH
511 if !exists("b:is_ksh93")
512 syn keyword kshSpecialVariables contained ERRNO
513 endif
514 syn keyword kshStatement vmstate alarm fds pids poll sha2sum alarm eloop fds mkservice pids compgen complete bind rename
515 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000516endif
517
518syn match shSource "^\.\s"
519syn match shSource "\s\.\s"
Bram Moolenaar5c736222010-01-06 20:54:52 +0100520"syn region shColon start="^\s*:" end="$" end="\s#"me=e-2 contains=@shColonList
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100521"syn region shColon start="^\s*\zs:" end="$" end="\s#"me=e-2
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200522if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaar91c49372016-05-08 09:50:29 +0200523 syn match shColon '^\s*\zs:'
524endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000525
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000526" String And Character Constants: {{{1
527"================================
Bram Moolenaar7db8f6f2016-03-29 23:12:46 +0200528syn match shNumber "\<\d\+\>#\="
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200529syn match shNumber "\<-\=\.\=\d\+\>#\="
Bram Moolenaar802a0d92016-06-26 16:17:58 +0200530syn match shCtrlSeq "\\\d\d\d\|\\[abcfnrtv0]" contained
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100531if exists("b:is_bash") || exists("b:is_kornshell")
Bram Moolenaar802a0d92016-06-26 16:17:58 +0200532 syn match shSpecial "[^\\]\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]" contained
533 syn match shSpecial "^\(\\\\\)*\zs\\\o\o\o\|\\x\x\x\|\\c[^"]\|\\[abefnrtv]" contained
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200534 syn region shExSingleQuote matchgroup=shQuote start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial nextgroup=shSpecialNxt
535 syn region shExDoubleQuote matchgroup=shQuote start=+\$"+ skip=+\\\\\|\\.\|\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,shSpecial nextgroup=shSpecialNxt
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100536elseif !exists("g:sh_no_error")
Bram Moolenaar9964e462007-05-05 17:54:07 +0000537 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial
Bram Moolenaare90ee312010-08-05 22:08:47 +0200538 syn region shExDoubleQuote matchGroup=Error start=+\$"+ skip=+\\\\\|\\.+ end=+"+ contains=shStringSpecial
Bram Moolenaardf177f62005-02-22 08:39:57 +0000539endif
Bram Moolenaard2855f52018-07-31 22:23:58 +0200540syn region shSingleQuote matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart,shSpecialSQ
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200541syn region shDoubleQuote matchgroup=shQuote start=+\%(\%(\\\\\)*\\\)\@<!"+ skip=+\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
Bram Moolenaar802a0d92016-06-26 16:17:58 +0200542syn match shStringSpecial "[^[:print:] \t]" contained
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200543syn match shStringSpecial "[^\\]\zs\%(\\\\\)*\(\\[\\"'`$()#]\)\+" nextgroup=shComment
544syn match shSpecialSQ "[^\\]\zs\%(\\\\\)*\(\\[\\"'`$()#]\)\+" contained nextgroup=shBkslshSnglQuote,@shNoZSList
545syn match shSpecialDQ "[^\\]\zs\%(\\\\\)*\(\\[\\"'`$()#]\)\+" contained nextgroup=shBkslshDblQuote,@shNoZSList
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200546syn match shSpecialStart "\%(\\\\\)*\\[\\"'`$()#]" contained nextgroup=shBkslshSnglQuote,shBkslshDblQuote,@shNoZSList
Bram Moolenaar60cce2f2015-10-13 23:21:27 +0200547syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100548syn match shSpecialNoZS contained "\%(\\\\\)*\\[\\"'`$()#]"
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200549syn match shSpecialNxt contained "\\[\\"'`$()#]"
Bram Moolenaar47e13952020-05-12 22:49:12 +0200550"syn region shBkslshSnglQuote contained matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart
551"syn region shBkslshDblQuote contained matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
Bram Moolenaar071d4272004-06-13 20:20:40 +0000552
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000553" Comments: {{{1
554"==========
Bram Moolenaar5c736222010-01-06 20:54:52 +0100555syn cluster shCommentGroup contains=shTodo,@Spell
Bram Moolenaar6d5ad4c2016-10-27 17:00:16 +0200556if exists("b:is_bash")
557 syn match shTodo contained "\<\%(COMBAK\|FIXME\|TODO\|XXX\)\ze:\=\>"
558else
559 syn keyword shTodo contained COMBAK FIXME TODO XXX
560endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100561syn match shComment "^\s*\zs#.*$" contains=@shCommentGroup
562syn match shComment "\s\zs#.*$" contains=@shCommentGroup
Bram Moolenaar97d62492012-11-15 21:28:22 +0100563syn match shComment contained "#.*$" contains=@shCommentGroup
Bram Moolenaar113cb512021-11-07 20:27:04 +0000564syn match shQuickComment contained "#.*$" contains=@shCommentGroup
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200565syn match shBQComment contained "#.\{-}\ze`" contains=@shCommentGroup
Bram Moolenaar071d4272004-06-13 20:20:40 +0000566
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000567" Here Documents: {{{1
Bram Moolenaard2ea7cf2021-05-30 20:54:13 +0200568" (modified by Felipe Contreras)
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000569" =========================================
Bram Moolenaar86b48162022-12-06 18:20:10 +0000570ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc01 start="<<\s*\z([^ \t|>]\+\)" matchgroup=shHereDoc01 end="^\z1$" contains=@shDblQuoteList
Bram Moolenaar71badf92023-04-22 22:40:14 +0100571ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc02 start="<<-\s*\z([^ \t|>]\+\)" matchgroup=shHereDoc02 end="^\t*\z1$" contains=@shDblQuoteList
Bram Moolenaar86b48162022-12-06 18:20:10 +0000572ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc03 start="<<\s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc03 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100573ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc04 start="<<-\s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc04 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000574ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc05 start="<<\s*'\z([^']\+\)'" matchgroup=shHereDoc05 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100575ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*'\z([^']\+\)'" matchgroup=shHereDoc06 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000576ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc07 start="<<\s*\"\z([^"]\+\)\"" matchgroup=shHereDoc07 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100577ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc08 start="<<-\s*\"\z([^"]\+\)\"" matchgroup=shHereDoc08 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000578ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc09 start="<<\s*\\\_$\_s*\z([^ \t|>]\+\)" matchgroup=shHereDoc09 end="^\z1$" contains=@shDblQuoteList
Bram Moolenaar71badf92023-04-22 22:40:14 +0100579ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t|>]\+\)" matchgroup=shHereDoc10 end="^\t*\z1$" contains=@shDblQuoteList
Bram Moolenaar86b48162022-12-06 18:20:10 +0000580ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<\s*\\\_$\_s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc11 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100581ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*\\\z([^ \t|>]\+\)" matchgroup=shHereDoc12 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000582ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<\s*\\\_$\_s*'\z([^']\+\)'" matchgroup=shHereDoc13 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100583ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc14 start="<<-\s*\\\_$\_s*'\z([^']\+\)'" matchgroup=shHereDoc14 end="^\t*\z1$"
Bram Moolenaar86b48162022-12-06 18:20:10 +0000584ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc15 start="<<\s*\\\_$\_s*\"\z([^"]\+\)\"" matchgroup=shHereDoc15 end="^\z1$"
Bram Moolenaar71badf92023-04-22 22:40:14 +0100585ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc16 start="<<-\s*\\\_$\_s*\"\z([^"]\+\)\"" matchgroup=shHereDoc16 end="^\t*\z1$"
Bram Moolenaar23515b42020-11-29 14:36:24 +0100586
Bram Moolenaar071d4272004-06-13 20:20:40 +0000587
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000588" Here Strings: {{{1
589" =============
Johnothan Kingb0691b42025-05-21 21:21:14 +0200590" available for: bash and ksh (except ksh88) but not if its a posix
591if exists("b:is_bash") || ((exists("b:is_kornshell") && !exists("b:is_ksh88")) && !exists("b:is_posix"))
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200592 syn match shHereString "<<<" skipwhite nextgroup=shCmdParenRegion
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000593endif
594
595" Identifiers: {{{1
596"=============
Bram Moolenaarc236c162008-07-13 17:41:49 +0000597syn match shSetOption "\s\zs[-+][a-zA-Z0-9]\+\>" contained
Bram Moolenaar23515b42020-11-29 14:36:24 +0100598syn match shVariable "\<\h\w*\ze=" nextgroup=shVarAssign
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100599if exists("b:is_bash")
600 " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
Doug Kearns87947a92025-05-06 17:59:25 +0200601 syn region shArrayValue contained start="\[\%(..\{-}\]=\)\@=" end="\]=\@=" contains=@shArrayValueList nextgroup=shVarAssign
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100602 syn cluster shArrayValueList contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,bashSpecialVariables,shParenError
Doug Kearns87947a92025-05-06 17:59:25 +0200603 syn region shArrayRegion contained matchgroup=shShellVariables start="(" skip='\\\\\|\\.' end=")" contains=@shArrayValueList,shArrayValue,shComment
Johnothan Kingb0691b42025-05-21 21:21:14 +0200604elseif (exists("b:is_kornshell") && !exists("b:is_ksh88"))
Doug Kearns87947a92025-05-06 17:59:25 +0200605 " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
606 syn region shArrayValue contained start="\[\%(..\{-}\]=\)\@=" end="\]=\@=" contains=@shArrayValueList nextgroup=shVarAssign
607 syn cluster shArrayValueList contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,kshSpecialVariables,shParenError
608 syn region shArrayRegion contained matchgroup=shShellVariables start="(" skip='\\\\\|\\.' end=")" contains=@shArrayValueList,shArrayValue,shComment,shArrayRegion
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100609endif
610if exists("b:is_bash") || exists("b:is_kornshell")
611 syn match shVariable "\<\h\w*\%(\[..\{-}\]\)\=\ze\%([|^&*/%+-]\|[<^]<\|[>^]>\)\==" contains=shDerefVarArray nextgroup=shVarAssign
612 syn match shVarAssign contained "\%([|^&*/%+-]\|[<^]<\|[>^]>\)\==" nextgroup=shArrayRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100613else
614 syn match shVarAssign contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
615endif
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100616syn match shVar contained "\h\w*"
Bram Moolenaarbc488a72013-07-05 21:01:22 +0200617syn region shAtExpr contained start="@(" end=")" contains=@shIdList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000618if exists("b:is_bash")
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100619 syn match shSet "^\s*set\ze\s\+$"
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100620 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 +0100621 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 +0200622elseif exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100623 syn match shSet "^\s*set\ze\s\+$"
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200624 if exists("b:is_dash")
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100625 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 +0200626 endif
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100627 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 +0100628 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 +0000629else
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100630 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 +0000631endif
632
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100633" KornShell namespace: {{{1
Johnothan Kingb0691b42025-05-21 21:21:14 +0200634if exists("b:is_kornshell") && !exists("b:is_ksh88") && !exists("b:is_mksh")
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100635 syn keyword shFunctionKey namespace skipwhite skipnl nextgroup=shFunctionTwo
636endif
637
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000638" Functions: {{{1
Bram Moolenaar690afe12017-01-28 18:34:47 +0100639if !exists("b:is_posix")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000640 syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
641endif
642
643if exists("b:is_bash")
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100644 syn keyword shFunctionKey coproc
Bram Moolenaar91c49372016-05-08 09:50:29 +0200645 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
646 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
647 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
648 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 +0000649else
Bram Moolenaar91c49372016-05-08 09:50:29 +0200650 ShFoldFunctions syn region shFunctionOne matchgroup=shFunction start="^\s*\h\w*\s*()\_s*{" end="}" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
651 ShFoldFunctions syn region shFunctionTwo matchgroup=shFunction start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{" end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
652 ShFoldFunctions syn region shFunctionThree matchgroup=shFunction start="^\s*\h\w*\s*()\_s*(" end=")" contains=@shFunctionList skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
653 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 +0000654endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000655
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000656" Parameter Dereferencing: {{{1
657" ========================
Bram Moolenaarbe4e0162023-02-02 13:59:48 +0000658" Note: sh04 failure with following line
659"if !exists("g:sh_no_error") && !(exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix"))
660if !exists("g:sh_no_error")
Bram Moolenaar91c49372016-05-08 09:50:29 +0200661 syn match shDerefWordError "[^}$[~]" contained
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100662endif
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100663syn match shDerefSimple "\$\%(\h\w*\|\d\)" nextgroup=@shNoZSList
Johnothan Kingb0691b42025-05-21 21:21:14 +0200664if exists("b:is_kornshell") && !exists("b:is_ksh88")
665 if exists("b:is_mksh")
666 syn region shDeref matchgroup=PreProc start="\${\ze[^ \t\n|]" end="}" contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
667 elseif exists("b:generic_korn")
668 syn region shDeref matchgroup=PreProc start="\${\ze[^ \t\n<|]" end="}" contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
669 else
670 syn region shDeref matchgroup=PreProc start="\${\ze[^ \t\n<]" end="}" contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
671 endif
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800672else
673 syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray nextgroup=shSpecialStart
674endif
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100675syn match shDerefSimple "\$[-#*@!?]" nextgroup=@shNoZSList
676syn match shDerefSimple "\$\$" nextgroup=@shNoZSList
Bram Moolenaar47e13952020-05-12 22:49:12 +0200677syn match shDerefSimple "\${\d}" nextgroup=@shNoZSList nextgroup=shSpecialStart
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200678if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaar47e13952020-05-12 22:49:12 +0200679 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList nextgroup=@shSpecialNoZS,shSpecialStart
680 syn region shDeref matchgroup=PreProc start="\${\$\$" end="}" contains=@shDerefList nextgroup=@shSpecialNoZS,shSpecialStart
Bram Moolenaar071d4272004-06-13 20:20:40 +0000681endif
682
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100683" ksh: ${.sh.*} variables: {{{1
684" ========================================
Johnothan Kingb0691b42025-05-21 21:21:14 +0200685if exists("b:is_kornshell") && !exists("b:is_ksh88") && !exists("b:is_mksh")
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100686 syn match shDerefVar contained "\.\+" nextgroup=@shDerefVarList
Johnothan Kingb0691b42025-05-21 21:21:14 +0200687 syn region shDeref matchgroup=PreProc start="\${\ze[\.]" end="}" contains=@shDerefVarList,shDerefPSR,shDerefPPS
Bram Moolenaar6ba83ba2022-06-12 22:15:57 +0100688endif
689
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100690" ksh: ${!var[*]} array index list syntax: {{{1
691" ========================================
Johnothan Kingb0691b42025-05-21 21:21:14 +0200692if (exists("b:is_kornshell") && !exists("b:is_ksh88")) || exists("b:is_posix")
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100693 syn region shDeref matchgroup=PreProc start="\${!" end="}" contains=@shDerefVarArray
694endif
695
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000696" bash: ${!prefix*} and ${#parameter}: {{{1
697" ====================================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000698if exists("b:is_bash")
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200699 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOffset
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200700 syn match shDerefVar contained "{\@<=!\h\w*" nextgroup=@shDerefVarList
Bram Moolenaar071d4272004-06-13 20:20:40 +0000701endif
Johnothan Kingb0691b42025-05-21 21:21:14 +0200702if (exists("b:is_kornshell") && !exists("b:is_ksh88"))
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200703 syn match shDerefVar contained "{\@<=!\h\w*[[:alnum:]_.]*" nextgroup=@shDerefVarList
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100704endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000705
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200706syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOffset,shDerefOpError
Bram Moolenaar071d4272004-06-13 20:20:40 +0000707syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200708syn match shDerefVar contained "{\@<=\h\w*" nextgroup=@shDerefVarList
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200709syn match shDerefVar contained '\d' nextgroup=@shDerefVarList
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200710if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarbc8801c2016-08-02 21:04:33 +0200711 syn match shDerefVar contained "{\@<=\h\w*[[:alnum:]_.]*" nextgroup=@shDerefVarList
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100712endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000713
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000714" sh ksh bash : ${var[... ]...} array reference: {{{1
Lucien Grondince3b0132023-11-04 09:41:37 +0100715syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError,shDerefOffset
Bram Moolenaar071d4272004-06-13 20:20:40 +0000716
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000717" Special ${parameter OPERATOR word} handling: {{{1
Bram Moolenaare2719092015-01-10 15:09:25 +0100718" sh ksh bash : ${parameter:-word} word is default value
719" sh ksh bash : ${parameter:=word} assign word as default value
720" sh ksh bash : ${parameter:?word} display word if parameter is null
721" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing
722" ksh bash : ${parameter#pattern} remove small left pattern
723" ksh bash : ${parameter##pattern} remove large left pattern
724" ksh bash : ${parameter%pattern} remove small right pattern
725" ksh bash : ${parameter%%pattern} remove large right pattern
Johnothan Kingb0691b42025-05-21 21:21:14 +0200726" ksh bash : ${parameter^pattern} Case modification
727" ksh bash : ${parameter^^pattern} Case modification
728" ksh bash : ${parameter,pattern} Case modification
729" ksh bash : ${parameter,,pattern} Case modification
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200730" bash : ${@:start:qty} display command line arguments from start to start+qty-1 (inferred)
Bram Moolenaardd60c362023-02-27 15:49:53 +0000731" bash : ${parameter@operator} transforms parameter (operator∈[uULqEPARa])
Bram Moolenaar071d4272004-06-13 20:20:40 +0000732syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100733if !exists("g:sh_no_error")
734 syn match shDerefOpError contained ":[[:punct:]]"
735endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000736syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList
737syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200738if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200739 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList
740 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100741 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern skipnl
Bram Moolenaar071d4272004-06-13 20:20:40 +0000742 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100743 " Match parametric bracket expressions with a leading whitespace character.
744 syn region shDerefPattern contained matchgroup=shBracketExprDelim start="\[" end="\]" contains=@shBracketExprList,shDoubleQuote nextgroup=shDerefPattern
745 call s:GenerateBracketExpressionItems({'itemGroup': 'shDerefPattern', 'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'contained nextgroup=shDerefPattern'})
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000746 syn match shDerefEscape contained '\%(\\\\\)*\\.'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000747endif
Johnothan Kingb0691b42025-05-21 21:21:14 +0200748if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88") && !exists("b:is_mksh") && !exists("b:is_ksh93u") && !exists("b:is_ksh2020"))
Bram Moolenaard960d762011-09-21 19:22:10 +0200749 syn match shDerefOp contained "[,^]\{1,2}" nextgroup=@shDerefPatternList
Johnothan Kingb0691b42025-05-21 21:21:14 +0200750endif
751if exists("b:is_bash")
Bram Moolenaardd60c362023-02-27 15:49:53 +0000752 syn match shDerefOp contained "@[uULQEPAKa]"
Bram Moolenaard960d762011-09-21 19:22:10 +0200753endif
Doug Kearnsfe228672025-05-05 20:10:11 +0200754syn region shDerefString contained matchgroup=shDerefDelim start=+\%(\\\)\@<!'+ end=+'+
Bram Moolenaar4b22cdb2010-08-02 22:12:46 +0200755syn region shDerefString contained matchgroup=shDerefDelim start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial
Bram Moolenaarc236c162008-07-13 17:41:49 +0000756syn match shDerefString contained "\\["']" nextgroup=shDerefPattern
Bram Moolenaar071d4272004-06-13 20:20:40 +0000757
Johnothan Kingb0691b42025-05-21 21:21:14 +0200758if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88")) || exists("b:is_posix")
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200759 " bash ksh posix : ${parameter:offset}
760 " bash ksh posix : ${parameter:offset:length}
761 syn region shDerefOffset contained start=':[^-=?+]' end='\ze:' end='\ze}' contains=shDeref,shDerefSimple,shDerefEscape nextgroup=shDerefLen,shDeref,shDerefSimple
762 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 +0200763 syn match shDerefLen contained ":[^}]\+" contains=shDeref,shDerefSimple,shArithmetic
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200764endif
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000765
Johnothan Kingb0691b42025-05-21 21:21:14 +0200766if exists("b:is_bash") || (exists("b:is_kornshell") && !exists("b:is_ksh88"))
767 " bash ksh : ${parameter/pattern/string}
768 " bash ksh : ${parameter//pattern/string}
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +0000769 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200770 syn region shDerefPPSleft contained start='.' skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp end='/' end='\ze}' end='"' nextgroup=shDerefPPSright contains=@shPPSLeftList
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100771 syn region shDerefPPSright contained start='.' skip=@\%(\\\\\)\+@ end='\ze}' contains=@shPPSRightList
Bram Moolenaaracb4f222016-01-10 15:59:26 +0100772
Johnothan Kingb0691b42025-05-21 21:21:14 +0200773 " bash ksh : ${parameter/#pattern/string}
774 " bash ksh : ${parameter/%pattern/string}
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100775 syn match shDerefPSR contained '/[#%]' nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
776 syn region shDerefPSRleft contained start='[^"']' skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp end='/' end='\ze}' nextgroup=shDerefPSRright contains=shBracketExpr
Bram Moolenaaracb4f222016-01-10 15:59:26 +0100777 syn region shDerefPSRright contained start='.' skip=@\%(\\\\\)\+@ end='\ze}'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000778endif
779
Bram Moolenaarc236c162008-07-13 17:41:49 +0000780" Arithmetic Parenthesized Expressions: {{{1
Bram Moolenaarbc488a72013-07-05 21:01:22 +0200781"syn region shParen matchgroup=shArithRegion start='[^$]\zs(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
782syn region shParen matchgroup=shArithRegion start='\$\@!(\%(\ze[^(]\|$\)' end=')' contains=@shArithParenList
Bram Moolenaarc236c162008-07-13 17:41:49 +0000783
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200784" Additional sh Keywords: {{{1
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000785" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +0000786syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait
787syn keyword shConditional contained elif else then
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100788if !exists("g:sh_no_error")
789 syn keyword shCondError elif else then
790endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000791
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200792" Additional ksh Keywords and Aliases: {{{1
793" ===================================
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100794if exists("b:is_kornshell") || exists("b:is_posix")
795 syn keyword shStatement bg builtin disown enum export false fg getconf getopts hist jobs let printf sleep true unalias whence
796 syn keyword shStatement typeset skipwhite nextgroup=shSetOption
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200797 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 +0100798 if exists("b:is_posix")
Bram Moolenaarc236c162008-07-13 17:41:49 +0000799 syn keyword shStatement command
800 else
801 syn keyword shStatement time
802 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000803
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200804" Additional bash Keywords: {{{1
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000805" =====================
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100806elseif exists("b:is_bash")
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100807 syn keyword shStatement bg builtin disown export false fg getopts jobs let printf true unalias
Bram Moolenaarb730f0c2018-11-25 03:56:26 +0100808 syn keyword shStatement typeset nextgroup=shSetOption
809 syn keyword shStatement fc hash history source suspend times type
Eisuke Kawashima54cb5142025-01-18 10:11:28 +0100810 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 +0100811else
812 syn keyword shStatement login newgrp
Bram Moolenaar071d4272004-06-13 20:20:40 +0000813endif
814
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000815" Synchronization: {{{1
816" ================
Bram Moolenaar03413f42016-04-12 21:07:15 +0200817if !exists("g:sh_minlines")
818 let s:sh_minlines = 200
819else
820 let s:sh_minlines= g:sh_minlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000821endif
Bram Moolenaar03413f42016-04-12 21:07:15 +0200822if !exists("g:sh_maxlines")
823 let s:sh_maxlines = 2*s:sh_minlines
824 if s:sh_maxlines < 25
825 let s:sh_maxlines= 25
826 endif
827else
828 let s:sh_maxlines= g:sh_maxlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000829endif
Bram Moolenaar03413f42016-04-12 21:07:15 +0200830exec "syn sync minlines=" . s:sh_minlines . " maxlines=" . s:sh_maxlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000831syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
832syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
833syn sync match shDoSync grouphere shDo "\<do\>"
834syn sync match shDoSync groupthere shDo "\<done\>"
835syn sync match shForSync grouphere shFor "\<for\>"
836syn sync match shForSync groupthere shFor "\<in\>"
837syn sync match shIfSync grouphere shIf "\<if\>"
838syn sync match shIfSync groupthere shIf "\<fi\>"
839syn sync match shUntilSync grouphere shRepeat "\<until\>"
840syn sync match shWhileSync grouphere shRepeat "\<while\>"
841
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000842" Default Highlighting: {{{1
843" =====================
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200844if !exists("skip_sh_syntax_inits")
845 hi def link shArithRegion shShellVariables
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100846 hi def link shArrayValue shDeref
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200847 hi def link shAstQuote shDoubleQuote
848 hi def link shAtExpr shSetList
Bram Moolenaard2855f52018-07-31 22:23:58 +0200849 hi def link shBkslshSnglQuote shSingleQuote
850 hi def link shBkslshDblQuote shDOubleQuote
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200851 hi def link shBeginHere shRedir
852 hi def link shCaseBar shConditional
853 hi def link shCaseCommandSub shCommandSub
854 hi def link shCaseDoubleQuote shDoubleQuote
855 hi def link shCaseIn shConditional
856 hi def link shQuote shOperator
857 hi def link shCaseSingleQuote shSingleQuote
858 hi def link shCaseStart shConditional
859 hi def link shCmdSubRegion shShellVariables
860 hi def link shColon shComment
861 hi def link shDerefOp shOperator
862 hi def link shDerefPOL shDerefOp
863 hi def link shDerefPPS shDerefOp
864 hi def link shDerefPSR shDerefOp
865 hi def link shDeref shShellVariables
866 hi def link shDerefDelim shOperator
867 hi def link shDerefSimple shDeref
868 hi def link shDerefSpecial shDeref
869 hi def link shDerefString shDoubleQuote
870 hi def link shDerefVar shDeref
871 hi def link shDoubleQuote shString
872 hi def link shEcho shString
873 hi def link shEchoDelim shOperator
874 hi def link shEchoQuote shString
875 hi def link shForPP shLoop
876 hi def link shFunction Function
877 hi def link shEmbeddedEcho shString
878 hi def link shEscape shCommandSub
879 hi def link shExDoubleQuote shDoubleQuote
880 hi def link shExSingleQuote shSingleQuote
881 hi def link shHereDoc shString
882 hi def link shHereString shRedir
883 hi def link shHerePayload shHereDoc
884 hi def link shLoop shStatement
885 hi def link shSpecialNxt shSpecial
886 hi def link shNoQuote shDoubleQuote
887 hi def link shOption shCommandSub
888 hi def link shPattern shString
889 hi def link shParen shArithmetic
890 hi def link shPosnParm shShellVariables
891 hi def link shQuickComment shComment
Bram Moolenaar93a1df22018-09-10 11:51:50 +0200892 hi def link shBQComment shComment
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200893 hi def link shRange shOperator
894 hi def link shRedir shOperator
895 hi def link shSetListDelim shOperator
896 hi def link shSetOption shOption
897 hi def link shSingleQuote shString
898 hi def link shSource shOperator
899 hi def link shStringSpecial shSpecial
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200900 hi def link shSpecialStart shSpecial
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200901 hi def link shSubShRegion shOperator
902 hi def link shTestOpr shConditional
903 hi def link shTestPattern shString
904 hi def link shTestDoubleQuote shString
905 hi def link shTestSingleQuote shString
906 hi def link shTouchCmd shStatement
907 hi def link shVariable shSetList
908 hi def link shWrapLineOperator shOperator
Bram Moolenaar071d4272004-06-13 20:20:40 +0000909
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200910 if exists("b:is_bash")
911 hi def link bashAdminStatement shStatement
912 hi def link bashSpecialVariables shShellVariables
913 hi def link bashStatement shStatement
914 hi def link shCharClass shSpecial
Bram Moolenaard58a3bf2020-09-28 21:48:16 +0200915 hi def link shDerefOffset shDerefOp
916 hi def link shDerefLen shDerefOffset
Bram Moolenaar6be7f872012-01-20 21:08:56 +0100917 endif
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200918 if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200919 hi def link kshSpecialVariables shShellVariables
920 hi def link kshStatement shStatement
921 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000922
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200923 if !exists("g:sh_no_error")
924 hi def link shCaseError Error
925 hi def link shCondError Error
926 hi def link shCurlyError Error
927 hi def link shDerefOpError Error
928 hi def link shDerefWordError Error
929 hi def link shDoError Error
930 hi def link shEsacError Error
931 hi def link shIfError Error
932 hi def link shInError Error
933 hi def link shParenError Error
934 hi def link shTestError Error
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +0200935 if exists("b:is_kornshell") || exists("b:is_posix")
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200936 hi def link shDTestError Error
937 endif
938 endif
939
940 hi def link shArithmetic Special
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100941 hi def link shBracketExprDelim Delimiter
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200942 hi def link shCharClass Identifier
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100943 hi def link shCollSymb shCharClass
944 hi def link shEqClass shCharClass
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200945 hi def link shSnglCase Statement
946 hi def link shCommandSub Special
Bram Moolenaard2855f52018-07-31 22:23:58 +0200947 hi def link shCommandSubBQ shCommandSub
Johnothan Kingadd31ba2024-01-22 11:19:54 -0800948 hi def link shSubshare shCommandSub
949 hi def link shValsub shCommandSub
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200950 hi def link shComment Comment
951 hi def link shConditional Conditional
952 hi def link shCtrlSeq Special
953 hi def link shExprRegion Delimiter
954 hi def link shFunctionKey Function
955 hi def link shFunctionName Function
956 hi def link shNumber Number
957 hi def link shOperator Operator
958 hi def link shRepeat Repeat
959 hi def link shSet Statement
960 hi def link shSetList Identifier
961 hi def link shShellVariables PreProc
962 hi def link shSpecial Special
Bram Moolenaard2855f52018-07-31 22:23:58 +0200963 hi def link shSpecialDQ Special
964 hi def link shSpecialSQ Special
Bram Moolenaarb0d45e72017-11-05 18:19:24 +0100965 hi def link shSpecialNoZS shSpecial
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200966 hi def link shStatement Statement
967 hi def link shString String
968 hi def link shTodo Todo
969 hi def link shAlias Identifier
970 hi def link shHereDoc01 shRedir
971 hi def link shHereDoc02 shRedir
972 hi def link shHereDoc03 shRedir
973 hi def link shHereDoc04 shRedir
974 hi def link shHereDoc05 shRedir
975 hi def link shHereDoc06 shRedir
976 hi def link shHereDoc07 shRedir
977 hi def link shHereDoc08 shRedir
978 hi def link shHereDoc09 shRedir
979 hi def link shHereDoc10 shRedir
980 hi def link shHereDoc11 shRedir
981 hi def link shHereDoc12 shRedir
982 hi def link shHereDoc13 shRedir
983 hi def link shHereDoc14 shRedir
984 hi def link shHereDoc15 shRedir
Bram Moolenaar23515b42020-11-29 14:36:24 +0100985 hi def link shHereDoc16 shRedir
Bram Moolenaarf37506f2016-08-31 22:22:10 +0200986endif
Bram Moolenaarb4ff5182015-11-10 21:15:48 +0100987
988" Delete shell folding commands {{{1
989" =============================
990delc ShFoldFunctions
991delc ShFoldHereDoc
992delc ShFoldIfDoFor
Bram Moolenaar071d4272004-06-13 20:20:40 +0000993
Aliaksei Budavei48fa3192024-12-30 10:23:50 +0100994" Delete the bracket expression function {{{1
995" ======================================
996delfun s:GenerateBracketExpressionItems
997
Bram Moolenaard4755bb2004-09-02 19:12:26 +0000998" Set Current Syntax: {{{1
999" ===================
Bram Moolenaar071d4272004-06-13 20:20:40 +00001000if exists("b:is_bash")
1001 let b:current_syntax = "bash"
1002elseif exists("b:is_kornshell")
1003 let b:current_syntax = "ksh"
Bram Moolenaar51ad4ea2018-04-06 11:14:11 +02001004elseif exists("b:is_posix")
1005 let b:current_syntax = "posix"
Bram Moolenaar071d4272004-06-13 20:20:40 +00001006else
1007 let b:current_syntax = "sh"
1008endif
1009
Bram Moolenaard4755bb2004-09-02 19:12:26 +00001010" vim: ts=16 fdm=marker