1" Vim syntax file 2" Language: shell (sh) Korn shell (ksh) bash (sh) 3" Maintainer: Dr. Charles E. Campbell, Jr. <[email protected]> 4" Previous Maintainer: Lennart Schultz <[email protected]> 5" Last Change: Sep 06, 2005 6" Version: 77 7" URL: http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax 8" 9" Using the following VIM variables: {{{1 10" b:is_kornshell if defined, enhance with kornshell syntax 11" b:is_bash if defined, enhance with bash syntax 12" is_kornshell if neither b:is_kornshell or b:is_bash is 13" defined, then if is_kornshell is set 14" b:is_kornshell is default 15" is_bash if none of the previous three variables are 16" defined, then if is_bash is set b:is_bash is default 17" g:sh_fold_enabled if non-zero, syntax folding is enabled 18" sh_minlines sets up syn sync minlines (default: 200) 19" sh_maxlines sets up syn sync maxlines (default: twice sh_minlines) 20" 21" This file includes many ideas from �ric Brunet ([email protected]) 22 23" For version 5.x: Clear all syntax items {{{1 24" For version 6.x: Quit when a syntax file was already loaded 25if version < 600 26 syntax clear 27elseif exists("b:current_syntax") 28 finish 29endif 30 31" handling /bin/sh with is_kornshell/is_sh {{{1 32" b:is_sh is set when "#! /bin/sh" is found; 33" However, it often is just a masquerade by bash (typically Linux) 34" or kornshell (typically workstations with Posix "sh"). 35" So, when the user sets "is_bash" or "is_kornshell", 36" a b:is_sh is converted into b:is_bash/b:is_kornshell, 37" respectively. 38if !exists("b:is_kornshell") && !exists("b:is_bash") 39 if exists("is_kornshell") 40 let b:is_kornshell= 1 41 if exists("b:is_sh") 42 unlet b:is_sh 43 endif 44 elseif exists("is_bash") 45 let b:is_bash= 1 46 if exists("b:is_sh") 47 unlet b:is_sh 48 endif 49 else 50 let b:is_sh= 1 51 endif 52endif 53 54" set up default g:sh_fold_enabled {{{1 55if !exists("g:sh_fold_enabled") 56 let g:sh_fold_enabled= 0 57elseif g:sh_fold_enabled != 0 && !has("folding") 58 let g:sh_fold_enabled= 0 59 echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile vim for +fold support" 60endif 61if g:sh_fold_enabled && &fdm == "manual" 62 set fdm=syntax 63endif 64 65" sh syntax is case sensitive {{{1 66syn case match 67 68" Clusters: contains=@... clusters {{{1 69"================================== 70syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shSpecial 71syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shSpecial 72syn cluster shColonList contains=@shCaseList 73syn cluster shCommandSubList contains=shArithmetic,shDeref,shDerefSimple,shNumber,shOperator,shPosnParm,shSpecial,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest 74syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial 75syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shSpecial,shPosnParm 76syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS 77syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError 78syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial 79syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple 80syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest 81syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shSpecial,shOperator,shFunctionStart 82syn cluster shHereBeginList contains=@shCommandSubList 83syn cluster shHereList contains=shBeginHere,shHerePayload 84syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload 85syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr 86syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest 87syn cluster shSubShList contains=@shCaseList 88syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shSpecial,shTestOpr,shTest 89 90 91" Echo: {{{1 92" ==== 93" This one is needed INSIDE a CommandSub, so that `echo bla` be correct 94syn region shEcho matchgroup=shStatement start="\<echo\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList 95syn region shEcho matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|()]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=@shEchoList 96 97" This must be after the strings, so that bla \" be correct 98syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shOperator end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="#"me=e-1 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shSpecial,shOperator,shDoubleQuote,shCharClass 99 100" Alias: {{{1 101" ===== 102if exists("b:is_kornshell") || exists("b:is_bash") 103 syn match shStatement "\<alias\>" 104 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`" 105 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="=" 106endif 107 108" Error Codes: {{{1 109" ============ 110syn match shDoError "\<done\>" 111syn match shIfError "\<fi\>" 112syn match shInError "\<in\>" 113syn match shCaseError ";;" 114syn match shEsacError "\<esac\>" 115syn match shCurlyError "}" 116syn match shParenError ")" 117if exists("b:is_kornshell") 118 syn match shDTestError "]]" 119endif 120syn match shTestError "]" 121 122" Options Interceptor: {{{1 123" ==================== 124syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1 125syn match shOption "\s--\S\+"ms=s+1 126 127" Operators: {{{1 128" ========== 129syn match shOperator "[!&;|]" 130syn match shOperator "\[[[^:]\|\]]" 131syn match shOperator "!\==" skipwhite nextgroup=shPattern 132syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref 133 134" Subshells: {{{1 135" ========== 136syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 137syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList 138 139" Tests: {{{1 140"======= 141"syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList 142syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList 143syn region shTest transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1 144syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!=<>]" 145if exists("b:is_kornshell") || exists("b:is_bash") 146 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList 147 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList 148endif 149 150" Character Class In Range: {{{1 151" ========================= 152syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]" 153 154" Loops: do, if, while, until {{{1 155" ====== 156syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList 157syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen 158syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen skipwhite nextgroup=shCurlyIn 159if exists("b:is_kornshell") || exists("b:is_bash") 160 syn cluster shCaseList add=shRepeat 161 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace 162 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace 163 syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList 164else 165 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2 contains=@shLoopList 166 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2 contains=@shLoopList 167endif 168syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}" contains=@shCurlyList 169syn match shComma contained "," 170 171" Case: case...esac {{{1 172" ==== 173syn match shCaseBar contained skipwhite "[^|"`'()]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote 174syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar 175syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="[^#$()]\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,,shComment 176syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList 177syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote 178if exists("b:is_bash") 179 syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained 180else 181 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained 182endif 183syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained 184syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained 185syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained 186 187" Misc: {{{1 188"====== 189syn match shWrapLineOperator "\\$" 190syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList 191 192" $() and $(()): {{{1 193" $(..) is not supported by sh (Bourne shell). However, apparently 194" some systems (HP?) have as their /bin/sh a (link to) Korn shell 195" (ie. Posix compliant shell). /bin/ksh should work for those 196" systems too, however, so the following syntax will flag $(..) as 197" an Error under /bin/sh. By consensus of vimdev'ers! 198if exists("b:is_kornshell") || exists("b:is_bash") 199 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList 200 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList 201 syn match shSkipInitWS contained "^\s\+" 202else 203 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList 204endif 205 206if exists("b:is_bash") 207 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement 208 syn cluster shCaseList add=bashAdminStatement,bashStatement 209 syn keyword bashSpecialVariables contained BASH BASH_ENV BASH_VERSINFO BASH_VERSION CDPATH DIRSTACK EUID FCEDIT FIGNORE GLOBIGNORE GROUPS HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_MESSAGES LINENO MACHTYPE MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS PPID PROMPT_COMMAND PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELLOPTS SHLVL TIMEFORMAT TIMEOUT UID auto_resume histchars 210 syn keyword bashStatement chmod clear complete du egrep expr fgrep find gnufind gnugrep grep install less ls mkdir mv rm rmdir rpm sed sleep sort strip tail touch 211 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop 212endif 213 214if exists("b:is_kornshell") 215 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement 216 syn cluster shCaseList add=kshStatement 217 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 218 syn keyword kshStatement cat chmod clear cp du egrep expr fgrep find grep install killall less ls mkdir mv nice printenv rm rmdir sed sort strip stty tail touch tput 219endif 220 221syn match shSource "^\.\s" 222syn match shSource "\s\.\s" 223syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList 224 225" String And Character Constants: {{{1 226"================================ 227syn match shNumber "-\=\<\d\+\>" 228if exists("b:is_bash") 229 syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained 230else 231 syn match shSpecial "\\\d\d\d\|\\[abcfnrtv0]" contained 232endif 233if exists("b:is_bash") 234 syn region shExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial 235else 236 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial 237endif 238syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial 239syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial 240syn match shStringSpecial "[^[:print:]]" contained 241syn match shSpecial "\\[\\\"\'`$()#]" 242 243" Comments: {{{1 244"========== 245syn cluster shCommentGroup contains=shTodo,@Spell 246syn keyword shTodo contained TODO 247syn match shComment "#.*$" contains=@shCommentGroup 248 249" File Redirection Highlighted As Operators: {{{1 250"=========================================== 251syn match shRedir "\d\=>\(&[-0-9]\)\=" 252syn match shRedir "\d\=>>-\=" 253syn match shRedir "\d\=<\(&[-0-9]\)\=" 254syn match shRedir "\d<<-\=" 255 256" Here Documents: {{{1 257" ========================================= 258if version < 600 259 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList 260 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^\s*END[a-zA-Z_0-9]*$" contains=@shDblQuoteList 261 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList 262 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList 263 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList 264 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList 265 266elseif g:sh_fold_enabled 267 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList 268 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 269 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$" 270 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList 271 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 272 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 273 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" 274 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 275 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 276 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" 277 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 278 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$" 279 280else 281 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList 282 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 283 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList 284 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 285 syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$" 286 syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 287 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" 288 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" 289 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 290 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$" 291 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 292 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 293endif 294 295" Here Strings: {{{1 296" ============= 297if exists("b:is_bash") 298 syn match shRedir "<<<" 299endif 300 301" Identifiers: {{{1 302"============= 303syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier 304syn match shIdWhiteSpace contained "\s" 305syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote 306if exists("b:is_bash") 307 syn region shSetList matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="#\|="me=e-1 contains=@shIdList 308 syn region shSetList matchgroup=shSet start="\<set\>[^/]"me=e-1 end="$" end="\\ze[|)]" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList 309 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)$" 310elseif exists("b:is_kornshell") 311 syn region shSetList matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList 312 syn region shSetList matchgroup=shSet start="\<set\>\ze[^/]" end="$\|\ze[})]" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList 313 syn match shSet "\<\(typeset\|set\|export\|unset\)$" 314else 315 syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]" matchgroup=shOperator end="[;&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList 316 syn match shStatement "\<\(set\|export\|unset\)$" 317endif 318 319" Functions: {{{1 320syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo 321syn match shFunctionStart "{" contained 322if g:sh_fold_enabled 323 syn region shFunctionOne transparent fold start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList 324 syn region shFunctionTwo transparent fold start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained 325else 326 syn region shFunctionOne transparent start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList 327 syn region shFunctionTwo transparent start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained 328endif 329 330" Parameter Dereferencing: {{{1 331" ======================== 332syn match shDerefSimple "\$\%(\h\w*\|\d\)" 333syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray 334syn match shDerefWordError "[^}$[]" contained 335syn match shDerefSimple "\$[-#*@!?]" 336syn match shDerefSimple "\$\$" 337if exists("b:is_bash") || exists("b:is_kornshell") 338 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList 339endif 340 341" bash: ${!prefix*} and ${#parameter}: {{{1 342" ==================================== 343if exists("b:is_bash") 344 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp 345 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList 346endif 347 348syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError 349syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp 350syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList 351 352" sh ksh bash : ${var[... ]...} array reference: {{{1 353syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError 354 355" Special ${parameter OPERATOR word} handling: {{{1 356" sh ksh bash : ${parameter:-word} word is default value 357" sh ksh bash : ${parameter:=word} assign word as default value 358" sh ksh bash : ${parameter:?word} display word if parameter is null 359" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing 360" ksh bash : ${parameter#pattern} remove small left pattern 361" ksh bash : ${parameter##pattern} remove large left pattern 362" ksh bash : ${parameter%pattern} remove small right pattern 363" ksh bash : ${parameter%%pattern} remove large right pattern 364syn cluster shDerefPatternList contains=shDerefPattern,shDerefString 365syn match shDerefOpError contained ":[[:punct:]]" 366syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList 367syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList 368if exists("b:is_bash") || exists("b:is_kornshell") 369 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList 370 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList 371 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern 372 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern 373 syn match shDerefEscape contained '\%(\\\\\)*\\.' 374endif 375syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial 376syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial 377syn match shDerefString contained "\\["']" 378 379if exists("b:is_bash") 380 " bash : ${parameter:offset} 381 " bash : ${parameter:offset:length} 382 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL 383 syn match shDerefPOL contained ":[^}]\+" contains=@shCommandSubList 384 385 " bash : ${parameter//pattern/string} 386 " bash : ${parameter//pattern} 387 syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft 388 syn region shDerefPPSleft contained start='.' skip=@\%(\\\)\/@ matchgroup=shDerefOp end='/' nextgroup=shDerefPPSright contains=@shCommandSubList 389 syn region shDerefPPSright contained start='.' end='\ze}' contains=@shCommandSubList 390endif 391 392" Useful sh Keywords: {{{1 393" =================== 394syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait 395syn keyword shConditional contained elif else then 396syn keyword shCondError elif else then 397 398" Useful ksh Keywords: {{{1 399" ==================== 400if exists("b:is_kornshell") || exists("b:is_bash") 401 syn keyword shStatement autoload bg false fc fg functions getopts hash history integer jobs let nohup print printf r stop suspend time times true type unalias whence 402 403" Useful bash Keywords: {{{1 404" ===================== 405 if exists("b:is_bash") 406 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source 407 else 408 syn keyword shStatement login newgrp 409 endif 410endif 411 412" Synchronization: {{{1 413" ================ 414if !exists("sh_minlines") 415 let sh_minlines = 200 416endif 417if !exists("sh_maxlines") 418 let sh_maxlines = 2 * sh_minlines 419endif 420exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines 421syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>" 422syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>" 423syn sync match shDoSync grouphere shDo "\<do\>" 424syn sync match shDoSync groupthere shDo "\<done\>" 425syn sync match shForSync grouphere shFor "\<for\>" 426syn sync match shForSync groupthere shFor "\<in\>" 427syn sync match shIfSync grouphere shIf "\<if\>" 428syn sync match shIfSync groupthere shIf "\<fi\>" 429syn sync match shUntilSync grouphere shRepeat "\<until\>" 430syn sync match shWhileSync grouphere shRepeat "\<while\>" 431 432" Default Highlighting: {{{1 433" ===================== 434hi def link shArithRegion shShellVariables 435hi def link shBeginHere shRedir 436hi def link shCaseBar shConditional 437hi def link shCaseCommandSub shCommandSub 438hi def link shCaseDoubleQuote shDoubleQuote 439hi def link shCaseIn shConditional 440hi def link shCaseSingleQuote shSingleQuote 441hi def link shCaseStart shConditional 442hi def link shCmdSubRegion shShellVariables 443hi def link shColon shStatement 444hi def link shDerefOp shOperator 445hi def link shDerefPOL shDerefOp 446hi def link shDerefPPS shDerefOp 447hi def link shDeref shShellVariables 448hi def link shDerefSimple shDeref 449hi def link shDerefSpecial shDeref 450hi def link shDerefString shDoubleQuote 451hi def link shDerefVar shDeref 452hi def link shDoubleQuote shString 453hi def link shEcho shString 454hi def link shEmbeddedEcho shString 455hi def link shExSingleQuote shSingleQuote 456hi def link shFunctionStart Delimiter 457hi def link shHereDoc shString 458hi def link shHerePayload shHereDoc 459hi def link shLoop shStatement 460hi def link shOption shCommandSub 461hi def link shPattern shString 462hi def link shPosnParm shShellVariables 463hi def link shRange shOperator 464hi def link shRedir shOperator 465hi def link shSingleQuote shString 466hi def link shSource shOperator 467hi def link shStringSpecial shSpecial 468hi def link shSubShRegion shOperator 469hi def link shTestOpr shConditional 470hi def link shVariable shSetList 471hi def link shWrapLineOperator shOperator 472 473if exists("b:is_bash") 474 hi def link bashAdminStatement shStatement 475 hi def link bashSpecialVariables shShellVariables 476 hi def link bashStatement shStatement 477 hi def link shFunctionParen Delimiter 478 hi def link shFunctionDelim Delimiter 479endif 480if exists("b:is_kornshell") 481 hi def link kshSpecialVariables shShellVariables 482 hi def link kshStatement shStatement 483 hi def link shFunctionParen Delimiter 484endif 485 486hi def link shCaseError Error 487hi def link shCondError Error 488hi def link shCurlyError Error 489hi def link shDerefError Error 490hi def link shDerefOpError Error 491hi def link shDerefWordError Error 492hi def link shDoError Error 493hi def link shEsacError Error 494hi def link shIfError Error 495hi def link shInError Error 496hi def link shParenError Error 497hi def link shTestError Error 498if exists("b:is_kornshell") 499 hi def link shDTestError Error 500endif 501 502hi def link shArithmetic Special 503hi def link shCharClass Identifier 504hi def link shSnglCase Statement 505hi def link shCommandSub Special 506hi def link shComment Comment 507hi def link shConditional Conditional 508hi def link shExprRegion Delimiter 509hi def link shFunctionKey Function 510hi def link shFunctionName Function 511hi def link shNumber Number 512hi def link shOperator Operator 513hi def link shRepeat Repeat 514hi def link shSet Statement 515hi def link shSetList Identifier 516hi def link shShellVariables PreProc 517hi def link shSpecial Special 518hi def link shStatement Statement 519hi def link shString String 520hi def link shTodo Todo 521hi def link shAlias Identifier 522 523" Set Current Syntax: {{{1 524" =================== 525if exists("b:is_bash") 526 let b:current_syntax = "bash" 527elseif exists("b:is_kornshell") 528 let b:current_syntax = "ksh" 529else 530 let b:current_syntax = "sh" 531endif 532 533" vim: ts=16 fdm=marker 534