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