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: Mar 24, 2005 6" Version: 74 7" URL: http://www.erols.com/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 shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shSpecial,shPosnParm 75syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError 76syn cluster shDerefVarList contains=shDerefOp,shDerefVarArray,shDerefOpError 77syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial 78syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shSpecial,shExpr,shDblBrace,shDeref,shDerefSimple 79syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest 80syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shSpecial,shOperator,shFunctionStart 81syn cluster shHereBeginList contains=@shCommandSubList 82syn cluster shHereList contains=shBeginHere,shHerePayload 83syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload 84syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shSpecial,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr 85syn cluster shLoopList contains=@shCaseList,shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest 86syn cluster shSubShList contains=@shCaseList 87syn cluster shTestList contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shSpecial,shTestOpr,shTest 88 89 90" Echo: {{{1 91" ==== 92" This one is needed INSIDE a CommandSub, so that `echo bla` be correct 93syn 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 94syn 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 95 96" This must be after the strings, so that bla \" be correct 97syn 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 98 99" Alias: {{{1 100" ===== 101if exists("b:is_kornshell") || exists("b:is_bash") 102 syn match shStatement "\<alias\>" 103 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)\@=" skip="\\$" end="\>\|`" 104 syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)\@=" skip="\\$" end="=" 105endif 106 107" Error Codes: {{{1 108" ============ 109syn match shDoError "\<done\>" 110syn match shIfError "\<fi\>" 111syn match shInError "\<in\>" 112syn match shCaseError ";;" 113syn match shEsacError "\<esac\>" 114syn match shCurlyError "}" 115syn match shParenError ")" 116if exists("b:is_kornshell") 117 syn match shDTestError "]]" 118endif 119syn match shTestError "]" 120 121" Options Interceptor: {{{1 122" ==================== 123syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1 124syn match shOption "\s--\S\+"ms=s+1 125 126" Operators: {{{1 127" ========== 128syn match shOperator "[!&;|]" 129syn match shOperator "\[[[^:]\|\]]" 130syn match shOperator "!\==" skipwhite nextgroup=shPattern 131syn match shPattern "\<\S\+\())\)\@=" contained contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref 132 133" Subshells: {{{1 134" ========== 135syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 136syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")" contains=@shSubShList 137 138" Tests: {{{1 139"======= 140"syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList 141syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]" contains=@shTestList 142syn region shTest transparent matchgroup=shStatement start="\<test\>" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1 143syn match shTestOpr contained "<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!=<>]" 144if exists("b:is_kornshell") || exists("b:is_bash") 145 syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+ end="\]\]" contains=@shTestList 146 syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+ end="))" contains=@shTestList 147endif 148 149" Character Class In Range: {{{1 150" ========================= 151syn match shCharClass contained "\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]" 152 153" Loops: do, if, while, until {{{1 154" ====== 155syn region shDo transparent matchgroup=shConditional start="\<do\>" matchgroup=shConditional end="\<done\>" contains=@shLoopList 156syn region shIf transparent matchgroup=shConditional start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" contains=@shLoopList,shDblBrace,shDblParen 157syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen 158if exists("b:is_kornshell") || exists("b:is_bash") 159 syn cluster shCaseList add=shRepeat 160 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace 161 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>" end="\<do\>"me=e-2 contains=@shLoopList,shDblParen,shDblBrace 162 syn region shCaseEsac matchgroup=shConditional start="\<select\>" matchgroup=shConditional end="\<in\>" end="\<do\>" contains=@shLoopList 163else 164 syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2 contains=@shLoopList 165 syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2 contains=@shLoopList 166endif 167 168" Case: case...esac {{{1 169" ==== 170syn match shCaseBar contained skipwhite "[^|"`'()]\{-}|"hs=e nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote 171syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar 172syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="[^#$()]\{-})"ms=s,hs=e end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,,shComment 173syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList 174syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote 175if exists("b:is_bash") 176 syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite skipnl nextgroup=shCaseBar contained 177else 178 syn region shCaseExSingleQuote matchgroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained 179endif 180syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained 181syn region shCaseDoubleQuote matchgroup=shOperator start=+"+ skip=+\\\\\|\\.+ end=+"+ contains=@shDblQuoteList,shStringSpecial skipwhite skipnl nextgroup=shCaseBar contained 182syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+ contains=@shCommandSubList skipwhite skipnl nextgroup=shCaseBar contained 183 184" Misc: {{{1 185"====== 186syn match shWrapLineOperator "\\$" 187syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList 188 189" $() and $(()): {{{1 190" $(..) is not supported by sh (Bourne shell). However, apparently 191" some systems (HP?) have as their /bin/sh a (link to) Korn shell 192" (ie. Posix compliant shell). /bin/ksh should work for those 193" systems too, however, so the following syntax will flag $(..) as 194" an Error under /bin/sh. By consensus of vimdev'ers! 195if exists("b:is_kornshell") || exists("b:is_bash") 196 syn region shCommandSub matchgroup=shCmdSubRegion start="\$(" skip='\\\\\|\\.' end=")" contains=@shCommandSubList 197 syn region shArithmetic matchgroup=shArithRegion start="\$((" skip='\\\\\|\\.' end="))" contains=@shCommandSubList 198 syn match shSkipInitWS contained "^\s\+" 199else 200 syn region shCommandSub matchgroup=Error start="\$(" end=")" contains=@shCommandSubList 201endif 202 203if exists("b:is_bash") 204 syn cluster shCommandSubList add=bashSpecialVariables,bashStatement 205 syn cluster shCaseList add=bashAdminStatement,bashStatement 206 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 207 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 208 syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop 209endif 210 211if exists("b:is_kornshell") 212 syn cluster shCommandSubList add=kshSpecialVariables,kshStatement 213 syn cluster shCaseList add=kshStatement 214 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 215 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 216endif 217 218syn match shSource "^\.\s" 219syn match shSource "\s\.\s" 220syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 contains=@shColonList 221 222" String And Character Constants: {{{1 223"================================ 224syn match shNumber "-\=\<\d\+\>" 225if exists("b:is_bash") 226 syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained 227else 228 syn match shSpecial "\\\d\d\d\|\\[abcfnrtv0]" contained 229endif 230if exists("b:is_bash") 231 syn region shExSingleQuote matchgroup=shOperator start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial 232else 233 syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial 234endif 235syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial 236syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial 237syn match shStringSpecial "[^[:print:]]" contained 238syn match shSpecial "\\[\\\"\'`$()#]" 239 240" Comments: {{{1 241"========== 242syn cluster shCommentGroup contains=shTodo,@Spell 243syn keyword shTodo contained TODO 244syn match shComment "#.*$" contains=@shCommentGroup 245 246" File Redirection Highlighted As Operators: {{{1 247"=========================================== 248syn match shRedir "\d\=>\(&[-0-9]\)\=" 249syn match shRedir "\d\=>>-\=" 250syn match shRedir "\d\=<\(&[-0-9]\)\=" 251syn match shRedir "\d<<-\=" 252 253" Here Documents: {{{1 254" ========================================= 255if version < 600 256 syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**" matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" contains=@shDblQuoteList 257 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 258 syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**" matchgroup=shRedir end="^EOF$" contains=@shDblQuoteList 259 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**" matchgroup=shRedir end="^\s*EOF$" contains=@shDblQuoteList 260 syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**" matchgroup=shRedir end="^\.$" contains=@shDblQuoteList 261 syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**" matchgroup=shRedir end="^\s*\.$" contains=@shDblQuoteList 262 263elseif g:sh_fold_enabled 264 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList 265 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 266 syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$" 267 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList 268 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 269 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 270 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" 271 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 272 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 273 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" 274 syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 275 syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'" matchgroup=shRedir end="^\z1\s*$" 276 277else 278 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" contains=@shDblQuoteList 279 syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$" 280 syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" contains=@shDblQuoteList 281 syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'" matchgroup=shRedir end="^\s*\z1\s*$" 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*$" 284 syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\z1\s*$" 285 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)" matchgroup=shRedir end="^\s*\z1\s*$" 286 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_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="^\z1\s*$" 289 syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$" 290endif 291 292" Here Strings: {{{1 293" ============= 294if exists("b:is_bash") 295 syn match shRedir "<<<" 296endif 297 298" Identifiers: {{{1 299"============= 300syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shSetIdentifier 301syn match shIdWhiteSpace contained "\s" 302syn match shSetIdentifier contained "=" nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote 303if exists("b:is_bash") 304 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 305 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 306 syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)$" 307elseif exists("b:is_kornshell") 308 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 309 syn region shSetList matchgroup=shSet start="\<set\>\ze[^/]" end="$\|\ze[})]" matchgroup=shOperator end="[;&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList 310 syn match shSet "\<\(typeset\|set\|export\|unset\)$" 311else 312 syn region shSetList matchgroup=shSet start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]" matchgroup=shOperator end="[;&]" matchgroup=NONE end="[#=]"me=e-1 contains=@shIdList 313 syn match shStatement "\<\(set\|export\|unset\)$" 314endif 315 316" Functions: {{{1 317syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo 318syn match shFunctionStart "{" contained 319if g:sh_fold_enabled 320 syn region shFunctionOne transparent fold start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList 321 syn region shFunctionTwo transparent fold start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained 322else 323 syn region shFunctionOne transparent start="^\s*\h\w*\s*()\_s*\ze{" matchgroup=shFunctionStart end="}" contains=@shFunctionList 324 syn region shFunctionTwo transparent start="\h\w*\s*\%(()\)\=\_s*\ze{" matchgroup=shFunctionStart end="}" contains=shFunctionKey,@shFunctionList contained 325endif 326 327" Parameter Dereferencing: {{{1 328" ======================== 329syn match shDerefSimple "\$\%(\h\w*\|\d\)" 330syn region shDeref matchgroup=PreProc start="\${" end="}" contains=@shDerefList,shDerefVarArray 331syn match shDerefWordError "[^}$[]" contained 332syn match shDerefSimple "\$[-#*@!?]" 333syn match shDerefSimple "\$\$" 334if exists("b:is_bash") || exists("b:is_kornshell") 335 syn region shDeref matchgroup=PreProc start="\${##\=" end="}" contains=@shDerefList 336endif 337 338" bash: ${!prefix*} and ${#parameter}: {{{1 339" ==================================== 340if exists("b:is_bash") 341 syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" contains=@shDerefList,shDerefOp 342 syn match shDerefVar contained "{\@<=!\w\+" nextgroup=@shDerefVarList 343endif 344 345syn match shDerefSpecial contained "{\@<=[-*@?0]" nextgroup=shDerefOp,shDerefOpError 346syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:]*@_]\+" nextgroup=@shDerefVarList,shDerefOp 347syn match shDerefVar contained "{\@<=\w\+" nextgroup=@shDerefVarList 348 349" sh ksh bash : ${var[... ]...} array reference: {{{1 350syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]" contains=@shCommandSubList nextgroup=shDerefOp,shDerefOpError 351 352" Special ${parameter OPERATOR word} handling: {{{1 353" sh ksh bash : ${parameter:-word} word is default value 354" sh ksh bash : ${parameter:=word} assign word as default value 355" sh ksh bash : ${parameter:?word} display word if parameter is null 356" sh ksh bash : ${parameter:+word} use word if parameter is not null, otherwise nothing 357" ksh bash : ${parameter#pattern} remove small left pattern 358" ksh bash : ${parameter##pattern} remove large left pattern 359" ksh bash : ${parameter%pattern} remove small right pattern 360" ksh bash : ${parameter%%pattern} remove large right pattern 361syn cluster shDerefPatternList contains=shDerefPattern,shDerefString 362syn match shDerefOpError contained ":[[:punct:]]" 363syn match shDerefOp contained ":\=[-=?]" nextgroup=@shDerefPatternList 364syn match shDerefOp contained ":\=+" nextgroup=@shDerefPatternList 365if exists("b:is_bash") || exists("b:is_kornshell") 366 syn match shDerefOp contained "#\{1,2}" nextgroup=@shDerefPatternList 367 syn match shDerefOp contained "%\{1,2}" nextgroup=@shDerefPatternList 368 syn match shDerefPattern contained "[^{}]\+" contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub nextgroup=shDerefPattern 369 syn region shDerefPattern contained start="{" end="}" contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern 370endif 371syn region shDerefString contained matchgroup=shOperator start=+'+ end=+'+ contains=shStringSpecial 372syn region shDerefString contained matchgroup=shOperator start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial 373syn match shDerefString contained "\\["']" 374 375" bash : ${parameter:offset} 376" bash : ${parameter:offset:length} 377" bash : ${parameter//pattern/string} 378" bash : ${parameter//pattern} 379if exists("b:is_bash") 380 syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1 end=":"me=e-1 end="}"me=e-1 contains=@shCommandSubList nextgroup=shDerefPOL 381 syn match shDerefPOL contained ":[^}]\{1,}" contains=@shCommandSubList 382 syn match shDerefOp contained "/\{1,2}" nextgroup=shDerefPat 383 syn match shDerefPat contained "[^/}]\{1,}" nextgroup=shDerefPatStringOp 384 syn match shDerefPatStringOp contained "/" nextgroup=shDerefPatString 385 syn match shDerefPatString contained "[^}]\{1,}" 386endif 387 388" Useful sh Keywords: {{{1 389" =================== 390syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait 391syn keyword shConditional contained elif else then 392syn keyword shCondError elif else then 393 394" Useful ksh Keywords: {{{1 395" ==================== 396if exists("b:is_kornshell") || exists("b:is_bash") 397 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 398 399" Useful bash Keywords: {{{1 400" ===================== 401 if exists("b:is_bash") 402 syn keyword shStatement bind builtin dirs disown enable help local logout popd pushd shopt source 403 else 404 syn keyword shStatement login newgrp 405 endif 406endif 407 408" Synchronization: {{{1 409" ================ 410if !exists("sh_minlines") 411 let sh_minlines = 200 412endif 413if !exists("sh_maxlines") 414 let sh_maxlines = 2 * sh_minlines 415endif 416exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines 417syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>" 418syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>" 419syn sync match shDoSync grouphere shDo "\<do\>" 420syn sync match shDoSync groupthere shDo "\<done\>" 421syn sync match shForSync grouphere shFor "\<for\>" 422syn sync match shForSync groupthere shFor "\<in\>" 423syn sync match shIfSync grouphere shIf "\<if\>" 424syn sync match shIfSync groupthere shIf "\<fi\>" 425syn sync match shUntilSync grouphere shRepeat "\<until\>" 426syn sync match shWhileSync grouphere shRepeat "\<while\>" 427 428" Default Highlighting: {{{1 429" ===================== 430hi def link shArithRegion shShellVariables 431hi def link shBeginHere shRedir 432hi def link shCaseBar shConditional 433hi def link shCaseCommandSub shCommandSub 434hi def link shCaseDoubleQuote shDoubleQuote 435hi def link shCaseIn shConditional 436hi def link shCaseSingleQuote shSingleQuote 437hi def link shCaseStart shConditional 438hi def link shCmdSubRegion shShellVariables 439hi def link shColon shStatement 440hi def link shDerefOp shOperator 441hi def link shDerefPatStringOp shDerefOp 442hi def link shDerefPatString shDerefPattern 443hi def link shDerefPOL shDerefOp 444hi def link shDeref shShellVariables 445hi def link shDerefSimple shDeref 446hi def link shDerefSpecial shDeref 447hi def link shDerefString shDoubleQuote 448hi def link shDerefVar shDeref 449hi def link shDoubleQuote shString 450hi def link shEcho shString 451hi def link shEmbeddedEcho shString 452hi def link shExSingleQuote shSingleQuote 453hi def link shFunctionStart Delimiter 454hi def link shHereDoc shString 455hi def link shHerePayload shHereDoc 456hi def link shLoop shStatement 457hi def link shOption shCommandSub 458hi def link shPattern shString 459hi def link shPosnParm shShellVariables 460hi def link shRange shOperator 461hi def link shRedir shOperator 462hi def link shSingleQuote shString 463hi def link shSource shOperator 464hi def link shStringSpecial shSpecial 465hi def link shSubShRegion shOperator 466hi def link shTestOpr shConditional 467hi def link shVariable shSetList 468hi def link shWrapLineOperator shOperator 469 470if exists("b:is_bash") 471 hi def link bashAdminStatement shStatement 472 hi def link bashSpecialVariables shShellVariables 473 hi def link bashStatement shStatement 474 hi def link shFunctionParen Delimiter 475 hi def link shFunctionDelim Delimiter 476endif 477if exists("b:is_kornshell") 478 hi def link kshSpecialVariables shShellVariables 479 hi def link kshStatement shStatement 480 hi def link shFunctionParen Delimiter 481endif 482 483hi def link shCaseError Error 484hi def link shCondError Error 485hi def link shCurlyError Error 486hi def link shDerefError Error 487hi def link shDerefOpError Error 488hi def link shDerefWordError Error 489hi def link shDoError Error 490hi def link shEsacError Error 491hi def link shIfError Error 492hi def link shInError Error 493hi def link shParenError Error 494hi def link shTestError Error 495if exists("b:is_kornshell") 496 hi def link shDTestError Error 497endif 498 499hi def link shArithmetic Special 500hi def link shCharClass Identifier 501hi def link shSnglCase Statement 502hi def link shCommandSub Special 503hi def link shComment Comment 504hi def link shConditional Conditional 505hi def link shExprRegion Delimiter 506hi def link shFunctionKey Function 507hi def link shFunctionName Function 508hi def link shNumber Number 509hi def link shOperator Operator 510hi def link shRepeat Repeat 511hi def link shSet Statement 512hi def link shSetList Identifier 513hi def link shShellVariables PreProc 514hi def link shSpecial Special 515hi def link shStatement Statement 516hi def link shString String 517hi def link shTodo Todo 518hi def link shAlias Identifier 519 520" Set Current Syntax: {{{1 521" =================== 522if exists("b:is_bash") 523 let b:current_syntax = "bash" 524elseif exists("b:is_kornshell") 525 let b:current_syntax = "ksh" 526else 527 let b:current_syntax = "sh" 528endif 529 530" vim: ts=16 fdm=marker 531