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