James Vega wrote:
Charles,
As shown below, sh.vim is too loosely interpreting the arithmetic
expansion syntax. As noted in Bash's manpage and SUS[0], arithmetic
expansion should be treated as if the contained expression were within
double quotes. shArithmetic should contain a cluster that doesn't
include shSubSh.
Also, I noticed that the default syntax highlighting highlights $(()) as
an error. Should that be the case since it is specified in SUS?
On Thu, Feb 28, 2008 at 10:31:15AM -0500, Edward Allcutt wrote:
The following is highlighted badly:
==== start file ========
#!/bin/bash
echo $(( ( 2 << 5 ) + 1 ))
echo foo bar
==== end file ==========
The 5 is the wrong colour and everything following until the end of file
is highlighted as if it were quoted text. Removing the parentheses around
the sub-expression corrects the highlighting but changes the meaning of the
expression.
Hello!
The << was getting treated as the start of a here document -- so that
explains the "treated as text" problem. Please try the attached file.
Regards,
Chip Campbell
[0] -
http://www.opengroup.org/onlinepubs/000095399/utilities/xcu_chap02.html#tag_02_06_04
" Vim syntax file
" Language: shell (sh) Korn shell (ksh) bash (sh)
" Maintainer: Dr. Charles E. Campbell, Jr. <[EMAIL PROTECTED]>
" Previous Maintainer: Lennart Schultz <[EMAIL PROTECTED]>
" Last Change: Mar 02, 2008
" Version: 96 ASTRO-ONLY
" URL:
http://mysite.verizon.net/astronaut/vim/index.html#vimlinks_syntax
" For options and settings, please use: :help ft-sh-syntax
" This file includes many ideas from Éric Brunet ([EMAIL PROTECTED])
" For version 5.x: Clear all syntax items {{{1
" For version 6.x: Quit when a syntax file was already loaded
if version < 600
syntax clear
elseif exists("b:current_syntax")
finish
endif
" handling /bin/sh with is_kornshell/is_sh {{{1
" b:is_sh is set when "#! /bin/sh" is found;
" However, it often is just a masquerade by bash (typically Linux)
" or kornshell (typically workstations with Posix "sh").
" So, when the user sets "is_bash" or "is_kornshell",
" a b:is_sh is converted into b:is_bash/b:is_kornshell,
" respectively.
if !exists("b:is_kornshell") && !exists("b:is_bash")
if exists("g:is_posix") && !exists("g:is_kornshell")
let g:is_kornshell= g:is_posix
endif
if exists("g:is_kornshell")
let b:is_kornshell= 1
if exists("b:is_sh")
unlet b:is_sh
endif
elseif exists("g:is_bash")
let b:is_bash= 1
if exists("b:is_sh")
unlet b:is_sh
endif
else
let b:is_sh= 1
endif
endif
" set up default g:sh_fold_enabled {{{1
if !exists("g:sh_fold_enabled")
let g:sh_fold_enabled= 0
elseif g:sh_fold_enabled != 0 && !has("folding")
let g:sh_fold_enabled= 0
echomsg "Ignoring g:sh_fold_enabled=".g:sh_fold_enabled."; need to re-compile
vim for +fold support"
endif
if !exists("s:sh_fold_functions")
let s:sh_fold_functions = 1
endif
if !exists("s:sh_fold_heredoc")
let s:sh_fold_heredoc = 2
endif
if !exists("s:sh_fold_ifdofor")
let s:sh_fold_ifdofor = 4
endif
if g:sh_fold_enabled && &fdm == "manual"
set fdm=syntax
endif
" sh syntax is case sensitive {{{1
syn case match
" Clusters: [EMAIL PROTECTED] clusters {{{1
"==================================
syn cluster shErrorList
contains=shDoError,shIfError,shInError,shCaseError,shEsacError,shCurlyError,shParenError,shTestError
if exists("b:is_kornshell")
syn cluster ErrorList add=shDTestError
endif
syn cluster shArithParenList
contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen
syn cluster shArithList [EMAIL PROTECTED],shParenError
syn cluster shCaseEsacList
contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial
syn cluster shCaseList [EMAIL
PROTECTED],shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
syn cluster shColonList [EMAIL PROTECTED]
syn cluster shCommandSubList
contains=shArithmetic,shDeref,shDerefSimple,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shSingleQuote,shDoubleQuote,shStatement,shVariable,shSubSh,shAlias,shTest,shCtrlSeq,shSpecial
syn cluster shCurlyList
contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
syn cluster shDblQuoteList
contains=shCommandSub,shDeref,shDerefSimple,shPosnParm,shExSingleQuote,shCtrlSeq,shSpecial
syn cluster shDerefList
contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPPS
syn cluster shDerefVarList
contains=shDerefOp,shDerefVarArray,shDerefOpError
syn cluster shEchoList
contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shExpr,shExSingleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
syn cluster shExprList1
contains=shCharClass,shNumber,shOperator,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
syn cluster shExprList2 [EMAIL PROTECTED],@shCaseList,shTest
syn cluster shFunctionList [EMAIL
PROTECTED],shCaseEsac,shColon,shCommandSub,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shFunctionStart,shCtrlSeq
if exists("b:is_kornshell") || exists("b:is_bash")
syn cluster shFunctionList add=shRepeat
syn cluster shFunctionList add=shDblBrace,shDblParen
endif
syn cluster shHereBeginList [EMAIL PROTECTED]
syn cluster shHereList contains=shBeginHere,shHerePayload
syn cluster shHereListDQ
contains=shBeginHere,@shDblQuoteList,shHerePayload
syn cluster shIdList
contains=shCommandSub,shWrapLineOperator,shIdWhiteSpace,shDeref,shDerefSimple,shRedir,shExSingleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial
syn cluster shLoopList [EMAIL
PROTECTED],shTestOpr,shExpr,shDblBrace,shConditional,shCaseEsac,shTest,@shErrorList,shSet
syn cluster shSubShList [EMAIL PROTECTED],shOperator
syn cluster shTestList
contains=shCharClass,shComment,shCommandSub,shDeref,shDerefSimple,shDoubleQuote,shExpr,shExpr,shNumber,shOperator,shExSingleQuote,shSingleQuote,shTestOpr,shTest,shCtrlSeq
" Echo: {{{1
" ====
" This one is needed INSIDE a CommandSub, so that `echo bla` be correct
syn 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 [EMAIL PROTECTED] skipwhite
nextgroup=shQuickComment
syn 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 [EMAIL PROTECTED] skipwhite
nextgroup=shQuickComment
syn match shEchoQuote contained '\%(\\\\\)*\\["`']'
" This must be after the strings, so that ... \" will be correct
syn 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,shOperator,shDoubleQuote,shCharClass,shCtrlSeq
" Alias: {{{1
" =====
if exists("b:is_kornshell") || exists("b:is_bash")
syn match shStatement "\<alias\>"
syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+\)[EMAIL
PROTECTED]" skip="\\$" end="\>\|`"
syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\w\+=\)[EMAIL
PROTECTED]" skip="\\$" end="="
endif
" Error Codes: {{{1
" ============
syn match shDoError "\<done\>"
syn match shIfError "\<fi\>"
syn match shInError "\<in\>"
syn match shCaseError ";;"
syn match shEsacError "\<esac\>"
syn match shCurlyError "}"
syn match shParenError ")"
if exists("b:is_kornshell")
syn match shDTestError "]]"
endif
syn match shTestError "]"
" Options Interceptor: {{{1
" ====================
syn match shOption "\s[\-+][a-zA-Z0-9]\+\>"ms=s+1
syn match shOption "\s--[^ \t$`'"|]\+"ms=s+1
" File Redirection Highlighted As Operators: {{{1
"===========================================
syn match shRedir "\d\=>\(&[-0-9]\)\="
syn match shRedir "\d\=>>-\="
syn match shRedir "\d\=<\(&[-0-9]\)\="
syn match shRedir "\d<<-\="
" Operators: {{{1
" ==========
syn match shOperator "<<\|>>" contained
syn match shOperator "[!&;|]"
syn match shOperator "\[[[^:]\|\]]"
syn match shOperator "!\==" skipwhite nextgroup=shPattern
syn match shPattern "\<\S\+\())\)[EMAIL PROTECTED]" contained
contains=shExSingleQuote,shSingleQuote,shDoubleQuote,shDeref
" Subshells: {{{1
" ==========
syn region shExpr transparent matchgroup=shExprRegion start="{" end="}"
[EMAIL PROTECTED]
syn region shSubSh transparent matchgroup=shSubShRegion start="(" end=")"
[EMAIL PROTECTED]
" Tests: {{{1
"=======
"syn region shExpr transparent matchgroup=shRange start="\[" skip=+\\\\\|\\$+
end="\]" [EMAIL PROTECTED]
syn region shExpr matchgroup=shRange start="\[" skip=+\\\\\|\\$+ end="\]"
[EMAIL PROTECTED]
syn region shTest transparent matchgroup=shStatement start="\<test\>"
skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" [EMAIL PROTECTED]
syn match shTestOpr contained
"<=\|>=\|!=\|==\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
syn match shTestOpr contained '=' skipwhite
nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
syn match shTestPattern contained '\w\+'
syn match shTestDoubleQuote contained '"[^"]*"'
syn match shTestSingleQuote contained '\\.'
syn match shTestSingleQuote contained "'[^']*'"
if exists("b:is_kornshell") || exists("b:is_bash")
syn region shDblBrace matchgroup=Delimiter start="\[\[" skip=+\\\\\|\\$+
end="\]\]" [EMAIL PROTECTED]
syn region shDblParen matchgroup=Delimiter start="((" skip=+\\\\\|\\$+
end="))" [EMAIL PROTECTED]
endif
" Character Class In Range: {{{1
" =========================
syn match shCharClass contained
"\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
" Loops: do, if, while, until {{{1
" ======
if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
syn region shDo fold transparent matchgroup=shConditional
start="\<do\>" matchgroup=shConditional end="\<done\>" [EMAIL PROTECTED]
syn region shIf fold transparent matchgroup=shConditional
start="\<if\>" matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>"
[EMAIL PROTECTED],shDblBrace,shDblParen,shFunctionKey
syn region shFor fold matchgroup=shLoop start="\<for\>" end="\<in\>"
end="\<do\>"me=e-2 [EMAIL PROTECTED],shDblParen skipwhite nextgroup=shCurlyIn
else
syn region shDo transparent matchgroup=shConditional start="\<do\>"
matchgroup=shConditional end="\<done\>" [EMAIL PROTECTED]
syn region shIf transparent matchgroup=shConditional start="\<if\>"
matchgroup=shConditional end="\<;\_s*then\>" end="\<fi\>" [EMAIL
PROTECTED],shDblBrace,shDblParen,shFunctionKey
syn region shFor matchgroup=shLoop start="\<for\>" end="\<in\>"
end="\<do\>"me=e-2 [EMAIL PROTECTED],shDblParen skipwhite
nextgroup=shCurlyIn
endif
if exists("b:is_kornshell") || exists("b:is_bash")
syn cluster shCaseList add=shRepeat
syn cluster shFunctionList add=shRepeat
syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<in\>"
end="\<do\>"me=e-2 [EMAIL PROTECTED],shDblParen,shDblBrace
syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<in\>"
end="\<do\>"me=e-2 [EMAIL PROTECTED],shDblParen,shDblBrace
syn region shCaseEsac matchgroup=shConditional start="\<select\>"
matchgroup=shConditional end="\<in\>" end="\<do\>" [EMAIL PROTECTED]
else
syn region shRepeat matchgroup=shLoop start="\<while\>" end="\<do\>"me=e-2
[EMAIL PROTECTED]
syn region shRepeat matchgroup=shLoop start="\<until\>" end="\<do\>"me=e-2
[EMAIL PROTECTED]
endif
syn region shCurlyIn contained matchgroup=Delimiter start="{" end="}"
[EMAIL PROTECTED]
syn match shComma contained ","
" Case: case...esac {{{1
" ====
syn match shCaseBar contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|"
nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
syn match shCaseStart contained skipwhite skipnl "("
nextgroup=shCase,shCaseBar
syn region shCase contained skipwhite skipnl matchgroup=shSnglCase
start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 [EMAIL
PROTECTED] nextgroup=shCaseStart,shCase,shComment
if (g:sh_fold_enabled % (s:sh_fold_ifdofor * 2))/s:sh_fold_ifdofor
syn region shCaseEsac fold matchgroup=shConditional start="\<case\>"
end="\<esac\>" [EMAIL PROTECTED]
else
syn region shCaseEsac matchgroup=shConditional start="\<case\>"
end="\<esac\>" [EMAIL PROTECTED]
endif
syn keyword shCaseIn contained skipwhite skipnl in
nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
if exists("b:is_bash")
syn region shCaseExSingleQuote matchgroup=shOperator start=+\$'+
skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial skipwhite
skipnl nextgroup=shCaseBar contained
else
syn region shCaseExSingleQuote matchgroup=Error start=+\$'+
skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial skipwhite skipnl
nextgroup=shCaseBar contained
endif
syn region shCaseSingleQuote matchgroup=shOperator start=+'+ end=+'+
contains=shStringSpecial skipwhite skipnl nextgroup=shCaseBar
contained
syn region shCaseDoubleQuote matchgroup=shOperator start=+"+
skip=+\\\\\|\\.+ end=+"+ [EMAIL PROTECTED],shStringSpecial
skipwhite skipnl nextgroup=shCaseBar contained
syn region shCaseCommandSub start=+`+ skip=+\\\\\|\\.+ end=+`+
[EMAIL PROTECTED] skipwhite skipnl nextgroup=shCaseBar
contained
" Misc: {{{1
"======
syn match shWrapLineOperator "\\$"
syn region shCommandSub start="`" skip="\\\\\|\\." end="`" [EMAIL PROTECTED]
syn match shEscape contained '\\.'
" $() and $(()): {{{1
" $(..) is not supported by sh (Bourne shell). However, apparently
" some systems (HP?) have as their /bin/sh a (link to) Korn shell
" (ie. Posix compliant shell). /bin/ksh should work for those
" systems too, however, so the following syntax will flag $(..) as
" an Error under /bin/sh. By consensus of vimdev'ers!
if exists("b:is_kornshell") || exists("b:is_bash")
syn region shCommandSub matchgroup=shCmdSubRegion start="\$("
skip='\\\\\|\\.' end=")" [EMAIL PROTECTED]
syn region shArithmetic matchgroup=shArithRegion start="\$(("
skip='\\\\\|\\.' end="))" [EMAIL PROTECTED]
syn match shSkipInitWS contained "^\s\+"
else
syn region shCommandSub matchgroup=Error start="\$(" end=")" [EMAIL PROTECTED]
endif
if exists("b:is_bash")
syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
syn cluster shCaseList add=bashAdminStatement,bashStatement
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
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
syn keyword bashAdminStatement daemon killall killproc nice reload restart
start status stop
endif
if exists("b:is_kornshell")
syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
syn cluster shCaseList add=kshStatement
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
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
endif
syn match shSource "^\.\s"
syn match shSource "\s\.\s"
syn region shColon start="^\s*:" end="$\|" end="#"me=e-1 [EMAIL PROTECTED]
" String And Character Constants: {{{1
"================================
syn match shNumber "-\=\<\d\+\>#\="
syn match shCtrlSeq "\\\d\d\d\|\\[abcfnrtv0]" contained
if exists("b:is_bash")
syn match shSpecial "\\\o\o\o\|\\x\x\x\|\\c.\|\\[abefnrtv]" contained
endif
if exists("b:is_bash")
syn region shExSingleQuote matchgroup=shOperator start=+\$'+
skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial,shSpecial
else
syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+
end=+'+ contains=shStringSpecial
endif
syn region shSingleQuote matchgroup=shOperator start=+'+ end=+'+
contains=shStringSpecial,@Spell
syn region shDoubleQuote matchgroup=shOperator start=+"+ skip=+\\"+
end=+"+ [EMAIL PROTECTED],shStringSpecial,@Spell
syn match shStringSpecial "[^[:print:]]" contained
syn match shStringSpecial "\%(\\\\\)*\\[\\"'`$()#]"
syn match shSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
" Comments: {{{1
"==========
syn cluster shCommentGroup contains=shTodo,@Spell
syn keyword shTodo contained COMBAK FIXME TODO XXX
syn match shComment "^\s*\zs#.*$" [EMAIL PROTECTED]
syn match shComment "\s\zs#.*$" [EMAIL PROTECTED]
syn match shQuickComment contained "#.*$"
" Here Documents: {{{1
" =========================================
if version < 600
syn region shHereDoc matchgroup=shRedir start="<<\s*\**END[a-zA-Z_0-9]*\**"
matchgroup=shRedir end="^END[a-zA-Z_0-9]*$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<-\s*\**END[a-zA-Z_0-9]*\**"
matchgroup=shRedir end="^\s*END[a-zA-Z_0-9]*$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<\s*\**EOF\**"
matchgroup=shRedir end="^EOF$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<-\s*\**EOF\**"
matchgroup=shRedir end="^\s*EOF$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<\s*\**\.\**"
matchgroup=shRedir end="^\.$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<-\s*\**\.\**"
matchgroup=shRedir end="^\s*\.$" [EMAIL PROTECTED]
elseif (g:sh_fold_enabled % (s:sh_fold_heredoc * 2))/s:sh_fold_heredoc
syn region shHereDoc matchgroup=shRedir fold start="<<\s*\z(\S*\)"
matchgroup=shRedir end="^\z1\s*$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir fold start="<<\s*\"\z(\S*\)\""
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<\s*'\z(\S*\)'"
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\z(\S*\)"
matchgroup=shRedir end="^\s*\z1\s*$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\"\z(\S*\)\""
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<-\s*'\z(\S*\)'"
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*\z(\S*\)"
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold
start="<<\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*'\z(\S*\)'"
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<-\s*\\\_$\_s*\z(\S*\)"
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold
start="<<-\s*\\\_$\_s*\"\z(\S*\)\"" matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<\s*\\\_$\_s*'\z(\S*\)'"
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir fold start="<<\\\z(\S*\)"
matchgroup=shRedir end="^\z1\s*$"
else
syn region shHereDoc matchgroup=shRedir start="<<\s*\\\=\z(\S*\)"
matchgroup=shRedir end="^\z1\s*$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<\s*\"\z(\S*\)\""
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<-\s*\z(\S*\)"
matchgroup=shRedir end="^\s*\z1\s*$" [EMAIL PROTECTED]
syn region shHereDoc matchgroup=shRedir start="<<-\s*'\z(\S*\)'"
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<\s*'\z(\S*\)'"
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<-\s*\"\z(\S*\)\""
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\z(\S*\)"
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\z(\S*\)"
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*'\z(\S*\)'"
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*'\z(\S*\)'"
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<\s*\\\_$\_s*\"\z(\S*\)\""
matchgroup=shRedir end="^\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<-\s*\\\_$\_s*\"\z(\S*\)\""
matchgroup=shRedir end="^\s*\z1\s*$"
syn region shHereDoc matchgroup=shRedir start="<<\\\z(\S*\)"
matchgroup=shRedir end="^\z1\s*$"
endif
" Here Strings: {{{1
" =============
if exists("b:is_bash")
syn match shRedir "<<<"
endif
" Identifiers: {{{1
"=============
syn match shVariable "\<\([bwglsav]:\)[EMAIL PROTECTED],]*\ze="
nextgroup=shSetIdentifier
syn match shIdWhiteSpace contained "\s\+"
syn match shSetIdentifier contained "="
nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shSingleQuote,shExSingleQuote
if exists("b:is_bash")
syn region shSetList oneline keepend matchgroup=shSet
start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$"
matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="#\|="me=e-1
[EMAIL PROTECTED]
syn region shSetList oneline keepend matchgroup=shSet start="\<set\>\ze[^/]"
end="$" end="\\ze[|)]" matchgroup=shOperator end="\ze[|);&]"me=e-1
matchgroup=NONE end="[#=]"me=e-1 [EMAIL PROTECTED]
syn match shSet "\<\(declare\|typeset\|local\|export\|set\|unset\)\>"
elseif exists("b:is_kornshell")
syn region shSetList oneline keepend matchgroup=shSet
start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$"
matchgroup=shOperator end="\ze[|);&]"me=e-1 matchgroup=NONE end="[#=]"me=e-1
[EMAIL PROTECTED]
syn region shSetList oneline keepend matchgroup=shSet start="\<set\>\ze[^/]"
end="$\|\ze[})]" matchgroup=shOperator end="\ze[|);&]"me=e-1
matchgroup=NONE end="[#=]"me=e-1 [EMAIL PROTECTED]
syn match shSet "\<\(typeset\|set\|export\|unset\)\>" skipwhite
nextgroup=shOption
else
syn region shSetList matchgroup=shSet
start="\<\(set\|export\|unset\)\>\ze[^/]" end="$\|\ze[|)]"
matchgroup=shOperator end="\ze[|);&]" matchgroup=NONE end="[#=]"me=e-1 [EMAIL
PROTECTED]
syn match shStatement "\<\(set\|export\|unset\)\>"
endif
" Functions: {{{1
syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
if (g:sh_fold_enabled % (s:sh_fold_functions * 2))/s:sh_fold_functions
syn region shFunctionOne fold matchgroup=shFunction
start="^\s*\h\w*\s*()\_s*{" end="}" [EMAIL PROTECTED]
skipwhite skipnl nextgroup=shFunctionStart,shQuickComment
syn region shFunctionTwo fold matchgroup=shFunction
start="\h\w*\s*\%(()\)\=\_s*{" end="}"
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl
nextgroup=shFunctionStart,shQuickComment
else
syn region shFunctionOne matchgroup=shFunction
start="^\s*\h\w*\s*()\_s*{" end="}" [EMAIL PROTECTED]
syn region shFunctionTwo matchgroup=shFunction
start="\h\w*\s*\%(()\)\=\_s*{" end="}"
contains=shFunctionKey,@shFunctionList contained
endif
" Parameter Dereferencing: {{{1
" ========================
syn match shDerefSimple "\$\%(\h\w*\|\d\)"
syn region shDeref matchgroup=PreProc start="\${" end="}" [EMAIL
PROTECTED],shDerefVarArray
syn match shDerefWordError "[^}$[]" contained
syn match shDerefSimple "[EMAIL PROTECTED]"
syn match shDerefSimple "\$\$"
if exists("b:is_bash") || exists("b:is_kornshell")
syn region shDeref matchgroup=PreProc start="\${##\=" end="}" [EMAIL
PROTECTED]
syn region shDeref matchgroup=PreProc start="\${\$\$" end="}" [EMAIL
PROTECTED]
endif
" bash: ${!prefix*} and ${#parameter}: {{{1
" ====================================
if exists("b:is_bash")
syn region shDeref matchgroup=PreProc start="\${!" end="\*\=}" [EMAIL
PROTECTED],shDerefOp
syn match shDerefVar contained "{\@<=!\w\+" [EMAIL
PROTECTED]
endif
syn match shDerefSpecial contained "{\@<[EMAIL PROTECTED]"
nextgroup=shDerefOp,shDerefOpError
syn match shDerefSpecial contained "\({[#!]\)\@<=[[:alnum:[EMAIL
PROTECTED]" [EMAIL PROTECTED],shDerefOp
syn match shDerefVar contained "{\@<=\w\+" [EMAIL
PROTECTED]
" sh ksh bash : ${var[... ]...} array reference: {{{1
syn region shDerefVarArray contained matchgroup=shDeref start="\[" end="]"
[EMAIL PROTECTED] nextgroup=shDerefOp,shDerefOpError
" Special ${parameter OPERATOR word} handling: {{{1
" sh ksh bash : ${parameter:-word} word is default value
" sh ksh bash : ${parameter:=word} assign word as default value
" sh ksh bash : ${parameter:?word} display word if parameter is null
" sh ksh bash : ${parameter:+word} use word if parameter is not null,
otherwise nothing
" ksh bash : ${parameter#pattern} remove small left pattern
" ksh bash : ${parameter##pattern} remove large left pattern
" ksh bash : ${parameter%pattern} remove small right pattern
" ksh bash : ${parameter%%pattern} remove large right pattern
syn cluster shDerefPatternList contains=shDerefPattern,shDerefString
syn match shDerefOpError contained ":[[:punct:]]"
syn match shDerefOp contained ":\=[-=?]" [EMAIL PROTECTED]
syn match shDerefOp contained ":\=+" [EMAIL PROTECTED]
if exists("b:is_bash") || exists("b:is_kornshell")
syn match shDerefOp contained "#\{1,2}" [EMAIL PROTECTED]
syn match shDerefOp contained "%\{1,2}" [EMAIL PROTECTED]
syn match shDerefPattern contained "[^{}]\+"
contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape
nextgroup=shDerefPattern
syn region shDerefPattern contained start="{" end="}"
contains=shDeref,shDerefSimple,shDerefString,shCommandSub
nextgroup=shDerefPattern
syn match shDerefEscape contained '\%(\\\\\)*\\.'
endif
syn region shDerefString contained matchgroup=shOperator
start=+\%(\\\)\@<!'+ end=+'+ contains=shStringSpecial
syn region shDerefString contained matchgroup=shOperator
start=+\%(\\\)\@<!"+ skip=+\\"+ end=+"+ [EMAIL PROTECTED],shStringSpecial
syn match shDerefString contained "\\["']"
nextgroup=shDerefPattern
if exists("b:is_bash")
" bash : ${parameter:offset}
" bash : ${parameter:offset:length}
syn region shDerefOp contained start=":[$[:alnum:]_]"me=e-1
end=":"me=e-1 end="}"me=e-1 [EMAIL PROTECTED] nextgroup=shDerefPOL
syn match shDerefPOL contained ":[^}]\+" [EMAIL PROTECTED]
" bash : ${parameter//pattern/string}
" bash : ${parameter//pattern}
syn match shDerefPPS contained '/\{1,2}' nextgroup=shDerefPPSleft
syn region shDerefPPSleft contained start='.' [EMAIL
PROTECTED](\\\)\/@ matchgroup=shDerefOp end='/' end='\ze}'
nextgroup=shDerefPPSright [EMAIL PROTECTED]
syn region shDerefPPSright contained start='.' end='\ze}'
[EMAIL PROTECTED]
endif
" Arithmetic Parenthesized Expressions: {{{1
syn region shParen matchgroup=shArithRegion start='(\ze[^(]' end=')' [EMAIL
PROTECTED]
" Useful sh Keywords: {{{1
" ===================
syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd
read readonly return shift test trap ulimit umask wait
syn keyword shConditional contained elif else then
syn keyword shCondError elif else then
" Useful ksh Keywords: {{{1
" ====================
if exists("b:is_kornshell") || exists("b:is_bash")
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
" Useful bash Keywords: {{{1
" =====================
if exists("b:is_bash")
syn keyword shStatement bind builtin dirs disown enable help local logout
popd pushd shopt source
else
syn keyword shStatement login newgrp
endif
endif
" Synchronization: {{{1
" ================
if !exists("sh_minlines")
let sh_minlines = 200
endif
if !exists("sh_maxlines")
let sh_maxlines = 2 * sh_minlines
endif
exec "syn sync minlines=" . sh_minlines . " maxlines=" . sh_maxlines
syn sync match shCaseEsacSync grouphere shCaseEsac "\<case\>"
syn sync match shCaseEsacSync groupthere shCaseEsac "\<esac\>"
syn sync match shDoSync grouphere shDo "\<do\>"
syn sync match shDoSync groupthere shDo "\<done\>"
syn sync match shForSync grouphere shFor "\<for\>"
syn sync match shForSync groupthere shFor "\<in\>"
syn sync match shIfSync grouphere shIf "\<if\>"
syn sync match shIfSync groupthere shIf "\<fi\>"
syn sync match shUntilSync grouphere shRepeat "\<until\>"
syn sync match shWhileSync grouphere shRepeat "\<while\>"
" Default Highlighting: {{{1
" =====================
hi def link shArithRegion shShellVariables
hi def link shBeginHere shRedir
hi def link shCaseBar shConditional
hi def link shCaseCommandSub shCommandSub
hi def link shCaseDoubleQuote shDoubleQuote
hi def link shCaseIn shConditional
hi def link shCaseSingleQuote shSingleQuote
hi def link shCaseStart shConditional
hi def link shCmdSubRegion shShellVariables
hi def link shColon shStatement
hi def link shDerefOp shOperator
hi def link shDerefPOL shDerefOp
hi def link shDerefPPS shDerefOp
hi def link shDeref shShellVariables
hi def link shDerefSimple shDeref
hi def link shDerefSpecial shDeref
hi def link shDerefString shDoubleQuote
hi def link shDerefVar shDeref
hi def link shDoubleQuote shString
hi def link shEcho shString
hi def link shEchoQuote shString
hi def link shEmbeddedEcho shString
hi def link shEscape shCommandSub
hi def link shExSingleQuote shSingleQuote
hi def link shFunction Function
hi def link shHereDoc shString
hi def link shHerePayload shHereDoc
hi def link shLoop shStatement
hi def link shOption shCommandSub
hi def link shPattern shString
hi def link shParen shArithmetic
hi def link shPosnParm shShellVariables
hi def link shQuickComment shComment
hi def link shRange shOperator
hi def link shRedir shOperator
hi def link shSingleQuote shString
hi def link shSource shOperator
hi def link shStringSpecial shSpecial
hi def link shSubShRegion shOperator
hi def link shTestOpr shConditional
hi def link shTestPattern shString
hi def link shTestDoubleQuote shString
hi def link shTestSingleQuote shString
hi def link shVariable shSetList
hi def link shWrapLineOperator shOperator
if exists("b:is_bash")
hi def link bashAdminStatement shStatement
hi def link bashSpecialVariables shShellVariables
hi def link bashStatement shStatement
hi def link shFunctionParen Delimiter
hi def link shFunctionDelim Delimiter
endif
if exists("b:is_kornshell")
hi def link kshSpecialVariables shShellVariables
hi def link kshStatement shStatement
hi def link shFunctionParen Delimiter
endif
hi def link shCaseError Error
hi def link shCondError Error
hi def link shCurlyError Error
hi def link shDerefError Error
hi def link shDerefOpError Error
hi def link shDerefWordError Error
hi def link shDoError Error
hi def link shEsacError Error
hi def link shIfError Error
hi def link shInError Error
hi def link shParenError Error
hi def link shTestError Error
if exists("b:is_kornshell")
hi def link shDTestError Error
endif
hi def link shArithmetic Special
hi def link shCharClass Identifier
hi def link shSnglCase Statement
hi def link shCommandSub Special
hi def link shComment Comment
hi def link shConditional Conditional
hi def link shCtrlSeq Special
hi def link shExprRegion Delimiter
hi def link shFunctionKey Function
hi def link shFunctionName Function
hi def link shNumber Number
hi def link shOperator Operator
hi def link shRepeat Repeat
hi def link shSet Statement
hi def link shSetList Identifier
hi def link shShellVariables PreProc
hi def link shSpecial Special
hi def link shStatement Statement
hi def link shString String
hi def link shTodo Todo
hi def link shAlias Identifier
" Set Current Syntax: {{{1
" ===================
if exists("b:is_bash")
let b:current_syntax = "bash"
elseif exists("b:is_kornshell")
let b:current_syntax = "ksh"
else
let b:current_syntax = "sh"
endif
" vim: ts=16 fdm=marker