]> ruderich.org/simon Gitweb - config/dotfiles.git/commitdiff
Merge plugins
authorSimon Ruderich <simon@ruderich.org>
Mon, 13 Jul 2009 22:25:15 +0000 (00:25 +0200)
committerSimon Ruderich <simon@ruderich.org>
Mon, 13 Jul 2009 22:25:15 +0000 (00:25 +0200)
29 files changed:
vim/autoload/deb.vim [new file with mode: 0644]
vim/doc/NERD_commenter.txt [new file with mode: 0644]
vim/doc/matchit.txt [new file with mode: 0644]
vim/doc/screenpaste.txt [new file with mode: 0644]
vim/doc/surround.txt [new file with mode: 0644]
vim/ftdetect/asciidoc_filetype.vim [new file with mode: 0644]
vim/ftdetect/vimperator.vim [new file with mode: 0644]
vim/indent/tcl.vim [new file with mode: 0644]
vim/plugin/NERD_commenter.vim [new file with mode: 0644]
vim/plugin/debPlugin.vim [new file with mode: 0644]
vim/plugin/matchit.vim [new file with mode: 0644]
vim/plugin/matrix.vim [new file with mode: 0644]
vim/plugin/minibufexpl.vim [new file with mode: 0644]
vim/plugin/qname.vim [new file with mode: 0644]
vim/plugin/repeat.vim [new file with mode: 0644]
vim/plugin/screenpaste.vim [new file with mode: 0644]
vim/plugin/securemodelines.vim [new file with mode: 0644]
vim/plugin/surround.vim [new file with mode: 0644]
vim/syntax/asciidoc.vim [new file with mode: 0644]
vim/syntax/deb.vim [new file with mode: 0644]
vim/syntax/getmailrc.vim [new file with mode: 0644]
vim/syntax/mkd.vim [new file with mode: 0644]
vim/syntax/perl.vim [new file with mode: 0644]
vim/syntax/php.vim [new file with mode: 0644]
vim/syntax/privoxy.vim [new file with mode: 0644]
vim/syntax/python.vim [new file with mode: 0644]
vim/syntax/tcl.vim [new file with mode: 0644]
vim/syntax/vimperator.vim [new file with mode: 0644]
vim/syntax/yaml.vim [new file with mode: 0644]

diff --git a/vim/autoload/deb.vim b/vim/autoload/deb.vim
new file mode 100644 (file)
index 0000000..9e6fd1e
--- /dev/null
@@ -0,0 +1,258 @@
+" Vim autoload file for browsing debian package.
+" copyright (C) 2007-2008, arno renevier <arenevier@fdn.fr>
+" Distributed under the GNU General Public License (version 2 or above)
+" Last Change: 2008 april 1
+" 
+" Inspired by autoload/tar.vim by Charles E Campbell
+"
+" Latest version of that file can be found at
+" http://www.fdn.fr/~arenevier/vim/autoload/deb.vim
+" It should also be available at
+" http://www.vim.org/scripts/script.php?script_id=1970
+
+if &cp || exists("g:loaded_deb") || v:version < 700
+    finish
+endif
+let g:loaded_deb= "v1.4"
+
+fun! deb#read(debfile, member)
+
+    " checks if ar and tar are installed
+    if !s:hascmd("ar") || !s:hascmd("tar")
+        return
+    endif
+
+    let l:target = a:member
+
+    let l:archmember = s:dataFileName(a:debfile) " default archive member to extract
+    if l:archmember == ""
+        echohl WarningMsg | echo "***error*** (deb#read) no valid data file found in debian archive"
+        return
+    elseif l:archmember == "data.tar.gz"
+        let l:unpcmp = "tar zxfO "
+    elseif l:archmember == "data.tar.bz2"
+        let l:unpcmp = "tar jxfO "
+    elseif l:archmember == "data.tar.lzma"
+        if !s:hascmd("lzma")
+            return
+        endif
+        let l:unpcmp = "lzma -d | tar xfO "
+    elseif l:archmember == "data.tar"
+        let l:unpcmp = "tar xfO "
+    endif
+
+    if a:member =~ '^\* ' " information control file
+        let l:archmember = "control.tar.gz"
+        let l:target = substitute(l:target, "^\* ", "", "")
+        let l:unpcmp = "tar zxfO "
+    elseif a:member =~ ' -> ' " symbolic link
+        let l:target = split(a:member,' -> ')[0]
+        let l:linkname = split(a:member,' -> ')[1]
+
+        if l:linkname =~ "^\/" " direct symlink: path is already absolute
+            let l:target = ".".l:linkname
+
+        else 
+        " transform relative path to absolute path
+
+            " first, get basename for target
+            let l:target = substitute(l:target, "\/[^/]*$", "", "")
+
+            " while it begins with ../
+            while l:linkname =~ "^\.\.\/" 
+
+                " removes one level of ../ in linkname
+                let l:linkname = substitute(l:linkname, "^\.\.\/", "", "")
+
+                " go one directory up in target
+                let l:target = substitute(l:target, "\/[^/]*$", "", "")
+            endwhile
+
+            let l:target = l:target."/".l:linkname
+        endif
+    endif
+    
+    " we may preprocess some files (such as man pages, or changelogs)
+    let l:preproccmd = ""
+        
+    "
+    " unzip man pages
+    "
+    if l:target =~ "\.\/usr\/share\/man\/.*\.gz$"
+        
+        " try to fail gracefully if a command is not available
+        if !s:hascmd("gzip")
+            return
+        elseif !s:hascmd("nroff") 
+            let l:preproccmd = "| gzip -cd"
+        elseif !s:hascmd("col")
+            let l:preproccmd = "| gzip -cd | nroff -mandoc"
+        else
+            let l:preproccmd = "| gzip -cd | nroff -mandoc | col -b"
+        endif
+    
+    "
+    " unzip other .gz files
+    "
+    elseif l:target =~ '.*\.gz$'
+        if !s:hascmd("gzip")
+            return
+        endif
+        let l:preproccmd = "| gzip -cd"
+    endif
+
+    " read content
+    exe "silent r! ar p " . s:QuoteFile(a:debfile) . " " . s:QuoteFile(l:archmember) . " | " . l:unpcmp . " - " . s:QuoteFile(l:target) . l:preproccmd
+    " error will be treated in calling function
+    if v:shell_error != 0
+        return
+    endif
+
+    exe "file deb:".l:target
+
+    0d
+
+    setlocal nomodifiable nomodified readonly
+
+endfun
+
+fun! deb#browse(file)
+
+    " checks if necessary utils are installed
+    if !s:hascmd("dpkg") || !s:hascmd("ar") || !s:hascmd("tar")
+        return
+    endif
+
+    " checks if file is readable
+    if !filereadable(a:file)
+        return
+    endif
+    if a:file =~ "'"
+        echohl WarningMsg | echo "***error*** (deb#Browse) filename cannot contain quote character (" . a:file . ")"
+        return
+    endif
+
+    let keepmagic = &magic
+    set magic
+
+    " set filetype to "deb"
+    set ft=deb
+
+    setlocal modifiable noreadonly
+
+    " set header
+    exe "$put ='".'\"'." deb.vim version ".g:loaded_deb."'"
+    exe "$put ='".'\"'." Browsing debian package ".a:file."'"
+    $put=''
+
+    " package info
+    "exe "silent read! dpkg -I ".a:file
+    "$put=''
+
+    " display information control files
+    let l:infopos = line(".")
+    exe "silent read! ar p " . s:QuoteFile(a:file) . " control.tar.gz | tar zt"
+
+    $put=''
+
+    " display data files
+    let l:listpos = line(".")
+    exe "silent read! dpkg -c ". s:QuoteFile(a:file)
+
+    " format information control list
+    " removes '* ./' line
+    exe (l:infopos + 1). 'd'
+    " add a star before each line
+    exe "silent " . (l:infopos + 1). ',' . (l:listpos - 2) . 's/^/\* /'
+    
+    " format data list
+    exe "silent " . l:listpos . ',$s/^.*\s\(\.\/\(\S\|\).*\)$/\1/'
+    
+    if v:shell_error != 0
+        echohl WarningMsg | echo "***warning*** (deb#Browse) error when listing content of " . a:file
+        let &magic = keepmagic
+        return
+    endif
+
+    0d
+
+    setlocal nomodifiable readonly
+    noremap <silent> <buffer> <cr> :call <SID>DebBrowseSelect()<cr>
+    let &magic = keepmagic
+
+endfun
+
+fun! s:DebBrowseSelect()
+    let l:fname= getline(".")
+
+    " sanity check
+    if (l:fname !~ '^\.\/') && (l:fname !~ '^\* \.\/')
+        return
+    endif
+    if l:fname =~ "'"
+        echohl WarningMsg | echo "***error*** (DebBrowseSelect) filename cannot contain quote character (" . l:fname . ")"
+        return
+    endif
+
+    " do nothing on directories
+    " TODO: find a way to detect symlinks to directories, to be able not to
+    " open them
+    if (l:fname =~ '\/$')
+        return
+    endif
+
+    " need to get it now since a new window will open
+    let l:curfile= expand("%")
+   
+    " open new window
+    new
+    wincmd _
+
+    call deb#read(l:curfile, l:fname)
+
+    if v:shell_error != 0
+        echohl WarningMsg | echo "***warning*** (DebBrowseSelect) error when reading " . l:fname
+        return
+    endif
+
+    filetype detect
+
+    " zipped files, are unziped in deb#read, but filetype may not
+    " automatically work.
+    if l:fname =~ "\.\/usr\/share\/man\/.*\.gz$"
+        set filetype=man
+    elseif l:fname =~ "\.\/usr\/share\/doc\/.*\/changelog.Debian.gz$"
+        set filetype=debchangelog
+    endif
+
+endfun
+
+" return data file name for debian package. This can be either data.tar.gz,
+" data.tar.bz2 or data.tar.lzma
+fun s:dataFileName(deb)
+    for fn in ["data.tar.gz", "data.tar.bz2", "data.tar.lzma", "data.tar"]
+        " [0:-2] is to remove trailing null character from command output
+        if (system("ar t " . "'" . a:deb . "'" . " " . fn))[0:-2] == fn
+            return fn
+        endif
+    endfor
+    return "" " no debian data format in this archive
+endfun
+
+fun s:QuoteFile(file)
+    " we need to escape %, #, <, and >
+    " see :help cmdline-specialk
+    return "'" .  substitute(a:file, '\([%#<>]\)', '\\\1', 'g') . "'"
+endfun
+
+" return 1 if cmd exists
+" display error message and return 0 otherwise
+fun s:hascmd(cmd)
+    if executable(a:cmd)
+        return 1
+    else
+        echohl Error | echo "***error*** " . a:cmd . " not available on your system"
+        return 0
+    else
+endfu
+
diff --git a/vim/doc/NERD_commenter.txt b/vim/doc/NERD_commenter.txt
new file mode 100644 (file)
index 0000000..d79d278
--- /dev/null
@@ -0,0 +1,991 @@
+*NERD_commenter.txt*         Plugin for commenting code
+
+
+                        NERD COMMENTER REFERENCE MANUAL~
+
+
+
+
+
+==============================================================================
+CONTENTS                                               *NERDCommenterContents*
+
+    1.Intro...................................|NERDCommenter|
+    2.Functionality provided..................|NERDComFunctionality|
+        2.1 Functionality Summary.............|NERDComFunctionalitySummary|
+        2.2 Functionality Details.............|NERDComFunctionalityDetails|
+            2.2.1 Comment map.................|NERDComComment|
+            2.2.2 Nested comment map..........|NERDComNestedComment|
+            2.2.3 Toggle comment map..........|NERDComToggleComment|
+            2.2.4 Minimal comment map.........|NERDComMinimalComment|
+            2.2.5 Invert comment map..........|NERDComInvertComment|
+            2.2.6 Sexy comment map............|NERDComSexyComment|
+            2.2.7 Yank comment map............|NERDComYankComment|
+            2.2.8 Comment to EOL map..........|NERDComEOLComment|
+            2.2.9 Append com to line map......|NERDComAppendComment|
+            2.2.10 Insert comment map.........|NERDComInsertComment|
+            2.2.11 Use alternate delims map...|NERDComAltDelim|
+            2.2.12 Comment aligned maps.......|NERDComAlignedComment|
+            2.2.13 Uncomment line map.........|NERDComUncommentLine|
+        2.3 Supported filetypes...............|NERDComFiletypes|
+        2.4 Sexy Comments.....................|NERDComSexyComments|
+        2.5 The NERDComment function..........|NERDComNERDComment|
+    3.Options.................................|NERDComOptions|
+        3.1 Options summary...................|NERDComOptionsSummary|
+        3.2 Options details...................|NERDComOptionsDetails|
+        3.3 Default delimiter Options.........|NERDComDefaultDelims|
+    4. Customising key mappings...............|NERDComMappings|
+    5. Issues with the script.................|NERDComIssues|
+        5.1 Delimiter detection heuristics....|NERDComHeuristics|
+        5.2 Nesting issues....................|NERDComNesting|
+    6.About..     ............................|NERDComAbout|
+    7.Changelog...............................|NERDComChangelog|
+    8.Credits.................................|NERDComCredits|
+    9.License.................................|NERDComLicense|
+
+==============================================================================
+1. Intro                                                       *NERDCommenter*
+
+The NERD commenter provides many different commenting operations and styles
+which are invoked via key mappings and a menu. These operations are available
+for most filetypes.
+
+There are also options that allow to tweak the commenting engine to your
+taste.
+
+==============================================================================
+2. Functionality provided                               *NERDComFunctionality*
+
+------------------------------------------------------------------------------
+2.1 Functionality summary                        *NERDComFunctionalitySummary*
+
+The following key mappings are provided by default (there is also a menu
+with items corresponding to all the mappings below):
+
+[count],cc |NERDComComment|
+Comment out the current line or text selected in visual mode.
+
+
+[count],cn |NERDComNestedComment|
+Same as ,cc but forces nesting.
+
+
+[count],c<space> |NERDComToggleComment|
+Toggles the comment state of the selected line(s). If the topmost selected
+line is commented, all selected lines are uncommented and vice versa.
+
+
+[count],cm |NERDComMinimalComment|
+Comments the given lines using only one set of multipart delimiters.
+
+
+[count],ci |NERDComInvertComment|
+Toggles the comment state of the selected line(s) individually.
+
+
+[count],cs |NERDComSexyComment|
+Comments out the selected lines ``sexily''
+
+
+[count],cy |NERDComYankComment|
+Same as ,cc except that the commented line(s) are yanked first.
+
+
+,c$ |NERDComEOLComment|
+Comments the current line from the cursor to the end of line.
+
+
+,cA |NERDComAppendComment|
+Adds comment delimiters to the end of line and goes into insert mode between
+them.
+
+
+|NERDComInsertComment|
+Adds comment delimiters at the current cursor position and inserts between.
+Disabled by default.
+
+
+,ca |NERDComAltDelim|
+Switches to the alternative set of delimiters.
+
+
+[count],cl
+[count],cb    |NERDComAlignedComment|
+Same as |NERDComComment| except that the delimiters are aligned down the
+left side (,cl) or both sides (,cb).
+
+
+[count],cu |NERDComUncommentLine|
+Uncomments the selected line(s).
+
+------------------------------------------------------------------------------
+2.2 Functionality details                        *NERDComFunctionalityDetails*
+
+------------------------------------------------------------------------------
+2.2.1 Comment map                                             *NERDComComment*
+
+Default mapping: [count],cc
+Mapped to: <plug>NERDCommenterComment
+Applicable modes: normal visual visual-line visual-block.
+
+
+Comments out the current line. If multiple lines are selected in visual-line
+mode, they are all commented out.  If some text is selected in visual or
+visual-block mode then the script will try to comment out the exact text that
+is selected using multi-part delimiters if they are available.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+2.2.2 Nested comment map                                *NERDComNestedComment*
+
+Default mapping: [count],cn
+Mapped to: <plug>NERDCommenterNest
+Applicable modes: normal visual visual-line visual-block.
+
+Performs nested commenting.  Works the same as ,cc except that if a line is
+already commented then it will be commented again.
+
+If |'NERDUsePlaceHolders'| is set then the previous comment delimiters will
+be replaced by place-holder delimiters if needed.  Otherwise the nested
+comment will only be added if the current commenting delimiters have no right
+delimiter (to avoid syntax errors)
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+Related options:
+|'NERDDefaultNesting'|
+
+------------------------------------------------------------------------------
+2.2.3 Toggle comment map                                *NERDComToggleComment*
+
+Default mapping: [count],c<space>
+Mapped to: <plug>NERDCommenterToggle
+Applicable modes: normal visual-line.
+
+Toggles commenting of the lines selected. The behaviour of this mapping
+depends on whether the first line selected is commented or not.  If so, all
+selected lines are uncommented and vice versa.
+
+With this mapping, a line is only considered to be commented if it starts with
+a left delimiter.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+2.2.4 Minimal comment map                              *NERDComMinimalComment*
+
+Default mapping: [count],cm
+Mapped to: <plug>NERDCommenterMinimal
+Applicable modes: normal visual-line.
+
+Comments the selected lines using one set of multipart delimiters if possible.
+
+For example: if you are programming in c and you select 5 lines and press ,cm
+then a '/*' will be placed at the start of the top line and a '*/' will be
+placed at the end of the last line.
+
+Sets of multipart comment delimiters that are between the top and bottom
+selected lines are replaced with place holders (see |'NERDLPlace'|) if
+|'NERDUsePlaceHolders'| is set for the current filetype. If it is not, then
+the comment will be aborted if place holders are required to prevent illegal
+syntax.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+2.2.5 Invert comment map                                *NERDComInvertComment*
+
+Default mapping: ,ci
+Mapped to: <plug>NERDCommenterInvert
+Applicable modes: normal visual-line.
+
+Inverts the commented state of each selected line. If the a selected line is
+commented then it is uncommented and vice versa. Each line is examined and
+commented/uncommented individually.
+
+With this mapping, a line is only considered to be commented if it starts with
+a left delimiter.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+2.2.6 Sexy comment map                                    *NERDComSexyComment*
+
+Default mapping: [count],cs
+Mapped to: <plug>NERDCommenterSexy
+Applicable modes: normal, visual-line.
+
+Comments the selected line(s) ``sexily''... see |NERDComSexyComments| for
+a description of what sexy comments are. Can only be done on filetypes for
+which there is at least one set of multipart comment delimiters specified.
+
+Sexy comments cannot be nested and lines inside a sexy comment cannot be
+commented again.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+Related options:
+|'NERDCompactSexyComs'|
+
+------------------------------------------------------------------------------
+2.2.7 Yank comment map                                    *NERDComYankComment*
+
+Default mapping: [count],cy
+Mapped to: <plug>NERDCommenterYank
+Applicable modes: normal visual visual-line visual-block.
+
+Same as ,cc except that it yanks the line(s) that are commented first.
+
+------------------------------------------------------------------------------
+2.2.8 Comment to EOL map                                   *NERDComEOLComment*
+
+Default mapping: ,c$
+Mapped to: <plug>NERDCommenterToEOL
+Applicable modes: normal.
+
+Comments the current line from the current cursor position up to the end of
+the line.
+
+------------------------------------------------------------------------------
+2.2.9 Append com to line map                            *NERDComAppendComment*
+
+Default mapping: ,cA
+Mapped to: <plug>NERDCommenterAppend
+Applicable modes: normal.
+
+Appends comment delimiters to the end of the current line and goes
+to insert mode between the new delimiters.
+
+------------------------------------------------------------------------------
+2.2.10 Insert comment map                               *NERDComInsertComment*
+
+Default mapping: disabled by default.
+Map it to: <plug>NERDCommenterInInsert
+Applicable modes: insert.
+
+Adds comment delimiters at the current cursor position and inserts
+between them.
+
+NOTE: prior to version 2.1.17 this was mapped to ctrl-c. To restore this
+mapping add >
+    let NERDComInsertMap='<c-c>'
+<
+to your vimrc.
+
+------------------------------------------------------------------------------
+2.2.11 Use alternate delims map                              *NERDComAltDelim*
+
+Default mapping: ,ca
+Mapped to: <plug>NERDCommenterAltDelims
+Applicable modes: normal.
+
+Changes to the alternative commenting style if one is available. For example,
+if the user is editing a c++ file using // comments and they hit ,ca
+then they will be switched over to /**/ comments.
+
+See also |NERDComDefaultDelims|
+
+------------------------------------------------------------------------------
+2.2.12 Comment aligned maps                            *NERDComAlignedComment*
+
+Default mappings: [count],cl   [count],cb
+Mapped to: <plug>NERDCommenterAlignLeft
+           <plug>NERDCommenterAlignBoth
+Applicable modes: normal visual-line.
+
+Same as ,cc except that the comment delimiters are aligned on the left side or
+both sides respectively. These comments are always nested if the line(s) are
+already commented.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+------------------------------------------------------------------------------
+2.2.13 Uncomment line map                               *NERDComUncommentLine*
+
+Default mapping: [count],cu
+Mapped to: <plug>NERDCommenterUncomment
+Applicable modes: normal visual visual-line visual-block.
+
+Uncomments the current line. If multiple lines are selected in
+visual mode then they are all uncommented.
+
+When uncommenting, if the line contains multiple sets of delimiters then the
+``outtermost'' pair of delimiters will be removed.
+
+The script uses a set of heurisics to distinguish ``real'' delimiters from
+``fake'' ones when uncommenting. See |NERDComIssues| for details.
+
+If a [count] is given in normal mode, the mapping works as though that many
+lines were selected in visual-line mode.
+
+Related  options:
+|'NERDRemoveAltComs'|
+|'NERDRemoveExtraSpaces'|
+
+------------------------------------------------------------------------------
+2.3 Supported filetypes                                     *NERDComFiletypes*
+
+Filetypes that can be commented by this plugin:
+abaqus abc acedb ada ahdl amiga aml ampl ant apache apachestyle asm68k asm asn
+aspvbs atlas autohotkey autoit automake ave awk basic b bc bdf bib bindzone
+bst btm caos catalog c cfg cg ch changelog cl clean clipper cmake conf config
+context cpp crontab cs csc csp css cterm cupl csv cvs dcl debchangelog
+debcontrol debsources def diff django docbk dns dosbatch dosini dot dracula
+dsl dtd dtml dylan ecd eiffel elf elmfilt erlang eruby eterm expect exports
+fetchmail fgl focexec form fortran foxpro fstab fvwm fx gdb gdmo geek
+gentoo-package-keywords' gentoo-package-mask' gentoo-package-use' gnuplot
+gtkrc haskell hb h help hercules hog html htmldjango htmlos ia64 icon idlang
+idl indent inform inittab ishd iss ist jam java javascript jess jgraph
+jproperties jproperties jsp kconfig kix kscript lace lex lftp lifelines lilo
+lisp lite lotos lout lprolog lscript lss lua lynx m4 mail make maple masm
+master matlab mel mf mib mma model moduala.  modula2 modula3 monk mush muttrc
+named nasm nastran natural ncf netdict netrw nqc nroff nsis objc ocaml occam
+omlet omnimark openroad opl ora otl ox pascal passwd pcap pccts perl pfmain
+php phtml pic pike pilrc pine plaintex plm plsql po postscr pov povini ppd
+ppwiz procmail progress prolog psf ptcap python python qf radiance ratpoison r
+rc readline rebol registry remind rexx robots rpl rtf ruby sa samba sas sass
+sather scheme scilab screen scsh sdl sed selectbuf sgml sgmldecl sgmllnx sh
+sicad simula sinda skill slang sl slrnrc sm smarty smil smith sml snnsnet
+snnspat snnsres snobol4 spec specman spice sql sqlforms sqlj sqr squid st stp
+strace svn systemverilog tads taglist tags tak tasm tcl terminfo tex text
+plaintex texinfo texmf tf tidy tli trasys tsalt tsscl tssgm uc uil vb verilog
+verilog_systemverilog vgrindefs vhdl vim viminfo virata vo_base vrml vsejcl
+webmacro wget winbatch wml wvdial xdefaults xf86conf xhtml xkb xmath xml
+xmodmap xpm2 xpm xslt yacc yaml z8a
+
+If a language is not in the list of hardcoded supported filetypes then the
+&commentstring vim option is used.
+
+------------------------------------------------------------------------------
+2.4 Sexy Comments                                        *NERDComSexyComments*
+These are comments that use one set of multipart comment delimiters as well as
+one other marker symbol. For example: >
+    /*
+     * This is a c style sexy comment
+     * So there!
+     */
+
+    /* This is a c style sexy comment
+     * So there!
+     * But this one is ``compact'' style */
+<
+Here the multipart delimiters are /* and */ and the marker is *.
+
+------------------------------------------------------------------------------
+2.5 The NERDComment function                             *NERDComNERDComment*
+
+All of the NERD commenter mappings and menu items invoke a single function
+which delegates the commenting work to other functions. This function is
+public and has the prototype: >
+    function! NERDComment(isVisual, type)
+<
+The arguments to this function are simple:
+    - isVisual: if you wish to do any kind of visual comment then set this to
+      1 and the function will use the '< and '> marks to find the comment
+      boundries. If set to 0 then the function will operate on the current
+      line.
+    - type: is used to specify what type of commenting operation is to be
+      performed, and it can be one of the following: "sexy", "invert",
+      "minimal", "toggle", "alignLeft", "alignBoth", "norm", "nested",
+      "toEOL", "append", "insert", "uncomment", "yank"
+
+For example, if you typed >
+    :call NERDComment(1, 'sexy')
+<
+then the script would do a sexy comment on the last visual selection.
+
+
+==============================================================================
+3. Options                                                    *NERDComOptions*
+
+------------------------------------------------------------------------------
+3.1 Options summary                                    *NERDComOptionsSummary*
+
+|'loaded_nerd_comments'|              Turns off the script.
+|'NERDAllowAnyVisualDelims'|          Allows multipart alternative delims to
+                                      be used when commenting in
+                                      visual/visual-block mode.
+|'NERDBlockComIgnoreEmpty'|           Forces right delims to be placed when
+                                      doing visual-block comments.
+|'NERDCommentWholeLinesInVMode'|      Changes behaviour of visual comments.
+|'NERDCreateDefaultMappings'|         Turn the default mappings on/off.
+|'NERDDefaultNesting'|                Tells the script to use nested comments
+                                      by default.
+|'NERDMenuMode'|                      Specifies how the NERD commenter menu
+                                      will appear (if at all).
+|'NERDLPlace'|                        Specifies what to use as the left
+                                      delimiter placeholder when nesting
+                                      comments.
+|'NERDUsePlaceHolders'|               Specifies which filetypes may use
+                                      placeholders when nesting comments.
+|'NERDRemoveAltComs'|                 Tells the script whether to remove
+                                      alternative comment delimiters when
+                                      uncommenting.
+|'NERDRemoveExtraSpaces'|             Tells the script to always remove the
+                                      extra spaces when uncommenting
+                                      (regardless of whether NERDSpaceDelims
+                                      is set)
+|'NERDRPlace'|                        Specifies what to use as the right
+                                      delimiter placeholder when nesting
+                                      comments.
+|'NERDSpaceDelims'|                   Specifies whether to add extra spaces
+                                      around delimiters when commenting, and
+                                      whether to remove them when
+                                      uncommenting.
+|'NERDCompactSexyComs'|               Specifies whether to use the compact
+                                      style sexy comments.
+
+------------------------------------------------------------------------------
+3.3 Options details                                    *NERDComOptionsDetails*
+
+To enable any of the below options you should put the given line in your
+~/.vimrc
+
+                                                       *'loaded_nerd_comments'*
+If this script is driving you insane you can turn it off by setting this
+option >
+    let loaded_nerd_comments=1
+<
+------------------------------------------------------------------------------
+                                                    *'NERDAllowAnyVisualDelims'*
+Values: 0 or 1.
+Default: 1.
+
+If set to 1 then, when doing a visual or visual-block comment (but not a
+visual-line comment), the script will choose the right delimiters to use for
+the comment. This means either using the current delimiters if they are
+multipart or using the alternative delimiters if THEY are multipart.  For
+example if we are editing the following java code: >
+    float foo = 1221;
+    float bar = 324;
+    System.out.println(foo * bar);
+<
+If we are using // comments and select the "foo" and "bar" in visual-block
+mode, as shown left below (where '|'s are used to represent the visual-block
+boundary), and comment it then the script will use the alternative delims as
+shown on the right: >
+
+    float |foo| = 1221;                   float /*foo*/ = 1221;
+    float |bar| = 324;                    float /*bar*/ = 324;
+    System.out.println(foo * bar);        System.out.println(foo * bar);
+<
+------------------------------------------------------------------------------
+                                                     *'NERDBlockComIgnoreEmpty'*
+Values: 0 or 1.
+Default: 1.
+
+This option  affects visual-block mode commenting. If this option is turned
+on, lines that begin outside the right boundary of the selection block will be
+ignored.
+
+For example, if you are commenting this chunk of c code in visual-block mode
+(where the '|'s are used to represent the visual-block boundary) >
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <stdio.h>
+   |int| main(){
+   |   | printf("SUCK THIS\n");
+   |   | while(1){
+   |   |     fork();
+   |   | }
+   |}  |
+<
+If NERDBlockComIgnoreEmpty=0 then this code will become: >
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <stdio.h>
+    /*int*/ main(){
+    /*   */ printf("SUCK THIS\n");
+    /*   */ while(1){
+    /*   */     fork();
+    /*   */ }
+    /*}  */
+<
+Otherwise, the code block would become: >
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <stdio.h>
+    /*int*/ main(){
+    printf("SUCK THIS\n");
+    while(1){
+        fork();
+    }
+    /*}  */
+<
+------------------------------------------------------------------------------
+                                                *'NERDCommentWholeLinesInVMode'*
+Values: 0, 1 or 2.
+Default: 0.
+
+By default the script tries to comment out exactly what is selected in visual
+mode (v). For example if you select and comment the following c code (using |
+to represent the visual boundary): >
+    in|t foo = 3;
+    int bar =| 9;
+    int baz = foo + bar;
+<
+This will result in: >
+    in/*t foo = 3;*/
+    /*int bar =*/ 9;
+    int baz = foo + bar;
+<
+But some people prefer it if the whole lines are commented like: >
+    /*int foo = 3;*/
+    /*int bar = 9;*/
+    int baz = foo + bar;
+<
+If you prefer the second option then stick this line in your vimrc: >
+    let NERDCommentWholeLinesInVMode=1
+<
+
+If the filetype you are editing only has no multipart delimiters (for example
+a shell script) and you hadnt set this option then the above would become >
+    in#t foo = 3;
+    #int bar = 9;
+<
+(where # is the comment delimiter) as this is the closest the script can
+come to commenting out exactly what was selected. If you prefer for whole
+lines to be commented out when there is no multipart delimiters but the EXACT
+text that was selected to be commented out if there IS multipart delimiters
+then stick the following line in your vimrc: >
+    let NERDCommentWholeLinesInVMode=2
+<
+
+Note that this option does not affect the behaviour of commenting in
+|visual-block| mode.
+
+------------------------------------------------------------------------------
+                                                *'NERDCreateDefaultMappings'*
+Values: 0 or 1.
+Default: 1.
+
+If set to 0, none of the default mappings will be created.
+
+See also |NERDComMappings|.
+
+------------------------------------------------------------------------------
+                                                           *'NERDRemoveAltComs'*
+Values: 0 or 1.
+Default: 1.
+
+When uncommenting a line (for a filetype with an alternative commenting style)
+this option tells the script whether to look for, and remove, comment
+delimiters of the alternative style.
+
+For example, if you are editing a c++ file using // style comments and you go
+,cu on this line: >
+    /* This is a c++ comment baby! */
+<
+It will not be uncommented if the NERDRemoveAltComs is set to 0.
+
+------------------------------------------------------------------------------
+                                                       *'NERDRemoveExtraSpaces'*
+Values: 0 or 1.
+Default: 1.
+
+By default, the NERD commenter will remove spaces around comment delimiters if
+either:
+1. |'NERDSpaceDelims'| is set to 1.
+2. NERDRemoveExtraSpaces is set to 1.
+
+This means that if we have the following lines in a c code file: >
+    /* int foo = 5; */
+    /* int bar = 10; */
+    int baz = foo + bar
+<
+If either of the above conditions hold then if these lines are uncommented
+they will become: >
+    int foo = 5;
+    int bar = 10;
+    int baz = foo + bar
+<
+Otherwise they would become: >
+     int foo = 5;
+     int bar = 10;
+    int baz = foo + bar
+<
+If you want the spaces to be removed only if |'NERDSpaceDelims'| is set then
+set NERDRemoveExtraSpaces to 0.
+
+------------------------------------------------------------------------------
+                                                                  *'NERDLPlace'*
+                                                                  *'NERDRPlace'*
+Values: arbitrary string.
+Default:
+    NERDLPlace: "[>"
+    NERDRPlace: "<]"
+
+These options are used to control the strings used as place-holder delimiters.
+Place holder delimiters are used when performing nested commenting when the
+filetype supports commenting styles with both left and right delimiters.
+To set these options use lines like: >
+    let NERDLPlace="FOO"
+    let NERDRPlace="BAR"
+<
+Following the above example, if we have line of c code: >
+    /* int horse */
+<
+and we comment it with ,cn it will be changed to: >
+    /*FOO int horse BAR*/
+<
+When we uncomment this line it will go back to what it was.
+
+------------------------------------------------------------------------------
+                                                                *'NERDMenuMode'*
+Values: 0, 1, 2, 3.
+Default: 3
+
+This option can take 4 values:
+    "0": Turns the menu off.
+    "1": Turns the 'comment' menu on with no menu shortcut.
+    "2": Turns the 'comment 'menu on with <alt>-c as the shortcut.
+    "3": Turns the 'Plugin -> comment' menu on with <alt>-c as the shortcut.
+
+------------------------------------------------------------------------------
+                                                         *'NERDUsePlaceHolders'*
+Values: 0 or 1.
+Default 1.
+
+This option is used to specify whether place-holder delimiters should be used
+when creating a nested comment.
+
+------------------------------------------------------------------------------
+                                                             *'NERDSpaceDelims'*
+Values: 0 or 1.
+Default 0.
+
+Some people prefer a space after the left delimiter and before the right
+delimiter like this: >
+    /* int foo=2; */
+<
+as opposed to this: >
+    /*int foo=2;*/
+<
+If you want spaces to be added then set NERDSpaceDelims to 1 in your vimrc.
+
+See also |'NERDRemoveExtraSpaces'|.
+
+------------------------------------------------------------------------------
+                                                         *'NERDCompactSexyComs'*
+Values: 0 or 1.
+Default 0.
+
+Some people may want their sexy comments to be like this: >
+    /* Hi There!
+     * This is a sexy comment
+     * in c */
+<
+As opposed to like this: >
+    /*
+     * Hi There!
+     * This is a sexy comment
+     * in c
+     */
+<
+If this option is set to 1 then the top style will be used.
+
+------------------------------------------------------------------------------
+                                                          *'NERDDefaultNesting'*
+Values: 0 or 1.
+Default 1.
+
+When this option is set to 1, comments are nested automatically. That is, if
+you hit ,cc on a line that is already commented it will be commented again
+
+------------------------------------------------------------------------------
+3.3 Default delimiter customisation                     *NERDComDefaultDelims*
+
+If you want the NERD commenter to use the alternative delimiters for a
+specific filetype by default then put a line of this form into your vimrc: >
+    let NERD_<filetype>_alt_style=1
+<
+Example: java uses // style comments by default, but you want it to default to
+/* */ style comments instead. You would put this line in your vimrc: >
+    let NERD_java_alt_style=1
+<
+
+See |NERDComAltDelim| for switching commenting styles at runtime.
+
+==============================================================================
+4. Key mapping customisation                                *NERDComMappings*
+
+To change a mapping just map another key combo to the internal <plug> mapping.
+For example, to remap the |NERDComComment| mapping to ",omg" you would put
+this line in your vimrc: >
+    map ,omg <plug>NERDCommenterComment
+<
+This will stop the corresponding default mappings from being created.
+
+See the help for the mapping in question to see which <plug> mapping to
+map to.
+
+See also |'NERDCreateDefaultMappings'|.
+
+==============================================================================
+5. Issues with the script                                      *NERDComIssues*
+
+
+------------------------------------------------------------------------------
+5.1 Delimiter detection heuristics                         *NERDComHeuristics*
+
+Heuristics are used to distinguish the real comment delimiters
+
+Because we have comment mappings that place delimiters in the middle of lines,
+removing comment delimiters is a bit tricky. This is because if comment
+delimiters appear in a line doesnt mean they really ARE delimiters. For
+example, Java uses // comments but the line >
+    System.out.println("//");
+<
+clearly contains no real comment delimiters.
+
+To distinguish between ``real'' comment delimiters and ``fake'' ones we use a
+set of heuristics. For example, one such heuristic states that any comment
+delimiter that has an odd number of non-escaped " characters both preceding
+and following it on the line is not a comment because it is probably part of a
+string. These heuristics, while usually pretty accurate, will not work for all
+cases.
+
+------------------------------------------------------------------------------
+5.2 Nesting issues                                            *NERDComNesting*
+
+If we have some line of code like this: >
+    /*int foo */ = /*5 + 9;*/
+<
+This will not be uncommented legally. The NERD commenter will remove the
+"outter most" delimiters so the line will become: >
+    int foo */ = /*5 + 9;
+<
+which almost certainly will not be what you want. Nested sets of comments will
+uncomment fine though. Eg: >
+    /*int/* foo =*/ 5 + 9;*/
+<
+will become: >
+    int/* foo =*/ 5 + 9;
+<
+(Note that in the above examples I have deliberately not used place holders
+for simplicity)
+
+==============================================================================
+6. About                                                        *NERDComAbout*
+
+The author of the NERD commenter is Martyzillatron --- the half robot, half
+dinosaur bastard son of Megatron and Godzilla. He enjoys destroying
+metropolises and eating tourist busses.
+
+Drop him a line at martin_grenfell at msn.com. He would love to hear from you.
+its a lonely life being the worlds premier terror machine. How would you feel
+if your face looked like a toaster and a t-rex put together? :(
+
+The latest stable versions can be found at
+    http://www.vim.org/scripts/script.php?script_id=1218
+
+The latest dev versions are on github
+    http://github.com/scrooloose/nerdcommenter
+
+==============================================================================
+8. Changelog                                                *NERDComChangelog*
+
+2.2.2
+    - remove the NERDShutup option and the message is suppresses, this makes
+      the plugin silently rely on &commentstring for unknown filetypes.
+    - add support for dhcpd, limits, ntp, resolv, rgb, sysctl, udevconf and
+      udevrules. Thanks to Thilo Six.
+    - match filetypes case insensitively
+    - add support for mp (metapost), thanks to Andrey Skvortsov.
+    - add support for htmlcheetah, thanks to Simon Hengel.
+    - add support for javacc, thanks to Matt Tolton.
+    - make <%# %> the default delims for eruby, thanks to tpope.
+    - add support for javascript.jquery, thanks to Ivan Devat.
+    - add support for cucumber and pdf. Fix sass and railslog delims,
+      thanks to tpope
+
+2.2.1
+    - add support for newlisp and clojure, thanks to Matthew Lee Hinman.
+    - fix automake comments, thanks to Elias Pipping
+    - make haml comments default to -# with / as the alternative delimiter,
+      thanks to tpope
+    - add support for actionscript and processing thanks to Edwin Benavides
+    - add support for ps1 (powershell), thanks to Jason Mills
+    - add support for hostsaccess, thanks to Thomas Rowe
+    - add support for CVScommit
+    - add support for asciidoc, git and gitrebase. Thanks to Simon Ruderich.
+    - use # for gitcommit comments, thanks to Simon Ruderich.
+    - add support for mako and genshi, thanks to Keitheis.
+    - add support for conkyrc, thanks to David
+    - add support for SVNannotate, thanks to Miguel Jaque Barbero.
+    - add support for sieve, thanks to Stefan Walk
+    - add support for objj, thanks to Adam Thorsen.
+
+2.2.0
+    - rewrote the mappings system to be more "standard".
+      - removed all the mapping options. Now, mappings to <plug> mappings are
+        used
+      - see :help NERDComMappings, and :help NERDCreateDefaultMappings for
+        more info
+    - remove "prepend comments" and "right aligned comments".
+    - add support for applescript, calbire, man, SVNcommit, potwiki, txt2tags and SVNinfo.
+      Thanks to nicothakis, timberke, sgronblo, mntnoe, Bernhard Grotz, John
+      O'Shea, François and Giacomo Mariani respectively.
+    - bugfix for haskell delimiters. Thanks to mntnoe.
+2.1.18
+    - add support for llvm. Thanks to nicothakis.
+    - add support for xquery. Thanks to Phillip Kovalev.
+2.1.17
+    - fixed haskell delimiters (hackily). Thanks to Elias Pipping.
+    - add support for mailcap. Thanks to Pascal Brueckner.
+    - add support for stata. Thanks to Jerónimo Carballo.
+    - applied a patch from ewfalor to fix an error in the help file with the
+      NERDMapleader doc
+    - disable the insert mode ctrl-c mapping by default, see :help
+      NERDComInsertComment if you wish to restore it
+
+==============================================================================
+8. Credits                                                    *NERDComCredits*
+
+Thanks to the follow people for suggestions and patches:
+
+Nick Brettell
+Matthew Hawkins
+Mathieu Clabaut
+Greg Searle
+Nguyen
+Litchi
+Jorge Scandaliaris
+Shufeng Zheng
+Martin Stubenschrott
+Markus Erlmann
+Brent Rice
+Richard Willis
+Igor Prischepoff
+Harry
+David Bourgeois
+Eike Von Seggern
+Torsten Blix
+Alexander Bosecke
+Stefano Zacchiroli
+Norick Chen
+Joseph Barker
+Gary Church
+Tim Carey-Smith
+Markus Klinik
+Anders
+Seth Mason
+James Hales
+Heptite
+Cheng Fang
+Yongwei Wu
+David Miani
+Jeremy Hinegardner
+Marco
+Ingo Karkat
+Zhang Shuhan
+tpope
+Ben Schmidt
+David Fishburn
+Erik Falor
+JaGoTerr
+Elias Pipping
+mntnoe
+Mark S.
+
+
+Thanks to the following people for sending me new filetypes to support:
+
+The hackers                         The filetypes~
+Sam R                               verilog
+Jonathan                            Derque context, plaintext and mail
+Vigil                               fetchmail
+Michael Brunner                     kconfig
+Antono Vasiljev                     netdict
+Melissa Reid                        omlet
+Ilia N Ternovich                    quickfix
+John O'Shea                         RTF, SVNcommitlog and vcscommit, SVNCommit
+Anders                              occam
+Mark Woodward                       csv
+fREW                                gentoo-package-mask,
+                                    gentoo-package-keywords,
+                                    gentoo-package-use, and vo_base
+Alexey                              verilog_systemverilog, systemverilog
+Lizendir                            fstab
+Michael Böhler                      autoit, autohotkey and docbk
+Aaron Small                         cmake
+Ramiro                              htmldjango and django
+Stefano Zacchiroli                  debcontrol, debchangelog, mkd
+Alex Tarkovsky                      ebuild and eclass
+Jorge Rodrigues                     gams
+Rainer Müller                       Objective C
+Jason Mills                         Groovy, ps1
+Normandie Azucena                   vera
+Florian Apolloner                   ldif
+David Fishburn                      lookupfile
+Niels Aan de Brugh                  rst
+Don Hatlestad                       ahk
+Christophe Benz                     Desktop and xsd
+Eyolf Ã˜strem                        lilypond, bbx and lytex
+Ingo Karkat                         dosbatch
+Nicolas Weber                       markdown, objcpp
+tinoucas                            gentoo-conf-d
+Greg Weber                          D, haml
+Bruce Sherrod                       velocity
+timberke                            cobol, calibre
+Aaron Schaefer                      factor
+Mr X                                asterisk, mplayerconf
+Kuchma Michael                      plsql
+Brett Warneke                       spectre
+Pipp                                lhaskell
+Renald Buter                        scala
+Vladimir Lomov                      asymptote
+Marco                               mrxvtrc, aap
+nicothakis                          SVNAnnotate, CVSAnnotate, SVKAnnotate,
+                                    SVNdiff, gitAnnotate, gitdiff, dtrace
+                                    llvm, applescript
+Chen Xing                           Wikipedia
+Jacobo Diaz                         dakota, patran
+Li Jin                              gentoo-env-d, gentoo-init-d,
+                                    gentoo-make-conf, grub, modconf, sudoers
+SpookeyPeanut                       rib
+Greg Jandl                          pyrex/cython
+Christophe Benz                     services, gitcommit
+A Pontus                            vimperator
+Stromnov                            slice, bzr
+Martin Kustermann                   pamconf
+Indriði Einarsson                   mason
+Chris                               map
+Krzysztof A. Adamski                group
+Pascal Brueckner                    mailcap
+Jerónimo Carballo                   stata
+Phillip Kovalev                     xquery
+Bernhard Grotz                      potwiki
+sgronblo                            man
+François                            txt2tags
+Giacomo Mariani                     SVNinfo
+Matthew Lee Hinman                  newlisp, clojure
+Elias Pipping                       automake
+Edwin Benavides                     actionscript, processing
+Thomas Rowe                         hostsaccess
+Simon Ruderich                      asciidoc, git, gitcommit, gitrebase
+Keitheis                            mako, genshi
+David                               conkyrc
+Miguel Jaque Barbero                SVNannotate
+Stefan Walk                         sieve
+Adam Thorsen                        objj
+Thilo Six                           dhcpd, limits, ntp, resolv, rgb, sysctl,
+                                    udevconf, udevrules
+Andrey Skvortsov                    mp
+Simon Hengel                        htmlcheetah
+Matt Tolton                         javacc
+Ivan Devat                          javascript.jquery
+tpope                               cucumber,pdf
+==============================================================================
+9. License                                                    *NERDComLicense*
+
+The NERD commenter is released under the wtfpl.
+See http://sam.zoy.org/wtfpl/COPYING.
diff --git a/vim/doc/matchit.txt b/vim/doc/matchit.txt
new file mode 100644 (file)
index 0000000..8a3a96e
--- /dev/null
@@ -0,0 +1,406 @@
+*matchit.txt*   Extended "%" matching
+
+For instructions on installing this file, type
+       :help matchit-install
+inside Vim.
+
+For Vim version 6.3.  Last change:  2007 Aug 29
+
+
+                 VIM REFERENCE MANUAL    by Benji Fisher
+
+*matchit* *matchit.vim*
+
+1. Extended matching with "%"                          |matchit-intro|
+2. Activation                                          |matchit-activate|
+3. Configuration                                       |matchit-configure|
+4. Supporting a New Language                           |matchit-newlang|
+5. Known Bugs and Limitations                          |matchit-bugs|
+
+The functionality mentioned here is a plugin, see |add-plugin|.
+This plugin is only available if 'compatible' is not set.
+You can avoid loading this plugin by setting the "loaded_matchit" variable
+in your |vimrc| file: >
+       :let loaded_matchit = 1
+
+{Vi does not have any of this}
+
+==============================================================================
+1. Extended matching with "%"                          *matchit-intro*
+
+                                                       *matchit-%*
+%      Cycle forward through matching groups, such as "if", "else", "endif",
+       as specified by |b:match_words|.
+
+                                                       *g%* *v_g%* *o_g%*
+g%     Cycle backwards through matching groups, as specified by
+       |b:match_words|.  For example, go from "if" to "endif" to "else".
+
+                                                       *[%* *v_[%* *o_[%*
+[%     Go to [count] previous unmatched group, as specified by
+       |b:match_words|.  Similar to |[{|.
+
+                                                       *]%* *v_]%* *o_]%*
+]%     Go to [count] next unmatched group, as specified by
+       |b:match_words|.  Similar to |]}|.
+
+                                                       *v_a%*
+a%     In Visual mode, select the matching group, as specified by
+       |b:match_words|, containing the cursor.  Similar to |v_a[|.
+       A [count] is ignored, and only the first character of the closing
+       pattern is selected.
+
+In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace,
+bracket, or paren to its match.  This can be configured with the 'matchpairs'
+option.  The matchit plugin extends this in several ways:
+
+           You can match whole words, such as "if" and "endif", not just
+       single characters.  You can also specify a |regular-expression|.
+           You can define groups with more than two words, such as "if",
+       "else", "endif".  Banging on the "%" key will cycle from the "if" to
+       the first "else", the next "else", ..., the closing "endif", and back
+       to the opening "if".  Nested structures are skipped.  Using |g%| goes
+       in the reverse direction.
+           By default, words inside comments and strings are ignored, unless
+       the cursor is inside a comment or string when you type "%".  If the
+       only thing you want to do is modify the behavior of "%" so that it
+       behaves this way, you do not have to define |b:match_words|, since the
+       script uses the 'matchpairs' option as well as this variable.
+
+See |matchit-details| for details on what the script does, and |b:match_words|
+for how to specify matching patterns.
+
+MODES:                 *matchit-modes* *matchit-v_%* *matchit-o_%*
+
+Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in
+|motion| commands in |Operator-pending| and |Visual| modes.  However, you
+cannot make these motions |linewise| or |characterwise|, since the |:omap|s
+that define them start with "v" in order to make the default behavior
+inclusive.  (See |o_v|.)  In other words, "dV%" will not work.  The
+work-around is to go through Visual mode:  "V%d" will work.
+
+LANGUAGES:                                     *matchit-languages*
+
+Currently, the following languages are supported:  Ada, ASP with VBS, Csh,
+DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal,
+SGML, Shell, Tcsh, Vim, XML.  Other languages may already have support via
+the default |filetype-plugin|s in the standard vim distribution.
+
+To support a new language, see |matchit-newlang| below.
+
+DETAILS:                               *matchit-details* *matchit-parse*
+
+Here is an outline of what matchit.vim does each time you hit the "%" key.  If
+there are |backref|s in |b:match_words| then the first step is to produce a
+version in which these back references have been eliminated; if there are no
+|backref|s then this step is skipped.  This step is called parsing.  For
+example, "\(foo\|bar\):end\1" is parsed to yield
+"\(foo\|bar\):end\(foo\|bar\)".  This can get tricky, especially if there are
+nested groups.  If debugging is turned on, the parsed version is saved as
+|b:match_pat|.
+
+                                                       *matchit-choose*
+Next, the script looks for a word on the current line that matches the pattern
+just constructed.  It includes the patterns from the 'matchpairs' option.
+The goal is to do what you expect, which turns out to be a little complicated.
+The script follows these rules:
+
+       Insist on a match that ends on or after the cursor.
+       Prefer a match that includes the cursor position (that is, one that
+               starts on or before the cursor).
+       Prefer a match that starts as close to the cursor as possible.
+       If more than one pattern in |b:match_words| matches, choose the one
+               that is listed first.
+
+Examples:
+
+       Suppose you >
+               :let b:match_words = '<:>,<tag>:</tag>'
+<      and hit "%" with the cursor on or before the "<" in "a <tag> is born".
+       The pattern '<' comes first, so it is preferred over '<tag>', which
+       also matches.  If the cursor is on the "t", however, then '<tag>' is
+       preferred, because this matches a bit of text containing the cursor.
+       If the two groups of patterns were reversed then '<' would never be
+       preferred.
+
+       Suppose you >
+               :let b:match_words = 'if:end if'
+<      (Note the space!) and hit "%" with the cursor at the end of "end if".
+       Then "if" matches, which is probably not what you want, but if the
+       cursor starts on the "end " then "end if" is chosen.  (You can avoid
+       this problem by using a more complicated pattern.)
+
+If there is no match, the cursor does not move.  (Before version 1.13 of the
+script, it would fall back on the usual behavior of |%|).  If debugging is
+turned on, the matched bit of text is saved as |b:match_match| and the cursor
+column of the start of the match is saved as |b:match_col|.
+
+Next, the script looks through |b:match_words| (original and parsed versions)
+for the group and pattern that match.  If debugging is turned on, the group is
+saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest).  If
+there are |backref|s then, in addition, the matching pattern is saved as
+|b:match_word| and a table of translations is saved as |b:match_table|.  If
+there are |backref|s, these are determined from the matching pattern and
+|b:match_match| and substituted into each pattern in the matching group.
+
+The script decides whether to search forwards or backwards and chooses
+arguments for the |searchpair()| function.  Then, the cursor is moved to the
+start of the match, and |searchpair()| is called.  By default, matching
+structures inside strings and comments are ignored.  This can be changed by
+setting |b:match_skip|.
+
+==============================================================================
+2. Activation                                          *matchit-activate*
+
+You can use this script as a plugin, by copying it to your plugin directory.
+See |add-global-plugin| for instructions.  You can also add a line to your
+|vimrc| file, such as >
+       :source $VIMRUNTIME/macros/matchit.vim
+or >
+       :runtime macros/matchit.vim
+Either way, the script should start working the next time you start up Vim.
+
+(Earlier versions of the script did nothing unless a |buffer-variable| named
+|b:match_words| was defined.  Even earlier versions contained autocommands
+that set this variable for various file types.  Now, |b:match_words| is
+defined in many of the default |filetype-plugin|s instead.)
+
+For a new language, you can add autocommands to the script or to your vimrc
+file, but the recommended method is to add a line such as >
+       let b:match_words = '\<foo\>:\<bar\>'
+to the |filetype-plugin| for your language.  See |b:match_words| below for how
+this variable is interpreted.
+
+TROUBLESHOOTING                                        *matchit-troubleshoot*
+
+The script should work in most installations of Vim.  It may not work if Vim
+was compiled with a minimal feature set, for example if the |+syntax| option
+was not enabled.  If your Vim has support for syntax compiled in, but you do
+not have |syntax| highlighting turned on, matchit.vim should work, but it may
+fail to skip matching groups in comments and strings.  If the |filetype|
+mechanism is turned off, the |b:match_words| variable will probably not be
+defined automatically.
+
+==============================================================================
+3. Configuration                                       *matchit-configure*
+
+There are several variables that govern the behavior of matchit.vim.  Note
+that these are variables local to the buffer, not options, so use |:let| to
+define them, not |:set|.  Some of these variables have values that matter; for
+others, it only matters whether the variable has been defined.  All of these
+can be defined in the |filetype-plugin| or autocommand that defines
+|b:match_words| or "on the fly."
+
+The main variable is |b:match_words|.  It is described in the section below on
+supporting a new language.
+
+                               *MatchError* *matchit-hl* *matchit-highlight*
+MatchError is the highlight group for error messages from the script.  By
+default, it is linked to WarningMsg.  If you do not want to be bothered by
+error messages, you can define this to be something invisible.  For example,
+if you use the GUI version of Vim and your command line is normally white, you
+can do >
+       :hi MatchError guifg=white guibg=white
+<
+                                               *b:match_ignorecase*
+If you >
+       :let b:match_ignorecase = 1
+then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END"
+are equivalent.  If you >
+       :let b:match_ignorecase = 0
+then matchit.vim treats "end" and "END" differently.  (There will be no
+b:match_infercase option unless someone requests it.)
+
+                                               *b:match_debug*
+Define b:match_debug if you want debugging information to be saved.  See
+|matchit-debug|, below.
+
+                                               *b:match_skip*
+If b:match_skip is defined, it is passed as the skip argument to
+|searchpair()|.  This controls when matching structures are skipped, or
+ignored.  By default, they are ignored inside comments and strings, as
+determined by the |syntax| mechanism.  (If syntax highlighting is turned off,
+nothing is skipped.)  You can set b:match_skip to a string, which evaluates to
+a non-zero, numerical value if the match is to be skipped or zero if the match
+should not be skipped.  In addition, the following special values are
+supported by matchit.vim:
+       s:foo becomes (current syntax item) =~ foo
+       S:foo becomes (current syntax item) !~ foo
+       r:foo becomes (line before cursor) =~ foo
+       R:foo becomes (line before cursor) !~ foo
+(The "s" is meant to suggest "syntax", and the "r" is meant to suggest
+"regular expression".)
+
+Examples:
+
+       You can get the default behavior with >
+               :let b:match_skip = 's:comment\|string'
+<
+       If you want to skip matching structures unless they are at the start
+       of the line (ignoring whitespace) then you can >
+               :let b:match_skip = 'R:^\s*'
+<      Do not do this if strings or comments can span several lines, since
+       the normal syntax checking will not be done if you set b:match_skip.
+
+       In LaTeX, since "%" is used as the comment character, you can >
+               :let b:match_skip = 'r:%'
+<      Unfortunately, this will skip anything after "\%", an escaped "%".  To
+       allow for this, and also "\\%" (an excaped backslash followed by the
+       comment character) you can >
+               :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%'
+<
+       See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both
+       syntax and a regular expression.
+
+==============================================================================
+4. Supporting a New Language                           *matchit-newlang*
+                                                       *b:match_words*
+In order for matchit.vim to support a new language, you must define a suitable
+pattern for |b:match_words|.  You may also want to set some of the
+|matchit-configure| variables, as described above.  If your language has a
+complicated syntax, or many keywords, you will need to know something about
+Vim's |regular-expression|s.
+
+The format for |b:match_words| is similar to that of the 'matchpairs' option:
+it is a comma (,)-separated list of groups; each group is a colon(:)-separated
+list of patterns (regular expressions).  Commas and backslashes that are part
+of a pattern should be escaped with backslashes ('\:' and '\,').  It is OK to
+have only one group; the effect is undefined if a group has only one pattern.
+A simple example is >
+       :let b:match_words = '\<if\>:\<endif\>,'
+               \ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>'
+(In Vim regular expressions, |\<| and |\>| denote word boundaries.  Thus "if"
+matches the end of "endif" but "\<if\>" does not.)  Then banging on the "%"
+key will bounce the cursor between "if" and the matching "endif"; and from
+"while" to any matching "continue" or "break", then to the matching "endwhile"
+and back to the "while".  It is almost always easier to use |literal-string|s
+(single quotes) as above:  '\<if\>' rather than "\\<if\\>" and so on.
+
+Exception:  If the ":" character does not appear in b:match_words, then it is
+treated as an expression to be evaluated.  For example, >
+       :let b:match_words = 'GetMatchWords()'
+allows you to define a function.  This can return a different string depending
+on the current syntax, for example.
+
+Once you have defined the appropriate value of |b:match_words|, you will
+probably want to have this set automatically each time you edit the
+appropriate file type.  The recommended way to do this is by adding the
+definition to a |filetype-plugin| file.
+
+Tips: Be careful that your initial pattern does not match your final pattern.
+See the example above for the use of word-boundary expressions.  It is usually
+better to use ".\{-}" (as many as necessary) instead of ".*" (as many as
+possible).  See |\{-|.  For example, in the string "<tag>label</tag>", "<.*>"
+matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and
+"</tag>".
+
+                               *matchit-spaces* *matchit-s:notend*
+If "if" is to be paired with "end if" (Note the space!) then word boundaries
+are not enough.  Instead, define a regular expression s:notend that will match
+anything but "end" and use it as follows: >
+       :let s:notend = '\%(\<end\s\+\)\@<!'
+       :let b:match_words = s:notend . '\<if\>:\<end\s\+if\>'
+<                                                      *matchit-s:sol*
+This is a simplified version of what is done for Ada.  The s:notend is a
+|script-variable|.  Similarly, you may want to define a start-of-line regular
+expression >
+       :let s:sol = '\%(^\|;\)\s*'
+if keywords are only recognized after the start of a line or after a
+semicolon (;), with optional white space.
+
+                                       *matchit-backref* *matchit-\1*
+In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the
+INITIAL pattern enclosed in |\(|escaped parentheses|\)|.  These are referred
+to as back references, or backrefs.  For example, >
+       :let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>'
+means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on.  Note
+that "\1" does not refer to the "\(h\)" in this example.  If you have
+"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything
+up to and including the matching "\)":  in "\(nested\(parentheses\)\)", "\1"
+refers to everything and "\2" refers to "\(parentheses\)".  If you use a
+variable such as |s:notend| or |s:sol| in the previous paragraph then remember
+to count any "\(" patterns in this variable.  You do not have to count groups
+defined by |\%(\)|.
+
+It should be possible to resolve back references from any pattern in the
+group.  For example, >
+       :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2'
+would not work because "\2" cannot be determined from "morefoo" and "\1"
+cannot be determined from "andbar".  On the other hand, >
+       :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
+should work (and have the same effect as "foobar:barfoo:endfoobar"), although
+this has not been thoroughly tested.
+
+You can use |zero-width| patterns such as |\@<=| and |\zs|.  (The latter has
+not been thouroughly tested in matchit.vim.)  For example, if the keyword "if"
+must occur at the start of the line, with optional white space, you might use
+the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of
+at the start of the line.  For another example, if HTML had only one tag then
+one could >
+       :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>'
+so that "%" can bounce between matching "<" and ">" pairs or (starting on
+"tag" or "/tag") between matching tags.  Without the |\@<=|, the script would
+bounce from "tag" to the "<" in "</tag>", and another "%" would not take you
+back to where you started.
+
+DEBUGGING                              *matchit-debug* *:MatchDebug*
+
+If you are having trouble figuring out the appropriate definition of
+|b:match_words| then you can take advantage of the same information I use when
+debugging the script.  This is especially true if you are not sure whether
+your patterns or my script are at fault!  To make this more convenient, I have
+made the command :MatchDebug, which defines the variable |b:match_debug| and
+creates a Matchit menu.  This menu makes it convenient to check the values of
+the variables described below.  You will probably also want to read
+|matchit-details| above.
+
+Defining the variable |b:match_debug| causes the script to set the following
+variables, each time you hit the "%" key.  Several of these are only defined
+if |b:match_words| includes |backref|s.
+
+                                                       *b:match_pat*
+The b:match_pat variable is set to |b:match_words| with |backref|s parsed.
+                                                       *b:match_match*
+The b:match_match variable is set to the bit of text that is recognized as a
+match.
+                                                       *b:match_col*
+The b:match_col variable is set to the cursor column of the start of the
+matching text.
+                                                       *b:match_wholeBR*
+The b:match_wholeBR variable is set to the comma-separated group of patterns
+that matches, with |backref|s unparsed.
+                                                       *b:match_iniBR*
+The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|.
+                                                       *b:match_ini*
+The b:match_ini variable is set to the first pattern in |b:match_wholeBR|,
+with |backref|s resolved from |b:match_match|.
+                                                       *b:match_tail*
+The b:match_tail variable is set to the remaining patterns in
+|b:match_wholeBR|, with |backref|s resolved from |b:match_match|.
+                                                       *b:match_word*
+The b:match_word variable is set to the pattern from |b:match_wholeBR| that
+matches |b:match_match|.
+                                                       *b:match_table*
+The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in
+|b:match_word|.
+
+==============================================================================
+5. Known Bugs and Limitations                          *matchit-bugs*
+
+Just because I know about a bug does not mean that it is on my todo list.  I
+try to respond to reports of bugs that cause real problems.  If it does not
+cause serious problems, or if there is a work-around, a bug may sit there for
+a while.  Moral:  if a bug (known or not) bothers you, let me know.
+
+The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may
+have undesired effects in Select mode |Select-mode-mapping|.  At least, if you
+want to replace the selection with any character in "ag%[]" there will be a
+pause of |'updatetime'| first.
+
+It would be nice if "\0" were recognized as the entire pattern.  That is, it
+would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1".  I may
+try to implement this in a future version.  (This is not so easy to arrange as
+you might think!)
+
+==============================================================================
+vim:tw=78:fo=tcq2:
diff --git a/vim/doc/screenpaste.txt b/vim/doc/screenpaste.txt
new file mode 100644 (file)
index 0000000..11a50e8
--- /dev/null
@@ -0,0 +1,437 @@
+*screenpaste.txt* Paste/insert GNU Screen buffer in (almost) any mode  v5.92
+
+Author:        Christian Ebert <blacktrash@gmx.net>
+
+
+               SCREENPASTE REFERENCE MANUAL~
+
+*screenpaste* *screenpaste.vim*
+
+==============================================================================
+
+1. Contents                                            *screenpaste-toc*
+
+       Screen Paste Plugin                             |screenpaste-intro|
+       Activation                                      |screenpaste-activate|
+       Usage                                           |screenpaste-usage|
+       Options                                         |screenpaste-options|
+       Changing Mappings                               |screenpaste-mappings|
+       Commands                                        |screenpaste-commands|
+       Bugs and Limitations                            |screenpaste-bugs|
+       Credits                                         |screenpaste-credits|
+
+==============================================================================
+
+2. Screen Paste Plugin                                 *screenpaste-intro*
+
+The terminal window manager Screen http://www.gnu.org/software/screen
+offers the capability to copy and paste between windows.
+
+In principle you can just do "C-a ]" (default) to paste the current Screen
+buffer into a vim buffer. However this gives unexpected results when 'paste'
+is not set or in Vim's command-line.
+
+This script provides mappings and commands to get correct results.
+
+As an additional feature the current Screen buffer is available in any Vim
+instance, even those /outside/ the current Screen session.
+
+When pasting into command-line in Vim7 many commands are autodetected and the
+behaviour adapts automatically (|getcmdtype()|).
+
+The underlying mechanism of screenpaste consists in getting hold of the
+current Screen buffer via calling to Screen to write it to a temporary file.
+At this point Vim takes over, reads the contents of the file, and puts them to
+use either directly (in Insert, Replace or Command-line mode) or, in Normal
+and Visual mode, by writing to a register and, most often, putting the
+contents of the register into the Vim buffer.  Which is why the default
+keybindings mimic |p|, |P|, |gp|, |gP|, with the |mapleader| prepended, as
+well as |:ScreenPut| and |:ScreenYank| behave almost like |:put| and |:yank|
+respectively.
+
+==============================================================================
+
+3. Activation                                          *screenpaste-activate*
+
+Either copy screenpaste.vim to your plugin directory (|add-global-plugin|),
+or to your macros directory and source it (manually or from |vimrc|): >
+       :runtime macros/screenpaste.vim
+or >
+       :source $HOME/.vim/macros/screenpaste.vim
+
+The Vim Help documentation installs itself when you restart Vim.
+
+The GNU Screen executable has to be in $PATH. Otherwise screenpaste bails out
+giving an error message.
+
+==============================================================================
+
+4. Usage                                               *screenpaste-usage*
+
+Think of the current Screen buffer as of a register at your disposal via the
+|screenpaste| mappings and commands.
+
+                                                       *screenpaste-put*
+When you type the plugin's Ex command
+>
+       :ScreenPut
+
+this works like executing |:put| with the current Screen buffer as register.
+It puts the text after the current line.  Like |:put| it accepts a prepended
+number as parameter designating the target line as well as an appended bang
+to put the text before the indicated line and an optional register argument
+which defaults to |screen_register| when omitted.
+
+|:ScreenPut| differs from |:put| as the register is not only written into the
+buffer but filled with the current Screen buffer beforehand.
+
+                                                       *screenpaste-yank*
+If you want to just get hold of the current Screen buffer for further
+processing, type
+>
+       :ScreenYank
+>
+and the Screen buffer is at your disposal in the |screen_register|.  Similar
+to |:yank| you can also execute the command with an explicit register
+argument.
+
+Note: Screen's copy mechanism discards spaces at the end and the beginning of
+a selection in case there are printable characters in the same line.  In Vim
+terms one could consider this like selecting 'exclusive', and to get a
+|linewise| "yank" the selection has to span visually more than one line, the
+newline at the end of a visually selected single line is not included.
+
+
+All other commands configure the treatment of the current Screen buffer when
+it is pasted into the command-line.  Please refer to |screen_clmode| and
+|screenpaste-commands| for further information.
+
+
+Mappings:~
+
+In |Insert|, |Replace|, and |Command-line| modes (by default) simply type: >
+       \p
+to paste the current Screen buffer.  In these modes the |screen_register| is
+not changed.
+
+Note: mappings are ignored in Insert mode while |'paste'| is set. But in that
+case Screen's "paste" command (bound to "C-a]" by default) works just fine and
+there's no need to work around this via |'pastetoggle'|.
+
+
+The plugin's mappings for |Normal| and |Visual| mode emulate the non-Ex
+commands |p|, |P|, |gp|, and |gP|:  They put the text of the current Screen
+buffer after or before the cursor, or replace the visual selection with it,
+just as if the unnamed register would contain the current Screen buffer (see
+|screen_register|).
+
+If the Screen buffer is empty they do nothing, the registers stay untouched,
+and only a corresponding message is displayed in the menu.
+
+Note however that the optional initial [count] argument to the original non-Ex
+commands will not work with these mappings (|screenpaste-bugs|).
+
+In their default state the |Normal| and |Visual| mode mappings consist of the
+same letters as the corresponding non-Ex commands with the |mapleader|
+prepended: >
+
+       <Leader>p
+       <Leader>P       (not in Visual)
+       <Leader>gp
+       <Leader>gP      (not in Visual)
+
+For simplicity we use the default |screenpaste-mappings| and the default
+|<Leader>| "\" in the following description.
+
+                                                       *screenpaste-p*
+\p                     Put current Screen buffer after the cursor.
+
+                                                       *screenpaste-P*
+\P                     Put current Screen buffer before the cursor.
+                       Not available in Visual mode.
+
+                                                       *screenpaste-gp*
+\gp                    Like "\p" but leave the cursor after the pasted text.
+
+                                                       *screenpaste-gP*
+\gP                    Like "\P" but leave the cursor after the pasted text.
+                       Not available in Visual mode.
+
+In |Visual| mode we do not need "\P" and "\gP" as "\p" and "\P" have the same
+effect of replacing the Visual selected text with the current Screen buffer.
+
+
+To summarize, supposing the default |<Leader>| "\" and the default
+|screenpaste-mappings| you can type:
+>
+       \p  in Normal mode to put Screen buffer after cursor
+       \gp in Normal mode to put Screen buffer after cursor and leave cursor
+               after the end of new text
+       \P  in Normal mode to put Screen buffer before cursor
+       \gP in Normal mode to put Screen buffer before cursor and leave cursor
+               after the end of new text
+       \p  in Visual mode to replace visual selection with Screen buffer
+       \gp in Visual mode to put Screen buffer after cursor and leave cursor
+               after the end of new text
+       \p  in Insert and Replace mode to paste Screen buffer
+       \p  in Command-line-mode to put Screen buffer in command line
+
+==============================================================================
+
+5. Options                                             *screenpaste-options*
+
+g:loaded_screenpaste                                   *loaded_screenpaste*
+
+       This option normally is set by screenpaste to avoid loading the script
+       more than once. But you can use it to get the current script version: >
+               :echo loaded_screenpaste
+<
+       If you want to disable screenpaste, put the following line in your
+       |vimrc|: >
+               let g:loaded_screenpaste = 1
+
+g:screen_executable                                    *screen_executable*
+
+Type           String
+Default Value  'screen'
+
+       Set this option if the name of your GNU Screen executable differs from
+       "screen", or if you like to specify it's full path: >
+               let g:screen_executable = "/usr/local/bin/screen"
+
+g:screen_visualselect                                  *screen_visualselect*
+Type           Boolean
+Default Value  0
+
+        If set to 1 and in Visual mode the text from the Screen buffer is
+        visually selected after the put operation.
+
+g:screen_register                                      *screen_register*
+
+Type           String
+Valid Values   "a-z0-9A-Z
+Default Value  '"'
+
+       The non-Ex put "commands" (mappings) act in a twofold operation when
+       executed in Normal or Visual mode: they yank the Screen buffer into a
+       register in the background, and then put the register into the buffer
+       or command-line.  This variable controls the register that is used for
+       the first part of the operation.  It defaults to the unnamed register
+       "" (|quotequote|).
+
+       Normally you should be fine with the default setting.  But if you
+       prefer to reserve a register of your choice for the Screen buffer you
+       can do so with this option.  Besides the default "", you may choose
+       any named (|quote_alpha|) or numbered (|quote_number|) register.
+       Consult |registers| about their behaviour.
+
+       For a one time operation with a special register the use of
+       |ScreenPut| ex-command and its register argument is recommended.
+
+       Note: Due to the mechanics of the script even a numbered register has
+       to be passed as string, ie. it has to quoted when you set it; eg. >
+               :let g:screen_register = "8"
+<      Note as well that specifying an uppercase letter means that the
+       contents of the Screen buffer will be appended to the register named
+       with the corresponding lowercase character (|quote_alpha|).
+
+g:screen_clmode                                                *screen_clmode*
+
+Type           String
+Valid Values   'search', 'sub', 'noesc'
+Default Value   'search'
+
+       This setting controls how the Screen buffer is treated when pasted in
+       the command line.
+
+       You can change the setting at startup in your |vimrc|: >
+               let g:screen_clmode = "sub"
+<
+       To change its value in a vim session you might want to use one of the
+       |:ScreenCmdlineConf|, |:ScreenSearch|, |:ScreenSub|, |:ScreenNoEsc|
+       commands as they also give a short informative message on how the mode
+       of your choice will act, and prevent you from setting an invalid value.
+
+       Information on the current value and the resulting behaviour is also
+       available via the |:ScreenCmdlineInfo| command.
+
+Modes and their behaviour:
+                                                       *screenpaste-search*
+'search' ~
+       Converts end-of-line to literal '\n'.
+       Escapes characters according to the current setting of 'magic':
+       magic:    [ ] / \ ^ * . ~ $
+       nomagic:    ] / \ ^       $
+
+       Use this mode to search for occurrences of current Screen buffer.
+       Example as typed using default mapleader: >
+               :ScreenSearch
+               :%s/\p/repl/g
+<      If the current Screen buffer is `[hello world.]' and 'magic' is set,
+       the above becomes: >
+               :%s/\[hello world\.\]/repl/g
+<                                                      *screenpaste-sub*
+'sub' ~
+       Converts end-of-line to literal '\r'.
+       Escapes characters according to the current setting of 'magic':
+       magic:    /  \  ~  &
+       nomagic:  /  \
+
+       Use this mode to substitute a pattern with current Screen buffer.
+       Example as typed using default mapleader: >
+               :ScreenSub
+               :%s/pattern/\p/g
+<      If the current Screen buffer is `http://www.vim.org', the above
+       becomes: >
+               :%s/pattern/http:\/\/www.vim.org/g
+<                                                      *screenpaste-noesc*
+'noesc' ~
+       Converts end-of-line to literal '\n'.
+
+       Use this mode to paste current Screen buffer literally into command
+       line.
+
+Vim7:
+       |/|, |?|, |input()|, |:insert|, and |:append| commands are
+       autodetected when not in 'noesc' |screen_clmode|. This means that even
+       when you are in 'sub' mode you can type: >
+               /\p
+<      and this becomes (using above example for 'search'): >
+               /\[hello world\.\]
+<
+       Note: If you paste a Screen buffer containing newlines while in an
+       |:insert| or |:append| but outside a running Screen session the
+       newlines are escaped because we cannot call Screen's paste mechanism
+       without clobbering a parallel Screen session, and Vim would insert
+       <Nul> characters instead (see |NL-used-for-Nul|).
+
+Vim6:
+       For |:insert| and |:append| commands use Screen's "C-a ]"
+
+==============================================================================
+
+6. Changing Mappings                                   *screenpaste-mappings*
+                                                       *ScreenpastePut*
+                                                       *ScreenpasteGPut*
+                                                       *ScreenpastePutBefore*
+                                                       *ScreenpasteGPutBefore*
+
+The right-hand-side |{rhs}| mappings provided by this plugin and the modes in
+which to apply them are: >
+
+       <Plug>ScreenpastePut            Normal, Visual, Insert, Command-line
+       <Plug>ScreenpasteGPut           Normal, Visual
+       <Plug>ScreenpastePutBefore      Normal
+       <Plug>ScreenpasteGPutBefore     Normal
+<
+Use these to customize the default mappings <Leader>p, <Leader>gp, <Leader>P,
+and <Leader>gP to your taste (see |using-<Plug>| and |:map-modes|).
+
+The default mappings would look like this in a |vimrc|:
+
+map  <Leader>p  <Plug>ScreenpastePut           " Normal, Visual mode
+map! <Leader>p  <Plug>ScreenpastePut           " Insert, Command-line mode
+map  <Leader>gp <Plug>ScreenpasteGPut          " Normal, Visual mode
+nmap <Leader>P  <Plug>ScreenpastePutBefore     " Normal mode
+nmap <Leader>gP <Plug>ScreenpasteGPutBefore    " Normal mode
+
+You can tweak them by changing their left-hand-side |{lhs}|.
+
+Normal (put after cursor) and Visual mode:
+                                                       default
+:map   {lhs}   <Plug>ScreenpastePut                      \p
+:map   {lhs}   <Plug>ScreenpasteGPut                     \gp
+
+       Vimrc example: >
+               map  <Leader>P <Plug>ScreenpastePut
+
+Normal mode (put before cursor):
+
+:nmap  {lhs}   <Plug>ScreenpastePutBefore                \P
+:nmap  {lhs}   <Plug>ScreenpasteGPutBefore               \gP
+
+       Vimrc example: >
+               nmap <Leader>I <Plug>ScreenpastePutBefore
+
+Insert and Command-line mode:
+
+:map!  {lhs}   <Plug>ScreenpastePut                      \p
+
+       Vimrc example, to avoid character mappings when inserting: >
+               map! <F7> <Plug>ScreenpastePut
+
+==============================================================================
+
+7. Commands                                            *screenpaste-commands*
+
+                                                       *:ScreenYank*
+:ScreenYank [x]                Yank current Screen buffer into register [x] (default
+                       |screen_register|).
+
+                                                       *:ScreenPut*
+:[line]ScreenPut [x]   Put the text from current Screen buffer after [line]
+                       (default current line) using register [x] (default
+                       |screen_register|).
+
+       You can use this command for instance to append the contents of the
+       Screen buffer to a named register and then paste in one go: >
+               :3 ScreenPut A
+<      puts the contents of register "a and the Screen buffer after line 3.
+
+:[line]ScreenPut! [x]  Put the text from current Screen buffer before [line]
+                       (default current line) using register [x] (default
+                       |screen_register|).
+
+                                                       *:ScreenCmdlineConf*
+:ScreenCmdlineConf {mode}
+                       Tell screenpaste to convert the current Screen
+                       buffer in command-line-mode according to {mode}.
+                       Takes one argument of: "search", "sub", "noesc" (w/o
+                       quotes).
+                       Changes |screen_clmode| accordingly.
+       Example: >
+               :ScreenCmdlineConf noesc
+<
+                                                       *:ScreenCmdlineInfo*
+:ScreenComdlineInfo    Display information on current command-line-mode
+                       behaviour, ie. current |screen_clmode| and what it
+                       does.
+
+                                                       *:ScreenSearch*
+:ScreenSearch          Set |screen_clmode| to 'search'.
+       Equivalent to: >
+               :ScreenCmdlineConf search
+<
+                                                       *:ScreenSub*
+:ScreenSub             Set |screen_clmode| to 'sub'.
+       Equivalent to: >
+               :ScreenCmdlineConf sub
+<
+                                                       *:ScreenNoEsc*
+:ScreenNoEsc           Set |screen_clmode| to 'noesc'.
+       Equivalent to: >
+               :ScreenCmdlineConf noesc
+
+==============================================================================
+
+8. Bugs and Limitations                                        *screenpaste-bugs*
+
+Found no way (yet?) to make optional initial [count] argument work with
+(Normal mode) mappings.
+
+Screen's copy mechanism treats spaces (including newlines) at the beginning or
+the end of a selection in a different manner than Vim's visual yank does.
+
+Screen expands tabs, expect incorrect results if the Screen buffer contains
+tabs.
+
+==============================================================================
+
+Credits                                                        *screenpaste-credits*
+
+Mathieu Clabaut, Guo-Peng Wen  let me steal and tweak the inline
+                               self-install code for this Help document.
+
+==============================================================================
+
+ vim:tw=78:ts=8:ft=help:norl:
diff --git a/vim/doc/surround.txt b/vim/doc/surround.txt
new file mode 100644 (file)
index 0000000..fec64a2
--- /dev/null
@@ -0,0 +1,218 @@
+*surround.txt*  Plugin for deleting, changing, and adding "surroundings"
+
+Author:  Tim Pope <vimNOSPAM@tpope.info>        *surround-author*
+License: Same terms as Vim itself (see |license|)
+
+This plugin is only available if 'compatible' is not set.
+
+INTRODUCTION                                    *surround*
+
+This plugin is a tool for dealing with pairs of "surroundings."  Examples
+of surroundings include parentheses, quotes, and HTML tags.  They are
+closely related to what Vim refers to as |text-objects|.  Provided
+are mappings to allow for removing, changing, and adding surroundings.
+
+Details follow on the exact semantics, but first, consider the following
+examples.  An asterisk (*) is used to denote the cursor position.
+
+  Old text                  Command     New text ~
+  "Hello *world!"           ds"         Hello world!
+  [123+4*56]/2              cs])        (123+456)/2
+  "Look ma, I'm *HTML!"     cs"<q>      <q>Look ma, I'm HTML!</q>
+  if *x>3 {                 ysW(        if ( x>3 ) {
+  my $str = *whee!;         vlllls'     my $str = 'whee!';
+
+While a few features of this plugin will work in older versions of Vim,
+Vim 7 is recommended for full functionality.
+
+MAPPINGS                                        *surround-mappings*
+
+Delete surroundings is *ds* .  The next character given determines the target
+to delete.  The exact nature of the target are explained in |surround-targets|
+but essentially it is the last character of a |text-object|.  This mapping
+deletes the difference between the "inner" object and "an" object.  This is
+easiest to understand with some examples:
+
+  Old text                  Command     New text ~
+  "Hello *world!"           ds"         Hello world!
+  (123+4*56)/2              ds)         123+456/2
+  <div>Yo!*</div>           dst         Yo!
+
+Change surroundings is *cs* .  It takes two arguments, a target like with
+|ds|, and a replacement.  Details about the second argument can be found
+below in |surround-replacements|.  Once again, examples are in order.
+
+  Old text                  Command     New text ~
+  "Hello *world!"           cs"'        'Hello world!'
+  "Hello *world!"           cs"<q>      <q>Hello world!</q>
+  (123+4*56)/2              cs)]        [123+456]/2
+  (123+4*56)/2              cs)[        [ 123+456 ]/2
+  <div>Yo!*</div>           cst<p>      <p>Yo!</p>
+
+*ys* takes an valid Vim motion or text object as the first object, and wraps
+it using the second argument as with |cs|.  (Unfortunately there's no good
+mnemonic for "ys".)
+
+  Old text                  Command     New text ~
+  Hello w*orld!             ysiw)       Hello (world)!
+
+As a special case, *yss* operates on the current line, ignoring leading
+whitespace.
+
+  Old text                  Command     New text ~
+      Hello w*orld!         yssB            {Hello world!}
+
+There is also *yS* and *ySS* which indent the surrounded text and place it
+on a line of its own.
+
+In visual mode, a simple "s" with an argument wraps the selection.  This is
+referred to as the *vs* mapping, although ordinarily there will be
+additional keystrokes between the v and s.  In linewise visual mode, the
+surroundings are placed on separate lines.  In blockwise visual mode, each
+line is surrounded.
+
+An "S" in visual mode (*vS*) behaves similarly but always places the
+surroundings on separate lines.  Additionally, the surrounded text is
+indented.  In blockwise visual mode, using "S" instead of "s" instead skips
+trailing whitespace.
+
+Note that "s" and "S" already have valid meaning in visual mode, but it is
+identical to "c".  If you have muscle memory for "s" and would like to use a
+different key, add your own mapping and the existing one will be disabled.
+>
+  vmap <Leader>s <Plug>Vsurround
+  vmap <Leader>S <Plug>VSurround
+<
+                                                *i_CTRL-G_s* *i_CTRL-G_S*
+Finally, there is an experimental insert mode mapping on <C-G>s and <C-S>.
+Beware that the latter won't work on terminals with flow control (if you
+accidentally freeze your terminal, use <C-Q> to unfreeze it).  The mapping
+inserts the specified surroundings and puts the cursor between them.  If,
+immediately after the mapping and before the replacement, a second <C-S> or
+carriage return is pressed, the prefix, cursor, and suffix will be placed on
+three separate lines.  <C-G>S (not <C-G>s) also exhibits this behavior.
+
+TARGETS                                         *surround-targets*
+
+The |ds| and |cs| commands both take a target as their first argument.  The
+possible targets are based closely on the |text-objects| provided by Vim.
+In order for a target to work, the corresponding text object must be
+supported in the version of Vim used (Vim 7 adds several text objects, and
+thus is highly recommended).  All targets are currently just one character.
+
+Eight punctuation marks, (, ), {, }, [, ], <, and >, represent themselves
+and their counterpart.  If the opening mark is used, contained whitespace is
+also trimmed.  The targets b, B, r, and a are aliases for ), }, ], and >
+(the first two mirror Vim; the second two are completely arbitrary and
+subject to change).
+
+Three quote marks, ', ", `, represent themselves, in pairs.  They are only
+searched for on the current line.
+
+A t is a pair of HTML or XML tags.  See |tag-blocks| for details.  Remember
+that you can specify a numerical argument if you want to get to a tag other
+than the innermost one.
+
+The letters w, W, and s correspond to a |word|, a |WORD|, and a |sentence|,
+respectively.  These are special in that they have nothing to delete, and
+used with |ds| they are a no-op.  With |cs|, one could consider them a
+slight shortcut for ysi (cswb == ysiwb, more or less).
+
+A p represents a |paragraph|.  This behaves similarly to w, W, and s above;
+however, newlines are sometimes added and/or removed.
+
+REPLACEMENTS                                    *surround-replacements*
+
+A replacement argument is a single character, and is required by |cs|, |ys|,
+and |vs|.  Undefined replacement characters (with the exception of alphabetic
+characters) default to placing themselves at the beginning and end of the
+destination, which can be useful for characters like / and |.
+
+If either ), }, ], or > is used, the text is wrapped in the appropriate pair
+of characters.  Similar behavior can be found with (, {, and [ (but not <),
+which append an additional space to the inside.  Like with the targets above,
+b, B, r, and a are aliases for ), }, ], and >.  To fulfill the common need for
+code blocks in C-style languages, <C-}> (which is really <C-]>) adds braces on
+lines separate from the content.
+
+If t or < is used, Vim prompts for an HTML/XML tag to insert.  You may specify
+attributes here and they will be stripped from the closing tag.  End your
+input by pressing <CR> or >.  If <C-T> is used, the tags will appear on lines
+by themselves.
+
+A deprecated replacement of a LaTeX environment is provided on \ and l.  The
+name of the environment and any arguments will be input from a prompt.  This
+will be removed once a more fully functional customization system is
+implemented.  The following shows the resulting environment from
+csp\tabular}{lc<CR>
+>
+  \begin{tabular}{lc}
+  \end{tabular}
+<
+CUSTOMIZING                                     *surround-customizing*
+
+The following adds a potential replacement on "-" (ASCII 45) in PHP files.
+(To determine the ASCII code to use, :echo char2nr("-")).  The carriage
+return will be replaced by the original text.
+>
+  autocmd FileType php let b:surround_45 = "<?php \r ?>"
+<
+This can be used in a PHP file as in the following example.
+
+  Old text                  Command     New text ~
+  print "Hello *world!"     yss-        <?php print "Hello world!" ?>
+
+Additionally, one can use a global variable for globally available
+replacements.
+>
+  let g:surround_45 = "<% \r %>"
+  let g:surround_61 = "<%= \r %>"
+<
+Advanced, experimental, and subject to change:  One can also prompt for
+replacement text.  The syntax for this is to surround the replacement in pairs
+of low numbered control characters.  If this sounds confusing, that's because
+it is (but it makes the parsing easy).  Consider the following example for a
+LaTeX environment on the "l" replacement.
+>
+  let g:surround_108 = "\\begin{\1environment: \1}\r\\end{\1\1}"
+<
+When this replacement is used,  the user is prompted with an "environment: "
+prompt for input.  This input is inserted between each set of \1's.
+Additional inputs up to \7 can be used.
+
+Furthermore, one can specify a regular expression substitution to apply.
+>
+  let g:surround_108 = "\\begin{\1environment: \1}\r\\end{\1\r}.*\r\1}"
+<
+This will remove anything after the first } in the input when the text is
+placed within the \end{} slot.  The first \r marks where the pattern begins,
+and the second where the replacement text begins.
+
+Here's a second example for creating an HTML <div>.  The substitution cleverly
+prompts for an id, but only adds id="" if it is non-blank.  You may have to
+read this one a few times slowly before you understand it.
+>
+  let g:surround_{char2nr("d")} = "<div\1id: \r..*\r id=\"&\"\1>\r</div>"
+<
+Inputting text replacements is a proof of concept at this point. The ugly,
+unintuitive interface and the brevity of the documentation reflect this.
+
+Finally, It is possible to always append a string to surroundings in insert
+mode (and only insert mode).  This is useful with certain plugins and mappings
+that allow you to jump to such markings.
+>
+  let g:surround_insert_tail = "<++>"
+<
+ISSUES                                          *surround-issues*
+
+Vim could potentially get confused when deleting/changing occurs at the very
+end of the line.  Please report any repeatable instances of this.
+
+Do we need to use |inputsave()|/|inputrestore()| with the tag replacement?
+
+Indenting is handled haphazardly.  Need to decide the most appropriate
+behavior and implement it.  Right now one can do :let b:surround_indent = 1
+(or the global equivalent) to enable automatic re-indenting by Vim via |=|;
+should this be the default?
+
+ vim:tw=78:ts=8:ft=help:norl:
diff --git a/vim/ftdetect/asciidoc_filetype.vim b/vim/ftdetect/asciidoc_filetype.vim
new file mode 100644 (file)
index 0000000..9a936e0
--- /dev/null
@@ -0,0 +1,53 @@
+" Vim filetype detection file
+" Language:     AsciiDoc
+" Author:       Stuart Rackham <srackham@gmail.com>
+" Last Change:  AsciiDoc 8.2.0
+" URL:          http://www.methods.co.nz/asciidoc/
+" Licence:      GPL (http://www.gnu.org)
+" Remarks:      Vim 6 or greater
+
+" COMMENT OUT ONE OF THE TWO FOLLOWING COMMANDS
+" The first sets asciidoc syntax highlighting on all .txt files, the second
+" only existing files *.txt that appear to be AsciiDoc files.
+
+"au BufNewFile,BufRead *.txt,README,TODO,CHANGELOG,NOTES  setfiletype asciidoc
+au BufRead *.txt,README,TODO,CHANGELOG,NOTES call s:FTasciidoc()
+
+" This function checks for a valid AsciiDoc document title after first
+" skipping any leading comments.
+function! s:FTasciidoc()
+  let in_comment_block = 0
+  let n = 1
+  while n < 50
+    let line = getline(n)
+    let n = n + 1
+    if line =~ '^/\{4,}$'
+      if ! in_comment_block
+        let in_comment_block = 1
+      else
+        let in_comment_block = 0
+      endif
+      continue
+    endif
+    if in_comment_block
+      continue
+    endif
+    if line !~ '\(^//\)\|\(^\s*$\)'
+      break
+    endif
+  endwhile
+  if line !~ '.\{3,}'
+    return
+  endif
+  let len = len(line)
+  let line = getline(n)
+  if line !~ '[-=]\{3,}'
+    return
+  endif
+  if len < len(line) - 3 || len > len(line) + 3
+    return
+  endif
+  setfiletype asciidoc
+endfunction
+
+" vim: et sw=2 ts=2 sts=2:
diff --git a/vim/ftdetect/vimperator.vim b/vim/ftdetect/vimperator.vim
new file mode 100644 (file)
index 0000000..b7ee1a4
--- /dev/null
@@ -0,0 +1,2 @@
+" Vimperator
+au BufNewFile,BufRead *vimperatorrc*,*.vimp set filetype=vimperator
diff --git a/vim/indent/tcl.vim b/vim/indent/tcl.vim
new file mode 100644 (file)
index 0000000..b9b0a8b
--- /dev/null
@@ -0,0 +1,478 @@
+" Vim indent file for Tcl/tk language
+" Language:    Tcl
+" Maintained:  SM Smithfield <m_smithfield@yahoo.com>
+" Last Change: 02/08/2007 (06:35:02)
+" Filenames:    *.tcl
+" Version:      0.3.6
+" ------------------------------------------------------------------
+" GetLatestVimScripts: 1717 1 :AutoInstall: indent/tcl.vim
+" ------------------------------------------------------------------
+
+" if there is another, bail
+if exists("b:did_indent")
+  finish
+endif
+
+let b:did_indent = 1
+
+setlocal nosmartindent
+
+" indent expression and keys that trigger it
+setlocal indentexpr=GetTclIndent()
+setlocal indentkeys-=:,0#
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+" say something once, why say it again
+if exists("*GetTclIndent")
+  finish
+endif
+
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+" syntax groups that should not be touched by the indent process
+let s:syng_com = '\<tcl\%(Comment\|CommentBraces\|Todo\|Start\)\>'
+" syntax groups that should be ignored by the indent process
+let s:syng_strcom = '\<tcl\%(Quotes\|Comment\|CommentBraces\|SemiColon\|Special\|Todo\|Start\)\>'
+" regexp that facilitates finding the correct mate to a brace, skipping comments, strings and such
+let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~ '".s:syng_strcom."'"
+
+function s:IsComment(lnum)
+    let pos = 0
+    " try to find a solid char
+    let line = getline(a:lnum)
+    let pos1 = matchend(line, '^\s*\S', 0)
+    if pos1 > 0
+        let pos = pos1
+    endif
+    let q = synIDattr(synID(a:lnum, pos, 0), 'name')
+    return (q =~ s:syng_com)
+endfunction
+
+" returns 0/1 whether the cursor pos is in a string/comment syntax run or no.
+function s:IsInStringOrComment(lnum, col)
+    let q = synIDattr(synID(a:lnum, a:col, 0), 'name') 
+    let retval = (q =~ s:syng_strcom)
+    return retval
+endfunction
+
+if version < 700
+    " for the purpose of the following tests, valid means that the character is
+    " not in a string/comment or other *bad* syntax run.
+
+    " returns the pos of the leftmost valid occurance of ch
+    " or -1 for no match
+    function s:leftmostChar(lnum, ch, pos0)
+        let line = getline(a:lnum)
+        let pos1 = match(line, a:ch, a:pos0)
+        if pos1>=0
+            if s:IsInStringOrComment(a:lnum, pos1+1) == 1
+                let pos2 = pos1
+                let pos1 = -1
+                while pos2>=0 && s:IsInStringOrComment(a:lnum, pos2+1)
+                    let pos2 = match(line, a:ch, pos2+1)
+                endwhile
+                if pos2>=0 
+                    let pos1 = pos2
+                endif
+            endif
+        endif
+        return pos1
+    endfunction
+
+    " returns the pos of the rightmost valid occurance of ch
+    " or -1 for no match
+    function s:rightmostChar(lnum, ch, pos0)
+        let line = getline(a:lnum)
+        if a:pos0 == -1
+            let posMax = strlen(line)
+        else
+            let posMax = a:pos0
+        endif
+        let pos1 = match(line, a:ch, 0)
+        let pos2 = -1
+        while pos1>=0 && pos1 < posMax
+            if !s:IsInStringOrComment(a:lnum, pos1+1)
+                let pos2 = pos1
+            endif
+            let pos1 = match(line, a:ch, pos1+1)
+        endwhile
+        return pos2
+    endfunction
+
+else
+    " returns the pos of the leftmost valid occurance of ch
+    " or -1 for no match
+    function s:leftmostChar(lnum, ch, pos0)
+        let line = getline(a:lnum)
+        let pos1 = stridx(line, a:ch, a:pos0)
+        if pos1>=0
+            if s:IsInStringOrComment(a:lnum, pos1+1) == 1
+                let pos2 = pos1
+                let pos1 = -1
+                while pos2>=0 && s:IsInStringOrComment(a:lnum, pos2+1)
+                    let pos2 = stridx(line, a:ch, pos2+1)
+                endwhile
+                if pos2>=0 
+                    let pos1 = pos2
+                endif
+            endif
+        endif
+        return pos1
+    endfunction
+
+    " returns the pos of the rightmost valid occurance of ch
+    " or -1 for no match
+    function s:rightmostChar(lnum, ch, pos0)
+        let line = getline(a:lnum)
+        if a:pos0 == -1
+            let pos = strlen(line)
+        else
+            let pos = a:pos0
+        endif
+        let pos1 = strridx(line, a:ch, pos)
+        if pos1>=0
+            if s:IsInStringOrComment(a:lnum, pos1+1) == 1
+                let pos2 = pos1
+                let pos1 = -1
+                while pos2>=0 && s:IsInStringOrComment(a:lnum, pos2+1)
+                    let pos2 = strridx(line, a:ch, pos2-1)
+                endwhile
+                if pos2>=0
+                    let pos1 = pos2
+                endif
+            endif
+        endif
+        return pos1
+    endfunction
+endif
+
+
+" returns the position of the brace that opens the current line
+" or -1 for no match
+function s:GetOpenBrace(lnum)
+    let openpos = s:rightmostChar(a:lnum, '{', -1)
+    let closepos = s:rightmostChar(a:lnum, '}', -1)
+
+    let sum = 0
+
+    while openpos >= 0
+        if closepos < 0
+            let sum = sum + 1
+            if sum > 0
+                return openpos
+            endif
+            let openpos = s:rightmostChar(a:lnum, '{', openpos-1)
+        elseif openpos > closepos
+            let sum = sum + 1
+            if sum > 0
+                return openpos
+            endif
+            let closepos = s:rightmostChar(a:lnum, '}', openpos-1)
+            let openpos = s:rightmostChar(a:lnum, '{', openpos-1)
+        else
+            let sum = sum - 1
+            let openpos = s:rightmostChar(a:lnum, '{', closepos-1)
+            let closepos = s:rightmostChar(a:lnum, '}', closepos-1)
+        endif
+    endwhile
+    return -1
+endfunction
+
+" returns the position of the brace that closes the current line
+" or -1 for no match
+function s:GetCloseBrace(lnum)
+    let openpos = s:leftmostChar(a:lnum, '{', -1)
+    let closepos = s:leftmostChar(a:lnum, '}', -1)
+
+    let sum = 0
+
+    while closepos >= 0
+        if openpos < 0
+            let sum = sum + 1
+            if sum > 0
+                return closepos
+            endif
+            let closepos = s:leftmostChar(a:lnum, '}', closepos+1)
+        elseif closepos < openpos
+            let sum = sum + 1
+            if sum > 0
+                return closepos
+            endif
+            let openpos = s:leftmostChar(a:lnum, '{', closepos+1)
+            let closepos = s:leftmostChar(a:lnum, '}', closepos+1)
+        else
+            let sum = sum - 1
+            let closepos = s:leftmostChar(a:lnum, '}', openpos+1)
+            let openpos = s:leftmostChar(a:lnum, '{', openpos+1)
+        endif
+    endwhile
+    return -1
+endfunction
+
+function s:HasLeadingStuff(lnu, pos)
+    let rv = 0
+    let line = getline(a:lnu)
+    let pos1 = matchend(line, '{\s*\S', a:pos)
+    if pos1 >= 0
+        let rv = !s:IsInStringOrComment(a:lnu,pos1)
+    endif
+    return rv
+endfunction
+
+
+function s:HasTrailingStuff(lnu, pos)
+    " find the first non-ws-char after matchopen, is NOT string/comment -> has stuff
+    let rv = 0
+    let line = getline(a:lnu)
+    let expr = '\S\s*\%'.(a:pos+1).'c}'
+    let pos1 = match(line, expr)
+    return (pos1 >= 0)
+endfunction
+
+function s:LineContinueIndent(lnu)
+    " returns a relative indent offset
+    let delt_ind = 0
+    if a:lnu > 1 
+        " echo "lc-0"
+        let pline = getline(a:lnu-1)
+        let line = getline(a:lnu)
+        if !s:IsComment(a:lnu) 
+            " echo "lc-1" line_is_comment pline_is_comment
+            if pline =~ '\\$'
+                " echo "lc-2"
+                if line !~ '\\$'
+                    " echo "lc-3"
+                    let delt_ind = -&sw
+                endif
+            else
+                " echo "lc-4"
+                if line =~ '^\(#\)\@!.*\\$'
+                    " echo "lc-5"
+                    let delt_ind = &sw
+                endif
+            endif
+        endif
+    endif
+    return delt_ind
+endfunction
+
+function s:CloseBracePriorIter(lnu,pos)
+    " what is the ind for a line that has this close brace previous?
+    " this function often depends on the previous open brace
+    let ind = -1
+    call cursor(a:lnu, a:pos+1) 
+    " seek the mate
+    let matchopenlnum = searchpair('{', '', '}', 'bW', s:skip_expr)
+    " does it have a mate
+    if  matchopenlnum >= 0
+        let closeopenpos = s:GetCloseBrace(matchopenlnum)
+        if closeopenpos >= 0
+            " recurse
+            let ind = s:CloseBracePriorIter(matchopenlnum, closeopenpos)
+        else
+            let ind = indent(matchopenlnum)
+            " if matchopenlnum, is lc-bumped, then remove that bump
+            let pline = getline(matchopenlnum-1)
+            if pline =~ '\\$'
+                let ind = ind - &sw
+                let ind = ind - (ind % &sw)
+            endif
+        endif
+    endif
+    return ind
+endfunction
+
+function s:CloseBraceInd(lnu, pos)
+    let ind = -1
+    call cursor(a:lnu, a:pos+1) 
+    " seek the mate
+    let matchopenlnum = searchpair('{', '', '}', 'bW', s:skip_expr)
+    " does it have a mate
+    if  matchopenlnum >= 0
+        let matchopen = s:GetOpenBrace(matchopenlnum)
+        let matchopenline = getline(matchopenlnum)
+        let closeopenpos = s:GetCloseBrace(matchopenlnum)
+
+        if closeopenpos >= 0
+            " recurse
+            let ind = s:CloseBracePriorIter(matchopenlnum, closeopenpos)
+        else
+            let hasLeadingStuff = s:HasLeadingStuff(matchopenlnum, matchopen)
+            let hasTrailingStuff = s:HasTrailingStuff(a:lnu, a:pos)
+
+            if hasLeadingStuff && hasTrailingStuff
+                " seek to the first nonwhite and make a hanging indent
+                let ind = matchend(matchopenline, '{\s*', matchopen)
+            elseif hasTrailingStuff
+                " indent of openbrace PLUS shiftwidth
+                let ind = indent(matchopenlnum) + &sw
+            elseif hasLeadingStuff
+                " let ind = matchend(matchopenline, '{\s*', matchopen)
+                let ind = indent(matchopenlnum)
+            else
+                " indent of openbrace
+                let ind = indent(matchopenlnum)
+            endif
+
+            let pline = getline(matchopenlnum-1)
+            if pline =~ '\\$'
+                let ind = ind - &sw
+                let ind = ind - (ind % &sw)
+            endif
+        endif
+
+    endif
+    return ind
+endfunction
+
+function s:CloseBracePriorInd(lnu,pos)
+    " what is the ind for a line that has this close brace previous?
+    " this function often depends on the previous open brace
+    let ind = -1
+    call cursor(a:lnu, a:pos+1) 
+    " seek the mate
+    let matchopenlnum = searchpair('{', '', '}', 'bW', s:skip_expr)
+    " does it have a mate
+    if  matchopenlnum >= 0
+        let closeopenpos = s:GetCloseBrace(matchopenlnum)
+        if closeopenpos >= 0
+            " recurse
+            let ind = s:CloseBracePriorIter(matchopenlnum, closeopenpos)
+        else
+            let ind = indent(matchopenlnum)
+            " if matchopenlnum, is lc-bumped, then remove that bump
+            let pline = getline(matchopenlnum-1)
+            if pline =~ '\\$'
+                let ind = ind - &sw
+                let ind = ind - (ind % &sw)
+            endif
+        endif
+    endif
+    return ind
+endfunction
+
+function s:PrevLine(lnu)
+    " for my purposes, the previous line is
+    " the previous non-blank line that is NOT a comment (nor string?)
+    " 0 ==> top of file
+    let plnu = prevnonblank(a:lnu-1)
+    while plnu > 0 && s:IsComment(plnu)
+        let plnu = prevnonblank(plnu-1)
+    endwhile
+    return plnu
+endfunction
+
+function s:GetTclIndent(lnum0)
+
+    " cursor-restore-position 
+    let vcol = col('.')
+    let vlnu = a:lnum0
+
+    " ------------
+    " current line
+    " ------------
+
+    let line = getline(vlnu)
+    let ind1 = -1
+    let flag = 0
+
+
+    " a line may have an 'open' open brace and an 'open' close brace
+    let openbrace = s:GetOpenBrace(vlnu)
+    let closebrace = s:GetCloseBrace(vlnu)
+
+    " does the line have an 'open' closebrace?
+    if closebrace >= 0
+        " echo "cur-0"
+        let ind = s:CloseBraceInd(vlnu, closebrace)
+        let flag = 1
+    endif
+
+    if flag == 1
+        call cursor(vlnu, vcol)
+        return ind
+    endif
+
+    " ---------
+    " prev line
+    " ---------
+
+    let flag = 0
+    " let prevlnum = prevnonblank(vlnu - 1)
+    let prevlnum = s:PrevLine(vlnu)
+    let line = getline(prevlnum)
+    let ind2 = indent(prevlnum)
+
+    " at the start? => indent = 0
+    if prevlnum == 0
+        return 0
+    endif
+
+    " is the current line a comment? => simple use the prevline
+    if s:IsComment(vlnu)
+        let prevlnum = prevnonblank(vlnu-1)
+        let ind2 = indent(prevlnum)
+        return ind2
+    endif
+
+
+    if line =~ '}'
+        " echo "prev-cb-0"
+        " upto this point, the indent is simply inherited from prevlnum
+        let closebrace = s:GetCloseBrace(prevlnum)
+        if closebrace >= 0
+            " echo "prev-cb-1"
+            let ind2 = s:CloseBracePriorInd(prevlnum, closebrace)
+            let flag = 1
+        endif
+    endif
+
+
+    " if there is an open brace
+    if line =~ '{'
+        " echo "prev-ob-0"
+        let openbrace = s:GetOpenBrace(prevlnum)
+        if openbrace >= 0 
+            " echo "prev-ob-1"
+            " does the line end in a comment? or nothing?
+            if s:HasLeadingStuff(prevlnum, openbrace)
+                " echo "prev-ob-2"
+                " LineContinueIndent
+                let delt_ind = s:LineContinueIndent(prevlnum)
+                let ind2 = matchend(line, '{\s*', openbrace) + delt_ind
+            else
+                " echo "prev-ob-4"
+                let ind2 = ind2 + &sw
+            endif
+            let flag = 1
+        endif
+    endif
+
+    if flag == 0
+        " echo "prev-lc-0"
+        " if nothing else has changed the indentation, check for a
+        let delt_ind = s:LineContinueIndent(prevlnum)
+        let ind2 = ind2 + delt_ind
+        " echo "prev-lc- " ind2 delt_ind
+    endif
+
+    " restore the cursor to its original position
+    call cursor(vlnu, vcol)
+    return ind2
+endfunction
+
+function GetTclIndent()
+    let l:val = s:GetTclIndent(v:lnum)
+    return l:val
+endfunction
+
+function Gpeek()
+    let lnu = line('.')
+    let val = s:GetTclIndent(lnu)
+    let openbrace = s:GetOpenBrace(lnu)
+    let closebrace = s:GetCloseBrace(lnu)
+    let iscomment = s:IsComment(lnu)
+    let prevlnum = s:PrevLine(lnu)
+    echo "ind>" val ": (" openbrace closebrace ") : " prevlnum
+endfunction
diff --git a/vim/plugin/NERD_commenter.vim b/vim/plugin/NERD_commenter.vim
new file mode 100644 (file)
index 0000000..18a348f
--- /dev/null
@@ -0,0 +1,3132 @@
+" ============================================================================
+" File:        NERD_commenter.vim
+" Description: vim global plugin that provides easy code commenting
+" Maintainer:  Martin Grenfell <martin_grenfell at msn dot com>
+" Version:     2.2.2
+" Last Change: 30th March, 2008
+" License:     This program is free software. It comes without any warranty,
+"              to the extent permitted by applicable law. You can redistribute
+"              it and/or modify it under the terms of the Do What The Fuck You
+"              Want To Public License, Version 2, as published by Sam Hocevar.
+"              See http://sam.zoy.org/wtfpl/COPYING for more details.
+"
+" ============================================================================
+
+" Section: script init stuff {{{1
+if exists("loaded_nerd_comments")
+    finish
+endif
+if v:version < 700
+    echoerr "NERDCommenter: this plugin requires vim >= 7. DOWNLOAD IT! You'll thank me later!"
+    finish
+endif
+let loaded_nerd_comments = 1
+
+" Function: s:InitVariable() function {{{2
+" This function is used to initialise a given variable to a given value. The
+" variable is only initialised if it does not exist prior
+"
+" Args:
+"   -var: the name of the var to be initialised
+"   -value: the value to initialise var to
+"
+" Returns:
+"   1 if the var is set, 0 otherwise
+function s:InitVariable(var, value)
+    if !exists(a:var)
+        exec 'let ' . a:var . ' = ' . "'" . a:value . "'"
+        return 1
+    endif
+    return 0
+endfunction
+
+" Section: space string init{{{2
+" When putting spaces after the left delim and before the right we use
+" s:spaceStr for the space char. This way we can make it add anything after
+" the left and before the right by modifying this variable
+let s:spaceStr = ' '
+let s:lenSpaceStr = strlen(s:spaceStr)
+
+" Section: variable init calls {{{2
+call s:InitVariable("g:NERDAllowAnyVisualDelims", 1)
+call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0)
+call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0)
+call s:InitVariable("g:NERDCompactSexyComs", 0)
+call s:InitVariable("g:NERDCreateDefaultMappings", 1)
+call s:InitVariable("g:NERDDefaultNesting", 1)
+call s:InitVariable("g:NERDMenuMode", 3)
+call s:InitVariable("g:NERDLPlace", "[>")
+call s:InitVariable("g:NERDUsePlaceHolders", 1)
+call s:InitVariable("g:NERDRemoveAltComs", 1)
+call s:InitVariable("g:NERDRemoveExtraSpaces", 1)
+call s:InitVariable("g:NERDRPlace", "<]")
+call s:InitVariable("g:NERDSpaceDelims", 0)
+call s:InitVariable("g:NERDDelimiterRequests", 1)
+
+
+
+let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\"
+
+" Section: Comment mapping functions, autocommands and commands {{{1
+" ============================================================================
+" Section: Comment enabler autocommands {{{2
+" ============================================================================
+
+augroup commentEnablers
+
+    "if the user enters a buffer or reads a buffer then we gotta set up
+    "the comment delimiters for that new filetype
+    autocmd BufEnter,BufRead * :call s:SetUpForNewFiletype(&filetype, 0)
+
+    "if the filetype of a buffer changes, force the script to reset the
+    "delims for the buffer
+    autocmd Filetype * :call s:SetUpForNewFiletype(&filetype, 1)
+augroup END
+
+
+" Function: s:SetUpForNewFiletype(filetype) function {{{2
+" This function is responsible for setting up buffer scoped variables for the
+" given filetype.
+"
+" These variables include the comment delimiters for the given filetype and calls
+" MapDelimiters or MapDelimitersWithAlternative passing in these delimiters.
+"
+" Args:
+"   -filetype: the filetype to set delimiters for
+"   -forceReset: 1 if the delimiters should be reset if they have already be
+"    set for this buffer.
+"
+function s:SetUpForNewFiletype(filetype, forceReset)
+    "if we have already set the delimiters for this buffer then dont go thru
+    "it again
+    if !a:forceReset && exists("b:NERDLeft") && b:NERDLeft != ''
+        return
+    endif
+
+    let b:NERDSexyComMarker = ''
+
+    "check the filetype against all known filetypes to see if we have
+    "hardcoded the comment delimiters to use
+    if a:filetype ==? ""
+        call s:MapDelimiters('', '')
+    elseif a:filetype ==? "aap"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "abc"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "acedb"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "actionscript"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "ada"
+        call s:MapDelimitersWithAlternative('--','', '--  ', '')
+    elseif a:filetype ==? "ahdl"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "ahk"
+        call s:MapDelimitersWithAlternative(';', '', '/*', '*/')
+    elseif a:filetype ==? "amiga"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "aml"
+        call s:MapDelimiters('/*', '')
+    elseif a:filetype ==? "ampl"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "apache"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "apachestyle"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "asciidoc"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "applescript"
+        call s:MapDelimitersWithAlternative('--', '', '(*', '*)')
+    elseif a:filetype ==? "asm68k"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "asm"
+        call s:MapDelimitersWithAlternative(';', '', '#', '')
+    elseif a:filetype ==? "asn"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "aspvbs"
+        call s:MapDelimiters('''', '')
+    elseif a:filetype ==? "asterisk"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "asy"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "atlas"
+        call s:MapDelimiters('C','$')
+    elseif a:filetype ==? "autohotkey"
+        call s:MapDelimiters(';','')
+    elseif a:filetype ==? "autoit"
+        call s:MapDelimiters(';','')
+    elseif a:filetype ==? "ave"
+        call s:MapDelimiters("'",'')
+    elseif a:filetype ==? "awk"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "basic"
+        call s:MapDelimitersWithAlternative("'",'', 'REM ', '')
+    elseif a:filetype ==? "bbx"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "bc"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "bib"
+        call s:MapDelimiters('%','')
+    elseif a:filetype ==? "bindzone"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "bst"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "btm"
+        call s:MapDelimiters('::', '')
+    elseif a:filetype ==? "caos"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "calibre"
+        call s:MapDelimiters('//','')
+    elseif a:filetype ==? "catalog"
+        call s:MapDelimiters('--','--')
+    elseif a:filetype ==? "c"
+        call s:MapDelimitersWithAlternative('/*','*/', '//', '')
+    elseif a:filetype ==? "cfg"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "cg"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "ch"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "cl"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "clean"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "clipper"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "clojure"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "cmake"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "conkyrc"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "cpp"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "crontab"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "cs"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "csp"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "cterm"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "cucumber"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "cvs"
+        call s:MapDelimiters('CVS:','')
+    elseif a:filetype ==? "d"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "dcl"
+        call s:MapDelimiters('$!', '')
+    elseif a:filetype ==? "dakota"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "debcontrol"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "debsources"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "def"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "desktop"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "dhcpd"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "diff"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "django"
+        call s:MapDelimitersWithAlternative('<!--','-->', '{#', '#}')
+    elseif a:filetype ==? "docbk"
+        call s:MapDelimiters('<!--', '-->')
+    elseif a:filetype ==? "dns"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "dosbatch"
+        call s:MapDelimitersWithAlternative('REM ','', '::', '')
+    elseif a:filetype ==? "dosini"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "dot"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "dracula"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "dsl"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "dtml"
+        call s:MapDelimiters('<dtml-comment>','</dtml-comment>')
+    elseif a:filetype ==? "dylan"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? 'ebuild'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "ecd"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? 'eclass'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "eiffel"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "elf"
+        call s:MapDelimiters("'", '')
+    elseif a:filetype ==? "elmfilt"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "erlang"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "eruby"
+        call s:MapDelimitersWithAlternative('<%#', '%>', '<!--', '-->')
+    elseif a:filetype ==? "expect"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "exports"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "factor"
+        call s:MapDelimitersWithAlternative('! ', '', '!# ', '')
+    elseif a:filetype ==? "fgl"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "focexec"
+        call s:MapDelimiters('-*', '')
+    elseif a:filetype ==? "form"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "foxpro"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "fstab"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "fvwm"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "fx"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "gams"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "gdb"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "gdmo"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "geek"
+        call s:MapDelimiters('GEEK_COMMENT:', '')
+    elseif a:filetype ==? "genshi"
+        call s:MapDelimitersWithAlternative('<!--','-->', '{#', '#}')
+    elseif a:filetype ==? "gentoo-conf-d"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "gentoo-env-d"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "gentoo-init-d"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "gentoo-make-conf"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? 'gentoo-package-keywords'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? 'gentoo-package-mask'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? 'gentoo-package-use'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? 'gitcommit'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? 'gitconfig'
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? 'gitrebase'
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "gnuplot"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "groovy"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "gtkrc"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "haskell"
+        call s:MapDelimitersWithAlternative('{-','-}', '--', '')
+    elseif a:filetype ==? "hb"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "h"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "haml"
+        call s:MapDelimitersWithAlternative('-#', '', '/', '')
+    elseif a:filetype ==? "hercules"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "hog"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "hostsaccess"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "htmlcheetah"
+        call s:MapDelimiters('##','')
+    elseif a:filetype ==? "htmldjango"
+        call s:MapDelimitersWithAlternative('<!--','-->', '{#', '#}')
+    elseif a:filetype ==? "htmlos"
+        call s:MapDelimiters('#','/#')
+    elseif a:filetype ==? "ia64"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "icon"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "idlang"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "idl"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "inform"
+        call s:MapDelimiters('!', '')
+    elseif a:filetype ==? "inittab"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "ishd"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "iss"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "ist"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "java"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "javacc"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "javascript"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype == "javascript.jquery"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "jess"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "jgraph"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "jproperties"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "jsp"
+        call s:MapDelimiters('<%--', '--%>')
+    elseif a:filetype ==? "kix"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "kscript"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "lace"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "ldif"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "lilo"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "lilypond"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "liquid"
+        call s:MapDelimiters('{%', '%}')
+    elseif a:filetype ==? "lisp"
+        call s:MapDelimitersWithAlternative(';','', '#|', '|#')
+    elseif a:filetype ==? "llvm"
+        call s:MapDelimiters(';','')
+    elseif a:filetype ==? "lotos"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "lout"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "lprolog"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "lscript"
+        call s:MapDelimiters("'", '')
+    elseif a:filetype ==? "lss"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "lua"
+        call s:MapDelimitersWithAlternative('--','', '--[[', ']]')
+    elseif a:filetype ==? "lynx"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "lytex"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "mail"
+        call s:MapDelimiters('> ','')
+    elseif a:filetype ==? "mako"
+        call s:MapDelimiters('##', '')
+    elseif a:filetype ==? "man"
+        call s:MapDelimiters('."', '')
+    elseif a:filetype ==? "map"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "maple"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "markdown"
+        call s:MapDelimiters('<!--', '-->')
+    elseif a:filetype ==? "masm"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "mason"
+        call s:MapDelimiters('<% #', '%>')
+    elseif a:filetype ==? "master"
+        call s:MapDelimiters('$', '')
+    elseif a:filetype ==? "matlab"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "mel"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "mib"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "mkd"
+        call s:MapDelimiters('>', '')
+    elseif a:filetype ==? "mma"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "model"
+        call s:MapDelimiters('$','$')
+    elseif a:filetype =~ "moduala."
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "modula2"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "modula3"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "monk"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "mush"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "named"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "nasm"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "nastran"
+        call s:MapDelimiters('$', '')
+    elseif a:filetype ==? "natural"
+        call s:MapDelimiters('/*', '')
+    elseif a:filetype ==? "ncf"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "newlisp"
+        call s:MapDelimiters(';','')
+    elseif a:filetype ==? "nroff"
+        call s:MapDelimiters('\"', '')
+    elseif a:filetype ==? "nsis"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "ntp"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "objc"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "objcpp"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "objj"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "ocaml"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "occam"
+        call s:MapDelimiters('--','')
+    elseif a:filetype ==? "omlet"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "omnimark"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "openroad"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "opl"
+        call s:MapDelimiters("REM", "")
+    elseif a:filetype ==? "ora"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "ox"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "pascal"
+        call s:MapDelimitersWithAlternative('{','}', '(*', '*)')
+    elseif a:filetype ==? "patran"
+        call s:MapDelimitersWithAlternative('$','','/*', '*/')
+    elseif a:filetype ==? "pcap"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "pccts"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "pdf"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "pfmain"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "php"
+        call s:MapDelimitersWithAlternative('//','','/*', '*/')
+    elseif a:filetype ==? "pic"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "pike"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "pilrc"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "pine"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "plm"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "plsql"
+        call s:MapDelimitersWithAlternative('--', '', '/*', '*/')
+    elseif a:filetype ==? "po"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "postscr"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "pov"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "povini"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "ppd"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "ppwiz"
+        call s:MapDelimiters(';;', '')
+    elseif a:filetype ==? "processing"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "prolog"
+        call s:MapDelimitersWithAlternative('%','','/*','*/')
+    elseif a:filetype ==? "ps1"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "psf"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "ptcap"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "radiance"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "ratpoison"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "r"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "rc"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "rebol"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "registry"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "remind"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "resolv"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "rgb"
+        call s:MapDelimiters('!', '')
+    elseif a:filetype ==? "rib"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "robots"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "sa"
+        call s:MapDelimiters('--','')
+    elseif a:filetype ==? "samba"
+        call s:MapDelimitersWithAlternative(';','', '#', '')
+    elseif a:filetype ==? "sass"
+        call s:MapDelimitersWithAlternative('//','', '/*', '')
+    elseif a:filetype ==? "sather"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "scala"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "scilab"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "scsh"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "sed"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "sgmldecl"
+        call s:MapDelimiters('--','--')
+    elseif a:filetype ==? "sgmllnx"
+        call s:MapDelimiters('<!--','-->')
+    elseif a:filetype ==? "sicad"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "simula"
+        call s:MapDelimitersWithAlternative('%', '', '--', '')
+    elseif a:filetype ==? "sinda"
+        call s:MapDelimiters('$', '')
+    elseif a:filetype ==? "skill"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "slang"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "slice"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "slrnrc"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "sm"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "smarty"
+        call s:MapDelimiters('{*', '*}')
+    elseif a:filetype ==? "smil"
+        call s:MapDelimiters('<!','>')
+    elseif a:filetype ==? "smith"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "sml"
+        call s:MapDelimiters('(*','*)')
+    elseif a:filetype ==? "snnsnet"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "snnspat"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "snnsres"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "snobol4"
+        call s:MapDelimiters('*', '')
+    elseif a:filetype ==? "spec"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "specman"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "spectre"
+        call s:MapDelimitersWithAlternative('//', '', '*', '')
+    elseif a:filetype ==? "spice"
+        call s:MapDelimiters('$', '')
+    elseif a:filetype ==? "sql"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "sqlforms"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "sqlj"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "sqr"
+        call s:MapDelimiters('!', '')
+    elseif a:filetype ==? "squid"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "st"
+        call s:MapDelimiters('"','')
+    elseif a:filetype ==? "stp"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "systemverilog"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "tads"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "tags"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "tak"
+        call s:MapDelimiters('$', '')
+    elseif a:filetype ==? "tasm"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "tcl"
+        call s:MapDelimiters('#','')
+    elseif a:filetype ==? "texinfo"
+        call s:MapDelimiters("@c ", "")
+    elseif a:filetype ==? "texmf"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "tf"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "tidy"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "tli"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "trasys"
+        call s:MapDelimiters("$", "")
+    elseif a:filetype ==? "tsalt"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "tsscl"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "tssgm"
+        call s:MapDelimiters("comment = '","'")
+    elseif a:filetype ==? "txt2tags"
+        call s:MapDelimiters('%','')
+    elseif a:filetype ==? "uc"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "uil"
+        call s:MapDelimiters('!', '')
+    elseif a:filetype ==? "vb"
+        call s:MapDelimiters("'","")
+    elseif a:filetype ==? "velocity"
+        call s:MapDelimitersWithAlternative("##","", '#*', '*#')
+    elseif a:filetype ==? "vera"
+        call s:MapDelimitersWithAlternative('/*','*/','//','')
+    elseif a:filetype ==? "verilog"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "verilog_systemverilog"
+        call s:MapDelimitersWithAlternative('//','', '/*','*/')
+    elseif a:filetype ==? "vgrindefs"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "vhdl"
+        call s:MapDelimiters('--', '')
+    elseif a:filetype ==? "vimperator"
+        call s:MapDelimiters('"','')
+    elseif a:filetype ==? "virata"
+        call s:MapDelimiters('%', '')
+    elseif a:filetype ==? "vrml"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "vsejcl"
+        call s:MapDelimiters('/*', '')
+    elseif a:filetype ==? "webmacro"
+        call s:MapDelimiters('##', '')
+    elseif a:filetype ==? "wget"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "Wikipedia"
+        call s:MapDelimiters('<!--','-->')
+    elseif a:filetype ==? "winbatch"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "wml"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "wvdial"
+        call s:MapDelimiters(';', '')
+    elseif a:filetype ==? "xdefaults"
+        call s:MapDelimiters('!', '')
+    elseif a:filetype ==? "xkb"
+        call s:MapDelimiters('//', '')
+    elseif a:filetype ==? "xmath"
+        call s:MapDelimiters('#', '')
+    elseif a:filetype ==? "xpm2"
+        call s:MapDelimiters('!', '')
+    elseif a:filetype ==? "xquery"
+        call s:MapDelimiters('(:',':)')
+    elseif a:filetype ==? "z8a"
+        call s:MapDelimiters(';', '')
+
+    else
+
+        "extract the delims from &commentstring
+        let left= substitute(&commentstring, '\([^ \t]*\)\s*%s.*', '\1', '')
+        let right= substitute(&commentstring, '.*%s\s*\(.*\)', '\1', 'g')
+        call s:MapDelimiters(left,right)
+
+    endif
+endfunction
+
+" Function: s:MapDelimiters(left, right) function {{{2
+" This function is a wrapper for s:MapDelimiters(left, right, leftAlt, rightAlt, useAlt) and is called when there
+" is no alternative comment delimiters for the current filetype
+"
+" Args:
+"   -left: the left comment delimiter
+"   -right: the right comment delimiter
+function s:MapDelimiters(left, right)
+    call s:MapDelimitersWithAlternative(a:left, a:right, "", "")
+endfunction
+
+" Function: s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt) function {{{2
+" this function sets up the comment delimiter buffer variables
+"
+" Args:
+"   -left:  the string defining the comment start delimiter
+"   -right: the string defining the comment end delimiter
+"   -leftAlt:  the string for the alternative comment style defining the comment start delimiter
+"   -rightAlt: the string for the alternative comment style defining the comment end delimiter
+function s:MapDelimitersWithAlternative(left, right, leftAlt, rightAlt)
+    if !exists('g:NERD_' . &filetype . '_alt_style')
+        let b:NERDLeft = a:left
+        let b:NERDRight = a:right
+        let b:NERDLeftAlt = a:leftAlt
+        let b:NERDRightAlt = a:rightAlt
+    else
+        let b:NERDLeft = a:leftAlt
+        let b:NERDRight = a:rightAlt
+        let b:NERDLeftAlt = a:left
+        let b:NERDRightAlt = a:right
+    endif
+endfunction
+
+" Function: s:SwitchToAlternativeDelimiters(printMsgs) function {{{2
+" This function is used to swap the delimiters that are being used to the
+" alternative delimiters for that filetype. For example, if a c++ file is
+" being edited and // comments are being used, after this function is called
+" /**/ comments will be used.
+"
+" Args:
+"   -printMsgs: if this is 1 then a message is echoed to the user telling them
+"    if this function changed the delimiters or not
+function s:SwitchToAlternativeDelimiters(printMsgs)
+    "if both of the alternative delimiters are empty then there is no
+    "alternative comment style so bail out
+    if b:NERDLeftAlt == "" && b:NERDRightAlt == ""
+        if a:printMsgs
+            call s:NerdEcho("Cannot use alternative delimiters, none are specified", 0)
+        endif
+        return 0
+    endif
+
+    "save the current delimiters
+    let tempLeft = b:NERDLeft
+    let tempRight = b:NERDRight
+
+    "swap current delimiters for alternative
+    let b:NERDLeft = b:NERDLeftAlt
+    let b:NERDRight = b:NERDRightAlt
+
+    "set the previously current delimiters to be the new alternative ones
+    let b:NERDLeftAlt = tempLeft
+    let b:NERDRightAlt = tempRight
+
+    "tell the user what comment delimiters they are now using
+    if a:printMsgs
+        let leftNoEsc = b:NERDLeft
+        let rightNoEsc = b:NERDRight
+        call s:NerdEcho("Now using " . leftNoEsc . " " . rightNoEsc . " to delimit comments", 1)
+    endif
+
+    return 1
+endfunction
+
+" Section: Comment delimiter add/removal functions {{{1
+" ============================================================================
+" Function: s:AppendCommentToLine(){{{2
+" This function appends comment delimiters at the EOL and places the cursor in
+" position to start typing the comment
+function s:AppendCommentToLine()
+    let left = s:GetLeft(0,1,0)
+    let right = s:GetRight(0,1,0)
+
+    " get the len of the right delim
+    let lenRight = strlen(right)
+
+    let isLineEmpty = strlen(getline(".")) == 0
+    let insOrApp = (isLineEmpty==1 ? 'i' : 'A')
+
+    "stick the delimiters down at the end of the line. We have to format the
+    "comment with spaces as appropriate
+    execute ":normal! " . insOrApp . (isLineEmpty ? '' : ' ') . left . right . " "
+
+    " if there is a right delimiter then we gotta move the cursor left
+    " by the len of the right delimiter so we insert between the delimiters
+    if lenRight > 0
+        let leftMoveAmount = lenRight
+        execute ":normal! " . leftMoveAmount . "h"
+    endif
+    startinsert
+endfunction
+
+" Function: s:CommentBlock(top, bottom, lSide, rSide, forceNested ) {{{2
+" This function is used to comment out a region of code. This region is
+" specified as a bounding box by arguments to the function.
+"
+" Args:
+"   -top: the line number for the top line of code in the region
+"   -bottom: the line number for the bottom line of code in the region
+"   -lSide: the column number for the left most column in the region
+"   -rSide: the column number for the right most column in the region
+"   -forceNested: a flag indicating whether comments should be nested
+function s:CommentBlock(top, bottom, lSide, rSide, forceNested )
+    " we need to create local copies of these arguments so we can modify them
+    let top = a:top
+    let bottom = a:bottom
+    let lSide = a:lSide
+    let rSide = a:rSide
+
+    "if the top or bottom line starts with tabs we have to adjust the left and
+    "right boundaries so that they are set as though the tabs were spaces
+    let topline = getline(top)
+    let bottomline = getline(bottom)
+    if s:HasLeadingTabs(topline, bottomline)
+
+        "find out how many tabs are in the top line and adjust the left
+        "boundary accordingly
+        let numTabs = s:NumberOfLeadingTabs(topline)
+        if lSide < numTabs
+            let lSide = &ts * lSide
+        else
+            let lSide = (lSide - numTabs) + (&ts * numTabs)
+        endif
+
+        "find out how many tabs are in the bottom line and adjust the right
+        "boundary accordingly
+        let numTabs = s:NumberOfLeadingTabs(bottomline)
+        let rSide = (rSide - numTabs) + (&ts * numTabs)
+    endif
+
+    "we must check that bottom IS actually below top, if it is not then we
+    "swap top and bottom. Similarly for left and right.
+    if bottom < top
+        let temp = top
+        let top = bottom
+        let bottom = top
+    endif
+    if rSide < lSide
+        let temp = lSide
+        let lSide = rSide
+        let rSide = temp
+    endif
+
+    "if the current delimiters arent multipart then we will switch to the
+    "alternative delims (if THEY are) as the comment will be better and more
+    "accurate with multipart delims
+    let switchedDelims = 0
+    if !s:Multipart() && g:NERDAllowAnyVisualDelims && s:AltMultipart()
+        let switchedDelims = 1
+        call s:SwitchToAlternativeDelimiters(0)
+    endif
+
+    "start the commenting from the top and keep commenting till we reach the
+    "bottom
+    let currentLine=top
+    while currentLine <= bottom
+
+        "check if we are allowed to comment this line
+        if s:CanCommentLine(a:forceNested, currentLine)
+
+            "convert the leading tabs into spaces
+            let theLine = getline(currentLine)
+            let lineHasLeadTabs = s:HasLeadingTabs(theLine)
+            if lineHasLeadTabs
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+            endif
+
+            "dont comment lines that begin after the right boundary of the
+            "block unless the user has specified to do so
+            if theLine !~ '^ \{' . rSide . '\}' || !g:NERDBlockComIgnoreEmpty
+
+                "attempt to place the cursor in on the left of the boundary box,
+                "then check if we were successful, if not then we cant comment this
+                "line
+                call setline(currentLine, theLine)
+                if s:CanPlaceCursor(currentLine, lSide)
+
+                    let leftSpaced = s:GetLeft(0,1,0)
+                    let rightSpaced = s:GetRight(0,1,0)
+
+                    "stick the left delimiter down
+                    let theLine = strpart(theLine, 0, lSide-1) . leftSpaced . strpart(theLine, lSide-1)
+
+                    if s:Multipart()
+                        "stick the right delimiter down
+                        let theLine = strpart(theLine, 0, rSide+strlen(leftSpaced)) . rightSpaced . strpart(theLine, rSide+strlen(leftSpaced))
+
+                        let firstLeftDelim = s:FindDelimiterIndex(b:NERDLeft, theLine)
+                        let lastRightDelim = s:LastIndexOfDelim(b:NERDRight, theLine)
+
+                        if firstLeftDelim != -1 && lastRightDelim != -1
+                            let searchStr = strpart(theLine, 0, lastRightDelim)
+                            let searchStr = strpart(searchStr, firstLeftDelim+strlen(b:NERDLeft))
+
+                            "replace the outter most delims in searchStr with
+                            "place-holders
+                            let theLineWithPlaceHolders = s:ReplaceDelims(b:NERDLeft, b:NERDRight, g:NERDLPlace, g:NERDRPlace, searchStr)
+
+                            "add the right delimiter onto the line
+                            let theLine = strpart(theLine, 0, firstLeftDelim+strlen(b:NERDLeft)) . theLineWithPlaceHolders . strpart(theLine, lastRightDelim)
+                        endif
+                    endif
+                endif
+            endif
+
+            "restore tabs if needed
+            if lineHasLeadTabs
+                let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+            endif
+
+            call setline(currentLine, theLine)
+        endif
+
+        let currentLine = currentLine + 1
+    endwhile
+
+    "if we switched delims then we gotta go back to what they were before
+    if switchedDelims == 1
+        call s:SwitchToAlternativeDelimiters(0)
+    endif
+endfunction
+
+" Function: s:CommentLines(forceNested, alignLeft, alignRight, firstLine, lastLine) {{{2
+" This function comments a range of lines.
+"
+" Args:
+"   -forceNested: a flag indicating whether the called is requesting the comment
+"    to be nested if need be
+"   -align: should be "left" or "both" or "none"
+"   -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLines(forceNested, align, firstLine, lastLine)
+    " we need to get the left and right indexes of the leftmost char in the
+    " block of of lines and the right most char so that we can do alignment of
+    " the delimiters if the user has specified
+    let leftAlignIndx = s:LeftMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+    let rightAlignIndx = s:RightMostIndx(a:forceNested, 0, a:firstLine, a:lastLine)
+
+    " gotta add the length of the left delimiter onto the rightAlignIndx cos
+    " we'll be adding a left delim to the line
+    let rightAlignIndx = rightAlignIndx + strlen(s:GetLeft(0,1,0))
+
+    " now we actually comment the lines. Do it line by line
+    let currentLine = a:firstLine
+    while currentLine <= a:lastLine
+
+        " get the next line, check commentability and convert spaces to tabs
+        let theLine = getline(currentLine)
+        let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+        let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        if s:CanCommentLine(a:forceNested, currentLine)
+            "if the user has specified forceNesting then we check to see if we
+            "need to switch delimiters for place-holders
+            if a:forceNested && g:NERDUsePlaceHolders
+                let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+            endif
+
+            " find out if the line is commented using normal delims and/or
+            " alternate ones
+            let isCommented = s:IsCommented(b:NERDLeft, b:NERDRight, theLine) || s:IsCommented(b:NERDLeftAlt, b:NERDRightAlt, theLine)
+
+            " check if we can comment this line
+            if !isCommented || g:NERDUsePlaceHolders || s:Multipart()
+                if a:align == "left" || a:align == "both"
+                    let theLine = s:AddLeftDelimAligned(s:GetLeft(0,1,0), theLine, leftAlignIndx)
+                else
+                    let theLine = s:AddLeftDelim(s:GetLeft(0,1,0), theLine)
+                endif
+                if a:align == "both"
+                    let theLine = s:AddRightDelimAligned(s:GetRight(0,1,0), theLine, rightAlignIndx)
+                else
+                    let theLine = s:AddRightDelim(s:GetRight(0,1,0), theLine)
+                endif
+            endif
+        endif
+
+        " restore leading tabs if appropriate
+        if lineHasLeadingTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+
+        " we are done with this line
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+endfunction
+
+" Function: s:CommentLinesMinimal(firstLine, lastLine) {{{2
+" This function comments a range of lines in a minimal style. I
+"
+" Args:
+"   -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLinesMinimal(firstLine, lastLine)
+    "check that minimal comments can be done on this filetype
+    if !s:HasMultipartDelims()
+        throw 'NERDCommenter.Delimiters exception: Minimal comments can only be used for filetypes that have multipart delimiters'
+    endif
+
+    "if we need to use place holders for the comment, make sure they are
+    "enabled for this filetype
+    if !g:NERDUsePlaceHolders && s:DoesBlockHaveMultipartDelim(a:firstLine, a:lastLine)
+        throw 'NERDCommenter.Settings exception: Placeoholders are required but disabled.'
+    endif
+
+    "get the left and right delims to smack on
+    let left = s:GetSexyComLeft(g:NERDSpaceDelims,0)
+    let right = s:GetSexyComRight(g:NERDSpaceDelims,0)
+
+    "make sure all multipart delims on the lines are replaced with
+    "placeholders to prevent illegal syntax
+    let currentLine = a:firstLine
+    while(currentLine <= a:lastLine)
+        let theLine = getline(currentLine)
+        let theLine = s:ReplaceDelims(left, right, g:NERDLPlace, g:NERDRPlace, theLine)
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+    "add the delim to the top line
+    let theLine = getline(a:firstLine)
+    let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+    let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+    let theLine = s:AddLeftDelim(left, theLine)
+    if lineHasLeadingTabs
+        let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+    endif
+    call setline(a:firstLine, theLine)
+
+    "add the delim to the bottom line
+    let theLine = getline(a:lastLine)
+    let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+    let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+    let theLine = s:AddRightDelim(right, theLine)
+    if lineHasLeadingTabs
+        let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+    endif
+    call setline(a:lastLine, theLine)
+endfunction
+
+" Function: s:CommentLinesSexy(topline, bottomline) function {{{2
+" This function is used to comment lines in the 'Sexy' style. eg in c:
+" /*
+"  * This is a sexy comment
+"  */
+" Args:
+"   -topline: the line num of the top line in the sexy comment
+"   -bottomline: the line num of the bottom line in the sexy comment
+function s:CommentLinesSexy(topline, bottomline)
+    let left = s:GetSexyComLeft(0, 0)
+    let right = s:GetSexyComRight(0, 0)
+
+    "check if we can do a sexy comment with the available delimiters
+    if left == -1 || right == -1
+        throw 'NERDCommenter.Delimiters exception: cannot perform sexy comments with available delimiters.'
+    endif
+
+    "make sure the lines arent already commented sexually
+    if !s:CanSexyCommentLines(a:topline, a:bottomline)
+        throw 'NERDCommenter.Nesting exception: cannot nest sexy comments'
+    endif
+
+
+    let sexyComMarker = s:GetSexyComMarker(0,0)
+    let sexyComMarkerSpaced = s:GetSexyComMarker(1,0)
+
+
+    " we jam the comment as far to the right as possible
+    let leftAlignIndx = s:LeftMostIndx(1, 1, a:topline, a:bottomline)
+
+    "check if we should use the compact style i.e that the left/right
+    "delimiters should appear on the first and last lines of the code and not
+    "on separate lines above/below the first/last lines of code
+    if g:NERDCompactSexyComs
+        let spaceString = (g:NERDSpaceDelims ? s:spaceStr : '')
+
+        "comment the top line
+        let theLine = getline(a:topline)
+        let lineHasTabs = s:HasLeadingTabs(theLine)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        endif
+        let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+        let theLine = s:AddLeftDelimAligned(left . spaceString, theLine, leftAlignIndx)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+        call setline(a:topline, theLine)
+
+        "comment the bottom line
+        if a:bottomline != a:topline
+            let theLine = getline(a:bottomline)
+            let lineHasTabs = s:HasLeadingTabs(theLine)
+            if lineHasTabs
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+            endif
+            let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+        endif
+        let theLine = s:AddRightDelim(spaceString . right, theLine)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+        call setline(a:bottomline, theLine)
+    else
+
+        " add the left delimiter one line above the lines that are to be commented
+        call cursor(a:topline, 1)
+        execute 'normal! O'
+        call setline(a:topline, repeat(' ', leftAlignIndx) . left )
+
+        " add the right delimiter after bottom line (we have to add 1 cos we moved
+        " the lines down when we added the left delim
+        call cursor(a:bottomline+1, 1)
+        execute 'normal! o'
+        call setline(a:bottomline+2, repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . right )
+
+    endif
+
+    " go thru each line adding the sexyComMarker marker to the start of each
+    " line in the appropriate place to align them with the comment delims
+    let currentLine = a:topline+1
+    while currentLine <= a:bottomline + !g:NERDCompactSexyComs
+        " get the line and convert the tabs to spaces
+        let theLine = getline(currentLine)
+        let lineHasTabs = s:HasLeadingTabs(theLine)
+        if lineHasTabs
+            let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        endif
+
+        let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+
+        " add the sexyComMarker
+        let theLine = repeat(' ', leftAlignIndx) . repeat(' ', strlen(left)-strlen(sexyComMarker)) . sexyComMarkerSpaced . strpart(theLine, leftAlignIndx)
+
+        if lineHasTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+
+
+        " set the line and move onto the next one
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+endfunction
+
+" Function: s:CommentLinesToggle(forceNested, firstLine, lastLine) {{{2
+" Applies "toggle" commenting to the given range of lines
+"
+" Args:
+"   -forceNested: a flag indicating whether the called is requesting the comment
+"    to be nested if need be
+"   -firstLine/lastLine: the top and bottom lines to comment
+function s:CommentLinesToggle(forceNested, firstLine, lastLine)
+    let currentLine = a:firstLine
+    while currentLine <= a:lastLine
+
+        " get the next line, check commentability and convert spaces to tabs
+        let theLine = getline(currentLine)
+        let lineHasLeadingTabs = s:HasLeadingTabs(theLine)
+        let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+        if s:CanToggleCommentLine(a:forceNested, currentLine)
+
+            "if the user has specified forceNesting then we check to see if we
+            "need to switch delimiters for place-holders
+            if g:NERDUsePlaceHolders
+                let theLine = s:SwapOutterMultiPartDelimsForPlaceHolders(theLine)
+            endif
+
+            let theLine = s:AddLeftDelim(s:GetLeft(0, 1, 0), theLine)
+            let theLine = s:AddRightDelim(s:GetRight(0, 1, 0), theLine)
+        endif
+
+        " restore leading tabs if appropriate
+        if lineHasLeadingTabs
+            let theLine = s:ConvertLeadingSpacesToTabs(theLine)
+        endif
+
+        " we are done with this line
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+endfunction
+
+" Function: s:CommentRegion(topline, topCol, bottomLine, bottomCol) function {{{2
+" This function comments chunks of text selected in visual mode.
+" It will comment exactly the text that they have selected.
+" Args:
+"   -topLine: the line num of the top line in the sexy comment
+"   -topCol: top left col for this comment
+"   -bottomline: the line num of the bottom line in the sexy comment
+"   -bottomCol: the bottom right col for this comment
+"   -forceNested: whether the caller wants comments to be nested if the
+"    line(s) are already commented
+function s:CommentRegion(topLine, topCol, bottomLine, bottomCol, forceNested)
+
+    "switch delims (if we can) if the current set isnt multipart
+    let switchedDelims = 0
+    if !s:Multipart() && s:AltMultipart() && !g:NERDAllowAnyVisualDelims
+        let switchedDelims = 1
+        call s:SwitchToAlternativeDelimiters(0)
+    endif
+
+    "if there is only one line in the comment then just do it
+    if a:topLine == a:bottomLine
+        call s:CommentBlock(a:topLine, a:bottomLine, a:topCol, a:bottomCol, a:forceNested)
+
+    "there are multiple lines in the comment
+    else
+        "comment the top line
+        call s:CommentBlock(a:topLine, a:topLine, a:topCol, strlen(getline(a:topLine)), a:forceNested)
+
+        "comment out all the lines in the middle of the comment
+        let topOfRange = a:topLine+1
+        let bottomOfRange = a:bottomLine-1
+        if topOfRange <= bottomOfRange
+            call s:CommentLines(a:forceNested, "none", topOfRange, bottomOfRange)
+        endif
+
+        "comment the bottom line
+        let bottom = getline(a:bottomLine)
+        let numLeadingSpacesTabs = strlen(substitute(bottom, '^\([ \t]*\).*$', '\1', ''))
+        call s:CommentBlock(a:bottomLine, a:bottomLine, numLeadingSpacesTabs+1, a:bottomCol, a:forceNested)
+
+    endif
+
+    "stick the cursor back on the char it was on before the comment
+    call cursor(a:topLine, a:topCol + strlen(b:NERDLeft) + g:NERDSpaceDelims)
+
+    "if we switched delims then we gotta go back to what they were before
+    if switchedDelims == 1
+        call s:SwitchToAlternativeDelimiters(0)
+    endif
+
+endfunction
+
+" Function: s:InvertComment(firstLine, lastLine) function {{{2
+" Inverts the comments on the lines between and including the given line
+" numbers i.e all commented lines are uncommented and vice versa
+" Args:
+"   -firstLine: the top of the range of lines to be inverted
+"   -lastLine: the bottom of the range of lines to be inverted
+function s:InvertComment(firstLine, lastLine)
+
+    " go thru all lines in the given range
+    let currentLine = a:firstLine
+    while currentLine <= a:lastLine
+        let theLine = getline(currentLine)
+
+        let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine)
+
+        " if the line is commented normally, uncomment it
+        if s:IsCommentedFromStartOfLine(b:NERDLeft, theLine) || s:IsCommentedFromStartOfLine(b:NERDLeftAlt, theLine)
+            call s:UncommentLines(currentLine, currentLine)
+            let currentLine = currentLine + 1
+
+        " check if the line is commented sexually
+        elseif !empty(sexyComBounds)
+            let numLinesBeforeSexyComRemoved = s:NumLinesInBuf()
+            call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1])
+
+            "move to the line after last line of the sexy comment
+            let numLinesAfterSexyComRemoved = s:NumLinesInBuf()
+            let currentLine = bottomBound - (numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved) + 1
+
+        " the line isnt commented
+        else
+            call s:CommentLinesToggle(1, currentLine, currentLine)
+            let currentLine = currentLine + 1
+        endif
+
+    endwhile
+endfunction
+
+" Function: NERDComment(isVisual, type) function {{{2
+" This function is a Wrapper for the main commenting functions
+"
+" Args:
+"   -isVisual: a flag indicating whether the comment is requested in visual
+"    mode or not
+"   -type: the type of commenting requested. Can be 'sexy', 'invert',
+"    'minimal', 'toggle', 'alignLeft', 'alignBoth', 'norm',
+"    'nested', 'toEOL', 'append', 'insert', 'uncomment', 'yank'
+function! NERDComment(isVisual, type) range
+    " we want case sensitivity when commenting
+    let oldIgnoreCase = &ignorecase
+    set noignorecase
+
+    if a:isVisual
+        let firstLine = line("'<")
+        let lastLine = line("'>")
+        let firstCol = col("'<")
+        let lastCol = col("'>") - (&selection == 'exclusive' ? 1 : 0)
+    else
+        let firstLine = a:firstline
+        let lastLine = a:lastline
+    endif
+
+    let countWasGiven = (a:isVisual == 0 && firstLine != lastLine)
+
+    let forceNested = (a:type == 'nested' || g:NERDDefaultNesting)
+
+    if a:type == 'norm' || a:type == 'nested'
+        if a:isVisual && visualmode() == "\16"
+            call s:CommentBlock(firstLine, lastLine, firstCol, lastCol, forceNested)
+        elseif a:isVisual && visualmode() == "v" && (g:NERDCommentWholeLinesInVMode==0 || (g:NERDCommentWholeLinesInVMode==2 && s:HasMultipartDelims()))
+            call s:CommentRegion(firstLine, firstCol, lastLine, lastCol, forceNested)
+        else
+            call s:CommentLines(forceNested, "none", firstLine, lastLine)
+        endif
+
+    elseif a:type == 'alignLeft' || a:type == 'alignBoth'
+        let align = "none"
+        if a:type == "alignLeft"
+            let align = "left"
+        elseif a:type == "alignBoth"
+            let align = "both"
+        endif
+        call s:CommentLines(forceNested, align, firstLine, lastLine)
+
+    elseif a:type == 'invert'
+        call s:InvertComment(firstLine, lastLine)
+
+    elseif a:type == 'sexy'
+        try
+            call s:CommentLinesSexy(firstLine, lastLine)
+        catch /NERDCommenter.Delimiters/
+            call s:CommentLines(forceNested, "none", firstLine, lastLine)
+        catch /NERDCommenter.Nesting/
+            call s:NerdEcho("Sexy comment aborted. Nested sexy cannot be nested", 0)
+        endtry
+
+    elseif a:type == 'toggle'
+        let theLine = getline(firstLine)
+
+        if s:IsInSexyComment(firstLine) || s:IsCommentedFromStartOfLine(b:NERDLeft, theLine) || s:IsCommentedFromStartOfLine(b:NERDLeftAlt, theLine)
+            call s:UncommentLines(firstLine, lastLine)
+        else
+            call s:CommentLinesToggle(forceNested, firstLine, lastLine)
+        endif
+
+    elseif a:type == 'minimal'
+        try
+            call s:CommentLinesMinimal(firstLine, lastLine)
+        catch /NERDCommenter.Delimiters/
+            call s:NerdEcho("Minimal comments can only be used for filetypes that have multipart delimiters.", 0)
+        catch /NERDCommenter.Settings/
+            call s:NerdEcho("Place holders are required but disabled.", 0)
+        endtry
+
+    elseif a:type == 'toEOL'
+        call s:SaveScreenState()
+        call s:CommentBlock(firstLine, firstLine, col("."), col("$")-1, 1)
+        call s:RestoreScreenState()
+
+    elseif a:type == 'append'
+        call s:AppendCommentToLine()
+
+    elseif a:type == 'insert'
+        call s:PlaceDelimitersAndInsBetween()
+
+    elseif a:type == 'uncomment'
+        call s:UncommentLines(firstLine, lastLine)
+
+    elseif a:type == 'yank'
+        if a:isVisual
+            normal! gvy
+        elseif countWasGiven
+            execute firstLine .','. lastLine .'yank'
+        else
+            normal! yy
+        endif
+        execute firstLine .','. lastLine .'call NERDComment('. a:isVisual .', "norm")'
+    endif
+
+    let &ignorecase = oldIgnoreCase
+endfunction
+
+" Function: s:PlaceDelimitersAndInsBetween() function {{{2
+" This is function is called to place comment delimiters down and place the
+" cursor between them
+function s:PlaceDelimitersAndInsBetween()
+    " get the left and right delimiters without any escape chars in them
+    let left = s:GetLeft(0, 1, 0)
+    let right = s:GetRight(0, 1, 0)
+
+    let theLine = getline(".")
+    let lineHasLeadTabs = s:HasLeadingTabs(theLine) || (theLine =~ '^ *$' && !&expandtab)
+
+    "convert tabs to spaces and adjust the cursors column to take this into
+    "account
+    let untabbedCol = s:UntabbedCol(theLine, col("."))
+    call setline(line("."), s:ConvertLeadingTabsToSpaces(theLine))
+    call cursor(line("."), untabbedCol)
+
+    " get the len of the right delim
+    let lenRight = strlen(right)
+
+    let isDelimOnEOL = col(".") >= strlen(getline("."))
+
+    " if the cursor is in the first col then we gotta insert rather than
+    " append the comment delimiters here
+    let insOrApp = (col(".")==1 ? 'i' : 'a')
+
+    " place the delimiters down. We do it differently depending on whether
+    " there is a left AND right delimiter
+    if lenRight > 0
+        execute ":normal! " . insOrApp . left . right
+        execute ":normal! " . lenRight . "h"
+    else
+        execute ":normal! " . insOrApp . left
+
+        " if we are tacking the delim on the EOL then we gotta add a space
+        " after it cos when we go out of insert mode the cursor will move back
+        " one and the user wont be in position to type the comment.
+        if isDelimOnEOL
+            execute 'normal! a '
+        endif
+    endif
+    normal! l
+
+    "if needed convert spaces back to tabs and adjust the cursors col
+    "accordingly
+    if lineHasLeadTabs
+        let tabbedCol = s:TabbedCol(getline("."), col("."))
+        call setline(line("."), s:ConvertLeadingSpacesToTabs(getline(".")))
+        call cursor(line("."), tabbedCol)
+    endif
+
+    startinsert
+endfunction
+
+" Function: s:RemoveDelimiters(left, right, line) {{{2
+" this function is called to remove the first left comment delimiter and the
+" last right delimiter of the given line.
+"
+" The args left and right must be strings. If there is no right delimiter (as
+" is the case for e.g vim file comments) them the arg right should be ""
+"
+" Args:
+"   -left: the left comment delimiter
+"   -right: the right comment delimiter
+"   -line: the line to remove the delimiters from
+function s:RemoveDelimiters(left, right, line)
+
+    let l:left = a:left
+    let l:right = a:right
+    let lenLeft = strlen(left)
+    let lenRight = strlen(right)
+
+    let delimsSpaced = (g:NERDSpaceDelims || g:NERDRemoveExtraSpaces)
+
+    let line = a:line
+
+    "look for the left delimiter, if we find it, remove it.
+    let leftIndx = s:FindDelimiterIndex(a:left, line)
+    if leftIndx != -1
+        let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+lenLeft)
+
+        "if the user has specified that there is a space after the left delim
+        "then check for the space and remove it if it is there
+        if delimsSpaced && strpart(line, leftIndx, s:lenSpaceStr) == s:spaceStr
+            let line = strpart(line, 0, leftIndx) . strpart(line, leftIndx+s:lenSpaceStr)
+        endif
+    endif
+
+    "look for the right delimiter, if we find it, remove it
+    let rightIndx = s:FindDelimiterIndex(a:right, line)
+    if rightIndx != -1
+        let line = strpart(line, 0, rightIndx) . strpart(line, rightIndx+lenRight)
+
+        "if the user has specified that there is a space before the right delim
+        "then check for the space and remove it if it is there
+        if delimsSpaced && strpart(line, rightIndx-s:lenSpaceStr, s:lenSpaceStr) == s:spaceStr && s:Multipart()
+            let line = strpart(line, 0, rightIndx-s:lenSpaceStr) . strpart(line, rightIndx)
+        endif
+    endif
+
+    return line
+endfunction
+
+" Function: s:UncommentLines(topLine, bottomLine) {{{2
+" This function uncomments the given lines
+"
+" Args:
+" topLine: the top line of the visual selection to uncomment
+" bottomLine: the bottom line of the visual selection to uncomment
+function s:UncommentLines(topLine, bottomLine)
+    "make local copies of a:firstline and a:lastline and, if need be, swap
+    "them around if the top line is below the bottom
+    let l:firstline = a:topLine
+    let l:lastline = a:bottomLine
+    if firstline > lastline
+        let firstline = lastline
+        let lastline = a:topLine
+    endif
+
+    "go thru each line uncommenting each line removing sexy comments
+    let currentLine = firstline
+    while currentLine <= lastline
+
+        "check the current line to see if it is part of a sexy comment
+        let sexyComBounds = s:FindBoundingLinesOfSexyCom(currentLine)
+        if !empty(sexyComBounds)
+
+            "we need to store the num lines in the buf before the comment is
+            "removed so we know how many lines were removed when the sexy com
+            "was removed
+            let numLinesBeforeSexyComRemoved = s:NumLinesInBuf()
+
+            call s:UncommentLinesSexy(sexyComBounds[0], sexyComBounds[1])
+
+            "move to the line after last line of the sexy comment
+            let numLinesAfterSexyComRemoved = s:NumLinesInBuf()
+            let numLinesRemoved = numLinesBeforeSexyComRemoved - numLinesAfterSexyComRemoved
+            let currentLine = sexyComBounds[1] - numLinesRemoved + 1
+            let lastline = lastline - numLinesRemoved
+
+        "no sexy com was detected so uncomment the line as normal
+        else
+            call s:UncommentLinesNormal(currentLine, currentLine)
+            let currentLine = currentLine + 1
+        endif
+    endwhile
+
+endfunction
+
+" Function: s:UncommentLinesSexy(topline, bottomline) {{{2
+" This function removes all the comment characters associated with the sexy
+" comment spanning the given lines
+" Args:
+"   -topline/bottomline: the top/bottom lines of the sexy comment
+function s:UncommentLinesSexy(topline, bottomline)
+    let left = s:GetSexyComLeft(0,1)
+    let right = s:GetSexyComRight(0,1)
+
+
+    "check if it is even possible for sexy comments to exist with the
+    "available delimiters
+    if left == -1 || right == -1
+        throw 'NERDCommenter.Delimiters exception: cannot uncomment sexy comments with available delimiters.'
+    endif
+
+    let leftUnEsc = s:GetSexyComLeft(0,0)
+    let rightUnEsc = s:GetSexyComRight(0,0)
+
+    let sexyComMarker = s:GetSexyComMarker(0, 1)
+    let sexyComMarkerUnEsc = s:GetSexyComMarker(0, 0)
+
+    "the markerOffset is how far right we need to move the sexyComMarker to
+    "line it up with the end of the left delim
+    let markerOffset = strlen(leftUnEsc)-strlen(sexyComMarkerUnEsc)
+
+    " go thru the intermediate lines of the sexy comment and remove the
+    " sexy comment markers (eg the '*'s on the start of line in a c sexy
+    " comment)
+    let currentLine = a:topline+1
+    while currentLine < a:bottomline
+        let theLine = getline(currentLine)
+
+        " remove the sexy comment marker from the line. We also remove the
+        " space after it if there is one and if appropriate options are set
+        let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc)
+        if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr  && g:NERDSpaceDelims
+            let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr)
+        else
+            let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc))
+        endif
+
+        let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine)
+
+        let theLine = s:ConvertLeadingWhiteSpace(theLine)
+
+        " move onto the next line
+        call setline(currentLine, theLine)
+        let currentLine = currentLine + 1
+    endwhile
+
+    " gotta make a copy of a:bottomline cos we modify the position of the
+    " last line  it if we remove the topline
+    let bottomline = a:bottomline
+
+    " get the first line so we can remove the left delim from it
+    let theLine = getline(a:topline)
+
+    " if the first line contains only the left delim then just delete it
+    if theLine =~ '^[ \t]*' . left . '[ \t]*$' && !g:NERDCompactSexyComs
+        call cursor(a:topline, 1)
+        normal! dd
+        let bottomline = bottomline - 1
+
+    " topline contains more than just the left delim
+    else
+
+        " remove the delim. If there is a space after it
+        " then remove this too if appropriate
+        let delimIndx = stridx(theLine, leftUnEsc)
+        if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr && g:NERDSpaceDelims
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc)+s:lenSpaceStr)
+        else
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(leftUnEsc))
+        endif
+        let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine)
+        call setline(a:topline, theLine)
+    endif
+
+    " get the last line so we can remove the right delim
+    let theLine = getline(bottomline)
+
+    " if the bottomline contains only the right delim then just delete it
+    if theLine =~ '^[ \t]*' . right . '[ \t]*$'
+        call cursor(bottomline, 1)
+        normal! dd
+
+    " the last line contains more than the right delim
+    else
+        " remove the right delim. If there is a space after it and
+        " if the appropriate options are set then remove this too.
+        let delimIndx = s:LastIndexOfDelim(rightUnEsc, theLine)
+        if strpart(theLine, delimIndx+strlen(leftUnEsc), s:lenSpaceStr) == s:spaceStr  && g:NERDSpaceDelims
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc)+s:lenSpaceStr)
+        else
+            let theLine = strpart(theLine, 0, delimIndx) . strpart(theLine, delimIndx+strlen(rightUnEsc))
+        endif
+
+        " if the last line also starts with a sexy comment marker then we
+        " remove this as well
+        if theLine =~ '^[ \t]*' . sexyComMarker
+
+            " remove the sexyComMarker. If there is a space after it then
+            " remove that too
+            let sexyComMarkerIndx = stridx(theLine, sexyComMarkerUnEsc)
+            if strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc), s:lenSpaceStr) == s:spaceStr  && g:NERDSpaceDelims
+                let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc)+s:lenSpaceStr)
+            else
+                let theLine = strpart(theLine, 0, sexyComMarkerIndx - markerOffset ) . strpart(theLine, sexyComMarkerIndx+strlen(sexyComMarkerUnEsc))
+            endif
+        endif
+
+        let theLine = s:SwapOutterPlaceHoldersForMultiPartDelims(theLine)
+        call setline(bottomline, theLine)
+    endif
+endfunction
+
+" Function: s:UncommentLineNormal(line) {{{2
+" uncomments the given line and returns the result
+" Args:
+"   -line: the line to uncomment
+function s:UncommentLineNormal(line)
+    let line = a:line
+
+    "get the comment status on the line so we know how it is commented
+    let lineCommentStatus =  s:IsCommentedOuttermost(b:NERDLeft, b:NERDRight, b:NERDLeftAlt, b:NERDRightAlt, line)
+
+    "it is commented with b:NERDLeft and b:NERDRight so remove these delims
+    if lineCommentStatus == 1
+        let line = s:RemoveDelimiters(b:NERDLeft, b:NERDRight, line)
+
+    "it is commented with b:NERDLeftAlt and b:NERDRightAlt so remove these delims
+    elseif lineCommentStatus == 2 && g:NERDRemoveAltComs
+        let line = s:RemoveDelimiters(b:NERDLeftAlt, b:NERDRightAlt, line)
+
+    "it is not properly commented with any delims so we check if it has
+    "any random left or right delims on it and remove the outtermost ones
+    else
+        "get the positions of all delim types on the line
+        let indxLeft = s:FindDelimiterIndex(b:NERDLeft, line)
+        let indxLeftAlt = s:FindDelimiterIndex(b:NERDLeftAlt, line)
+        let indxRight = s:FindDelimiterIndex(b:NERDRight, line)
+        let indxRightAlt = s:FindDelimiterIndex(b:NERDRightAlt, line)
+
+        "remove the outter most left comment delim
+        if indxLeft != -1 && (indxLeft < indxLeftAlt || indxLeftAlt == -1)
+            let line = s:RemoveDelimiters(b:NERDLeft, '', line)
+        elseif indxLeftAlt != -1
+            let line = s:RemoveDelimiters(b:NERDLeftAlt, '', line)
+        endif
+
+        "remove the outter most right comment delim
+        if indxRight != -1 && (indxRight < indxRightAlt || indxRightAlt == -1)
+            let line = s:RemoveDelimiters('', b:NERDRight, line)
+        elseif indxRightAlt != -1
+            let line = s:RemoveDelimiters('', b:NERDRightAlt, line)
+        endif
+    endif
+
+
+    let indxLeft = s:FindDelimiterIndex(b:NERDLeft, line)
+    let indxLeftAlt = s:FindDelimiterIndex(b:NERDLeftAlt, line)
+    let indxLeftPlace = s:FindDelimiterIndex(g:NERDLPlace, line)
+
+    let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
+    let indxRightAlt = s:FindDelimiterIndex(b:NERDRightAlt, line)
+    let indxRightPlace = s:FindDelimiterIndex(g:NERDRPlace, line)
+
+    let right = b:NERDRight
+    let left = b:NERDLeft
+    if !s:Multipart()
+        let right = b:NERDRightAlt
+        let left = b:NERDLeftAlt
+    endif
+
+
+    "if there are place-holders on the line then we check to see if they are
+    "the outtermost delimiters on the line. If so then we replace them with
+    "real delimiters
+    if indxLeftPlace != -1
+        if (indxLeftPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+            let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
+        endif
+    elseif indxRightPlace != -1
+        if (indxRightPlace < indxLeft || indxLeft==-1) && (indxLeftPlace < indxLeftAlt || indxLeftAlt==-1)
+            let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, line)
+        endif
+
+    endif
+
+    let line = s:ConvertLeadingWhiteSpace(line)
+
+    return line
+endfunction
+
+" Function: s:UncommentLinesNormal(topline, bottomline) {{{2
+" This function is called to uncomment lines that arent a sexy comment
+" Args:
+"   -topline/bottomline: the top/bottom line numbers of the comment
+function s:UncommentLinesNormal(topline, bottomline)
+    let currentLine = a:topline
+    while currentLine <= a:bottomline
+        let line = getline(currentLine)
+        call setline(currentLine, s:UncommentLineNormal(line))
+        let currentLine = currentLine + 1
+    endwhile
+endfunction
+
+
+" Section: Other helper functions {{{1
+" ============================================================================
+
+" Function: s:AddLeftDelim(delim, theLine) {{{2
+" Args:
+function s:AddLeftDelim(delim, theLine)
+    return substitute(a:theLine, '^\([ \t]*\)', '\1' . a:delim, '')
+endfunction
+
+" Function: s:AddLeftDelimAligned(delim, theLine) {{{2
+" Args:
+function s:AddLeftDelimAligned(delim, theLine, alignIndx)
+
+    "if the line is not long enough then bung some extra spaces on the front
+    "so we can align the delim properly
+    let theLine = a:theLine
+    if strlen(theLine) < a:alignIndx
+        let theLine = repeat(' ', a:alignIndx - strlen(theLine))
+    endif
+
+    return strpart(theLine, 0, a:alignIndx) . a:delim . strpart(theLine, a:alignIndx)
+endfunction
+
+" Function: s:AddRightDelim(delim, theLine) {{{2
+" Args:
+function s:AddRightDelim(delim, theLine)
+    if a:delim == ''
+        return a:theLine
+    else
+        return substitute(a:theLine, '$', a:delim, '')
+    endif
+endfunction
+
+" Function: s:AddRightDelimAligned(delim, theLine, alignIndx) {{{2
+" Args:
+function s:AddRightDelimAligned(delim, theLine, alignIndx)
+    if a:delim == ""
+        return a:theLine
+    else
+
+        " when we align the right delim we are just adding spaces
+        " so we get a string containing the needed spaces (it
+        " could be empty)
+        let extraSpaces = ''
+        let extraSpaces = repeat(' ', a:alignIndx-strlen(a:theLine))
+
+        " add the right delim
+        return substitute(a:theLine, '$', extraSpaces . a:delim, '')
+    endif
+endfunction
+
+" Function: s:AltMultipart() {{{2
+" returns 1 if the alternative delims are multipart
+function s:AltMultipart()
+    return b:NERDRightAlt != ''
+endfunction
+
+" Function: s:CanCommentLine(forceNested, line) {{{2
+"This function is used to determine whether the given line can be commented.
+"It returns 1 if it can be and 0 otherwise
+"
+" Args:
+"   -forceNested: a flag indicating whether the caller wants comments to be nested
+"    if the current line is already commented
+"   -lineNum: the line num of the line to check for commentability
+function s:CanCommentLine(forceNested, lineNum)
+    let theLine = getline(a:lineNum)
+
+    " make sure we don't comment lines that are just spaces or tabs or empty.
+    if theLine =~ "^[ \t]*$"
+        return 0
+    endif
+
+    "if the line is part of a sexy comment then just flag it...
+    if s:IsInSexyComment(a:lineNum)
+        return 0
+    endif
+
+    let isCommented = s:IsCommentedNormOrSexy(a:lineNum)
+
+    "if the line isnt commented return true
+    if !isCommented
+        return 1
+    endif
+
+    "if the line is commented but nesting is allowed then return true
+    if a:forceNested && (!s:Multipart() || g:NERDUsePlaceHolders)
+        return 1
+    endif
+
+    return 0
+endfunction
+
+" Function: s:CanPlaceCursor(line, col) {{{2
+" returns 1 if the cursor can be placed exactly in the given position
+function s:CanPlaceCursor(line, col)
+    let c = col(".")
+    let l = line(".")
+    call cursor(a:line, a:col)
+    let success = (line(".") == a:line && col(".") == a:col)
+    call cursor(l,c)
+    return success
+endfunction
+
+" Function: s:CanSexyCommentLines(topline, bottomline) {{{2
+" Return: 1 if the given lines can be commented sexually, 0 otherwise
+function s:CanSexyCommentLines(topline, bottomline)
+    " see if the selected regions have any sexy comments
+    let currentLine = a:topline
+    while(currentLine <= a:bottomline)
+        if s:IsInSexyComment(currentLine)
+            return 0
+        endif
+        let currentLine = currentLine + 1
+    endwhile
+    return 1
+endfunction
+" Function: s:CanToggleCommentLine(forceNested, line) {{{2
+"This function is used to determine whether the given line can be toggle commented.
+"It returns 1 if it can be and 0 otherwise
+"
+" Args:
+"   -lineNum: the line num of the line to check for commentability
+function s:CanToggleCommentLine(forceNested, lineNum)
+    let theLine = getline(a:lineNum)
+    if (s:IsCommentedFromStartOfLine(b:NERDLeft, theLine) || s:IsCommentedFromStartOfLine(b:NERDLeftAlt, theLine)) && !a:forceNested
+        return 0
+    endif
+
+    " make sure we don't comment lines that are just spaces or tabs or empty.
+    if theLine =~ "^[ \t]*$"
+        return 0
+    endif
+
+    "if the line is part of a sexy comment then just flag it...
+    if s:IsInSexyComment(a:lineNum)
+        return 0
+    endif
+
+    return 1
+endfunction
+
+" Function: s:ConvertLeadingSpacesToTabs(line) {{{2
+" This function takes a line and converts all leading tabs on that line into
+" spaces
+"
+" Args:
+"   -line: the line whose leading tabs will be converted
+function s:ConvertLeadingSpacesToTabs(line)
+    let toReturn  = a:line
+    while toReturn =~ '^\t*' . s:TabSpace() . '\(.*\)$'
+        let toReturn = substitute(toReturn, '^\(\t*\)' . s:TabSpace() . '\(.*\)$'  ,  '\1\t\2' , "")
+    endwhile
+
+    return toReturn
+endfunction
+
+
+" Function: s:ConvertLeadingTabsToSpaces(line) {{{2
+" This function takes a line and converts all leading spaces on that line into
+" tabs
+"
+" Args:
+"   -line: the line whose leading spaces will be converted
+function s:ConvertLeadingTabsToSpaces(line)
+    let toReturn  = a:line
+    while toReturn =~ '^\( *\)\t'
+        let toReturn = substitute(toReturn, '^\( *\)\t',  '\1' . s:TabSpace() , "")
+    endwhile
+
+    return toReturn
+endfunction
+
+" Function: s:ConvertLeadingWhiteSpace(line) {{{2
+" Converts the leading white space to tabs/spaces depending on &ts
+"
+" Args:
+"   -line: the line to convert
+function s:ConvertLeadingWhiteSpace(line)
+    let toReturn = a:line
+    while toReturn =~ '^ *\t'
+        let toReturn = substitute(toReturn, '^ *\zs\t\ze', s:TabSpace(), "g")
+    endwhile
+
+    if !&expandtab
+        let toReturn = s:ConvertLeadingSpacesToTabs(toReturn)
+    endif
+
+    return toReturn
+endfunction
+
+
+" Function: s:CountNonESCedOccurances(str, searchstr, escChar) {{{2
+" This function counts the number of substrings contained in another string.
+" These substrings are only counted if they are not escaped with escChar
+" Args:
+"   -str: the string to look for searchstr in
+"   -searchstr: the substring to search for in str
+"   -escChar: the escape character which, when preceding an instance of
+"    searchstr, will cause it not to be counted
+function s:CountNonESCedOccurances(str, searchstr, escChar)
+    "get the index of the first occurrence of searchstr
+    let indx = stridx(a:str, a:searchstr)
+
+    "if there is an instance of searchstr in str process it
+    if indx != -1
+        "get the remainder of str after this instance of searchstr is removed
+        let lensearchstr = strlen(a:searchstr)
+        let strLeft = strpart(a:str, indx+lensearchstr)
+
+        "if this instance of searchstr is not escaped, add one to the count
+        "and recurse. If it is escaped, just recurse
+        if !s:IsEscaped(a:str, indx, a:escChar)
+            return 1 + s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar)
+        else
+            return s:CountNonESCedOccurances(strLeft, a:searchstr, a:escChar)
+        endif
+    endif
+endfunction
+" Function: s:DoesBlockHaveDelim(delim, top, bottom) {{{2
+" Returns 1 if the given block of lines has a delimiter (a:delim) in it
+" Args:
+"   -delim: the comment delimiter to check the block for
+"   -top: the top line number of the block
+"   -bottom: the bottom line number of the block
+function s:DoesBlockHaveDelim(delim, top, bottom)
+    let currentLine = a:top
+    while currentLine < a:bottom
+        let theline = getline(currentLine)
+        if s:FindDelimiterIndex(a:delim, theline) != -1
+            return 1
+        endif
+        let currentLine = currentLine + 1
+    endwhile
+    return 0
+endfunction
+
+" Function: s:DoesBlockHaveMultipartDelim(top, bottom) {{{2
+" Returns 1 if the given block has a >= 1 multipart delimiter in it
+" Args:
+"   -top: the top line number of the block
+"   -bottom: the bottom line number of the block
+function s:DoesBlockHaveMultipartDelim(top, bottom)
+    if s:HasMultipartDelims()
+        if s:Multipart()
+            return s:DoesBlockHaveDelim(b:NERDLeft, a:top, a:bottom) || s:DoesBlockHaveDelim(b:NERDRight, a:top, a:bottom)
+        else
+            return s:DoesBlockHaveDelim(b:NERDLeftAlt, a:top, a:bottom) || s:DoesBlockHaveDelim(b:NERDRightAlt, a:top, a:bottom)
+        endif
+    endif
+    return 0
+endfunction
+
+
+" Function: s:Esc(str) {{{2
+" Escapes all the tricky chars in the given string
+function s:Esc(str)
+    let charsToEsc = '*/\."&$+'
+    return escape(a:str, charsToEsc)
+endfunction
+
+" Function: s:FindDelimiterIndex(delimiter, line) {{{2
+" This function is used to get the string index of the input comment delimiter
+" on the input line. If no valid comment delimiter is found in the line then
+" -1 is returned
+" Args:
+"   -delimiter: the delimiter we are looking to find the index of
+"   -line: the line we are looking for delimiter on
+function s:FindDelimiterIndex(delimiter, line)
+
+    "make sure the delimiter isnt empty otherwise we go into an infinite loop.
+    if a:delimiter == ""
+        return -1
+    endif
+
+
+    let l:delimiter = a:delimiter
+    let lenDel = strlen(l:delimiter)
+
+    "get the index of the first occurrence of the delimiter
+    let delIndx = stridx(a:line, l:delimiter)
+
+    "keep looping thru the line till we either find a real comment delimiter
+    "or run off the EOL
+    while delIndx != -1
+
+        "if we are not off the EOL get the str before the possible delimiter
+        "in question and check if it really is a delimiter. If it is, return
+        "its position
+        if delIndx != -1
+            if s:IsDelimValid(l:delimiter, delIndx, a:line)
+                return delIndx
+            endif
+        endif
+
+        "we have not yet found a real comment delimiter so move past the
+        "current one we are lookin at
+        let restOfLine = strpart(a:line, delIndx + lenDel)
+        let distToNextDelim = stridx(restOfLine , l:delimiter)
+
+        "if distToNextDelim is -1 then there is no more potential delimiters
+        "on the line so set delIndx to -1. Otherwise, move along the line by
+        "distToNextDelim
+        if distToNextDelim == -1
+            let delIndx = -1
+        else
+            let delIndx = delIndx + lenDel + distToNextDelim
+        endif
+    endwhile
+
+    "there is no comment delimiter on this line
+    return -1
+endfunction
+
+" Function: s:FindBoundingLinesOfSexyCom(lineNum) {{{2
+" This function takes in a line number and tests whether this line number is
+" the top/bottom/middle line of a sexy comment. If it is then the top/bottom
+" lines of the sexy comment are returned
+" Args:
+"   -lineNum: the line number that is to be tested whether it is the
+"    top/bottom/middle line of a sexy com
+" Returns:
+"   A string that has the top/bottom lines of the sexy comment encoded in it.
+"   The format is 'topline,bottomline'. If a:lineNum turns out not to be the
+"   top/bottom/middle of a sexy comment then -1 is returned
+function s:FindBoundingLinesOfSexyCom(lineNum)
+
+    "find which delimiters to look for as the start/end delims of the comment
+    let left = ''
+    let right = ''
+    if s:Multipart()
+        let left = s:GetLeft(0,0,1)
+        let right = s:GetRight(0,0,1)
+    elseif s:AltMultipart()
+        let left = s:GetLeft(1,0,1)
+        let right = s:GetRight(1,0,1)
+    else
+        return []
+    endif
+
+    let sexyComMarker = s:GetSexyComMarker(0, 1)
+
+    "initialise the top/bottom line numbers of the sexy comment to -1
+    let top = -1
+    let bottom = -1
+
+    let currentLine = a:lineNum
+    while top == -1 || bottom == -1
+        let theLine = getline(currentLine)
+
+        "check if the current line is the top of the sexy comment
+        if currentLine <= a:lineNum && theLine =~ '^[ \t]*' . left && theLine !~ '.*' . right && currentLine < s:NumLinesInBuf()
+            let top = currentLine
+            let currentLine = a:lineNum
+
+        "check if the current line is the bottom of the sexy comment
+        elseif theLine =~ '^[ \t]*' . right && theLine !~ '.*' . left && currentLine > 1
+            let bottom = currentLine
+
+        "the right delimiter is on the same line as the last sexyComMarker
+        elseif theLine =~ '^[ \t]*' . sexyComMarker . '.*' . right
+            let bottom = currentLine
+
+        "we have not found the top or bottom line so we assume currentLine is an
+        "intermediate line and look to prove otherwise
+        else
+
+            "if the line doesnt start with a sexyComMarker then it is not a sexy
+            "comment
+            if theLine !~ '^[ \t]*' . sexyComMarker
+                return []
+            endif
+
+        endif
+
+        "if top is -1 then we havent found the top yet so keep looking up
+        if top == -1
+            let currentLine = currentLine - 1
+        "if we have found the top line then go down looking for the bottom
+        else
+            let currentLine = currentLine + 1
+        endif
+
+    endwhile
+
+    return [top, bottom]
+endfunction
+
+
+" Function: s:GetLeft(alt, space, esc) {{{2
+" returns the left/left-alternative delimiter
+" Args:
+"   -alt: specifies whether to get left or left-alternative delim
+"   -space: specifies whether the delim should be spaced or not
+"    (the space string will only be added if NERDSpaceDelims is set)
+"   -esc: specifies whether the tricky chars in the delim should be ESCed
+function s:GetLeft(alt, space, esc)
+    let delim = b:NERDLeft
+
+    if a:alt
+        if b:NERDLeftAlt == ''
+            return ''
+        else
+            let delim = b:NERDLeftAlt
+        endif
+    endif
+    if delim == ''
+        return ''
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let delim = delim . s:spaceStr
+    endif
+
+    if a:esc
+        let delim = s:Esc(delim)
+    endif
+
+    return delim
+endfunction
+
+" Function: s:GetRight(alt, space, esc) {{{2
+" returns the right/right-alternative delimiter
+" Args:
+"   -alt: specifies whether to get right or right-alternative delim
+"   -space: specifies whether the delim should be spaced or not
+"   (the space string will only be added if NERDSpaceDelims is set)
+"   -esc: specifies whether the tricky chars in the delim should be ESCed
+function s:GetRight(alt, space, esc)
+    let delim = b:NERDRight
+
+    if a:alt
+        if !s:AltMultipart()
+            return ''
+        else
+            let delim = b:NERDRightAlt
+        endif
+    endif
+    if delim == ''
+        return ''
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let delim = s:spaceStr . delim
+    endif
+
+    if a:esc
+        let delim = s:Esc(delim)
+    endif
+
+    return delim
+endfunction
+
+
+" Function: s:GetSexyComMarker() {{{2
+" Returns the sexy comment marker for the current filetype.
+"
+" C style sexy comments are assumed if possible. If not then the sexy comment
+" marker is the last char of the delimiter pair that has both left and right
+" delims and has the longest left delim
+"
+" Args:
+"   -space: specifies whether the marker is to have a space string after it
+"    (the space string will only be added if NERDSpaceDelims is set)
+"   -esc: specifies whether the tricky chars in the marker are to be ESCed
+function s:GetSexyComMarker(space, esc)
+    let sexyComMarker = b:NERDSexyComMarker
+
+    "if there is no hardcoded marker then we find one
+    if sexyComMarker == ''
+
+        "if the filetype has c style comments then use standard c sexy
+        "comments
+        if s:HasCStyleComments()
+            let sexyComMarker = '*'
+        else
+            "find a comment marker by getting the longest available left delim
+            "(that has a corresponding right delim) and taking the last char
+            let lenLeft = strlen(b:NERDLeft)
+            let lenLeftAlt = strlen(b:NERDLeftAlt)
+            let left = ''
+            let right = ''
+            if s:Multipart() && lenLeft >= lenLeftAlt
+                let left = b:NERDLeft
+            elseif s:AltMultipart()
+                let left = b:NERDLeftAlt
+            else
+                return -1
+            endif
+
+            "get the last char of left
+            let sexyComMarker = strpart(left, strlen(left)-1)
+        endif
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let sexyComMarker = sexyComMarker . s:spaceStr
+    endif
+
+    if a:esc
+        let sexyComMarker = s:Esc(sexyComMarker)
+    endif
+
+    return sexyComMarker
+endfunction
+
+" Function: s:GetSexyComLeft(space, esc) {{{2
+" Returns the left delimiter for sexy comments for this filetype or -1 if
+" there is none. C style sexy comments are used if possible
+" Args:
+"   -space: specifies if the delim has a space string on the end
+"   (the space string will only be added if NERDSpaceDelims is set)
+"   -esc: specifies whether the tricky chars in the string are ESCed
+function s:GetSexyComLeft(space, esc)
+    let lenLeft = strlen(b:NERDLeft)
+    let lenLeftAlt = strlen(b:NERDLeftAlt)
+    let left = ''
+
+    "assume c style sexy comments if possible
+    if s:HasCStyleComments()
+        let left = '/*'
+    else
+        "grab the longest left delim that has a right
+        if s:Multipart() && lenLeft >= lenLeftAlt
+            let left = b:NERDLeft
+        elseif s:AltMultipart()
+            let left = b:NERDLeftAlt
+        else
+            return -1
+        endif
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let left = left . s:spaceStr
+    endif
+
+    if a:esc
+        let left = s:Esc(left)
+    endif
+
+    return left
+endfunction
+
+" Function: s:GetSexyComRight(space, esc) {{{2
+" Returns the right delimiter for sexy comments for this filetype or -1 if
+" there is none. C style sexy comments are used if possible.
+" Args:
+"   -space: specifies if the delim has a space string on the start
+"   (the space string will only be added if NERDSpaceDelims
+"   is specified for the current filetype)
+"   -esc: specifies whether the tricky chars in the string are ESCed
+function s:GetSexyComRight(space, esc)
+    let lenLeft = strlen(b:NERDLeft)
+    let lenLeftAlt = strlen(b:NERDLeftAlt)
+    let right = ''
+
+    "assume c style sexy comments if possible
+    if s:HasCStyleComments()
+        let right = '*/'
+    else
+        "grab the right delim that pairs with the longest left delim
+        if s:Multipart() && lenLeft >= lenLeftAlt
+            let right = b:NERDRight
+        elseif s:AltMultipart()
+            let right = b:NERDRightAlt
+        else
+            return -1
+        endif
+    endif
+
+    if a:space && g:NERDSpaceDelims
+        let right = s:spaceStr . right
+    endif
+
+    if a:esc
+        let right = s:Esc(right)
+    endif
+
+    return right
+endfunction
+
+" Function: s:HasMultipartDelims() {{{2
+" Returns 1 iff the current filetype has at least one set of multipart delims
+function s:HasMultipartDelims()
+    return s:Multipart() || s:AltMultipart()
+endfunction
+
+" Function: s:HasLeadingTabs(...) {{{2
+" Returns 1 if any of the given strings have leading tabs
+function s:HasLeadingTabs(...)
+    for s in a:000
+        if s =~ '^\t.*'
+            return 1
+        end
+    endfor
+    return 0
+endfunction
+" Function: s:HasCStyleComments() {{{2
+" Returns 1 iff the current filetype has c style comment delimiters
+function s:HasCStyleComments()
+    return (b:NERDLeft == '/*' && b:NERDRight == '*/') || (b:NERDLeftAlt == '/*' && b:NERDRightAlt == '*/')
+endfunction
+
+" Function: s:IsCommentedNormOrSexy(lineNum) {{{2
+"This function is used to determine whether the given line is commented with
+"either set of delimiters or if it is part of a sexy comment
+"
+" Args:
+"   -lineNum: the line number of the line to check
+function s:IsCommentedNormOrSexy(lineNum)
+    let theLine = getline(a:lineNum)
+
+    "if the line is commented normally return 1
+    if s:IsCommented(b:NERDLeft, b:NERDRight, theLine) || s:IsCommented(b:NERDLeftAlt, b:NERDRightAlt, theLine)
+        return 1
+    endif
+
+    "if the line is part of a sexy comment return 1
+    if s:IsInSexyComment(a:lineNum)
+        return 1
+    endif
+    return 0
+endfunction
+
+" Function: s:IsCommented(left, right, line) {{{2
+"This function is used to determine whether the given line is commented with
+"the given delimiters
+"
+" Args:
+"   -line: the line that to check if commented
+"   -left/right: the left and right delimiters to check for
+function s:IsCommented(left, right, line)
+    "if the line isnt commented return true
+    if s:FindDelimiterIndex(a:left, a:line) != -1 && (s:FindDelimiterIndex(a:right, a:line) != -1 || !s:Multipart())
+        return 1
+    endif
+    return 0
+endfunction
+
+" Function: s:IsCommentedFromStartOfLine(left, line) {{{2
+"This function is used to determine whether the given line is commented with
+"the given delimiters at the start of the line i.e the left delimiter is the
+"first thing on the line (apart from spaces\tabs)
+"
+" Args:
+"   -line: the line that to check if commented
+"   -left: the left delimiter to check for
+function s:IsCommentedFromStartOfLine(left, line)
+    let theLine = s:ConvertLeadingTabsToSpaces(a:line)
+    let numSpaces = strlen(substitute(theLine, '^\( *\).*$', '\1', ''))
+    let delimIndx = s:FindDelimiterIndex(a:left, theLine)
+    return delimIndx == numSpaces
+endfunction
+
+" Function: s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line) {{{2
+" Finds the type of the outtermost delims on the line
+"
+" Args:
+"   -line: the line that to check if the outtermost comments on it are
+"    left/right
+"   -left/right: the left and right delimiters to check for
+"   -leftAlt/rightAlt: the left and right alternative delimiters to check for
+"
+" Returns:
+"   0 if the line is not commented with either set of delims
+"   1 if the line is commented with the left/right delim set
+"   2 if the line is commented with the leftAlt/rightAlt delim set
+function s:IsCommentedOuttermost(left, right, leftAlt, rightAlt, line)
+    "get the first positions of the left delims and the last positions of the
+    "right delims
+    let indxLeft = s:FindDelimiterIndex(a:left, a:line)
+    let indxLeftAlt = s:FindDelimiterIndex(a:leftAlt, a:line)
+    let indxRight = s:LastIndexOfDelim(a:right, a:line)
+    let indxRightAlt = s:LastIndexOfDelim(a:rightAlt, a:line)
+
+    "check if the line has a left delim before a leftAlt delim
+    if (indxLeft <= indxLeftAlt || indxLeftAlt == -1) && indxLeft != -1
+        "check if the line has a right delim after any rightAlt delim
+        if (indxRight > indxRightAlt && indxRight > indxLeft) || !s:Multipart()
+            return 1
+        endif
+
+        "check if the line has a leftAlt delim before a left delim
+    elseif (indxLeftAlt <= indxLeft || indxLeft == -1) && indxLeftAlt != -1
+        "check if the line has a rightAlt delim after any right delim
+        if (indxRightAlt > indxRight && indxRightAlt > indxLeftAlt) || !s:AltMultipart()
+            return 2
+        endif
+    else
+        return 0
+    endif
+
+    return 0
+
+endfunction
+
+
+" Function: s:IsDelimValid(delimiter, delIndx, line) {{{2
+" This function is responsible for determining whether a given instance of a
+" comment delimiter is a real delimiter or not. For example, in java the
+" // string is a comment delimiter but in the line:
+"               System.out.println("//");
+" it does not count as a comment delimiter. This function is responsible for
+" distinguishing between such cases. It does so by applying a set of
+" heuristics that are not fool proof but should work most of the time.
+"
+" Args:
+"   -delimiter: the delimiter we are validating
+"   -delIndx: the position of delimiter in line
+"   -line: the line that delimiter occurs in
+"
+" Returns:
+" 0 if the given delimiter is not a real delimiter (as far as we can tell) ,
+" 1 otherwise
+function s:IsDelimValid(delimiter, delIndx, line)
+    "get the delimiter without the escchars
+    let l:delimiter = a:delimiter
+
+    "get the strings before and after the delimiter
+    let preComStr = strpart(a:line, 0, a:delIndx)
+    let postComStr = strpart(a:line, a:delIndx+strlen(delimiter))
+
+    "to check if the delimiter is real, make sure it isnt preceded by
+    "an odd number of quotes and followed by the same (which would indicate
+    "that it is part of a string and therefore is not a comment)
+    if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, '"', "\\"))
+        return 0
+    endif
+    if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "'", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "'", "\\"))
+        return 0
+    endif
+    if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, "`", "\\")) && !s:IsNumEven(s:CountNonESCedOccurances(postComStr, "`", "\\"))
+        return 0
+    endif
+
+
+    "if the comment delimiter is escaped, assume it isnt a real delimiter
+    if s:IsEscaped(a:line, a:delIndx, "\\")
+        return 0
+    endif
+
+    "vim comments are so fuckin stupid!! Why the hell do they have comment
+    "delimiters that are used elsewhere in the syntax?!?! We need to check
+    "some conditions especially for vim
+    if &filetype == "vim"
+        if !s:IsNumEven(s:CountNonESCedOccurances(preComStr, '"', "\\"))
+            return 0
+        endif
+
+        "if the delimiter is on the very first char of the line or is the
+        "first non-tab/space char on the line then it is a valid comment delimiter
+        if a:delIndx == 0 || a:line =~ "^[ \t]\\{" . a:delIndx . "\\}\".*$"
+            return 1
+        endif
+
+        let numLeftParen =s:CountNonESCedOccurances(preComStr, "(", "\\")
+        let numRightParen =s:CountNonESCedOccurances(preComStr, ")", "\\")
+
+        "if the quote is inside brackets then assume it isnt a comment
+        if numLeftParen > numRightParen
+            return 0
+        endif
+
+        "if the line has an even num of unescaped "'s then we can assume that
+        "any given " is not a comment delimiter
+        if s:IsNumEven(s:CountNonESCedOccurances(a:line, "\"", "\\"))
+            return 0
+        endif
+    endif
+
+    return 1
+
+endfunction
+
+" Function: s:IsNumEven(num) {{{2
+" A small function the returns 1 if the input number is even and 0 otherwise
+" Args:
+"   -num: the number to check
+function s:IsNumEven(num)
+    return (a:num % 2) == 0
+endfunction
+
+" Function: s:IsEscaped(str, indx, escChar) {{{2
+" This function takes a string, an index into that string and an esc char and
+" returns 1 if the char at the index is escaped (i.e if it is preceded by an
+" odd number of esc chars)
+" Args:
+"   -str: the string to check
+"   -indx: the index into str that we want to check
+"   -escChar: the escape char the char at indx may be ESCed with
+function s:IsEscaped(str, indx, escChar)
+    "initialise numEscChars to 0 and look at the char before indx
+    let numEscChars = 0
+    let curIndx = a:indx-1
+
+    "keep going back thru str until we either reach the start of the str or
+    "run out of esc chars
+    while curIndx >= 0 && strpart(a:str, curIndx, 1) == a:escChar
+
+        "we have found another esc char so add one to the count and move left
+        "one char
+        let numEscChars  = numEscChars + 1
+        let curIndx = curIndx - 1
+
+    endwhile
+
+    "if there is an odd num of esc chars directly before the char at indx then
+    "the char at indx is escaped
+    return !s:IsNumEven(numEscChars)
+endfunction
+
+" Function: s:IsInSexyComment(line) {{{2
+" returns 1 if the given line number is part of a sexy comment
+function s:IsInSexyComment(line)
+    return !empty(s:FindBoundingLinesOfSexyCom(a:line))
+endfunction
+
+" Function: s:IsSexyComment(topline, bottomline) {{{2
+" This function takes in 2 line numbers and returns 1 if the lines between and
+" including the given line numbers are a sexy comment. It returns 0 otherwise.
+" Args:
+"   -topline: the line that the possible sexy comment starts on
+"   -bottomline: the line that the possible sexy comment stops on
+function s:IsSexyComment(topline, bottomline)
+
+    "get the delim set that would be used for a sexy comment
+    let left = ''
+    let right = ''
+    if s:Multipart()
+        let left = b:NERDLeft
+        let right = b:NERDRight
+    elseif s:AltMultipart()
+        let left = b:NERDLeftAlt
+        let right = b:NERDRightAlt
+    else
+        return 0
+    endif
+
+    "swap the top and bottom line numbers around if need be
+    let topline = a:topline
+    let bottomline = a:bottomline
+    if bottomline < topline
+        topline = bottomline
+        bottomline = a:topline
+    endif
+
+    "if there is < 2 lines in the comment it cannot be sexy
+    if (bottomline - topline) <= 0
+        return 0
+    endif
+
+    "if the top line doesnt begin with a left delim then the comment isnt sexy
+    if getline(a:topline) !~ '^[ \t]*' . left
+        return 0
+    endif
+
+    "if there is a right delim on the top line then this isnt a sexy comment
+    if s:FindDelimiterIndex(right, getline(a:topline)) != -1
+        return 0
+    endif
+
+    "if there is a left delim on the bottom line then this isnt a sexy comment
+    if s:FindDelimiterIndex(left, getline(a:bottomline)) != -1
+        return 0
+    endif
+
+    "if the bottom line doesnt begin with a right delim then the comment isnt
+    "sexy
+    if getline(a:bottomline) !~ '^.*' . right . '$'
+        return 0
+    endif
+
+    let sexyComMarker = s:GetSexyComMarker(0, 1)
+
+    "check each of the intermediate lines to make sure they start with a
+    "sexyComMarker
+    let currentLine = a:topline+1
+    while currentLine < a:bottomline
+        let theLine = getline(currentLine)
+
+        if theLine !~ '^[ \t]*' . sexyComMarker
+            return 0
+        endif
+
+        "if there is a right delim in an intermediate line then the block isnt
+        "a sexy comment
+        if s:FindDelimiterIndex(right, theLine) != -1
+            return 0
+        endif
+
+        let currentLine = currentLine + 1
+    endwhile
+
+    "we have not found anything to suggest that this isnt a sexy comment so
+    return 1
+
+endfunction
+
+" Function: s:LastIndexOfDelim(delim, str) {{{2
+" This function takes a string and a delimiter and returns the last index of
+" that delimiter in string
+" Args:
+"   -delim: the delimiter to look for
+"   -str: the string to look for delim in
+function s:LastIndexOfDelim(delim, str)
+    let delim = a:delim
+    let lenDelim = strlen(delim)
+
+    "set index to the first occurrence of delim. If there is no occurrence then
+    "bail
+    let indx = s:FindDelimiterIndex(delim, a:str)
+    if indx == -1
+        return -1
+    endif
+
+    "keep moving to the next instance of delim in str till there is none left
+    while 1
+
+        "search for the next delim after the previous one
+        let searchStr = strpart(a:str, indx+lenDelim)
+        let indx2 = s:FindDelimiterIndex(delim, searchStr)
+
+        "if we find a delim update indx to record the position of it, if we
+        "dont find another delim then indx is the last one so break out of
+        "this loop
+        if indx2 != -1
+            let indx = indx + indx2 + lenDelim
+        else
+            break
+        endif
+    endwhile
+
+    return indx
+
+endfunction
+
+" Function: s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2
+" This function takes in 2 line numbers and returns the index of the left most
+" char (that is not a space or a tab) on all of these lines.
+" Args:
+"   -countCommentedLines: 1 if lines that are commented are to be checked as
+"    well. 0 otherwise
+"   -countEmptyLines: 1 if empty lines are to be counted in the search
+"   -topline: the top line to be checked
+"   -bottomline: the bottom line to be checked
+function s:LeftMostIndx(countCommentedLines, countEmptyLines, topline, bottomline)
+
+    " declare the left most index as an extreme value
+    let leftMostIndx = 1000
+
+    " go thru the block line by line updating leftMostIndx
+    let currentLine = a:topline
+    while currentLine <= a:bottomline
+
+        " get the next line and if it is allowed to be commented, or is not
+        " commented, check it
+        let theLine = getline(currentLine)
+        if a:countEmptyLines || theLine !~ '^[ \t]*$'
+            if a:countCommentedLines || (!s:IsCommented(b:NERDLeft, b:NERDRight, theLine) && !s:IsCommented(b:NERDLeftAlt, b:NERDRightAlt, theLine))
+                " convert spaces to tabs and get the number of leading spaces for
+                " this line and update leftMostIndx if need be
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+                let leadSpaceOfLine = strlen( substitute(theLine, '\(^[ \t]*\).*$','\1','') )
+                if leadSpaceOfLine < leftMostIndx
+                    let leftMostIndx = leadSpaceOfLine
+                endif
+            endif
+        endif
+
+        " move on to the next line
+        let currentLine = currentLine + 1
+    endwhile
+
+    if leftMostIndx == 1000
+        return 0
+    else
+        return leftMostIndx
+    endif
+endfunction
+
+" Function: s:Multipart() {{{2
+" returns 1 if the current delims are multipart
+function s:Multipart()
+    return b:NERDRight != ''
+endfunction
+
+" Function: s:NerdEcho(msg, typeOfMsg) {{{2
+" Args:
+"   -msg: the message to echo
+"   -typeOfMsg: 0 = warning message
+"               1 = normal message
+function s:NerdEcho(msg, typeOfMsg)
+    if a:typeOfMsg == 0
+        echohl WarningMsg
+        echo 'NERDCommenter:' . a:msg
+        echohl None
+    elseif a:typeOfMsg == 1
+        echo 'NERDCommenter:' . a:msg
+    endif
+endfunction
+
+" Function: s:NumberOfLeadingTabs(s) {{{2
+" returns the number of leading tabs in the given string
+function s:NumberOfLeadingTabs(s)
+    return strlen(substitute(a:s, '^\(\t*\).*$', '\1', ""))
+endfunction
+
+" Function: s:NumLinesInBuf() {{{2
+" Returns the number of lines in the current buffer
+function s:NumLinesInBuf()
+    return line('$')
+endfunction
+
+" Function: s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str) {{{2
+" This function takes in a string, 2 delimiters in that string and 2 strings
+" to replace these delimiters with.
+"
+" Args:
+"   -toReplace1: the first delimiter to replace
+"   -toReplace2: the second delimiter to replace
+"   -replacor1: the string to replace toReplace1 with
+"   -replacor2: the string to replace toReplace2 with
+"   -str: the string that the delimiters to be replaced are in
+function s:ReplaceDelims(toReplace1, toReplace2, replacor1, replacor2, str)
+    let line = s:ReplaceLeftMostDelim(a:toReplace1, a:replacor1, a:str)
+    let line = s:ReplaceRightMostDelim(a:toReplace2, a:replacor2, line)
+    return line
+endfunction
+
+" Function: s:ReplaceLeftMostDelim(toReplace, replacor, str) {{{2
+" This function takes a string and a delimiter and replaces the left most
+" occurrence of this delimiter in the string with a given string
+"
+" Args:
+"   -toReplace: the delimiter in str that is to be replaced
+"   -replacor: the string to replace toReplace with
+"   -str: the string that contains toReplace
+function s:ReplaceLeftMostDelim(toReplace, replacor, str)
+    let toReplace = a:toReplace
+    let replacor = a:replacor
+    "get the left most occurrence of toReplace
+    let indxToReplace = s:FindDelimiterIndex(toReplace, a:str)
+
+    "if there IS an occurrence of toReplace in str then replace it and return
+    "the resulting string
+    if indxToReplace != -1
+        let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace))
+        return line
+    endif
+
+    return a:str
+endfunction
+
+" Function: s:ReplaceRightMostDelim(toReplace, replacor, str) {{{2
+" This function takes a string and a delimiter and replaces the right most
+" occurrence of this delimiter in the string with a given string
+"
+" Args:
+"   -toReplace: the delimiter in str that is to be replaced
+"   -replacor: the string to replace toReplace with
+"   -str: the string that contains toReplace
+"
+function s:ReplaceRightMostDelim(toReplace, replacor, str)
+    let toReplace = a:toReplace
+    let replacor = a:replacor
+    let lenToReplace = strlen(toReplace)
+
+    "get the index of the last delim in str
+    let indxToReplace = s:LastIndexOfDelim(toReplace, a:str)
+
+    "if there IS a delimiter in str, replace it and return the result
+    let line = a:str
+    if indxToReplace != -1
+        let line = strpart(a:str, 0, indxToReplace) . replacor . strpart(a:str, indxToReplace+strlen(toReplace))
+    endif
+    return line
+endfunction
+
+"FUNCTION: s:RestoreScreenState() {{{2
+"
+"Sets the screen state back to what it was when s:SaveScreenState was last
+"called.
+"
+function s:RestoreScreenState()
+    if !exists("t:NERDComOldTopLine") || !exists("t:NERDComOldPos")
+        throw 'NERDCommenter exception: cannot restore screen'
+    endif
+
+    call cursor(t:NERDComOldTopLine, 0)
+    normal! zt
+    call setpos(".", t:NERDComOldPos)
+endfunction
+
+" Function: s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline) {{{2
+" This function takes in 2 line numbers and returns the index of the right most
+" char on all of these lines.
+" Args:
+"   -countCommentedLines: 1 if lines that are commented are to be checked as
+"    well. 0 otherwise
+"   -countEmptyLines: 1 if empty lines are to be counted in the search
+"   -topline: the top line to be checked
+"   -bottomline: the bottom line to be checked
+function s:RightMostIndx(countCommentedLines, countEmptyLines, topline, bottomline)
+    let rightMostIndx = -1
+
+    " go thru the block line by line updating rightMostIndx
+    let currentLine = a:topline
+    while currentLine <= a:bottomline
+
+        " get the next line and see if it is commentable, otherwise it doesnt
+        " count
+        let theLine = getline(currentLine)
+        if a:countEmptyLines || theLine !~ '^[ \t]*$'
+
+            if a:countCommentedLines || (!s:IsCommented(b:NERDLeft, b:NERDRight, theLine) && !s:IsCommented(b:NERDLeftAlt, b:NERDRightAlt, theLine))
+
+                " update rightMostIndx if need be
+                let theLine = s:ConvertLeadingTabsToSpaces(theLine)
+                let lineLen = strlen(theLine)
+                if lineLen > rightMostIndx
+                    let rightMostIndx = lineLen
+                endif
+            endif
+        endif
+
+        " move on to the next line
+        let currentLine = currentLine + 1
+    endwhile
+
+    return rightMostIndx
+endfunction
+
+"FUNCTION: s:SaveScreenState() {{{2
+"Saves the current cursor position in the current buffer and the window
+"scroll position
+function s:SaveScreenState()
+    let t:NERDComOldPos = getpos(".")
+    let t:NERDComOldTopLine = line("w0")
+endfunction
+
+" Function: s:SwapOutterMultiPartDelimsForPlaceHolders(line) {{{2
+" This function takes a line and swaps the outter most multi-part delims for
+" place holders
+" Args:
+"   -line: the line to swap the delims in
+"
+function s:SwapOutterMultiPartDelimsForPlaceHolders(line)
+    " find out if the line is commented using normal delims and/or
+    " alternate ones
+    let isCommented = s:IsCommented(b:NERDLeft, b:NERDRight, a:line)
+    let isCommentedAlt = s:IsCommented(b:NERDLeftAlt, b:NERDRightAlt, a:line)
+
+    let line2 = a:line
+
+    "if the line is commented and there is a right delimiter, replace
+    "the delims with place-holders
+    if isCommented && s:Multipart()
+        let line2 = s:ReplaceDelims(b:NERDLeft, b:NERDRight, g:NERDLPlace, g:NERDRPlace, a:line)
+
+    "similarly if the line is commented with the alternative
+    "delimiters
+    elseif isCommentedAlt && s:AltMultipart()
+        let line2 = s:ReplaceDelims(b:NERDLeftAlt, b:NERDRightAlt, g:NERDLPlace, g:NERDRPlace, a:line)
+    endif
+
+    return line2
+endfunction
+
+" Function: s:SwapOutterPlaceHoldersForMultiPartDelims(line) {{{2
+" This function takes a line and swaps the outtermost place holders for
+" multi-part delims
+" Args:
+"   -line: the line to swap the delims in
+"
+function s:SwapOutterPlaceHoldersForMultiPartDelims(line)
+    let left = ''
+    let right = ''
+    if s:Multipart()
+        let left = b:NERDLeft
+        let right = b:NERDRight
+    elseif s:AltMultipart()
+        let left = b:NERDLeftAlt
+        let right = b:NERDRightAlt
+    endif
+
+    let line = s:ReplaceDelims(g:NERDLPlace, g:NERDRPlace, left, right, a:line)
+    return line
+endfunction
+" Function: s:TabbedCol(line, col) {{{2
+" Gets the col number for given line and existing col number. The new col
+" number is the col number when all leading spaces are converted to tabs
+" Args:
+"   -line:the line to get the rel col for
+"   -col: the abs col
+function s:TabbedCol(line, col)
+    let lineTruncated = strpart(a:line, 0, a:col)
+    let lineSpacesToTabs = substitute(lineTruncated, s:TabSpace(), '\t', 'g')
+    return strlen(lineSpacesToTabs)
+endfunction
+"FUNCTION: s:TabSpace() {{{2
+"returns a string of spaces equal in length to &tabstop
+function s:TabSpace()
+    let tabSpace = ""
+    let spacesPerTab = &tabstop
+    while spacesPerTab > 0
+        let tabSpace = tabSpace . " "
+        let spacesPerTab = spacesPerTab - 1
+    endwhile
+    return tabSpace
+endfunction
+
+" Function: s:UnEsc(str, escChar) {{{2
+" This function removes all the escape chars from a string
+" Args:
+"   -str: the string to remove esc chars from
+"   -escChar: the escape char to be removed
+function s:UnEsc(str, escChar)
+    return substitute(a:str, a:escChar, "", "g")
+endfunction
+
+" Function: s:UntabbedCol(line, col) {{{2
+" Takes a line and a col and returns the absolute column of col taking into
+" account that a tab is worth 3 or 4 (or whatever) spaces.
+" Args:
+"   -line:the line to get the abs col for
+"   -col: the col that doesnt take into account tabs
+function s:UntabbedCol(line, col)
+    let lineTruncated = strpart(a:line, 0, a:col)
+    let lineTabsToSpaces = substitute(lineTruncated, '\t', s:TabSpace(), 'g')
+    return strlen(lineTabsToSpaces)
+endfunction
+" Section: Comment mapping setup {{{1
+" ===========================================================================
+
+" switch to/from alternative delimiters
+nnoremap <plug>NERDCommenterAltDelims :call <SID>SwitchToAlternativeDelimiters(1)<cr>
+
+" comment out lines
+nnoremap <silent> <plug>NERDCommenterComment :call NERDComment(0, "norm")<cr>
+vnoremap <silent> <plug>NERDCommenterComment <ESC>:call NERDComment(1, "norm")<cr>
+
+" toggle comments
+nnoremap <silent> <plug>NERDCommenterToggle :call NERDComment(0, "toggle")<cr>
+vnoremap <silent> <plug>NERDCommenterToggle <ESC>:call NERDComment(1, "toggle")<cr>
+
+" minimal comments
+nnoremap <silent> <plug>NERDCommenterMinimal :call NERDComment(0, "minimal")<cr>
+vnoremap <silent> <plug>NERDCommenterMinimal <ESC>:call NERDComment(1, "minimal")<cr>
+
+" sexy comments
+nnoremap <silent> <plug>NERDCommenterSexy :call NERDComment(0, "sexy")<CR>
+vnoremap <silent> <plug>NERDCommenterSexy <ESC>:call NERDComment(1, "sexy")<CR>
+
+" invert comments
+nnoremap <silent> <plug>NERDCommenterInvert :call NERDComment(0, "invert")<CR>
+vnoremap <silent> <plug>NERDCommenterInvert <ESC>:call NERDComment(1, "invert")<CR>
+
+" yank then comment
+nmap <silent> <plug>NERDCommenterYank :call NERDComment(0, "yank")<CR>
+vmap <silent> <plug>NERDCommenterYank <ESC>:call NERDComment(1, "yank")<CR>
+
+" left aligned comments
+nnoremap <silent> <plug>NERDCommenterAlignLeft :call NERDComment(0, "alignLeft")<cr>
+vnoremap <silent> <plug>NERDCommenterAlignLeft <ESC>:call NERDComment(1, "alignLeft")<cr>
+
+" left and right aligned comments
+nnoremap <silent> <plug>NERDCommenterAlignBoth :call NERDComment(0, "alignBoth")<cr>
+vnoremap <silent> <plug>NERDCommenterAlignBoth <ESC>:call NERDComment(1, "alignBoth")<cr>
+
+" nested comments
+nnoremap <silent> <plug>NERDCommenterNest :call NERDComment(0, "nested")<cr>
+vnoremap <silent> <plug>NERDCommenterNest <ESC>:call NERDComment(1, "nested")<cr>
+
+" uncomment
+nnoremap <silent> <plug>NERDCommenterUncomment :call NERDComment(0, "uncomment")<cr>
+vnoremap <silent> <plug>NERDCommenterUncomment :call NERDComment(1, "uncomment")<cr>
+
+" comment till the end of the line
+nnoremap <silent> <plug>NERDCommenterToEOL :call NERDComment(0, "toEOL")<cr>
+
+" append comments
+nmap <silent> <plug>NERDCommenterAppend :call NERDComment(0, "append")<cr>
+
+" insert comments
+inoremap <silent> <plug>NERDCommenterInInsert <SPACE><BS><ESC>:call NERDComment(0, "insert")<CR>
+
+
+function! s:CreateMaps(target, combo)
+    if !hasmapto(a:target, 'n')
+        exec 'nmap ' . a:combo . ' ' . a:target
+    endif
+
+    if !hasmapto(a:target, 'v')
+        exec 'vmap ' . a:combo . ' ' . a:target
+    endif
+endfunction
+
+if g:NERDCreateDefaultMappings
+    call s:CreateMaps('<plug>NERDCommenterComment',    ',cc')
+    call s:CreateMaps('<plug>NERDCommenterToggle',     ',c<space>')
+    call s:CreateMaps('<plug>NERDCommenterMinimal',    ',cm')
+    call s:CreateMaps('<plug>NERDCommenterSexy',       ',cs')
+    call s:CreateMaps('<plug>NERDCommenterInvert',     ',ci')
+    call s:CreateMaps('<plug>NERDCommenterYank',       ',cy')
+    call s:CreateMaps('<plug>NERDCommenterAlignLeft',  ',cl')
+    call s:CreateMaps('<plug>NERDCommenterAlignBoth',  ',cb')
+    call s:CreateMaps('<plug>NERDCommenterNest',       ',cn')
+    call s:CreateMaps('<plug>NERDCommenterUncomment',  ',cu')
+    call s:CreateMaps('<plug>NERDCommenterToEOL',      ',c$')
+    call s:CreateMaps('<plug>NERDCommenterAppend',     ',cA')
+
+    if !hasmapto('<plug>NERDCommenterAltDelims', 'n')
+        nmap ,ca <plug>NERDCommenterAltDelims
+    endif
+endif
+
+
+
+" Section: Menu item setup {{{1
+" ===========================================================================
+"check if the user wants the menu to be displayed
+if g:NERDMenuMode != 0
+
+    let menuRoot = ""
+    if g:NERDMenuMode == 1
+        let menuRoot = 'comment'
+    elseif g:NERDMenuMode == 2
+        let menuRoot = '&comment'
+    elseif g:NERDMenuMode == 3
+        let menuRoot = '&Plugin.&comment'
+    endif
+
+    function! s:CreateMenuItems(target, desc, root)
+        exec 'nmenu <silent> ' . a:root . '.' . a:desc . ' ' . a:target
+        exec 'vmenu <silent> ' . a:root . '.' . a:desc . ' ' . a:target
+    endfunction
+    call s:CreateMenuItems("<plug>NERDCommenterComment",    'Comment', menuRoot)
+    call s:CreateMenuItems("<plug>NERDCommenterToggle",     'Toggle', menuRoot)
+    call s:CreateMenuItems('<plug>NERDCommenterMinimal',    'Minimal', menuRoot)
+    call s:CreateMenuItems('<plug>NERDCommenterNest',       'Nested', menuRoot)
+    exec 'nmenu <silent> '. menuRoot .'.To\ EOL <plug>NERDCommenterToEOL'
+    call s:CreateMenuItems('<plug>NERDCommenterInvert',     'Invert', menuRoot)
+    call s:CreateMenuItems('<plug>NERDCommenterSexy',       'Sexy', menuRoot)
+    call s:CreateMenuItems('<plug>NERDCommenterYank',       'Yank\ then\ comment', menuRoot)
+    exec 'nmenu <silent> '. menuRoot .'.Append <plug>NERDCommenterAppend'
+    exec 'menu <silent> '. menuRoot .'.-Sep-    :'
+    call s:CreateMenuItems('<plug>NERDCommenterAlignLeft',  'Left\ aligned', menuRoot)
+    call s:CreateMenuItems('<plug>NERDCommenterAlignBoth',  'Left\ and\ right\ aligned', menuRoot)
+    exec 'menu <silent> '. menuRoot .'.-Sep2-    :'
+    call s:CreateMenuItems('<plug>NERDCommenterUncomment',  'Uncomment', menuRoot)
+    exec 'nmenu <silent> '. menuRoot .'.Switch\ Delimiters <plug>NERDCommenterAltDelims'
+    exec 'imenu <silent> '. menuRoot .'.Insert\ Comment\ Here <plug>NERDCommenterInInsert'
+    exec 'menu <silent> '. menuRoot .'.-Sep3-    :'
+    exec 'menu <silent>'. menuRoot .'.Help :help NERDCommenterContents<CR>'
+endif
+" vim: set foldmethod=marker :
diff --git a/vim/plugin/debPlugin.vim b/vim/plugin/debPlugin.vim
new file mode 100644 (file)
index 0000000..4ae2f13
--- /dev/null
@@ -0,0 +1,18 @@
+" debPlugin.vim -- a Vim plugin for browsing debian packages
+" copyright (C) 2007, arno renevier <arenevier@fdn.fr>
+" Distributed under the GNU General Public License (version 2 or above)
+" Last Change: 2007 December 07
+"
+" This file only sets the autocommands. Functions are in autoload/deb.vim.
+"
+" Latest version of that file can be found at
+" http://www.fdn.fr/~arenevier/vim/plugin/debPlugin.vim
+" It should also be available at
+" http://www.vim.org/scripts/script.php?script_id=1970
+"
+if &cp || exists("g:loaded_debPlugin") || !has("unix") || v:version < 700
+    finish
+endif
+let g:loaded_debPlugin = 1
+
+autocmd BufReadCmd   *.deb             call deb#browse(expand("<amatch>"))
diff --git a/vim/plugin/matchit.vim b/vim/plugin/matchit.vim
new file mode 100644 (file)
index 0000000..e41cda9
--- /dev/null
@@ -0,0 +1,812 @@
+"  matchit.vim: (global plugin) Extended "%" matching
+"  Last Change: Fri Jan 25 10:00 AM 2008 EST
+"  Maintainer:  Benji Fisher PhD   <benji@member.AMS.org>
+"  Version:     1.13.2, for Vim 6.3+
+"  URL:                http://www.vim.org/script.php?script_id=39
+
+" Documentation:
+"  The documentation is in a separate file, matchit.txt .
+
+" Credits:
+"  Vim editor by Bram Moolenaar (Thanks, Bram!)
+"  Original script and design by Raul Segura Acevedo
+"  Support for comments by Douglas Potts
+"  Support for back references and other improvements by Benji Fisher
+"  Support for many languages by Johannes Zellner
+"  Suggestions for improvement, bug reports, and support for additional
+"  languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
+"  Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
+
+" Debugging:
+"  If you'd like to try the built-in debugging commands...
+"   :MatchDebug      to activate debugging for the current buffer
+"  This saves the values of several key script variables as buffer-local
+"  variables.  See the MatchDebug() function, below, for details.
+
+" TODO:  I should think about multi-line patterns for b:match_words.
+"   This would require an option:  how many lines to scan (default 1).
+"   This would be useful for Python, maybe also for *ML.
+" TODO:  Maybe I should add a menu so that people will actually use some of
+"   the features that I have implemented.
+" TODO:  Eliminate the MultiMatch function.  Add yet another argument to
+"   Match_wrapper() instead.
+" TODO:  Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
+" TODO:  Make backrefs safer by using '\V' (very no-magic).
+" TODO:  Add a level of indirection, so that custom % scripts can use my
+"   work but extend it.
+
+" allow user to prevent loading
+" and prevent duplicate loading
+if exists("loaded_matchit") || &cp
+  finish
+endif
+let loaded_matchit = 1
+let s:last_mps = ""
+let s:last_words = ":"
+
+let s:save_cpo = &cpo
+set cpo&vim
+
+nnoremap <silent> %  :<C-U>call <SID>Match_wrapper('',1,'n') <CR>
+nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR>
+vnoremap <silent> %  :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv``
+vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv``
+onoremap <silent> %  v:<C-U>call <SID>Match_wrapper('',1,'o') <CR>
+onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR>
+
+" Analogues of [{ and ]} using matching patterns:
+nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR>
+nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W",  "n") <CR>
+vmap [% <Esc>[%m'gv``
+vmap ]% <Esc>]%m'gv``
+" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv``
+" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W",  "v") <CR>m'gv``
+onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR>
+onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W",  "o") <CR>
+
+" text object:
+vmap a% <Esc>[%v]%
+
+" Auto-complete mappings:  (not yet "ready for prime time")
+" TODO Read :help write-plugin for the "right" way to let the user
+" specify a key binding.
+"   let g:match_auto = '<C-]>'
+"   let g:match_autoCR = '<C-CR>'
+" if exists("g:match_auto")
+"   execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
+" endif
+" if exists("g:match_autoCR")
+"   execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
+" endif
+" if exists("g:match_gthhoh")
+"   execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
+" endif " gthhoh = "Get the heck out of here!"
+
+let s:notslash = '\\\@<!\%(\\\\\)*'
+
+function! s:Match_wrapper(word, forward, mode) range
+  " In s:CleanUp(), :execute "set" restore_options .
+  let restore_options = (&ic ? " " : " no") . "ignorecase"
+  if exists("b:match_ignorecase")
+    let &ignorecase = b:match_ignorecase
+  endif
+  let restore_options = " ve=" . &ve . restore_options
+  set ve=
+  " If this function was called from Visual mode, make sure that the cursor
+  " is at the correct end of the Visual range:
+  if a:mode == "v"
+    execute "normal! gv\<Esc>"
+  endif
+  " In s:CleanUp(), we may need to check whether the cursor moved forward.
+  let startline = line(".")
+  let startcol = col(".")
+  " Use default behavior if called with a count.
+  if v:count
+    exe "normal! " . v:count . "%"
+    return s:CleanUp(restore_options, a:mode, startline, startcol)
+  end
+
+  " First step:  if not already done, set the script variables
+  "   s:do_BR  flag for whether there are backrefs
+  "   s:pat    parsed version of b:match_words
+  "   s:all    regexp based on s:pat and the default groups
+  "
+  if !exists("b:match_words") || b:match_words == ""
+    let match_words = ""
+    " Allow b:match_words = "GetVimMatchWords()" .
+  elseif b:match_words =~ ":"
+    let match_words = b:match_words
+  else
+    execute "let match_words =" b:match_words
+  endif
+" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion!
+  if (match_words != s:last_words) || (&mps != s:last_mps) ||
+    \ exists("b:match_debug")
+    let s:last_words = match_words
+    let s:last_mps = &mps
+    " The next several lines were here before
+    " BF started messing with this script.
+    " quote the special chars in 'matchpairs', replace [,:] with \| and then
+    " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif)
+    " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+',
+    "  \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>'
+    let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
+      \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>'
+    " s:all = pattern with all the keywords
+    let match_words = match_words . (strlen(match_words) ? "," : "") . default
+    if match_words !~ s:notslash . '\\\d'
+      let s:do_BR = 0
+      let s:pat = match_words
+    else
+      let s:do_BR = 1
+      let s:pat = s:ParseWords(match_words)
+    endif
+    let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
+    let s:all = '\%(' . s:all . '\)'
+    " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)'
+    if exists("b:match_debug")
+      let b:match_pat = s:pat
+    endif
+  endif
+
+  " Second step:  set the following local variables:
+  "     matchline = line on which the cursor started
+  "     curcol    = number of characters before match
+  "     prefix    = regexp for start of line to start of match
+  "     suffix    = regexp for end of match to end of line
+  " Require match to end on or after the cursor and prefer it to
+  " start on or before the cursor.
+  let matchline = getline(startline)
+  if a:word != ''
+    " word given
+    if a:word !~ s:all
+      echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
+      return s:CleanUp(restore_options, a:mode, startline, startcol)
+    endif
+    let matchline = a:word
+    let curcol = 0
+    let prefix = '^\%('
+    let suffix = '\)$'
+  " Now the case when "word" is not given
+  else " Find the match that ends on or after the cursor and set curcol.
+    let regexp = s:Wholematch(matchline, s:all, startcol-1)
+    let curcol = match(matchline, regexp)
+    " If there is no match, give up.
+    if curcol == -1
+      return s:CleanUp(restore_options, a:mode, startline, startcol)
+    endif
+    let endcol = matchend(matchline, regexp)
+    let suf = strlen(matchline) - endcol
+    let prefix = (curcol ? '^.*\%'  . (curcol + 1) . 'c\%(' : '^\%(')
+    let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$'  : '\)$')
+  endif
+  if exists("b:match_debug")
+    let b:match_match = matchstr(matchline, regexp)
+    let b:match_col = curcol+1
+  endif
+
+  " Third step:  Find the group and single word that match, and the original
+  " (backref) versions of these.  Then, resolve the backrefs.
+  " Set the following local variable:
+  " group = colon-separated list of patterns, one of which matches
+  "       = ini:mid:fin or ini:fin
+  "
+  " Reconstruct the version with unresolved backrefs.
+  let patBR = substitute(match_words.',',
+    \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
+  let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g')
+  " Now, set group and groupBR to the matching group: 'if:endif' or
+  " 'while:endwhile' or whatever.  A bit of a kluge:  s:Choose() returns
+  " group . "," . groupBR, and we pick it apart.
+  let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
+  let i = matchend(group, s:notslash . ",")
+  let groupBR = strpart(group, i)
+  let group = strpart(group, 0, i-1)
+  " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
+  if s:do_BR " Do the hard part:  resolve those backrefs!
+    let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
+  endif
+  if exists("b:match_debug")
+    let b:match_wholeBR = groupBR
+    let i = matchend(groupBR, s:notslash . ":")
+    let b:match_iniBR = strpart(groupBR, 0, i-1)
+  endif
+
+  " Fourth step:  Set the arguments for searchpair().
+  let i = matchend(group, s:notslash . ":")
+  let j = matchend(group, '.*' . s:notslash . ":")
+  let ini = strpart(group, 0, i-1)
+  let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
+  let fin = strpart(group, j)
+  "Un-escape the remaining , and : characters.
+  let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
+  let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
+  let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
+  " searchpair() requires that these patterns avoid \(\) groups.
+  let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
+  let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
+  let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
+  " Set mid.  This is optimized for readability, not micro-efficiency!
+  if a:forward && matchline =~ prefix . fin . suffix
+    \ || !a:forward && matchline =~ prefix . ini . suffix
+    let mid = ""
+  endif
+  " Set flag.  This is optimized for readability, not micro-efficiency!
+  if a:forward && matchline =~ prefix . fin . suffix
+    \ || !a:forward && matchline !~ prefix . ini . suffix
+    let flag = "bW"
+  else
+    let flag = "W"
+  endif
+  " Set skip.
+  if exists("b:match_skip")
+    let skip = b:match_skip
+  elseif exists("b:match_comment") " backwards compatibility and testing!
+    let skip = "r:" . b:match_comment
+  else
+    let skip = 's:comment\|string'
+  endif
+  let skip = s:ParseSkip(skip)
+  if exists("b:match_debug")
+    let b:match_ini = ini
+    let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
+  endif
+
+  " Fifth step:  actually start moving the cursor and call searchpair().
+  " Later, :execute restore_cursor to get to the original screen.
+  let restore_cursor = virtcol(".") . "|"
+  normal! g0
+  let restore_cursor = line(".") . "G" .  virtcol(".") . "|zs" . restore_cursor
+  normal! H
+  let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
+  execute restore_cursor
+  call cursor(0, curcol + 1)
+  " normal! 0
+  " if curcol
+  "   execute "normal!" . curcol . "l"
+  " endif
+  if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
+    let skip = "0"
+  else
+    execute "if " . skip . "| let skip = '0' | endif"
+  endif
+  let sp_return = searchpair(ini, mid, fin, flag, skip)
+  let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
+  " Restore cursor position and original screen.
+  execute restore_cursor
+  normal! m'
+  if sp_return > 0
+    execute final_position
+  endif
+  return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin)
+endfun
+
+" Restore options and do some special handling for Operator-pending mode.
+" The optional argument is the tail of the matching group.
+fun! s:CleanUp(options, mode, startline, startcol, ...)
+  execute "set" a:options
+  " Open folds, if appropriate.
+  if a:mode != "o"
+    if &foldopen =~ "percent"
+      normal! zv
+    endif
+    " In Operator-pending mode, we want to include the whole match
+    " (for example, d%).
+    " This is only a problem if we end up moving in the forward direction.
+  elseif (a:startline < line(".")) ||
+       \ (a:startline == line(".") && a:startcol < col("."))
+    if a:0
+      " Check whether the match is a single character.  If not, move to the
+      " end of the match.
+      let matchline = getline(".")
+      let currcol = col(".")
+      let regexp = s:Wholematch(matchline, a:1, currcol-1)
+      let endcol = matchend(matchline, regexp)
+      if endcol > currcol  " This is NOT off by one!
+       execute "normal!" . (endcol - currcol) . "l"
+      endif
+    endif " a:0
+  endif " a:mode != "o" && etc.
+  return 0
+endfun
+
+" Example (simplified HTML patterns):  if
+"   a:groupBR  = '<\(\k\+\)>:</\1>'
+"   a:prefix   = '^.\{3}\('
+"   a:group    = '<\(\k\+\)>:</\(\k\+\)>'
+"   a:suffix   = '\).\{2}$'
+"   a:matchline        =  "123<tag>12" or "123</tag>12"
+" then extract "tag" from a:matchline and return "<tag>:</tag>" .
+fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
+  if a:matchline !~ a:prefix .
+    \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
+    return a:group
+  endif
+  let i = matchend(a:groupBR, s:notslash . ':')
+  let ini = strpart(a:groupBR, 0, i-1)
+  let tailBR = strpart(a:groupBR, i)
+  let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
+    \ a:groupBR)
+  let i = matchend(word, s:notslash . ":")
+  let wordBR = strpart(word, i)
+  let word = strpart(word, 0, i-1)
+  " Now, a:matchline =~ a:prefix . word . a:suffix
+  if wordBR != ini
+    let table = s:Resolve(ini, wordBR, "table")
+  else
+    " let table = "----------"
+    let table = ""
+    let d = 0
+    while d < 10
+      if tailBR =~ s:notslash . '\\' . d
+       " let table[d] = d
+       let table = table . d
+      else
+       let table = table . "-"
+      endif
+      let d = d + 1
+    endwhile
+  endif
+  let d = 9
+  while d
+    if table[d] != "-"
+      let backref = substitute(a:matchline, a:prefix.word.a:suffix,
+       \ '\'.table[d], "")
+       " Are there any other characters that should be escaped?
+      let backref = escape(backref, '*,:')
+      execute s:Ref(ini, d, "start", "len")
+      let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
+      let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
+       \ escape(backref, '\\'), 'g')
+    endif
+    let d = d-1
+  endwhile
+  if exists("b:match_debug")
+    if s:do_BR
+      let b:match_table = table
+      let b:match_word = word
+    else
+      let b:match_table = ""
+      let b:match_word = ""
+    endif
+  endif
+  return ini . ":" . tailBR
+endfun
+
+" Input a comma-separated list of groups with backrefs, such as
+"   a:groups = '\(foo\):end\1,\(bar\):end\1'
+" and return a comma-separated list of groups with backrefs replaced:
+"   return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
+fun! s:ParseWords(groups)
+  let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
+  let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
+  let parsed = ""
+  while groups =~ '[^,:]'
+    let i = matchend(groups, s:notslash . ':')
+    let j = matchend(groups, s:notslash . ',')
+    let ini = strpart(groups, 0, i-1)
+    let tail = strpart(groups, i, j-i-1) . ":"
+    let groups = strpart(groups, j)
+    let parsed = parsed . ini
+    let i = matchend(tail, s:notslash . ':')
+    while i != -1
+      " In 'if:else:endif', ini='if' and word='else' and then word='endif'.
+      let word = strpart(tail, 0, i-1)
+      let tail = strpart(tail, i)
+      let i = matchend(tail, s:notslash . ':')
+      let parsed = parsed . ":" . s:Resolve(ini, word, "word")
+    endwhile " Now, tail has been used up.
+    let parsed = parsed . ","
+  endwhile " groups =~ '[^,:]'
+  let parsed = substitute(parsed, ',$', '', '')
+  return parsed
+endfun
+
+" TODO I think this can be simplified and/or made more efficient.
+" TODO What should I do if a:start is out of range?
+" Return a regexp that matches all of a:string, such that
+" matchstr(a:string, regexp) represents the match for a:pat that starts
+" as close to a:start as possible, before being preferred to after, and
+" ends after a:start .
+" Usage:
+" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
+" let i      = match(getline("."), regexp)
+" let j      = matchend(getline("."), regexp)
+" let match  = matchstr(getline("."), regexp)
+fun! s:Wholematch(string, pat, start)
+  let group = '\%(' . a:pat . '\)'
+  let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
+  let len = strlen(a:string)
+  let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
+  if a:string !~ prefix . group . suffix
+    let prefix = ''
+  endif
+  return prefix . group . suffix
+endfun
+
+" No extra arguments:  s:Ref(string, d) will
+" find the d'th occurrence of '\(' and return it, along with everything up
+" to and including the matching '\)'.
+" One argument:  s:Ref(string, d, "start") returns the index of the start
+" of the d'th '\(' and any other argument returns the length of the group.
+" Two arguments:  s:Ref(string, d, "foo", "bar") returns a string to be
+" executed, having the effect of
+"   :let foo = s:Ref(string, d, "start")
+"   :let bar = s:Ref(string, d, "len")
+fun! s:Ref(string, d, ...)
+  let len = strlen(a:string)
+  if a:d == 0
+    let start = 0
+  else
+    let cnt = a:d
+    let match = a:string
+    while cnt
+      let cnt = cnt - 1
+      let index = matchend(match, s:notslash . '\\(')
+      if index == -1
+       return ""
+      endif
+      let match = strpart(match, index)
+    endwhile
+    let start = len - strlen(match)
+    if a:0 == 1 && a:1 == "start"
+      return start - 2
+    endif
+    let cnt = 1
+    while cnt
+      let index = matchend(match, s:notslash . '\\(\|\\)') - 1
+      if index == -2
+       return ""
+      endif
+      " Increment if an open, decrement if a ')':
+      let cnt = cnt + (match[index]=="(" ? 1 : -1)  " ')'
+      " let cnt = stridx('0(', match[index]) + cnt
+      let match = strpart(match, index+1)
+    endwhile
+    let start = start - 2
+    let len = len - start - strlen(match)
+  endif
+  if a:0 == 1
+    return len
+  elseif a:0 == 2
+    return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
+  else
+    return strpart(a:string, start, len)
+  endif
+endfun
+
+" Count the number of disjoint copies of pattern in string.
+" If the pattern is a literal string and contains no '0' or '1' characters
+" then s:Count(string, pattern, '0', '1') should be faster than
+" s:Count(string, pattern).
+fun! s:Count(string, pattern, ...)
+  let pat = escape(a:pattern, '\\')
+  if a:0 > 1
+    let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
+    let foo = substitute(a:string, pat, a:2, "g")
+    let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
+    return strlen(foo)
+  endif
+  let result = 0
+  let foo = a:string
+  let index = matchend(foo, pat)
+  while index != -1
+    let result = result + 1
+    let foo = strpart(foo, index)
+    let index = matchend(foo, pat)
+  endwhile
+  return result
+endfun
+
+" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
+" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'.  That is, the first
+" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
+" indicates that all other instances of '\1' in target are to be replaced
+" by '\3'.  The hard part is dealing with nesting...
+" Note that ":" is an illegal character for source and target,
+" unless it is preceded by "\".
+fun! s:Resolve(source, target, output)
+  let word = a:target
+  let i = matchend(word, s:notslash . '\\\d') - 1
+  let table = "----------"
+  while i != -2 " There are back references to be replaced.
+    let d = word[i]
+    let backref = s:Ref(a:source, d)
+    " The idea is to replace '\d' with backref.  Before we do this,
+    " replace any \(\) groups in backref with :1, :2, ... if they
+    " correspond to the first, second, ... group already inserted
+    " into backref.  Later, replace :1 with \1 and so on.  The group
+    " number w+b within backref corresponds to the group number
+    " s within a:source.
+    " w = number of '\(' in word before the current one
+    let w = s:Count(
+    \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
+    let b = 1 " number of the current '\(' in backref
+    let s = d " number of the current '\(' in a:source
+    while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
+    \ && s < 10
+      if table[s] == "-"
+       if w + b < 10
+         " let table[s] = w + b
+         let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
+       endif
+       let b = b + 1
+       let s = s + 1
+      else
+       execute s:Ref(backref, b, "start", "len")
+       let ref = strpart(backref, start, len)
+       let backref = strpart(backref, 0, start) . ":". table[s]
+       \ . strpart(backref, start+len)
+       let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
+      endif
+    endwhile
+    let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
+    let i = matchend(word, s:notslash . '\\\d') - 1
+  endwhile
+  let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
+  if a:output == "table"
+    return table
+  elseif a:output == "word"
+    return word
+  else
+    return table . word
+  endif
+endfun
+
+" Assume a:comma = ",".  Then the format for a:patterns and a:1 is
+"   a:patterns = "<pat1>,<pat2>,..."
+"   a:1 = "<alt1>,<alt2>,..."
+" If <patn> is the first pattern that matches a:string then return <patn>
+" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
+fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
+  let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
+  let i = matchend(tail, s:notslash . a:comma)
+  if a:0
+    let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
+    let j = matchend(alttail, s:notslash . a:comma)
+  endif
+  let current = strpart(tail, 0, i-1)
+  if a:branch == ""
+    let currpat = current
+  else
+    let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
+  endif
+  while a:string !~ a:prefix . currpat . a:suffix
+    let tail = strpart(tail, i)
+    let i = matchend(tail, s:notslash . a:comma)
+    if i == -1
+      return -1
+    endif
+    let current = strpart(tail, 0, i-1)
+    if a:branch == ""
+      let currpat = current
+    else
+      let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
+    endif
+    if a:0
+      let alttail = strpart(alttail, j)
+      let j = matchend(alttail, s:notslash . a:comma)
+    endif
+  endwhile
+  if a:0
+    let current = current . a:comma . strpart(alttail, 0, j-1)
+  endif
+  return current
+endfun
+
+" Call this function to turn on debugging information.  Every time the main
+" script is run, buffer variables will be saved.  These can be used directly
+" or viewed using the menu items below.
+if !exists(":MatchDebug")
+  command! -nargs=0 MatchDebug call s:Match_debug()
+endif
+
+fun! s:Match_debug()
+  let b:match_debug = 1        " Save debugging information.
+  " pat = all of b:match_words with backrefs parsed
+  amenu &Matchit.&pat  :echo b:match_pat<CR>
+  " match = bit of text that is recognized as a match
+  amenu &Matchit.&match        :echo b:match_match<CR>
+  " curcol = cursor column of the start of the matching text
+  amenu &Matchit.&curcol       :echo b:match_col<CR>
+  " wholeBR = matching group, original version
+  amenu &Matchit.wh&oleBR      :echo b:match_wholeBR<CR>
+  " iniBR = 'if' piece, original version
+  amenu &Matchit.ini&BR        :echo b:match_iniBR<CR>
+  " ini = 'if' piece, with all backrefs resolved from match
+  amenu &Matchit.&ini  :echo b:match_ini<CR>
+  " tail = 'else\|endif' piece, with all backrefs resolved from match
+  amenu &Matchit.&tail :echo b:match_tail<CR>
+  " fin = 'endif' piece, with all backrefs resolved from match
+  amenu &Matchit.&word :echo b:match_word<CR>
+  " '\'.d in ini refers to the same thing as '\'.table[d] in word.
+  amenu &Matchit.t&able        :echo '0:' . b:match_table . ':9'<CR>
+endfun
+
+" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
+" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
+" Return a "mark" for the original position, so that
+"   let m = MultiMatch("bW", "n") ... execute m
+" will return to the original position.  If there is a problem, do not
+" move the cursor and return "", unless a count is given, in which case
+" go up or down as many levels as possible and again return "".
+" TODO This relies on the same patterns as % matching.  It might be a good
+" idea to give it its own matching patterns.
+fun! s:MultiMatch(spflag, mode)
+  if !exists("b:match_words") || b:match_words == ""
+    return ""
+  end
+  let restore_options = (&ic ? "" : "no") . "ignorecase"
+  if exists("b:match_ignorecase")
+    let &ignorecase = b:match_ignorecase
+  endif
+  let startline = line(".")
+  let startcol = col(".")
+
+  " First step:  if not already done, set the script variables
+  "   s:do_BR  flag for whether there are backrefs
+  "   s:pat    parsed version of b:match_words
+  "   s:all    regexp based on s:pat and the default groups
+  " This part is copied and slightly modified from s:Match_wrapper().
+  let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
+    \ '\/\*:\*\/,#if\%(def\)\=:#else\>:#elif\>:#endif\>'
+  " Allow b:match_words = "GetVimMatchWords()" .
+  if b:match_words =~ ":"
+    let match_words = b:match_words
+  else
+    execute "let match_words =" b:match_words
+  endif
+  if (match_words != s:last_words) || (&mps != s:last_mps) ||
+    \ exists("b:match_debug")
+    let s:last_words = match_words
+    let s:last_mps = &mps
+    if match_words !~ s:notslash . '\\\d'
+      let s:do_BR = 0
+      let s:pat = match_words
+    else
+      let s:do_BR = 1
+      let s:pat = s:ParseWords(match_words)
+    endif
+    let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default,
+      \        '[,:]\+','\\|','g') . '\)'
+    if exists("b:match_debug")
+      let b:match_pat = s:pat
+    endif
+  endif
+
+  " Second step:  figure out the patterns for searchpair()
+  " and save the screen, cursor position, and 'ignorecase'.
+  " - TODO:  A lot of this is copied from s:Match_wrapper().
+  " - maybe even more functionality should be split off
+  " - into separate functions!
+  let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default
+  let open =  substitute(s:pat . cdefault,
+       \ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g')
+  let open =  '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '')
+  let close = substitute(s:pat . cdefault,
+       \ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g')
+  let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)'
+  if exists("b:match_skip")
+    let skip = b:match_skip
+  elseif exists("b:match_comment") " backwards compatibility and testing!
+    let skip = "r:" . b:match_comment
+  else
+    let skip = 's:comment\|string'
+  endif
+  let skip = s:ParseSkip(skip)
+  " let restore_cursor = line(".") . "G" . virtcol(".") . "|"
+  " normal! H
+  " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
+  let restore_cursor = virtcol(".") . "|"
+  normal! g0
+  let restore_cursor = line(".") . "G" .  virtcol(".") . "|zs" . restore_cursor
+  normal! H
+  let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
+  execute restore_cursor
+
+  " Third step: call searchpair().
+  " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
+  let openpat =  substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
+  let openpat = substitute(openpat, ',', '\\|', 'g')
+  let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
+  let closepat = substitute(closepat, ',', '\\|', 'g')
+  if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
+    let skip = '0'
+  else
+    execute "if " . skip . "| let skip = '0' | endif"
+  endif
+  mark '
+  let level = v:count1
+  while level
+    if searchpair(openpat, '', closepat, a:spflag, skip) < 1
+      call s:CleanUp(restore_options, a:mode, startline, startcol)
+      return ""
+    endif
+    let level = level - 1
+  endwhile
+
+  " Restore options and return a string to restore the original position.
+  call s:CleanUp(restore_options, a:mode, startline, startcol)
+  return restore_cursor
+endfun
+
+" Search backwards for "if" or "while" or "<tag>" or ...
+" and return "endif" or "endwhile" or "</tag>" or ... .
+" For now, this uses b:match_words and the same script variables
+" as s:Match_wrapper() .  Later, it may get its own patterns,
+" either from a buffer variable or passed as arguments.
+" fun! s:Autocomplete()
+"   echo "autocomplete not yet implemented :-("
+"   if !exists("b:match_words") || b:match_words == ""
+"     return ""
+"   end
+"   let startpos = s:MultiMatch("bW")
+"
+"   if startpos == ""
+"     return ""
+"   endif
+"   " - TODO:  figure out whether 'if' or '<tag>' matched, and construct
+"   " - the appropriate closing.
+"   let matchline = getline(".")
+"   let curcol = col(".") - 1
+"   " - TODO:  Change the s:all argument if there is a new set of match pats.
+"   let regexp = s:Wholematch(matchline, s:all, curcol)
+"   let suf = strlen(matchline) - matchend(matchline, regexp)
+"   let prefix = (curcol ? '^.\{'  . curcol . '}\%(' : '^\%(')
+"   let suffix = (suf ? '\).\{' . suf . '}$'  : '\)$')
+"   " Reconstruct the version with unresolved backrefs.
+"   let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
+"   let patBR = substitute(patBR, ':\{2,}', ':', "g")
+"   " Now, set group and groupBR to the matching group: 'if:endif' or
+"   " 'while:endwhile' or whatever.
+"   let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
+"   let i = matchend(group, s:notslash . ",")
+"   let groupBR = strpart(group, i)
+"   let group = strpart(group, 0, i-1)
+"   " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
+"   if s:do_BR
+"     let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
+"   endif
+" " let g:group = group
+"
+"   " - TODO:  Construct the closing from group.
+"   let fake = "end" . expand("<cword>")
+"   execute startpos
+"   return fake
+" endfun
+
+" Close all open structures.  "Get the heck out of here!"
+" fun! s:Gthhoh()
+"   let close = s:Autocomplete()
+"   while strlen(close)
+"     put=close
+"     let close = s:Autocomplete()
+"   endwhile
+" endfun
+
+" Parse special strings as typical skip arguments for searchpair():
+"   s:foo becomes (current syntax item) =~ foo
+"   S:foo becomes (current syntax item) !~ foo
+"   r:foo becomes (line before cursor) =~ foo
+"   R:foo becomes (line before cursor) !~ foo
+fun! s:ParseSkip(str)
+  let skip = a:str
+  if skip[1] == ":"
+    if skip[0] == "s"
+      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
+       \ strpart(skip,2) . "'"
+    elseif skip[0] == "S"
+      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
+       \ strpart(skip,2) . "'"
+    elseif skip[0] == "r"
+      let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
+    elseif skip[0] == "R"
+      let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
+    endif
+  endif
+  return skip
+endfun
+
+let &cpo = s:save_cpo
+
+" vim:sts=2:sw=2:
diff --git a/vim/plugin/matrix.vim b/vim/plugin/matrix.vim
new file mode 100644 (file)
index 0000000..9ed838d
--- /dev/null
@@ -0,0 +1,325 @@
+" matrix.vim - Don Yang (uguu.org)
+"
+" Matrix screensaver for VIM.
+"
+"Usage:
+" After loading the script, use :Matrix to start.
+" Press any key a few times to exit.
+"
+" You will need to edit s:mindelay and s:maxdelay below to match your
+" machine speed and window size.
+"
+"Known Issues:
+" Sometimes you need to press keys a few times to exit instead of just
+" once.  Press and hold is another way to go... feels like getchar is
+" checking for keypress state instead of keystroke availability.
+"
+" If the window is too small, script will not run.  If the window is
+" resized and become too small (less than 8 rows or 10 columns) after
+" the script started, script will abort and *buffers may be lost*, so
+" don't do that.  Resizing the window to most other sizes will be fine.
+"
+" Doesn't work if multiple windows exist before script started.  In
+" that case the script will abort with error message.
+"
+" If the current buffer is modified, some error messages will appear
+" before the script starts, and an extra window is left behind after
+" the script exits.  Workaround: save your buffers first.
+"
+"Other Info:
+" Inspired by cmatrix...
+" Didn't feel inspired enough to start using pico/nano, of course ^_^;
+"
+" 05/13/08 - disable cursorline, cursorcolumn and spell
+"            (thanks to Diederick Niehorster for the suggestion).
+" 12/21/06 - multiwindow support by S. Lockwood-Childs.
+" 10/03/05 - added silent! to cursor positioning code to stop drawing
+"            numbers during animation (thanks to David Eggum for the
+"            suggestion).
+" 10/02/05 - disable showmatch
+" 03/16/05 - make new buffer modifiable before running
+" 01/27/05 - added sleep to consume less CPU
+"            removed frame counter
+" 01/26/05 - initial version
+
+
+" Speed range, must be positive.  Lower delay = faster.
+let s:mindelay = 1
+let s:maxdelay = 5
+
+" Session file for preserving original window layout
+let s:session_file = tempname()
+
+
+function! s:Rand()
+   let b:seed = b:seed * 22695477 + 1
+   if b:seed < 0
+      return -b:seed
+   endif
+   return b:seed
+endfunction
+
+function! s:CreateObject(i)
+   while 1
+      let b:x{a:i} = s:Rand() % b:columns
+      if b:reserve{b:x{a:i}} > 4
+         break
+      endif
+   endwhile
+   let b:y{a:i} = 1
+   let b:t{a:i} = s:Rand() % b:s{b:x{a:i}}
+   let b:head{a:i} = s:Rand() % 4
+   let b:len{a:i} = s:Rand() % b:h + 3
+   let b:reserve{b:x{a:i}} = 1 - b:len{a:i}
+endfunction
+
+function! s:DrawObject(i)
+   let x = b:x{a:i} * 2 + 1
+   let y = b:y{a:i}
+
+   " Draw head
+   if y <= b:h
+      if b:head{a:i}
+         silent! exec 'norm! :' . y . nr2char(13) . x . '|R' . b:d[s:Rand()%b:dl] . '_' . nr2char(27)
+         if y > 1
+            silent! exec 'norm! kR' . ((s:Rand() % 2) ? '`' : ' ') . nr2char(27)
+         endif
+      else
+         let a = ((s:Rand() % 2) ? '`' : ' ') . nr2char(27)
+         silent! exec 'norm! :'. y . nr2char(13) . x . '|R' . b:d[s:Rand() % b:dl] . a
+      endif
+   else
+      if b:head{a:i} && y == b:h + 1
+         silent! exec 'norm! :' . b:h . nr2char(13) . (x + 1) . '|R' . ((s:Rand() % 2) ? '`' : ' ') . nr2char(27)
+      endif
+   endif
+
+   " Draw tail
+   let y = y - b:len{a:i}
+   if 1 <= y && y <= b:h
+      silent! exec 'norm! :'. y . nr2char(13) . x . '|R  ' . nr2char(27)
+   endif
+   let b:reserve{b:x{a:i}} = y
+endfunction
+
+function! s:Animate()
+   let i = 0
+
+   while i < b:objcount
+      " Animate object
+      if b:t{i} <= 0
+         if b:y{i} - b:len{i} <= b:h
+            " Draw
+            call s:DrawObject(i)
+            let b:t{i} = b:s{b:x{i}}
+            let b:y{i} = b:y{i} + 1
+         else
+            " Regenerate
+            call s:CreateObject(i)
+         endif
+      endif
+
+      let b:t{i} = b:t{i} - 1
+      let i = i + 1
+   endwhile
+   redraw
+   if getchar(1)
+      let b:run = 0
+   endif
+   sleep 20m
+endfunction
+
+function! s:Reset()
+   " Clear screen
+   let b:w = winwidth(0)
+   let b:h = winheight(0)
+   exec 'norm! gg"_dG' . b:h . 'O' . nr2char(27) . 'gg'
+   redraw
+   if b:w < 10 || b:h < 8
+      let b:run = 0
+      return
+   endif
+
+   " Set number of columns.  This is rounded down due to line wrapping
+   " at the last column if the screen width is even.  So you end up
+   " seeing the cursor blinking a lot at the right side of the screen.
+   " Alternatively, ':set rl' before running the script to have it
+   " blink on the left side.
+   let b:columns = (b:w - 1) / 2
+
+   " Initialize columns.
+   let i = 0
+   while i < b:columns
+      " Set delay time.  Each column gets the same delay time.
+      let b:s{i} = s:Rand() % (s:maxdelay - s:mindelay) + s:mindelay
+
+      " Unreserve column
+      let b:reserve{i} = b:h
+      let i = i + 1
+   endwhile
+
+   " Initialize objects
+   let b:objcount = b:columns - 2
+   let i = 0
+   while i < b:objcount
+      call s:CreateObject(i)
+      let i = i + 1
+   endwhile
+endfunction
+
+function! s:Init()
+   " Create new buffer and hide the existing buffers.  Hiding the
+   " existing buffers without switching to a new buffer preserves
+   " undo history.
+   exec 'mksession! ' . s:session_file
+   let s:num_orig_win = winnr("$")
+
+   " move to top window, so created window will become window 1,
+   " then attempt to create new window
+   1 wincmd w
+   silent! new
+
+   " check that there really is an additional window
+   if winnr("$") != s:num_orig_win + 1
+      return 1
+   endif
+   let s:newbuf = bufnr('%')
+
+   " close all but window 1, which is the new window
+   only
+
+   setl bh=delete bt=nofile ma nolist nonu noro noswf tw=0 nowrap
+
+   " Set GUI options
+   if has('gui')
+      let s:o_gcr = &gcr
+      let s:o_go = &go
+      set gcr=a:ver1-blinkon0 go=
+   endif
+   if has('cmdline_info')
+      let s:o_ru = &ru
+      let s:o_sc = &sc
+      set noru nosc
+   endif
+   if has('title')
+      let s:o_ts = &titlestring
+      exec 'set titlestring=\ '
+   endif
+   if v:version >= 700
+      let s:o_spell = &spell
+      let s:o_cul = &cul
+      let s:o_cuc = &cuc
+      set nospell nocul nocuc
+   endif
+   let s:o_ch = &ch
+   let s:o_ls = &ls
+   let s:o_lz = &lz
+   let s:o_siso = &siso
+   let s:o_sm = &sm
+   let s:o_smd = &smd
+   let s:o_so = &so
+   let s:o_ve = &ve
+   set ch=1 ls=0 lz nosm nosmd siso=0 so=0 ve=all
+
+   " Initialize PRNG
+   let b:seed = localtime()
+   let b:run = 1
+
+   " Clear screen and initialize objects
+   call s:Reset()
+
+   " Set colors.  Output looks better if your color scheme has black
+   " background.  I would rather not have the script change the
+   " current color scheme since there is no good way to restore them
+   " afterwards.
+   hi MatrixHidden ctermfg=Black ctermbg=Black guifg=#000000 guibg=#000000
+   hi MatrixNormal ctermfg=DarkGreen ctermbg=Black guifg=#008000 guibg=#000000
+   hi MatrixBold ctermfg=LightGreen ctermbg=Black guifg=#00ff00 guibg=#000000
+   hi MatrixHead ctermfg=White ctermbg=Black guifg=#ffffff guibg=#000000
+   sy match MatrixNormal /^.*/ contains=MatrixHidden
+   sy match MatrixHidden contained /.`/ contains=MatrixBold
+   sy match MatrixHidden contained /._/ contains=MatrixHead
+   sy match MatrixBold contained /.\(`\)\@=/
+   sy match MatrixHead contained /.\(_\)\@=/
+
+   " Create random char dictionary
+   let b:d = ''
+   let i = 33
+   while i < 127
+      if i != 95 && i != 96
+         let b:d = b:d . nr2char(i)
+      endif
+      let i = i + 1
+   endwhile
+   let b:dl = strlen(b:d)
+   return 0
+endfunction
+
+function! s:Cleanup()
+   " Restore options
+   if has('gui')
+      let &gcr = s:o_gcr
+      let &go = s:o_go
+      unlet s:o_gcr s:o_go
+   endif
+   if has('cmdline_info')
+      let &ru = s:o_ru
+      let &sc = s:o_sc
+      unlet s:o_ru s:o_sc
+   endif
+   if has('title')
+      let &titlestring = s:o_ts
+      unlet s:o_ts
+   endif
+   if v:version >= 700
+      let &spell = s:o_spell
+      let &cul = s:o_cul
+      let &cuc = s:o_cuc
+      unlet s:o_cul s:o_cuc
+   endif
+   let &ch = s:o_ch
+   let &ls = s:o_ls
+   let &lz = s:o_lz
+   let &siso = s:o_siso
+   let &sm = s:o_sm
+   let &smd = s:o_smd
+   let &so = s:o_so
+   let &ve = s:o_ve
+   unlet s:o_ch s:o_ls s:o_lz s:o_siso s:o_sm s:o_smd s:o_so s:o_ve
+
+   " Restore old buffers
+   exec 'source ' . s:session_file
+   exec 'bwipe ' . s:newbuf
+   unlet s:newbuf
+
+   " Clear keystroke
+   let c = getchar(0)
+endfunction
+
+function! Matrix()
+   if s:Init()
+      echohl ErrorMsg
+      echon 'Can not create window'
+      echohl None
+      return
+   endif
+
+   while b:run
+      if b:w != winwidth(0) || b:h != winheight(0)
+         call s:Reset()
+      else
+         call s:Animate()
+      endif
+   endwhile
+
+   call s:Cleanup()
+endfunction
+
+
+if !has('virtualedit') || !has('windows') || !has('syntax')
+   echohl ErrorMsg
+   echon 'Not enough features, need at least +virtualedit, +windows and +syntax'
+   echohl None
+else
+   command! Matrix call Matrix()
+endif
diff --git a/vim/plugin/minibufexpl.vim b/vim/plugin/minibufexpl.vim
new file mode 100644 (file)
index 0000000..4e78063
--- /dev/null
@@ -0,0 +1,1838 @@
+" Mini Buffer Explorer <minibufexpl.vim>
+"
+" HINT: Type zR if you don't know how to use folds
+"
+" Script Info and Documentation  {{{
+"=============================================================================
+"    Copyright: Copyright (C) 2002 & 2003 Bindu Wavell 
+"               Permission is hereby granted to use and distribute this code,
+"               with or without modifications, provided that this copyright
+"               notice is copied with it. Like anything else that's free,
+"               minibufexplorer.vim is provided *as is* and comes with no
+"               warranty of any kind, either expressed or implied. In no
+"               event will the copyright holder be liable for any damamges
+"               resulting from the use of this software.
+"
+" Name Of File: minibufexpl.vim
+"  Description: Mini Buffer Explorer Vim Plugin
+"   Maintainer: Bindu Wavell <bindu@wavell.net>
+"          URL: http://vim.sourceforge.net/scripts/script.php?script_id=159
+"  Last Change: Sunday, June 21, 2004
+"      Version: 6.3.2
+"               Derived from Jeff Lanzarotta's bufexplorer.vim version 6.0.7
+"               Jeff can be reached at (jefflanzarotta@yahoo.com) and the
+"               original plugin can be found at:
+"               http://lanzarotta.tripod.com/vim/plugin/6/bufexplorer.vim.zip
+"
+"        Usage: Normally, this file should reside in the plugins
+"               directory and be automatically sourced. If not, you must
+"               manually source this file using ':source minibufexplorer.vim'.
+"
+"               You may use the default keymappings of
+"
+"                 <Leader>mbe - Opens MiniBufExplorer
+"
+"               or you may want to add something like the following
+"               key mapping to your _vimrc/.vimrc file.
+"
+"                 map <Leader>b :MiniBufExplorer<cr>
+"
+"               However, in most cases you won't need any key-bindings at all.
+"
+"               <Leader> is usually backslash so type "\mbe" (quickly) to open 
+"               the -MiniBufExplorer- window.
+"
+"               Other keymappings include: <Leader>mbc to close the Explorer
+"               window,  <Leader>mbu to force the Explorer to Update and
+"               <Leader>mbt to toggle the Explorer window; it will open if
+"               closed or close if open. Each of these key bindings can be
+"               overridden (see the notes on <Leader>mbe above.)
+" 
+"               You can map these additional commands as follows:
+"
+"                 map <Leader>c :CMiniBufExplorer<cr>
+"                 map <Leader>u :UMiniBufExplorer<cr>
+"                 map <Leader>t :TMiniBufExplorer<cr>
+"
+"               NOTE: you can change the key binding used in these mappings
+"                     so that they fit with your configuration of vim.
+"
+"               You can also call each of these features by typing the
+"               following in command mode:
+"
+"                 :MiniBufExplorer    " Open and/or goto Explorer
+"                 :CMiniBufExplorer   " Close the Explorer if it's open
+"                 :UMiniBufExplorer   " Update Explorer without navigating
+"                 :TMiniBufExplorer   " Toggle the Explorer window open and 
+"                                       closed.
+"
+"               To control where the new split window goes relative to the 
+"               current window, use the setting:
+"
+"                 let g:miniBufExplSplitBelow=0  " Put new window above
+"                                                " current or on the
+"                                                " left for vertical split
+"                 let g:miniBufExplSplitBelow=1  " Put new window below
+"                                                " current or on the
+"                                                " right for vertical split
+"
+"               The default for this is read from the &splitbelow VIM option.
+"
+"               By default we are now (as of 6.0.2) forcing the -MiniBufExplorer-
+"               window to open up at the edge of the screen. You can turn this 
+"               off by setting the following variable in your .vimrc:
+"
+"                 let g:miniBufExplSplitToEdge = 0
+"
+"               If you would like a vertical explorer you can assign the column
+"               width (in characters) you want for your explorer window with the
+"               following .vimrc variable (this was introduced in 6.3.0):
+"
+"                 let g:miniBufExplVSplit = 20   " column width in chars
+"
+"               IN HORIZONTAL MODE:
+"               It is now (as of 6.1.1) possible to set a maximum height for
+"               the -MiniBufExplorer- window. You can set the max height by
+"               letting the following variable in your .vimrc:
+"
+"                 let g:miniBufExplMaxSize = <max lines: defualt 0>
+"               
+"               setting this to 0 will mean the window gets as big as
+"               needed to fit all your buffers. 
+"
+"               NOTE: This was g:miniBufExplMaxHeight before 6.3.0; the old
+"               setting is backwards compatible if you don't use MaxSize.
+"
+"               As of 6.2.2 it is possible to set a minimum height for the 
+"               -MiniBufExplorer- window. You can set the min height by
+"               letting the following variable in your .vimrc:
+"
+"                 let g:miniBufExplMinSize = <min height: default 1>
+"
+"               NOTE: This was g:miniBufExplMinHeight before 6.3.0; the old
+"               setting is backwards compatible if you don't use MinSize.
+"
+"               IN VERTICAL MODE: (as of 6.3.0)
+"               By default the vertical explorer has a fixed width. If you put:
+"
+"                 let g:miniBufExplMaxSize = <max width: default 0> 
+"
+"               into your .vimrc then MBE will attempt to set the width of the
+"               MBE window to be as wide as your widest tab. The width will not
+"               exceed MaxSize even if you have wider tabs. 
+"
+"               Accepting the default value of 0 for this will give you a fixed
+"               width MBE window.
+"
+"               You can specify a MinSize for the vertical explorer window by
+"               putting the following in your .vimrc:
+"
+"                 let g:miniBufExplMinSize = <min width: default 1>
+"
+"               This will have no effect unless you also specivy MaxSize.
+"
+"               By default we are now (as of 6.0.1) turning on the MoreThanOne
+"               option. This stops the -MiniBufExplorer- from opening 
+"               automatically until more than one eligible buffer is available.
+"               You can turn this feature off by setting the following variable
+"               in your .vimrc:
+"                 
+"                 let g:miniBufExplorerMoreThanOne=1
+"
+"               (The following enhancement is as of 6.2.2)
+"               Setting this to 0 will cause the MBE window to be loaded even
+"               if no buffers are available. Setting it to 1 causes the MBE
+"               window to be loaded as soon as an eligible buffer is read. You
+"               can also set it to larger numbers. So if you set it to 4 for
+"               example the MBE window wouldn't auto-open until 4 eligibles
+"               buffers had been loaded. This is nice for folks that don't 
+"               want an MBE window unless they are editing more than two or
+"               three buffers.
+"
+"               To enable the optional mapping of Control + Vim Direction Keys 
+"               [hjkl] to window movement commands, you can put the following into 
+"               your .vimrc:
+"
+"                 let g:miniBufExplMapWindowNavVim = 1
+"
+"               To enable the optional mapping of Control + Arrow Keys to window 
+"               movement commands, you can put the following into your .vimrc:
+"
+"                 let g:miniBufExplMapWindowNavArrows = 1
+"
+"               To enable the optional mapping of <C-TAB> and <C-S-TAB> to a 
+"               function that will bring up the next or previous buffer in the
+"               current window, you can put the following into your .vimrc:
+"
+"                 let g:miniBufExplMapCTabSwitchBufs = 1
+"
+"               To enable the optional mapping of <C-TAB> and <C-S-TAB> to mappings
+"               that will move to the next and previous (respectively) window, you
+"               can put the following into your .vimrc:
+"
+"                 let g:miniBufExplMapCTabSwitchWindows = 1
+"
+"
+"               NOTE: If you set the ...TabSwitchBufs AND ...TabSwitchWindows, 
+"                     ...TabSwitchBufs will be enabled and ...TabSwitchWindows 
+"                     will not.
+"               
+"               As of MBE 6.3.0, you can put the following into your .vimrc:
+"               
+"                 let g:miniBufExplUseSingleClick = 1
+"
+"               If you would like to single click on tabs rather than double
+"               clicking on them to goto the selected buffer. 
+"
+"               NOTE: If you use the single click option in taglist.vim you may 
+"                     need to get an updated version that includes a patch I 
+"                     provided to allow both explorers to provide single click 
+"                     buffer selection.
+"
+"               It is possible to customize the the highlighting for the tabs in 
+"               the MBE by configuring the following highlighting groups:
+"
+"                 MBENormal         - for buffers that have NOT CHANGED and
+"                                     are NOT VISIBLE.
+"                 MBEChanged        - for buffers that HAVE CHANGED and are
+"                                     NOT VISIBLE
+"                 MBEVisibleNormal  - buffers that have NOT CHANGED and are
+"                                     VISIBLE
+"                 MBEVisibleChanged - buffers that have CHANGED and are VISIBLE
+"
+"               You can either link to an existing highlighting group by
+"               adding a command like:
+"
+"                 hi link MBEVisibleChanged Error
+"
+"               to your .vimrc or you can specify exact foreground and background
+"               colors using the following syntax:
+"
+"                 hi MBEChanged guibg=darkblue ctermbg=darkblue termbg=white
+"
+"               NOTE: If you set a colorscheme in your .vimrc you should do it
+"                     BEFORE updating the MBE highlighting groups.
+"
+"               If you use other explorers like TagList you can (As of 6.2.8) put:
+"
+"                 let g:miniBufExplModSelTarget = 1
+" 
+"               into your .vimrc in order to force MBE to try to place selected 
+"               buffers into a window that does not have a nonmodifiable buffer.
+"               The upshot of this should be that if you go into MBE and select
+"               a buffer, the buffer should not show up in a window that is 
+"               hosting an explorer.
+"
+"               There is a VIM bug that can cause buffers to show up without 
+"               their highlighting. The following setting will cause MBE to
+"               try and turn highlighting back on (introduced in 6.3.1):
+"
+"                 let g:miniBufExplForceSyntaxEnable = 1
+"
+"               MBE has had a basic debugging capability for quite some time.
+"               However, it has not been very friendly in the past. As of 6.0.8, 
+"               you can put one of each of the following into your .vimrc:
+"
+"                 let g:miniBufExplorerDebugLevel = 0  " MBE serious errors output
+"                 let g:miniBufExplorerDebugLevel = 4  " MBE all errors output
+"                 let g:miniBufExplorerDebugLevel = 10 " MBE reports everything
+"
+"               You can also set a DebugMode to cause output to be target as
+"               follows (default is mode 3):
+"
+"                 let g:miniBufExplorerDebugMode  = 0  " Errors will show up in 
+"                                                      " a vim window
+"                 let g:miniBufExplorerDebugMode  = 1  " Uses VIM's echo function
+"                                                      " to display on the screen
+"                 let g:miniBufExplorerDebugMode  = 2  " Writes to a file
+"                                                      " MiniBufExplorer.DBG
+"                 let g:miniBufExplorerDebugMode  = 3  " Store output in global:
+"                                                 " g:miniBufExplorerDebugOutput
+"
+"               Or if you are able to start VIM, you might just perform these
+"               at a command prompt right before you do the operation that is
+"               failing.
+"
+"      History: Moved to end of file
+"      
+" Known Issues: When debugging is turned on and set to output to a window, there
+"               are some cases where the window is opened more than once, there
+"               are other cases where an old debug window can be lost.
+" 
+"               Several MBE commands can break the window history so <C-W>[pnw]
+"               might not take you to the expected window.
+"
+"         Todo: Add the ability to specify a regexp for eligible buffers
+"               allowing the ability to filter out certain buffers that 
+"               you don't want to control from MBE
+"
+"=============================================================================
+" }}}
+
+" Startup Check
+"
+" Has this plugin already been loaded? {{{
+"
+if exists('loaded_minibufexplorer')
+  finish
+endif
+let loaded_minibufexplorer = 1
+" }}}
+
+" Mappings and Commands
+"
+" MBE Keyboard Mappings {{{
+" If we don't already have keyboard mappings for MBE then create them 
+" 
+if !hasmapto('<Plug>MiniBufExplorer')
+  map <unique> <Leader>mbe <Plug>MiniBufExplorer
+endif
+if !hasmapto('<Plug>CMiniBufExplorer')
+  map <unique> <Leader>mbc <Plug>CMiniBufExplorer
+endif
+if !hasmapto('<Plug>UMiniBufExplorer')
+  map <unique> <Leader>mbu <Plug>UMiniBufExplorer
+endif
+if !hasmapto('<Plug>TMiniBufExplorer')
+  map <unique> <Leader>mbt <Plug>TMiniBufExplorer
+endif
+
+" }}}
+" MBE <Script> internal map {{{
+" 
+noremap <unique> <script> <Plug>MiniBufExplorer  :call <SID>StartExplorer(1, -1)<CR>:<BS>
+noremap <unique> <script> <Plug>CMiniBufExplorer :call <SID>StopExplorer(1)<CR>:<BS>
+noremap <unique> <script> <Plug>UMiniBufExplorer :call <SID>AutoUpdate(-1)<CR>:<BS>
+noremap <unique> <script> <Plug>TMiniBufExplorer :call <SID>ToggleExplorer()<CR>:<BS>
+
+" }}}
+" MBE commands {{{
+" 
+if !exists(':MiniBufExplorer')
+  command! MiniBufExplorer  call <SID>StartExplorer(1, -1)
+endif
+if !exists(':CMiniBufExplorer')
+  command! CMiniBufExplorer  call <SID>StopExplorer(1)
+endif
+if !exists(':UMiniBufExplorer')
+  command! UMiniBufExplorer  call <SID>AutoUpdate(-1)
+endif
+if !exists(':TMiniBufExplorer')
+  command! TMiniBufExplorer  call <SID>ToggleExplorer()
+endif
+if !exists(':MBEbn')
+  command! MBEbn call <SID>CycleBuffer(1)
+endif
+if !exists(':MBEbp')
+  command! MBEbp call <SID>CycleBuffer(0)
+endif " }}}
+
+" Global Configuration Variables
+"
+" Debug Level {{{
+"
+" 0 = no logging
+" 1=5 = errors ; 1 is the most important
+" 5-9 = info ; 5 is the most important
+" 10 = Entry/Exit
+if !exists('g:miniBufExplorerDebugLevel')
+  let g:miniBufExplorerDebugLevel = 0 
+endif
+
+" }}}
+" Debug Mode {{{
+"
+" 0 = debug to a window
+" 1 = use vim's echo facility
+" 2 = write to a file named MiniBufExplorer.DBG
+"     in the directory where vim was started
+"     THIS IS VERY SLOW
+" 3 = Write into g:miniBufExplorerDebugOutput
+"     global variable [This is the default]
+if !exists('g:miniBufExplorerDebugMode')
+  let g:miniBufExplorerDebugMode = 3 
+endif 
+
+" }}}
+" Allow auto update? {{{
+"
+" We start out with this off for startup, but once vim is running we 
+" turn this on.
+if !exists('g:miniBufExplorerAutoUpdate')
+  let g:miniBufExplorerAutoUpdate = 0
+endif
+
+" }}}
+" MoreThanOne? {{{
+" Display Mini Buf Explorer when there are 'More Than One' eligible buffers 
+"
+if !exists('g:miniBufExplorerMoreThanOne')
+  let g:miniBufExplorerMoreThanOne = 2
+endif 
+
+" }}}
+" Split below/above/left/right? {{{
+" When opening a new -MiniBufExplorer- window, split the new windows below or 
+" above the current window?  1 = below, 0 = above.
+"
+if !exists('g:miniBufExplSplitBelow')
+  let g:miniBufExplSplitBelow = &splitbelow
+endif 
+
+" }}}
+" Split to edge? {{{
+" When opening a new -MiniBufExplorer- window, split the new windows to the
+" full edge? 1 = yes, 0 = no.
+"
+if !exists('g:miniBufExplSplitToEdge')
+  let g:miniBufExplSplitToEdge = 1
+endif 
+
+" }}}
+" MaxHeight (depreciated) {{{
+" When sizing the -MiniBufExplorer- window, assign a maximum window height.
+" 0 = size to fit all buffers, otherwise the value is number of lines for
+" buffer. [Depreciated use g:miniBufExplMaxSize]
+"
+if !exists('g:miniBufExplMaxHeight')
+  let g:miniBufExplMaxHeight = 0
+endif 
+
+" }}}
+" MaxSize {{{
+" Same as MaxHeight but also works for vertical splits if specified with a
+" vertical split then vertical resizing will be performed. If left at 0 
+" then the number of columns in g:miniBufExplVSplit will be used as a
+" static window width.
+if !exists('g:miniBufExplMaxSize')
+  let g:miniBufExplMaxSize = g:miniBufExplMaxHeight
+endif
+
+" }}}
+" MinHeight (depreciated) {{{
+" When sizing the -MiniBufExplorer- window, assign a minumum window height.
+" the value is minimum number of lines for buffer. Setting this to zero can
+" cause strange height behavior. The default value is 1 [Depreciated use
+" g:miniBufExplMinSize]
+"
+if !exists('g:miniBufExplMinHeight')
+  let g:miniBufExplMinHeight = 1
+endif
+
+" }}}
+" MinSize {{{
+" Same as MinHeight but also works for vertical splits. For vertical splits, 
+" this is ignored unless g:miniBufExplMax(Size|Height) are specified.
+if !exists('g:miniBufExplMinSize')
+  let g:miniBufExplMinSize = g:miniBufExplMinHeight
+endif
+
+" }}}
+" Horizontal or Vertical explorer? {{{
+" For folks that like vertical explorers, I'm caving in and providing for
+" veritcal splits. If this is set to 0 then the current horizontal 
+" splitting logic will be run. If however you want a vertical split,
+" assign the width (in characters) you wish to assign to the MBE window.
+"
+if !exists('g:miniBufExplVSplit')
+  let g:miniBufExplVSplit = 0
+endif
+
+" }}}
+" TabWrap? {{{
+" By default line wrap is used (possibly breaking a tab name between two
+" lines.) Turning this option on (setting it to 1) can take more screen
+" space, but will make sure that each tab is on one and only one line.
+"
+if !exists('g:miniBufExplTabWrap')
+  let g:miniBufExplTabWrap = 0
+endif
+
+" }}}
+" Extended window navigation commands? {{{
+" Global flag to turn extended window navigation commands on or off
+" enabled = 1, dissabled = 0
+"
+if !exists('g:miniBufExplMapWindowNav')
+  " This is for backwards compatibility and may be removed in a
+  " later release, please use the ...NavVim and/or ...NavArrows 
+  " settings.
+  let g:miniBufExplMapWindowNav = 0
+endif
+if !exists('g:miniBufExplMapWindowNavVim')
+  let g:miniBufExplMapWindowNavVim = 0
+endif
+if !exists('g:miniBufExplMapWindowNavArrows')
+  let g:miniBufExplMapWindowNavArrows = 0
+endif
+if !exists('g:miniBufExplMapCTabSwitchBufs')
+  let g:miniBufExplMapCTabSwitchBufs = 0
+endif
+" Notice: that if CTabSwitchBufs is turned on then
+" we turn off CTabSwitchWindows.
+if g:miniBufExplMapCTabSwitchBufs == 1 || !exists('g:miniBufExplMapCTabSwitchWindows')
+  let g:miniBufExplMapCTabSwitchWindows = 0
+endif 
+
+"
+" If we have enabled control + vim direction key remapping
+" then perform the remapping
+"
+" Notice: I left g:miniBufExplMapWindowNav in for backward
+" compatibility. Eventually this mapping will be removed so
+" please use the newer g:miniBufExplMapWindowNavVim setting.
+if g:miniBufExplMapWindowNavVim || g:miniBufExplMapWindowNav
+  noremap <C-J> <C-W>j
+  noremap <C-K> <C-W>k
+  noremap <C-H> <C-W>h
+  noremap <C-L> <C-W>l
+endif
+
+"
+" If we have enabled control + arrow key remapping
+" then perform the remapping
+"
+if g:miniBufExplMapWindowNavArrows
+  noremap <C-Down>  <C-W>j
+  noremap <C-Up>    <C-W>k
+  noremap <C-Left>  <C-W>h
+  noremap <C-Right> <C-W>l
+endif
+
+" If we have enabled <C-TAB> and <C-S-TAB> to switch buffers
+" in the current window then perform the remapping
+"
+if g:miniBufExplMapCTabSwitchBufs
+  noremap <C-TAB>   :call <SID>CycleBuffer(1)<CR>:<BS>
+  noremap <C-S-TAB> :call <SID>CycleBuffer(0)<CR>:<BS>
+endif
+
+"
+" If we have enabled <C-TAB> and <C-S-TAB> to switch windows
+" then perform the remapping
+"
+if g:miniBufExplMapCTabSwitchWindows
+  noremap <C-TAB>   <C-W>w
+  noremap <C-S-TAB> <C-W>W
+endif
+
+" }}}
+" Modifiable Select Target {{{
+"
+if !exists('g:miniBufExplModSelTarget')
+  let g:miniBufExplModSelTarget = 0
+endif
+
+"}}}
+" Force Syntax Enable {{{
+"
+if !exists('g:miniBufExplForceSyntaxEnable')
+  let g:miniBufExplForceSyntaxEnable = 0
+endif
+
+" }}}
+" Single/Double Click? {{{
+" flag that can be set to 1 in a users .vimrc to allow 
+" single click switching of tabs. By default we use
+" double click for tab selection.
+"
+if !exists('g:miniBufExplUseSingleClick')
+  let g:miniBufExplUseSingleClick = 0
+endif 
+
+"
+" attempt to perform single click mapping, it would be much
+" nicer if we could nnoremap <buffer> ... however vim does
+" not fire the <buffer> <leftmouse> when you use the mouse
+" to enter a buffer.
+"
+if g:miniBufExplUseSingleClick == 1
+  let s:clickmap = ':if bufname("%") == "-MiniBufExplorer-" <bar> call <SID>MBEClick() <bar> endif <CR>'
+  if maparg('<LEFTMOUSE>', 'n') == '' 
+    " no mapping for leftmouse
+    exec ':nnoremap <silent> <LEFTMOUSE> <LEFTMOUSE>' . s:clickmap
+  else
+    " we have a mapping
+    let  g:miniBufExplDoneClickSave = 1
+    let  s:m = ':nnoremap <silent> <LEFTMOUSE> <LEFTMOUSE>'
+    let  s:m = s:m . substitute(substitute(maparg('<LEFTMOUSE>', 'n'), '|', '<bar>', 'g'), '\c^<LEFTMOUSE>', '', '')
+    let  s:m = s:m . s:clickmap
+    exec s:m
+  endif
+endif " }}}
+
+" Variables used internally
+"
+" Script/Global variables {{{
+" Global used to store the buffer list so we don't update the
+" UI unless the list has changed.
+if !exists('g:miniBufExplBufList')
+  let g:miniBufExplBufList = ''
+endif
+
+" Variable used as a mutex so that we don't do lots
+" of AutoUpdates at the same time.
+if !exists('g:miniBufExplInAutoUpdate')
+  let g:miniBufExplInAutoUpdate = 0
+endif
+
+" In debug mode 3 this variable will hold the debug output
+if !exists('g:miniBufExplorerDebugOutput')
+  let g:miniBufExplorerDebugOutput = ''
+endif
+
+" In debug mode 3 this variable will hold the debug output
+if !exists('g:miniBufExplForceDisplay')
+  let g:miniBufExplForceDisplay = 0
+endif
+
+" Variable used to pass maxTabWidth info between functions
+let s:maxTabWidth = 0 
+
+" Variable used to count debug output lines
+let s:debugIndex = 0 
+
+  
+" }}}
+" Setup an autocommand group and some autocommands {{{
+" that keep our explorer updated automatically.
+"
+augroup MiniBufExplorer
+autocmd MiniBufExplorer BufDelete   * call <SID>DEBUG('-=> BufDelete AutoCmd', 10) |call <SID>AutoUpdate(expand('<abuf>'))
+autocmd MiniBufExplorer BufEnter    * call <SID>DEBUG('-=> BufEnter  AutoCmd', 10) |call <SID>AutoUpdate(-1)
+autocmd MiniBufExplorer VimEnter    * call <SID>DEBUG('-=> VimEnter  AutoCmd', 10) |let g:miniBufExplorerAutoUpdate = 1 |call <SID>AutoUpdate(-1)
+" }}}
+
+" Functions
+"
+" StartExplorer - Sets up our explorer and causes it to be displayed {{{
+"
+function! <SID>StartExplorer(sticky, delBufNum)
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Entering StartExplorer()'   ,10)
+  call <SID>DEBUG('===========================',10)
+
+  if a:sticky == 1
+    let g:miniBufExplorerAutoUpdate = 1
+  endif
+
+  " Store the current buffer
+  let l:curBuf = bufnr('%')
+
+  " Prevent a report of our actions from showing up.
+  let l:save_rep = &report
+  let l:save_sc  = &showcmd
+  let &report    = 10000
+  set noshowcmd 
+
+  call <SID>FindCreateWindow('-MiniBufExplorer-', -1, 1, 1)
+
+  " Make sure we are in our window
+  if bufname('%') != '-MiniBufExplorer-'
+    call <SID>DEBUG('StartExplorer called in invalid window',1)
+    let &report  = l:save_rep
+    let &showcmd = l:save_sc
+    return
+  endif
+
+  " !!! We may want to make the following optional -- Bindu
+  " New windows don't cause all windows to be resized to equal sizes
+  set noequalalways
+  " !!! We may want to make the following optional -- Bindu
+  " We don't want the mouse to change focus without a click
+  set nomousefocus
+
+  " If folks turn numbering and columns on by default we will turn 
+  " them off for the MBE window
+  setlocal foldcolumn=0
+  setlocal nonumber
+  if has("syntax")
+    syn clear
+    syn match MBENormal             '\[[^\]]*\]'
+    syn match MBEChanged            '\[[^\]]*\]+'
+    syn match MBEVisibleNormal      '\[[^\]]*\]\*+\='
+    syn match MBEVisibleChanged     '\[[^\]]*\]\*+'
+    
+    if !exists("g:did_minibufexplorer_syntax_inits")
+      let g:did_minibufexplorer_syntax_inits = 1
+      hi def link MBENormal         Comment
+      hi def link MBEChanged        String
+      hi def link MBEVisibleNormal  Special
+      hi def link MBEVisibleChanged Special
+    endif
+  endif
+
+  " If you press return in the -MiniBufExplorer- then try
+  " to open the selected buffer in the previous window.
+  nnoremap <buffer> <CR> :call <SID>MBESelectBuffer()<CR>:<BS>
+  " If you DoubleClick in the -MiniBufExplorer- then try
+  " to open the selected buffer in the previous window.
+  nnoremap <buffer> <2-LEFTMOUSE> :call <SID>MBEDoubleClick()<CR>:<BS>
+  " If you press d in the -MiniBufExplorer- then try to
+  " delete the selected buffer.
+  nnoremap <buffer> d :call <SID>MBEDeleteBuffer()<CR>:<BS>
+  " If you press w in the -MiniBufExplorer- then switch back
+  " to the previous window.
+  nnoremap <buffer> p :wincmd p<CR>:<BS>
+  " The following allow us to use regular movement keys to 
+  " scroll in a wrapped single line buffer
+  nnoremap <buffer> j gj
+  nnoremap <buffer> k gk
+  nnoremap <buffer> <down> gj
+  nnoremap <buffer> <up> gk
+  " The following allows for quicker moving between buffer
+  " names in the [MBE] window it also saves the last-pattern
+  " and restores it.
+  nnoremap <buffer> <TAB>   :call search('\[[0-9]*:[^\]]*\]')<CR>:<BS>
+  nnoremap <buffer> <S-TAB> :call search('\[[0-9]*:[^\]]*\]','b')<CR>:<BS>
+  call <SID>DisplayBuffers(a:delBufNum)
+
+  if (l:curBuf != -1)
+    call search('\['.l:curBuf.':'.expand('#'.l:curBuf.':t').'\]')
+  else
+    call <SID>DEBUG('No current buffer to search for',9)
+  endif
+
+  let &report  = l:save_rep
+  let &showcmd = l:save_sc
+
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Completed StartExplorer()'  ,10)
+  call <SID>DEBUG('===========================',10)
+
+endfunction 
+
+" }}}
+" StopExplorer - Looks for our explorer and closes the window if it is open {{{
+"
+function! <SID>StopExplorer(sticky)
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Entering StopExplorer()'    ,10)
+  call <SID>DEBUG('===========================',10)
+
+  if a:sticky == 1
+    let g:miniBufExplorerAutoUpdate = 0
+  endif
+
+  let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+  if l:winNum != -1 
+    exec l:winNum.' wincmd w'
+    silent! close
+    wincmd p
+  endif
+
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Completed StopExplorer()'   ,10)
+  call <SID>DEBUG('===========================',10)
+
+endfunction
+
+" }}}
+" ToggleExplorer - Looks for our explorer and opens/closes the window {{{
+"
+function! <SID>ToggleExplorer()
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Entering ToggleExplorer()'  ,10)
+  call <SID>DEBUG('===========================',10)
+
+  let g:miniBufExplorerAutoUpdate = 0
+
+  let l:winNum = <SID>FindWindow('-MiniBufExplorer-', 1)
+
+  if l:winNum != -1 
+    call <SID>StopExplorer(1)
+  else
+    call <SID>StartExplorer(1, -1)
+    wincmd p
+  endif
+
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Completed ToggleExplorer()' ,10)
+  call <SID>DEBUG('===========================',10)
+
+endfunction
+
+" }}}
+" FindWindow - Return the window number of a named buffer {{{
+" If none is found then returns -1. 
+"
+function! <SID>FindWindow(bufName, doDebug)
+  if a:doDebug
+    call <SID>DEBUG('Entering FindWindow()',10)
+  endif
+
+  " Try to find an existing window that contains 
+  " our buffer.
+  let l:bufNum = bufnr(a:bufName)
+  if l:bufNum != -1
+    if a:doDebug
+      call <SID>DEBUG('Found buffer ('.a:bufName.'): '.l:bufNum,9)
+    endif
+    let l:winNum = bufwinnr(l:bufNum)
+  else
+    let l:winNum = -1
+  endif
+
+  return l:winNum
+
+endfunction
+
+" }}}
+" FindCreateWindow - Attempts to find a window for a named buffer. {{{
+"
+" If it is found then moves there. Otherwise creates a new window and 
+" configures it and moves there.
+"
+" forceEdge, -1 use defaults, 0 below, 1 above
+" isExplorer, 0 no, 1 yes 
+" doDebug, 0 no, 1 yes
+"
+function! <SID>FindCreateWindow(bufName, forceEdge, isExplorer, doDebug)
+  if a:doDebug
+    call <SID>DEBUG('Entering FindCreateWindow('.a:bufName.')',10)
+  endif
+
+  " Save the user's split setting.
+  let l:saveSplitBelow = &splitbelow
+
+  " Set to our new values.
+  let &splitbelow = g:miniBufExplSplitBelow
+
+  " Try to find an existing explorer window
+  let l:winNum = <SID>FindWindow(a:bufName, a:doDebug)
+
+  " If found goto the existing window, otherwise 
+  " split open a new window.
+  if l:winNum != -1
+    if a:doDebug
+      call <SID>DEBUG('Found window ('.a:bufName.'): '.l:winNum,9)
+    endif
+    exec l:winNum.' wincmd w'
+    let l:winFound = 1
+  else
+
+    if g:miniBufExplSplitToEdge == 1 || a:forceEdge >= 0
+
+        let l:edge = &splitbelow
+        if a:forceEdge >= 0
+            let l:edge = a:forceEdge
+        endif
+
+        if l:edge
+            if g:miniBufExplVSplit == 0
+              exec 'bo sp '.a:bufName
+            else
+              exec 'bo vsp '.a:bufName
+            endif
+        else
+            if g:miniBufExplVSplit == 0
+              exec 'to sp '.a:bufName
+            else
+              exec 'to vsp '.a:bufName
+            endif
+        endif
+    else
+        if g:miniBufExplVSplit == 0
+          exec 'sp '.a:bufName
+        else
+          " &splitbelow doesn't affect vertical splits
+          " so we have to do this explicitly.. ugh.
+          if &splitbelow
+            exec 'rightb vsp '.a:bufName
+          else
+            exec 'vsp '.a:bufName
+          endif
+        endif
+    endif
+
+    let g:miniBufExplForceDisplay = 1
+
+    " Try to find an existing explorer window
+    let l:winNum = <SID>FindWindow(a:bufName, a:doDebug)
+    if l:winNum != -1
+      if a:doDebug
+        call <SID>DEBUG('Created and then found window ('.a:bufName.'): '.l:winNum,9)
+      endif
+      exec l:winNum.' wincmd w'
+    else
+      if a:doDebug
+        call <SID>DEBUG('FindCreateWindow failed to create window ('.a:bufName.').',1)
+      endif
+      return
+    endif
+
+    if a:isExplorer
+      " Turn off the swapfile, set the buffer type so that it won't get written,
+      " and so that it will get deleted when it gets hidden and turn on word wrap.
+      setlocal noswapfile
+      setlocal buftype=nofile
+      setlocal bufhidden=delete
+      if g:miniBufExplVSplit == 0
+        setlocal wrap
+      else
+        setlocal nowrap
+        exec('setlocal winwidth='.g:miniBufExplMinSize)
+      endif
+    endif
+
+    if a:doDebug
+      call <SID>DEBUG('Window ('.a:bufName.') created: '.winnr(),9)
+    endif
+
+  endif
+
+  " Restore the user's split setting.
+  let &splitbelow = l:saveSplitBelow
+
+endfunction
+
+" }}}
+" DisplayBuffers - Wrapper for getting MBE window shown {{{
+"
+" Makes sure we are in our explorer, then erases the current buffer and turns 
+" it into a mini buffer explorer window.
+"
+function! <SID>DisplayBuffers(delBufNum)
+  call <SID>DEBUG('Entering DisplayBuffers()',10)
+  
+  " Make sure we are in our window
+  if bufname('%') != '-MiniBufExplorer-'
+    call <SID>DEBUG('DisplayBuffers called in invalid window',1)
+    return
+  endif
+
+  " We need to be able to modify the buffer
+  setlocal modifiable
+
+  call <SID>ShowBuffers(a:delBufNum)
+  call <SID>ResizeWindow()
+  
+  normal! zz
+  
+  " Prevent the buffer from being modified.
+  setlocal nomodifiable
+  set nobuflisted
+
+endfunction
+
+" }}}
+" Resize Window - Set width/height of MBE window {{{
+" 
+" Makes sure we are in our explorer, then sets the height/width for our explorer 
+" window so that we can fit all of our information without taking extra lines.
+"
+function! <SID>ResizeWindow()
+  call <SID>DEBUG('Entering ResizeWindow()',10)
+
+  " Make sure we are in our window
+  if bufname('%') != '-MiniBufExplorer-'
+    call <SID>DEBUG('ResizeWindow called in invalid window',1)
+    return
+  endif
+
+  let l:width  = winwidth('.')
+
+  " Horizontal Resize
+  if g:miniBufExplVSplit == 0
+
+    if g:miniBufExplTabWrap == 0
+      let l:length = strlen(getline('.'))
+      let l:height = 0
+      if (l:width == 0)
+        let l:height = winheight('.')
+      else
+        let l:height = (l:length / l:width) 
+        " handle truncation from div
+        if (l:length % l:width) != 0
+          let l:height = l:height + 1
+        endif
+      endif
+    else
+      exec("setlocal textwidth=".l:width)
+      normal gg
+      normal gq}
+      normal G
+      let l:height = line('.')
+      normal gg
+    endif
+  
+    " enforce max window height
+    if g:miniBufExplMaxSize != 0
+      if g:miniBufExplMaxSize < l:height
+        let l:height = g:miniBufExplMaxSize
+      endif
+    endif
+  
+    " enfore min window height
+    if l:height < g:miniBufExplMinSize || l:height == 0
+      let l:height = g:miniBufExplMinSize
+    endif
+  
+    call <SID>DEBUG('ResizeWindow to '.l:height.' lines',9)
+  
+    exec('resize '.l:height)
+  
+  " Vertical Resize
+  else 
+
+    if g:miniBufExplMaxSize != 0
+      let l:newWidth = s:maxTabWidth
+      if l:newWidth > g:miniBufExplMaxSize 
+          let l:newWidth = g:miniBufExplMaxSize
+      endif
+      if l:newWidth < g:miniBufExplMinSize
+          let l:newWidth = g:miniBufExplMinSize
+      endif
+    else
+      let l:newWidth = g:miniBufExplVSplit
+    endif
+
+    if l:width != l:newWidth
+      call <SID>DEBUG('ResizeWindow to '.l:newWidth.' columns',9)
+      exec('vertical resize '.l:newWidth)
+    endif
+
+  endif
+  
+endfunction
+
+" }}}
+" ShowBuffers - Clear current buffer and put the MBE text into it {{{
+" 
+" Makes sure we are in our explorer, then adds a list of all modifiable 
+" buffers to the current buffer. Special marks are added for buffers that 
+" are in one or more windows (*) and buffers that have been modified (+)
+"
+function! <SID>ShowBuffers(delBufNum)
+  call <SID>DEBUG('Entering ShowBuffers()',10)
+
+  let l:ListChanged = <SID>BuildBufferList(a:delBufNum, 1)
+
+  if (l:ListChanged == 1 || g:miniBufExplForceDisplay)
+    let l:save_rep = &report
+    let l:save_sc = &showcmd
+    let &report = 10000
+    set noshowcmd 
+
+    " Delete all lines in buffer.
+    1,$d _
+  
+    " Goto the end of the buffer put the buffer list 
+    " and then delete the extra trailing blank line
+    $
+    put! =g:miniBufExplBufList
+    $ d _
+
+    let g:miniBufExplForceDisplay = 0
+
+    let &report  = l:save_rep
+    let &showcmd = l:save_sc
+  else
+    call <SID>DEBUG('Buffer list not update since there was no change',9)
+  endif
+  
+endfunction
+
+" }}}
+" Max - Returns the max of two numbers {{{
+"
+function! <SID>Max(argOne, argTwo)
+  if a:argOne > a:argTwo
+    return a:argOne
+  else
+    return a:argTwo
+  endif
+endfunction
+
+" }}}
+" BuildBufferList - Build the text for the MBE window {{{
+" 
+" Creates the buffer list string and returns 1 if it is different than
+" last time this was called and 0 otherwise.
+"
+function! <SID>BuildBufferList(delBufNum, updateBufList)
+  call <SID>DEBUG('Entering BuildBufferList()',10)
+
+  let l:NBuffers = bufnr('$')     " Get the number of the last buffer.
+  let l:i = 0                     " Set the buffer index to zero.
+
+  let l:fileNames = ''
+  let l:maxTabWidth = 0
+
+  " Loop through every buffer less than the total number of buffers.
+  while(l:i <= l:NBuffers)
+    let l:i = l:i + 1
+   
+    " If we have a delBufNum and it is the current
+    " buffer then ignore the current buffer. 
+    " Otherwise, continue.
+    if (a:delBufNum == -1 || l:i != a:delBufNum)
+      " Make sure the buffer in question is listed.
+      if(getbufvar(l:i, '&buflisted') == 1)
+        " Get the name of the buffer.
+        let l:BufName = bufname(l:i)
+        " Check to see if the buffer is a blank or not. If the buffer does have
+        " a name, process it.
+        if(strlen(l:BufName))
+          " Only show modifiable buffers (The idea is that we don't 
+          " want to show Explorers)
+          if (getbufvar(l:i, '&modifiable') == 1 && BufName != '-MiniBufExplorer-')
+            
+            " Get filename & Remove []'s & ()'s
+            let l:shortBufName = fnamemodify(l:BufName, ":t")                  
+            let l:shortBufName = substitute(l:shortBufName, '[][()]', '', 'g') 
+            let l:tab = '['.l:i.':'.l:shortBufName.']'
+
+            " If the buffer is open in a window mark it
+            if bufwinnr(l:i) != -1
+              let l:tab = l:tab . '*'
+            endif
+
+            " If the buffer is modified then mark it
+            if(getbufvar(l:i, '&modified') == 1)
+              let l:tab = l:tab . '+'
+            endif
+
+            let l:maxTabWidth = <SID>Max(strlen(l:tab), l:maxTabWidth)
+            let l:fileNames = l:fileNames.l:tab
+
+            " If horizontal and tab wrap is turned on we need to add spaces
+            if g:miniBufExplVSplit == 0
+              if g:miniBufExplTabWrap != 0
+                let l:fileNames = l:fileNames.' '
+              endif
+            " If not horizontal we need a newline
+            else
+              let l:fileNames = l:fileNames . "\n"
+            endif
+          endif
+        endif
+      endif
+    endif
+  endwhile
+
+  if (g:miniBufExplBufList != l:fileNames)
+    if (a:updateBufList)
+      let g:miniBufExplBufList = l:fileNames
+      let s:maxTabWidth = l:maxTabWidth
+    endif
+    return 1
+  else
+    return 0
+  endif
+
+endfunction
+
+" }}}
+" HasEligibleBuffers - Are there enough MBE eligible buffers to open the MBE window? {{{
+" 
+" Returns 1 if there are any buffers that can be displayed in a 
+" mini buffer explorer. Otherwise returns 0. If delBufNum is
+" any non -1 value then don't include that buffer in the list
+" of eligible buffers.
+"
+function! <SID>HasEligibleBuffers(delBufNum)
+  call <SID>DEBUG('Entering HasEligibleBuffers()',10)
+
+  let l:save_rep = &report
+  let l:save_sc = &showcmd
+  let &report = 10000
+  set noshowcmd 
+  
+  let l:NBuffers = bufnr('$')     " Get the number of the last buffer.
+  let l:i        = 0              " Set the buffer index to zero.
+  let l:found    = 0              " No buffer found
+
+  if (g:miniBufExplorerMoreThanOne > 1)
+    call <SID>DEBUG('More Than One mode turned on',6)
+  endif
+  let l:needed = g:miniBufExplorerMoreThanOne
+
+  " Loop through every buffer less than the total number of buffers.
+  while(l:i <= l:NBuffers && l:found < l:needed)
+    let l:i = l:i + 1
+   
+    " If we have a delBufNum and it is the current
+    " buffer then ignore the current buffer. 
+    " Otherwise, continue.
+    if (a:delBufNum == -1 || l:i != a:delBufNum)
+      " Make sure the buffer in question is listed.
+      if (getbufvar(l:i, '&buflisted') == 1)
+        " Get the name of the buffer.
+        let l:BufName = bufname(l:i)
+        " Check to see if the buffer is a blank or not. If the buffer does have
+        " a name, process it.
+        if (strlen(l:BufName))
+          " Only show modifiable buffers (The idea is that we don't 
+          " want to show Explorers)
+          if ((getbufvar(l:i, '&modifiable') == 1) && (BufName != '-MiniBufExplorer-'))
+            
+              let l:found = l:found + 1
+  
+          endif
+        endif
+      endif
+    endif
+  endwhile
+
+  let &report  = l:save_rep
+  let &showcmd = l:save_sc
+
+  call <SID>DEBUG('HasEligibleBuffers found '.l:found.' eligible buffers of '.l:needed.' needed',6)
+
+  return (l:found >= l:needed)
+  
+endfunction
+
+" }}}
+" Auto Update - Function called by auto commands for auto updating the MBE {{{
+"
+" IF auto update is turned on        AND
+"    we are in a real buffer         AND
+"    we have enough eligible buffers THEN
+" Update our explorer and get back to the current window
+"
+" If we get a buffer number for a buffer that 
+" is being deleted, we need to make sure and 
+" remove the buffer from the list of eligible 
+" buffers in case we are down to one eligible
+" buffer, in which case we will want to close
+" the MBE window.
+"
+function! <SID>AutoUpdate(delBufNum)
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Entering AutoUpdate('.a:delBufNum.') : '.bufnr('%').' : '.bufname('%'),10)
+  call <SID>DEBUG('===========================',10)
+
+  if (g:miniBufExplInAutoUpdate == 1)
+    call <SID>DEBUG('AutoUpdate recursion stopped',9)
+    call <SID>DEBUG('===========================',10)
+    call <SID>DEBUG('Terminated AutoUpdate()'    ,10)
+    call <SID>DEBUG('===========================',10)
+    return
+  else
+    let g:miniBufExplInAutoUpdate = 1
+  endif
+
+  " Don't bother autoupdating the MBE window
+  if (bufname('%') == '-MiniBufExplorer-')
+    " If this is the only buffer left then toggle the buffer
+    if (winbufnr(2) == -1)
+        call <SID>CycleBuffer(1)
+        call <SID>DEBUG('AutoUpdate does not run for cycled windows', 9)
+    else
+      call <SID>DEBUG('AutoUpdate does not run for the MBE window', 9)
+    endif
+
+    call <SID>DEBUG('===========================',10)
+    call <SID>DEBUG('Terminated AutoUpdate()'    ,10)
+    call <SID>DEBUG('===========================',10)
+
+    let g:miniBufExplInAutoUpdate = 0
+    return
+
+  endif
+
+  if (a:delBufNum != -1)
+    call <SID>DEBUG('AutoUpdate will make sure that buffer '.a:delBufNum.' is not included in the buffer list.', 5)
+  endif
+  
+  " Only allow updates when the AutoUpdate flag is set
+  " this allows us to stop updates on startup.
+  if g:miniBufExplorerAutoUpdate == 1
+    " Only show MiniBufExplorer if we have a real buffer
+    if ((g:miniBufExplorerMoreThanOne == 0) || (bufnr('%') != -1 && bufname('%') != ""))
+      if <SID>HasEligibleBuffers(a:delBufNum) == 1
+        " if we don't have a window then create one
+        let l:bufnr = <SID>FindWindow('-MiniBufExplorer-', 0)
+        if (l:bufnr == -1)
+          call <SID>DEBUG('About to call StartExplorer (Create MBE)', 9)
+          call <SID>StartExplorer(0, a:delBufNum)
+        else
+        " otherwise only update the window if the contents have
+        " changed
+          let l:ListChanged = <SID>BuildBufferList(a:delBufNum, 0)
+          if (l:ListChanged)
+            call <SID>DEBUG('About to call StartExplorer (Update MBE)', 9) 
+            call <SID>StartExplorer(0, a:delBufNum)
+          endif
+        endif
+
+        " go back to the working buffer
+        if (bufname('%') == '-MiniBufExplorer-')
+          wincmd p
+        endif
+      else
+        call <SID>DEBUG('Failed in eligible check', 9)
+        call <SID>StopExplorer(0)
+      endif
+
+         " VIM sometimes turns syntax highlighting off,
+         " we can force it on, but this may cause weird
+         " behavior so this is an optional hack to force
+         " syntax back on when we enter a buffer
+         if g:miniBufExplForceSyntaxEnable
+               call <SID>DEBUG('Enable Syntax', 9)
+               exec 'syntax enable'
+         endif
+
+    else
+      call <SID>DEBUG('No buffers loaded...',9)
+    endif
+  else
+    call <SID>DEBUG('AutoUpdates are turned off, terminating',9)
+  endif
+
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Completed AutoUpdate()'     ,10)
+  call <SID>DEBUG('===========================',10)
+
+  let g:miniBufExplInAutoUpdate = 0
+
+endfunction
+
+" }}}
+" GetSelectedBuffer - From the MBE window, return the bufnum for buf under cursor {{{
+" 
+" If we are in our explorer window then return the buffer number
+" for the buffer under the cursor.
+"
+function! <SID>GetSelectedBuffer()
+  call <SID>DEBUG('Entering GetSelectedBuffer()',10)
+
+  " Make sure we are in our window
+  if bufname('%') != '-MiniBufExplorer-'
+    call <SID>DEBUG('GetSelectedBuffer called in invalid window',1)
+    return -1
+  endif
+
+  let l:save_reg = @"
+  let @" = ""
+  normal ""yi[
+  if @" != ""
+    let l:retv = substitute(@",'\([0-9]*\):.*', '\1', '') + 0
+    let @" = l:save_reg
+    return l:retv
+  else
+    let @" = l:save_reg
+    return -1
+  endif
+
+endfunction
+
+" }}}
+" MBESelectBuffer - From the MBE window, open buffer under the cursor {{{
+" 
+" If we are in our explorer, then we attempt to open the buffer under the
+" cursor in the previous window.
+"
+function! <SID>MBESelectBuffer()
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Entering MBESelectBuffer()' ,10)
+  call <SID>DEBUG('===========================',10)
+
+  " Make sure we are in our window
+  if bufname('%') != '-MiniBufExplorer-'
+    call <SID>DEBUG('MBESelectBuffer called in invalid window',1)
+    return 
+  endif
+
+  let l:save_rep = &report
+  let l:save_sc  = &showcmd
+  let &report    = 10000
+  set noshowcmd 
+  
+  let l:bufnr  = <SID>GetSelectedBuffer()
+  let l:resize = 0
+
+  if(l:bufnr != -1)             " If the buffer exists.
+
+    let l:saveAutoUpdate = g:miniBufExplorerAutoUpdate
+    let g:miniBufExplorerAutoUpdate = 0
+    " Switch to the previous window
+    wincmd p
+
+    " If we are in the buffer explorer or in a nonmodifiable buffer with
+    " g:miniBufExplModSelTarget set then try another window (a few times)
+    if bufname('%') == '-MiniBufExplorer-' || (g:miniBufExplModSelTarget == 1 && getbufvar(bufnr('%'), '&modifiable') == 0)
+      wincmd w
+      if bufname('%') == '-MiniBufExplorer-' || (g:miniBufExplModSelTarget == 1 && getbufvar(bufnr('%'), '&modifiable') == 0)
+        wincmd w
+        if bufname('%') == '-MiniBufExplorer-' || (g:miniBufExplModSelTarget == 1 && getbufvar(bufnr('%'), '&modifiable') == 0)
+          wincmd w
+          " The following handles the case where -MiniBufExplorer-
+          " is the only window left. We need to resize so we don't
+          " end up with a 1 or two line buffer.
+          if bufname('%') == '-MiniBufExplorer-'
+            let l:resize = 1
+          endif
+        endif
+      endif
+    endif
+
+    exec('b! '.l:bufnr)
+    if (l:resize)
+      resize
+    endif
+    let g:miniBufExplorerAutoUpdate = l:saveAutoUpdate
+    call <SID>AutoUpdate(-1)
+
+  endif
+
+  let &report  = l:save_rep
+  let &showcmd = l:save_sc
+
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Completed MBESelectBuffer()',10)
+  call <SID>DEBUG('===========================',10)
+
+endfunction
+
+" }}}
+" MBEDeleteBuffer - From the MBE window, delete selected buffer from list {{{
+" 
+" After making sure that we are in our explorer, This will delete the buffer 
+" under the cursor. If the buffer under the cursor is being displayed in a
+" window, this routine will attempt to get different buffers into the 
+" windows that will be affected so that windows don't get removed.
+"
+function! <SID>MBEDeleteBuffer()
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Entering MBEDeleteBuffer()' ,10)
+  call <SID>DEBUG('===========================',10)
+
+  " Make sure we are in our window
+  if bufname('%') != '-MiniBufExplorer-'
+    call <SID>DEBUG('MBEDeleteBuffer called in invalid window',1)
+    return 
+  endif
+
+  let l:curLine    = line('.')
+  let l:curCol     = virtcol('.')
+  let l:selBuf     = <SID>GetSelectedBuffer()
+  let l:selBufName = bufname(l:selBuf)
+
+  if l:selBufName == 'MiniBufExplorer.DBG' && g:miniBufExplorerDebugLevel > 0
+    call <SID>DEBUG('MBEDeleteBuffer will not delete the debug window, when debugging is turned on.',1)
+    return
+  endif
+
+  let l:save_rep = &report
+  let l:save_sc  = &showcmd
+  let &report    = 10000
+  set noshowcmd 
+  
+  
+  if l:selBuf != -1 
+
+    " Don't want auto updates while we are processing a delete
+    " request.
+    let l:saveAutoUpdate = g:miniBufExplorerAutoUpdate
+    let g:miniBufExplorerAutoUpdate = 0
+
+    " Save previous window so that if we show a buffer after
+    " deleting. The show will come up in the correct window.
+    wincmd p
+    let l:prevWin    = winnr()
+    let l:prevWinBuf = winbufnr(winnr())
+
+    call <SID>DEBUG('Previous window: '.l:prevWin.' buffer in window: '.l:prevWinBuf,5)
+    call <SID>DEBUG('Selected buffer is <'.l:selBufName.'>['.l:selBuf.']',5)
+
+    " If buffer is being displayed in a window then 
+    " move window to a different buffer before 
+    " deleting this one. 
+    let l:winNum = (bufwinnr(l:selBufName) + 0)
+    " while we have windows that contain our buffer
+    while l:winNum != -1 
+        call <SID>DEBUG('Buffer '.l:selBuf.' is being displayed in window: '.l:winNum,5)
+
+        " move to window that contains our selected buffer
+        exec l:winNum.' wincmd w'
+
+        call <SID>DEBUG('We are now in window: '.winnr().' which contains buffer: '.bufnr('%').' and should contain buffer: '.l:selBuf,5)
+
+        let l:origBuf = bufnr('%')
+        call <SID>CycleBuffer(1)
+        let l:curBuf  = bufnr('%')
+
+        call <SID>DEBUG('Window now contains buffer: '.bufnr('%').' which should not be: '.l:selBuf,5)
+
+        if l:origBuf == l:curBuf
+            " we wrapped so we are going to have to delete a buffer 
+            " that is in an open window.
+            let l:winNum = -1
+        else
+            " see if we have anymore windows with our selected buffer
+            let l:winNum = (bufwinnr(l:selBufName) + 0)
+        endif
+    endwhile
+
+    " Attempt to restore previous window
+    call <SID>DEBUG('Restoring previous window to: '.l:prevWin,5)
+    exec l:prevWin.' wincmd w'
+
+    " Try to get back to the -MiniBufExplorer- window 
+    let l:winNum = bufwinnr(bufnr('-MiniBufExplorer-'))
+    if l:winNum != -1
+        exec l:winNum.' wincmd w'
+        call <SID>DEBUG('Got to -MiniBufExplorer- window: '.winnr(),5)
+    else
+        call <SID>DEBUG('Unable to get to -MiniBufExplorer- window',1)
+    endif
+  
+    " Delete the buffer selected.
+    call <SID>DEBUG('About to delete buffer: '.l:selBuf,5)
+    exec('silent! bd '.l:selBuf)
+
+    let g:miniBufExplorerAutoUpdate = l:saveAutoUpdate 
+    call <SID>DisplayBuffers(-1)
+    call cursor(l:curLine, l:curCol)
+
+  endif
+
+  let &report  = l:save_rep
+  let &showcmd = l:save_sc
+
+  call <SID>DEBUG('===========================',10)
+  call <SID>DEBUG('Completed MBEDeleteBuffer()',10)
+  call <SID>DEBUG('===========================',10)
+
+endfunction
+
+" }}}
+" MBEClick - Handle mouse double click {{{
+"
+function! s:MBEClick()
+  call <SID>DEBUG('Entering MBEClick()',10)
+  call <SID>MBESelectBuffer()
+endfunction
+
+"
+" MBEDoubleClick - Double click with the mouse.
+"
+function! s:MBEDoubleClick()
+  call <SID>DEBUG('Entering MBEDoubleClick()',10)
+  call <SID>MBESelectBuffer()
+endfunction
+
+" }}}
+" CycleBuffer - Cycle Through Buffers {{{
+"
+" Move to next or previous buffer in the current window. If there 
+" are no more modifiable buffers then stay on the current buffer.
+" can be called with no parameters in which case the buffers are
+" cycled forward. Otherwise a single argument is accepted, if 
+" it's 0 then the buffers are cycled backwards, otherwise they
+" are cycled forward.
+"
+function! <SID>CycleBuffer(forward)
+
+  " The following hack handles the case where we only have one
+  " window open and it is too small
+  let l:saveAutoUpdate = g:miniBufExplorerAutoUpdate
+  if (winbufnr(2) == -1)
+    resize
+    let g:miniBufExplorerAutoUpdate = 0
+  endif
+  
+  " Change buffer (keeping track of before and after buffers)
+  let l:origBuf = bufnr('%')
+  if (a:forward == 1)
+    bn!
+  else
+    bp!
+  endif
+  let l:curBuf  = bufnr('%')
+
+  " Skip any non-modifiable buffers, but don't cycle forever
+  " This should stop us from stopping in any of the [Explorers]
+  while getbufvar(l:curBuf, '&modifiable') == 0 && l:origBuf != l:curBuf
+    if (a:forward == 1)
+        bn!
+    else
+        bp!
+    endif
+    let l:curBuf = bufnr('%')
+  endwhile
+
+  let g:miniBufExplorerAutoUpdate = l:saveAutoUpdate
+  if (l:saveAutoUpdate == 1)
+    call <SID>AutoUpdate(-1)
+  endif
+
+endfunction
+
+" }}}
+" DEBUG - Display debug output when debugging is turned on {{{
+"
+" Thanks to Charles E. Campbell, Jr. PhD <cec@NgrOyphSon.gPsfAc.nMasa.gov> 
+" for Decho.vim which was the inspiration for this enhanced debugging 
+" capability.
+"
+function! <SID>DEBUG(msg, level)
+
+  if g:miniBufExplorerDebugLevel >= a:level
+
+    " Prevent a report of our actions from showing up.
+    let l:save_rep    = &report
+    let l:save_sc     = &showcmd
+    let &report       = 10000
+    set noshowcmd 
+
+    " Debug output to a buffer
+    if g:miniBufExplorerDebugMode == 0
+        " Save the current window number so we can come back here
+        let l:prevWin     = winnr()
+        wincmd p
+        let l:prevPrevWin = winnr()
+        wincmd p
+
+        " Get into the debug window or create it if needed
+        call <SID>FindCreateWindow('MiniBufExplorer.DBG', 1, 0, 0)
+    
+        " Make sure we really got to our window, if not we 
+        " will display a confirm dialog and turn debugging
+        " off so that we won't break things even more.
+        if bufname('%') != 'MiniBufExplorer.DBG'
+            call confirm('Error in window debugging code. Dissabling MiniBufExplorer debugging.', 'OK')
+            let g:miniBufExplorerDebugLevel = 0
+        endif
+
+        " Write Message to DBG buffer
+        let res=append("$",s:debugIndex.':'.a:level.':'.a:msg)
+        norm G
+        "set nomodified
+
+        " Return to original window
+        exec l:prevPrevWin.' wincmd w'
+        exec l:prevWin.' wincmd w'
+    " Debug output using VIM's echo facility
+    elseif g:miniBufExplorerDebugMode == 1
+      echo s:debugIndex.':'.a:level.':'.a:msg
+    " Debug output to a file -- VERY SLOW!!!
+    " should be OK on UNIX and Win32 (not the 95/98 variants)
+    elseif g:miniBufExplorerDebugMode == 2
+        if has('system') || has('fork')
+            if has('win32') && !has('win95')
+                let l:result = system("cmd /c 'echo ".s:debugIndex.':'.a:level.':'.a:msg." >> MiniBufExplorer.DBG'")
+            endif
+            if has('unix')
+                let l:result = system("echo '".s:debugIndex.':'.a:level.':'.a:msg." >> MiniBufExplorer.DBG'")
+            endif
+        else
+            call confirm('Error in file writing version of the debugging code, vim not compiled with system or fork. Dissabling MiniBufExplorer debugging.', 'OK')
+            let g:miniBufExplorerDebugLevel = 0
+        endif
+    elseif g:miniBufExplorerDebugMode == 3
+        let g:miniBufExplorerDebugOutput = g:miniBufExplorerDebugOutput."\n".s:debugIndex.':'.a:level.':'.a:msg
+    endif
+    let s:debugIndex = s:debugIndex + 1
+
+    let &report  = l:save_rep
+    let &showcmd = l:save_sc
+
+  endif
+
+endfunc " }}}
+
+" MBE Script History {{{
+"=============================================================================
+"
+"      History: 6.3.2 o For some reason there was still a call to StopExplorer
+"                       with 2 params. Very old bug. I know I fixed before, 
+"                       any way many thanks to Jason Mills for reporting this!
+"               6.3.1 o Include folds in source so that it's easier to 
+"                       navigate.
+"                     o Added g:miniBufExplForceSyntaxEnable setting for folks
+"                       that want a :syntax enable to be called when we enter 
+"                       buffers. This can resolve issues caused by a vim bug
+"                       where buffers show up without highlighting when another 
+"                       buffer has been closed, quit, wiped or deleted.
+"               6.3.0 o Added an option to allow single click (rather than
+"                       the default double click) to select buffers in the
+"                       MBE window. This feature was requested by AW Law
+"                       and was inspired by taglist.vim. Note that you will 
+"                       need the latest version of taglist.vim if you want to 
+"                       use MBE and taglist both with singleclick turned on.
+"                       Also thanks to AW Law for pointing out that you can
+"                       make an Explorer not be listed in a standard :ls.
+"                     o Added the ability to have your tabs show up in a
+"                       vertical window rather than the standard horizontal
+"                       one. Just let g:miniBufExplVSplit = <width> in your
+"                       .vimrc and your will get this functionality.
+"                     o If you use the vertical explorer and you want it to
+"                       autosize then let g:miniBufExplMaxSize = <max width>
+"                       in your .vimrc. You may use the MinSize letting in
+"                       addition to the MaxLetting if you don't want a super
+"                       thin window.
+"                     o g:miniBufExplMaxHeight was renamed g:miniBufExplMaxSize
+"                       g:miniBufExplMinHeight was renamed g:miniBufExplMinSize
+"                       the old settings are backwards compatible if you don't
+"                       use the new settings, but they are depreciated.
+"               6.2.8 o Add an option to stop MBE from targeting non-modifiable
+"                       buffers when switching buffers. Thanks to AW Law for
+"                       the inspiration for this. This may not work if a user
+"                       has lots of explorer/help windows open.
+"               6.2.7 o Very minor bug fix for people who want to set
+"                       loaded_minibufexplorer in their .vimrc in order to
+"                       stop MBE from loading. 99.99% of users do not need
+"                       this update.
+"               6.2.6 o Moved history to end of source file
+"                     o Updated highlighting documentation
+"                     o Created global commands MBEbn and MBEbp that can be 
+"                       used in mappings if folks want to cycle buffers while 
+"                       skipping non-eligible buffers.
+"               6.2.5 o Added <Leader>mbt key mapping which will toggle
+"                       the MBE window. I map this to F3 in my .vimrc
+"                       with "map <F3> :TMiniBufExplorer<CR>" which 
+"                       means I can easily close the MBE window when I'm 
+"                       not using it and get it back when I want it.
+"                     o Changed default debug mode to 3 (write to global
+"                       g:miniBufExplorerDebugOutput)
+"                     o Made a pass through the documentation to clarify 
+"                       serveral issues and provide more complete docs
+"                       for mappings and commands.
+"               6.2.4 o Because of the autocommand switch (see 6.2.0) it 
+"                       was possible to remove the restriction on the
+"                       :set hidden option. It is now possible to use
+"                       this option with MBE.
+"               6.2.3 o Added miniBufExplTabWrap option. It is turned 
+"                       off by default. When turned on spaces are added
+"                       between tabs and gq} is issued to perform line
+"                       formatting. This won't work very well if filenames
+"                       contain spaces. It would be pretty easy to write
+"                       my own formatter, but I'm too lazy, so if someone
+"                       really needs that feature I'll add it :)
+"               6.2.2 o Changed the way the g:miniBufExplorerMoreThanOne
+"                       global is handled. You can set this to the number
+"                       of eligible buffers you want to be loaded before
+"                       the MBE window is loaded. Setting it to 0 causes
+"                       the MBE window to be opened even if there are no
+"                       buffers. Setting it to 4 causes the window to stay
+"                       closed until the 4th eligible buffer is loaded.
+"                     o Added a MinHeight option. This is nice if you want
+"                       the MBE window to always take the same amount of
+"                       space. For example set MaxSize and MinSize to 2
+"                       and set MoreThanOne to 0 and you will always have
+"                       a 2 row (plus the ruler :) MBE window.
+"                       NOTE: in 6.3.0 we started using MinSize instead of
+"                       Minheight. This will still work if MinSize is not
+"                       specified, but it is depreciated. Use MinSize instead.
+"                     o I now setlocal foldcomun=0 and nonumber in the MBE 
+"                       window. This is for those of you that like to have
+"                       these options turned on locally. I'm assuming noone
+"                       outthere wants foldcolumns and line numbers in the
+"                       MBE window? :)
+"                     o Fixed a bug where an empty MBE window was taking half
+"                       of the screen (partly why the MinHeight option was 
+"                       added.)
+"               6.2.1 o If MBE is the only window (because of :bd for example)
+"                       and there are still eligible buffers then one of them
+"                       will be displayed.
+"                     o The <Leader>mbe mapping now highlights the buffer from
+"                       the current window.
+"                     o The delete ('d') binding in the MBE window now restors
+"                       the cursor position, which can help if you want to 
+"                       delete several buffers in a row that are not at the
+"                       beginning of the buffer list.
+"                     o Added a new key binding ('p') in the MBE window to 
+"                       switch to the previous window (last edit window)
+"               6.2.0 o Major overhaul of autocommand and list updating code,
+"                       we now have much better handling of :bd (which is the 
+"                       most requested feature.) As well as resolving other
+"                       issues where the buffer list would not be updated
+"                       automatically. The old version tried to trap specific
+"                       events, this one just updates frequently, but it keeps
+"                       track and only changes the screen if there has been
+"                       a change.
+"                     o Added g:miniBufExplMaxHeight variable so you can keep
+"                       the -MiniBufExplorer- window small when you have lots
+"                       of buffers (or buffers with long names :)
+"                       NOTE: in 6.3.0 we started using MaxSize instead of
+"                       MaxHeight. This will still work if MaxSize is not
+"                       specified, but it is depreciated. Use MaxSize instead.
+"                     o Improvement to internal syntax highlighting code
+"                       I renamed the syntax group names. Anyone who has 
+"                       figured out how to use them already shouldn't have
+"                       any trouble with the new Nameing :)
+"                     o Added debug mode 3 which writes to a global variable
+"                       this is fast and doesn't mess with the buffer/window
+"                       lists.
+"               6.1.0 o <Leader>mbc was failing because I was calling one of
+"                       my own functions with the wrong number of args. :(
+"                       Thanks to Gerry Patterson for finding this!
+"                       This code is very stable (although it has some
+"                       idiocyncracies.)
+"               6.0.9 o Double clicking tabs was overwriting the cliboard 
+"                       register on MS Windows.  Thanks to Shoeb Bhinderwala 
+"                       for reporting this issue.
+"               6.0.8 o Apparently some VIM builds are having a hard time with
+"                       line continuation in scripts so the few that were here
+"                       have been removed.
+"                     o Generalized FindExplorer and FindCreateExplorer so
+"                       that they can be used for the debug window. Renaming
+"                       to FindWindow and FindCreateWindow.
+"                     o Updated debugging code so that debug output is put into
+"                       a buffer which can then be written to disk or emailed
+"                       to me when someone is having a major issue. Can also
+"                       write directly to a file (VERY SLOWLY) on UNIX or Win32
+"                       (not 95 or 98 at the moment) or use VIM's echo function 
+"                       to display the output to the screen.
+"                     o Several people have had issues when the hidden option 
+"                       is turned on. So I have put in several checks to make
+"                       sure folks know this if they try to use MBE with this
+"                       option set.
+"               6.0.7 o Handling BufDelete autocmd so that the UI updates 
+"                       properly when using :bd (rather than going through 
+"                       the MBE UI.)
+"                     o The AutoUpdate code will now close the MBE window when 
+"                       there is a single eligible buffer available.
+"                       This has the usefull side effect of stopping the MBE
+"                       window from blocking the VIM session open when you close 
+"                       the last buffer.
+"                     o Added functions, commands and maps to close & update
+"                       the MBE window (<leader>mbc and <leader>mbu.)
+"                     o Made MBE open/close state be sticky if set through
+"                       StartExplorer(1) or StopExplorer(1), which are 
+"                       called from the standard mappings. So if you close
+"                       the mbe window with \mbc it won't be automatically 
+"                       opened again unless you do a \mbe (or restart VIM).
+"                     o Removed spaces between "tabs" (even more mini :)
+"                     o Simplified MBE tab processing 
+"               6.0.6 o Fixed register overwrite bug found by Sébastien Pierre
+"               6.0.5 o Fixed an issue with window sizing when we run out of 
+"                       buffers.  
+"                     o Fixed some weird commenting bugs.  
+"                     o Added more optional fancy window/buffer navigation:
+"                     o You can turn on the capability to use control and the 
+"                       arrow keys to move between windows.
+"                     o You can turn on the ability to use <C-TAB> and 
+"                       <C-S-TAB> to open the next and previous (respectively) 
+"                       buffer in the current window.
+"                     o You can turn on the ability to use <C-TAB> and 
+"                       <C-S-TAB> to switch windows (forward and backwards 
+"                       respectively.)
+"               6.0.4 o Added optional fancy window navigation: 
+"                     o Holding down control and pressing a vim direction 
+"                       [hjkl] will switch windows in the indicated direction.
+"               6.0.3 o Changed buffer name to -MiniBufExplorer- to resolve
+"                       Issue in filename pattern matching on Windows.
+"               6.0.2 o 2 Changes requested by Suresh Govindachar:
+"                     o Added SplitToEdge option and set it on by default
+"                     o Added tab and shift-tab mappings in [MBE] window
+"               6.0.1 o Added MoreThanOne option and set it on by default
+"                       MiniBufExplorer will not automatically open until
+"                       more than one eligible buffers are opened. This
+"                       reduces cluter when you are only working on a
+"                       single file. 
+"                       NOTE: See change log for 6.2.2 for more details about 
+"                             this feature
+"               6.0.0 o Initial Release on November 20, 2001
+"
+"=============================================================================
+" }}}
+" vim:ft=vim:fdm=marker:ff=unix:nowrap:tabstop=4:shiftwidth=4:softtabstop=4:smarttab:shiftround:expandtab
diff --git a/vim/plugin/qname.vim b/vim/plugin/qname.vim
new file mode 100644 (file)
index 0000000..0556d75
--- /dev/null
@@ -0,0 +1,239 @@
+if !exists("g:qname_hotkey") || g:qname_hotkey == ""
+       let g:qname_hotkey = "<F3>"
+endif
+exe "nmap" g:qname_hotkey ":cal QNameInit(1)<cr>:~"
+let s:qname_hotkey = eval('"\'.g:qname_hotkey.'"')
+
+if exists("g:qname_loaded") && g:qname_loaded
+       finish
+endif
+let g:qname_loaded = 1
+
+function! QNameRun()
+       cal s:colPrinter.print()
+       echo "\rMatch" len(s:n)."/".len(s:ls) "names:" s:inp
+       call inputsave()
+       let _key = getchar()
+       if !type(_key)
+               let _key = nr2char(_key)
+       endif
+
+       if _key == "\<BS>"
+               let s:inp = s:inp[:-2]
+       elseif strlen(_key) == 1 && char2nr(_key) > 31
+               let s:inp = s:inp._key
+       endif
+       if _key == "\<ESC>" || _key == "\<CR>"
+               let _sel = s:colPrinter.sel
+               if _key == "\<CR>" && _sel < len(s:n) && _sel >= 0
+                       call s:swb(matchstr(s:s[_sel], '<\zs\d\+\ze>'),"")
+               endif
+               cal QNameInit(0)
+       elseif _key == "\<Up>"
+               cal s:colPrinter.vert(-1)
+       elseif _key == "\<Down>"
+               cal s:colPrinter.vert(1)
+       elseif _key == "\<Left>"
+               cal s:colPrinter.horz(-1)
+       elseif _key == "\<Right>"
+               cal s:colPrinter.horz(1)
+       elseif _key == s:qname_hotkey
+               cal QNameInit(0)
+       else
+               cal s:build()
+       endif
+       redraws
+       call inputrestore()
+endfunc
+
+function! QNameInit(start)
+       if a:start
+               cmap ~ cal QNameRun()<CR>:~
+               let s:pro = "Prompt: "
+               let s:cmdh = &cmdheight
+               if a:start != -1
+                       let s:inp = ""
+               endif
+               call s:baselist()
+               call s:build()
+               exe "set cmdheight=".(s:colPrinter.trow+1)
+       else
+               cmap ~ exe "cunmap \x7E"<cr>
+               exe "set cmdheight=".s:cmdh
+        endif
+endfunc
+
+function! s:build()
+       let s:s = []
+       let s:n = []
+       let s:blen = 0
+       let _cmp = tolower(tr(s:inp, '\', '/'))
+       for _line in s:ls
+               let _name = matchstr(_line, '^.\{-}\ze \+<')
+               if s:fmatch(tolower(_name), _cmp)
+                       cal add(s:s, _line)
+                       cal add(s:n, _name)
+               endif
+       endfor
+       if len(s:n) > s:colPrinter.trow
+               cal s:colPrinter.put(s:n)
+       else
+               cal s:colPrinter.put(s:s)
+       endif
+endfunc
+
+function! s:swb(bno,mod)
+       if bufwinnr(a:bno) == -1
+               exe "hid b".a:mod a:bno
+       else
+               exe bufwinnr(a:bno) . "winc w"
+       endif
+endfunc 
+
+function! s:fmatch(src,pat)
+       let _si = strlen(a:src)-1
+       let _pi = strlen(a:pat)-1
+       while _si>=0 && _pi>=0
+               if a:src[_si] == a:pat[_pi]
+                       let _pi -= 1
+               endif
+               let _si -= 1
+       endwhile
+       return _pi < 0
+endfunc
+
+function! s:baselist()
+       let s:ls = []
+       redir @y | silent ls! | redir END
+       for _line in split(@y,"\n")
+               if _line[3]!='u' || _line[6]!='-'
+                       let _bno = matchstr(_line, '^ *\zs\d*')+0
+                       let _fname = substitute(expand("#"._bno.":p"), '\', '/', 'g')
+                       if _fname == ""
+                               let _fname = "\xA0".matchstr(_line, '"\zs[^"]*')
+                       endif
+                       let _name = fnamemodify(_fname,":t")
+                       cal add(s:ls, _name." <"._bno."> ".fnamemodify(_fname,":h"))
+               endif
+       endfor
+       let _align = max(map(copy(s:ls),'stridx(v:val,">")'))
+       call map(s:ls, 'substitute(v:val, " <", repeat(" ",_align-stridx(v:val,">"))." <", "")')
+       cal sort(s:ls, 1)
+endfunc
+
+let s:colPrinter = {"trow": 4}
+function! s:colPrinter.put(its) dict
+       let _cols = []
+       let _trow = self.trow
+
+       let _its = copy(a:its)
+       let _len = len(_its)
+       let _i = 0
+       while _i < _len
+               if _i+_trow <= _len
+                       cal add(_cols, remove(_its,0,_trow-1))
+               else
+                       cal add(_cols, _its)
+               endif
+               let _i += _trow
+       endwhile
+
+       let _cpos = [0]
+       let _cw = []
+       let _t = 0
+       for _li in _cols
+               let _w = max(map(copy(_li),'strlen(v:val)'))+4
+               let _t += _w
+               cal add(_cpos,_t)
+               cal add(_cw,_w)
+       endfor
+
+       let _rows = []
+       for _i in range(_trow)
+               let _row = []
+               for _j in range(len(_cols))
+                       if _j*_trow+_i < _len
+                               cal add(_row,_cols[_j][_i])
+                       endif
+               endfor
+               cal add(_rows, _row)
+       endfor
+
+       let self.cols = _cols
+       let self.cw = _cw
+       let self.rows = _rows
+       let self.cpos = _cpos
+       let self.len = _len
+       let self.lcol = 0
+       let self.sel = 0
+endfunc
+
+function! s:colPrinter.horz(mv) dict
+       let _t = self.sel + a:mv*self.trow
+       if _t >= 0 && _t < self.len
+               let self.sel = _t
+       endif
+endfunc
+
+function! s:colPrinter.vert(mv) dict
+       let _t = self.sel + a:mv
+       let _len = self.len
+       if _t < 0 && _len > 0
+               let self.sel = _len-1
+       elseif _t >= _len
+               let self.sel = 0
+       else
+               let self.sel = _t
+       endif
+endfunc
+
+function! s:colPrinter.print() dict
+       let _len = self.len
+       let _trow = self.trow
+       if !_len
+               echo "  [...NO MATCH...]" repeat("\n",_trow)
+               return
+       endif
+       let _sel = self.sel
+       let _t = _sel/_trow
+       let _cpos = self.cpos
+       let _lcol = self.lcol
+       let _tcol = &columns
+       if _cpos[_lcol]+_tcol < _cpos[_t+1]
+               let _rcol = _t
+               let _pos = _cpos[_t+1]-_tcol-2
+               while _cpos[_lcol] < _pos
+                       let _lcol += 1
+               endwhile
+               let _lcol -= _lcol > _t
+       else
+               if _t < _lcol
+                       let _lcol = _t
+               endif
+               let _rcol = len(_cpos)-1
+               let _pos = _cpos[_lcol]+_tcol+2
+               while _cpos[_rcol] > _pos
+                       let _rcol -= 1
+               endwhile
+               let _rcol -= _rcol > _lcol
+       endif
+       let _cw = self.cw
+       let _pos = _cpos[_lcol]+_tcol
+       let self.lcol = _lcol
+       for _i in range(_trow)
+               let _row = self.rows[_i]
+               for _j in range(_lcol,_rcol)
+                       if _j*_trow+_i < _len
+                               let _txt = "  " . _row[_j]
+                               let _txt .= repeat(" ", _cw[_j] - strlen(_txt))
+                               let _txt = _txt[:_pos-_cpos[_j]-2]
+                               if _j*_trow + _i == _sel
+                                       echoh Search|echon _txt|echoh None
+                               else
+                                       echon _txt
+                               endif
+                       endif
+               endfor
+               echon "\n"
+       endfor
+endfunc
diff --git a/vim/plugin/repeat.vim b/vim/plugin/repeat.vim
new file mode 100644 (file)
index 0000000..e6ec409
--- /dev/null
@@ -0,0 +1,72 @@
+" repeat.vim - Let the repeat command repeat plugin maps
+" Maintainer:   Tim Pope
+" Version:      1.0
+
+" Installation:
+" Place in either ~/.vim/plugin/repeat.vim (to load at start up) or
+" ~/.vim/autoload/repeat.vim (to load automatically as needed).
+"
+" Developers:
+" Basic usage is as follows:
+"
+"   silent! call repeat#set("\<Plug>MappingToRepeatCommand",3)
+"
+" The first argument is the mapping that will be invoked when the |.| key is
+" pressed.  Typically, it will be the same as the mapping the user invoked.
+" This sequence will be stuffed into the input queue literally.  Thus you must
+" encode special keys by prefixing them with a backslash inside double quotes.
+"
+" The second argument is the default count.  This is the number that will be
+" prefixed to the mapping if no explicit numeric argument was given.  The
+" value of the v:count variable is usually correct and it will be used if the
+" second parameter is omitted.  If your mapping doesn't accept a numeric
+" argument and you never want to receive one, pass a value of -1.
+"
+" Make sure to call the repeat#set function _after_ making changes to the
+" file.
+
+if exists("g:loaded_repeat") || &cp || v:version < 700
+    finish
+endif
+let g:loaded_repeat = 1
+
+let g:repeat_tick = -1
+
+function! repeat#set(sequence,...)
+    silent exe "norm! \"=''\<CR>p"
+    let g:repeat_sequence = a:sequence
+    let g:repeat_count = a:0 ? a:1 : v:count
+    let g:repeat_tick = b:changedtick
+endfunction
+
+function! s:repeat(count)
+    if g:repeat_tick == b:changedtick
+        let c = g:repeat_count
+        let s = g:repeat_sequence
+        let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : ''))
+        call feedkeys(cnt . s)
+    else
+        call feedkeys((a:count ? a:count : '') . '.', 'n')
+    endif
+endfunction
+
+function! s:wrap(command,count)
+    let preserve = (g:repeat_tick == b:changedtick)
+    exe 'norm! '.(a:count ? a:count : '').a:command
+    if preserve
+        let g:repeat_tick = b:changedtick
+    endif
+endfunction
+
+nnoremap <silent> .     :<C-U>call <SID>repeat(v:count)<CR>
+nnoremap <silent> u     :<C-U>call <SID>wrap('u',v:count)<CR>
+nnoremap <silent> U     :<C-U>call <SID>wrap('U',v:count)<CR>
+nnoremap <silent> <C-R> :<C-U>call <SID>wrap("\<Lt>C-R>",v:count)<CR>
+
+augroup repeatPlugin
+    autocmd!
+    autocmd BufLeave,BufWritePre,BufReadPre * let g:repeat_tick = (g:repeat_tick == b:changedtick || g:repeat_tick == 0) ? 0 : -1
+    autocmd BufEnter,BufWritePost * if g:repeat_tick == 0|let g:repeat_tick = b:changedtick|endif
+augroup END
+
+" vim:set ft=vim et sw=4 sts=4:
diff --git a/vim/plugin/screenpaste.vim b/vim/plugin/screenpaste.vim
new file mode 100644 (file)
index 0000000..5ae6ec4
--- /dev/null
@@ -0,0 +1,1007 @@
+" File:          screenpaste.vim
+" Description:   pastes/inserts current GNU Screen buffer in (almost) any mode
+" Version:       5.92
+" Mercurial:     $Id: screenpaste.vim,v 41183f681647 2008-01-06 17:29 +0100 blacktrash $
+" Author:        Christian Ebert <blacktrash@gmx.net>
+" Credits:       Mathieu Clabaut and Guo-Peng Wen for inline doc self-install code
+" URL:           http://www.vim.org/script.php?script_id=1512
+" Requirements:  GNU Screen must be in $PATH
+" Documentation: :help screenpaste
+"                self installing to its current version when plugin is loaded
+"                to review before install go to last section of this file
+"
+" GetLatestVimScripts: 1512 1 :AutoInstall: screenpaste.vim
+
+" Init: store 'compatible' settings {{{1
+let s:save_cpo = &cpo
+set cpo&vim
+
+if !exists("g:loaded_screenpaste")
+  " Fast Load: global vars, mappings, commands, doc install
+  " load functions only on demand via autocmd
+  " at Vim startup only run checks, load global vars, mappings, commands,
+  " and install Help if not up to date or not present
+
+  " full path to plugin -- needed for Screen_UpdateDocs and demand load
+  let s:plug_path = expand("<sfile>:p")
+  " name of plugin w/o extension for messages
+  let s:plug_name = fnamemodify(s:plug_path, ":t:r")
+
+  " Global Variables: {{{1
+  " g:screen_executable: name of GNU Screen executable
+  if !exists("g:screen_executable")
+    let g:screen_executable = "screen"
+  endif
+
+  " g:screen_clmode: how screenpaste behaves in Vim's command-line
+  if !exists("g:screen_clmode")
+    let g:screen_clmode = "search"
+  elseif g:screen_clmode !~# '^\%(s\%(earch\|ub\)\|noesc\)$'
+    echomsg s:plug_name.": `".g:screen_clmode."':"
+          \ "invalid value for screen_clmode."
+          \ "Reset to 'search' (default)"
+    let g:screen_clmode = "search"
+  endif
+
+  " g:screen_register: instead of register "0 use this one
+  if !exists("g:screen_register")
+    let g:screen_register = '"'
+  elseif g:screen_register !~ '^["0-9a-zA-Z]$'
+    echomsg s:plug_name.": `".g:screen_register."':"
+          \ "invalid value for screen_register."
+          \ "Reset to '\"' (default)"
+    let g:screen_register = '"'
+  endif
+
+  if !exists("g:screen_visualselect")
+    let g:screen_visualselect = 0
+  endif
+
+  " Checks: for system() and Screen executable {{{1
+  function! s:Screen_CleanUp(msg)
+    echohl WarningMsg
+    echomsg s:plug_name.":" a:msg "Plugin not loaded"
+    echohl None
+    let g:loaded_screenpaste = "no"
+    let &cpo = s:save_cpo
+    unlet s:save_cpo s:plug_name g:screen_executable g:screen_clmode
+  endfunction
+
+  " bail out if system() is not available
+  if !exists("*system")
+    call <SID>Screen_CleanUp("builtin system() function not available.")
+    finish
+  endif
+
+  " bail out if GNUscreen is not present
+  if !executable(g:screen_executable)
+    call <SID>Screen_CleanUp("`".g:screen_executable."' not executable.")
+    finish
+  endif
+
+  let s:curr_version = "v5.92"
+
+  " Mappings: propose defaults {{{1
+  if !hasmapto("<Plug>ScreenpastePut") " nvo
+    map  <unique> <Leader>p <Plug>ScreenpastePut
+  endif
+  if !hasmapto("<Plug>ScreenpasteGPut") " nvo
+    map  <unique> <Leader>gp <Plug>ScreenpasteGPut
+  endif
+  if !hasmapto("<Plug>ScreenpastePutBefore", "n")
+    nmap <unique> <Leader>P <Plug>ScreenpastePutBefore
+  endif
+  if !hasmapto("<Plug>ScreenpasteGPutBefore", "n")
+    nmap <unique> <Leader>gP <Plug>ScreenpasteGPutBefore
+  endif
+  if !hasmapto("<Plug>ScreenpastePut", "ic")
+    map! <unique> <Leader>p <Plug>ScreenpastePut
+  endif
+
+  " Internal Mappings: {{{1
+  nnoremap <script> <silent> <Plug>ScreenpastePut
+        \ :call <SID>Screen_NPut("p")<CR>
+  nnoremap <script> <silent> <Plug>ScreenpasteGPut
+        \ :call <SID>Screen_NPut("gp")<CR>
+  nnoremap <script> <silent> <Plug>ScreenpastePutBefore
+        \ :call <SID>Screen_NPut("P")<CR>
+  nnoremap <script> <silent> <Plug>ScreenpasteGPutBefore
+        \ :call <SID>Screen_NPut("gP")<CR>
+  vnoremap <script> <silent> <Plug>ScreenpastePut
+        \ :<C-U> call <SID>Screen_VPut("")<CR>
+  vnoremap <script> <silent> <Plug>ScreenpasteGPut
+        \ :<C-U> call <SID>Screen_VPut("g")<CR>
+  inoremap <script> <silent> <Plug>ScreenpastePut
+        \ <C-R>=<SID>Screen_IPut()<CR><C-R>=<SID>Screen_TwRestore()<CR>
+  cnoremap <script>          <Plug>ScreenpastePut
+        \ <C-R>=<SID>Screen_CPut()<CR>
+
+  " Commands: {{{1
+  " configuration for command-line-mode
+  " in v:version >= 700 this works with <SID>
+  function! Screen_ClCfgComplete(A, L, P)
+    return "search\nsub\nnoesc"
+  endfunction
+  command -nargs=1 -complete=custom,Screen_ClCfgComplete
+        \ ScreenCmdlineConf call <SID>Screen_ClConfig(<f-args>, 1)
+  command ScreenCmdlineInfo call <SID>Screen_ClConfig(g:screen_clmode, 1)
+  command ScreenSearch      call <SID>Screen_ClConfig("search", 1)
+  command ScreenSub         call <SID>Screen_ClConfig("sub", 1)
+  command ScreenNoEsc       call <SID>Screen_ClConfig("noesc", 1)
+  " yank Screen buffer into register (default: screen_register)
+  command -register ScreenYank call <SID>Screen_Yank("<register>")
+  " buffer operation
+  command -count=0 -bang -register ScreenPut
+        \ call <SID>Screen_PutCommand("<count>", "<bang>", "<register>")
+
+  " }}}1
+" ===== end of public configuration ==========================================
+  " Help Install: automatically when needed {{{1
+  " Function: Screen_FlexiMkdir tries to adapt to system {{{2
+  function! s:Screen_FlexiMkdir(dir)
+    if exists("*mkdir")
+      call mkdir(a:dir)
+    elseif !exists("+shellslash")
+      call system("mkdir -p '".a:dir."'")
+    else
+      let l:ssl = &shellslash
+      try
+        set shellslash
+        " no single spaces for M$? (untested)
+        call system('mkdir "'.a:dir.'"')
+      finally
+        let &shellslash = l:ssl
+      endtry
+    endif
+  endfunction
+  " }}}2
+
+  " and now the doc install itself
+  function! s:Screen_UpdateDocs()
+    " figure out document path
+    let l:vim_doc_dir = fnamemodify(s:plug_path, ":h:h")."/doc"
+    if filewritable(l:vim_doc_dir) != 2
+      let l:doc_install_intro = s:plug_name." doc install:"
+      echomsg l:doc_install_intro "Trying doc path" l:vim_doc_dir
+      echomsg "  relative to" s:plug_path
+      silent! call <SID>Screen_FlexiMkdir(l:vim_doc_dir)
+      if filewritable(l:vim_doc_dir) != 2
+        " try first item in 'runtimepath' which is comma-separated list
+        let l:vim_doc_dir =
+              \ substitute(&runtimepath, '^\([^,]*\).*', '\1/doc', 'e')
+        echomsg l:doc_install_intro "Trying doc path" l:vim_doc_dir
+        echomsg "  using first item of 'runtimepath'"
+        if filewritable(l:vim_doc_dir) != 2
+          silent! call <SID>Screen_FlexiMkdir(l:vim_doc_dir)
+          if filewritable(l:vim_doc_dir) != 2
+            " give a warning
+            echomsg l:doc_install_intro "Unable to detect writeable doc directory"
+            echomsg "  type `:help add-local-help' for more information"
+            return 0
+          endif
+        endif
+      endif
+    endif
+    " full name of help file
+    let l:doc_file = l:vim_doc_dir."/".s:plug_name.".txt"
+    " bail out if document file is still up to date
+    if filereadable(l:doc_file) &&
+          \ getftime(s:plug_path) < getftime(l:doc_file)
+      return 0
+    endif
+    let l:lz = &lazyredraw
+    let l:hls = &hlsearch
+    set lazyredraw nohlsearch
+    " create a new buffer & read in the plugin file
+    1 new
+    setlocal noswapfile modifiable nomodeline
+    if has("folding")
+      setlocal nofoldenable
+    endif
+    silent execute "read" escape(s:plug_path, " ")
+    let l:doc_buf = bufnr("%")
+    1
+    " delete from first line line starting with
+    " === START_DOC
+    silent 1,/^=\{3,}\s\+START_DOC\C/ delete _
+    " delete from line starting with
+    " === END_DOC
+    " to end of buffer
+    silent /^=\{3,}\s\+END_DOC\C/,$ delete _
+    " add modeline for help, modeline string mangled intentionally
+    " to avoid its being recognized when it is parsed
+    call append(line("$"), "")
+    call append(line("$"), " v"."im:tw=78:ts=8:ft=help:norl:")
+    " replace revision
+    silent execute "normal :1s/#version#/ ".s:curr_version."/\<CR>"
+    " write file `screenpaste.txt'
+    silent execute "wq!" escape(l:doc_file, " ") "| bwipeout" l:doc_buf
+    " create help tags
+    silent execute "helptags" l:vim_doc_dir
+    let &hlsearch = l:hls
+    let &lazyredraw = l:lz
+    return 1
+  endfunction
+
+  if <SID>Screen_UpdateDocs()
+    echomsg s:plug_name s:curr_version.": updated documentation"
+  endif
+
+  " Demand Load: via autcmd FuncUndefined : {{{1
+  " get the current script ID
+  function! s:Screen_SID()
+    " <sfile> inside a function yields {function-name}
+    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
+  endfunction
+  " load functions on demand
+  execute "autocmd FuncUndefined"
+        \ "*".<SID>Screen_SID()."Screen_* source" escape(s:plug_path, " ")
+
+  " Purge Functions: that have done their one-time duty {{{1
+  delfunction <SID>Screen_CleanUp
+  delfunction <SID>Screen_FlexiMkdir
+  delfunction <SID>Screen_UpdateDocs
+  delfunction <SID>Screen_SID
+
+  let g:loaded_screenpaste = s:curr_version."_fast_load_done"
+
+  let &cpo = s:save_cpo
+  unlet s:save_cpo s:plug_path
+  finish
+endif
+
+if g:loaded_screenpaste != s:curr_version."_fast_load_done"
+  let &cpo = s:save_cpo
+  unlet s:save_cpo
+  finish
+endif
+
+let g:loaded_screenpaste = s:curr_version
+
+" }}}1
+" ===== end of fast load =====================================================
+" Script Vars: characters to be escaped on cmdline {{{1
+" static:
+" patterns and strings (for user info)
+let s:esc_search_ma    = '][/\^$*.~'
+let s:esc_search_noma  = ']/\^$'
+let s:esc_sub_ma       = '/\~&'
+let s:esc_sub_noma     = '/\'
+let s:info_search_ma   = "] [ / \\ ^ $ ~ * . (magic)"
+let s:info_search_noma = "] / \\ ^ $ (nomagic)"
+let s:info_sub_ma      = "/ \\ ~ & (magic)"
+let s:info_sub_noma    = "/ \\ (nomagic)"
+
+" dynamic:
+" these contain the current values for cmdline conversion, and,
+" at startup, are set to the values corresponding to 'noesc'
+" because for 'search' and 'sub' Screen_ClConfig is called with
+" the current value of screen_clmode everytime Screen_CPut is called
+" with the purpose to adapt to current setting of 'magic'
+let s:cl_esc = ''
+let s:cl_eol = '\\n'
+
+" Function: Screen_BufEscape escapes chars in Screen buffer for cmdline {{{1
+function! s:Screen_BufEscape()
+  let l:screen_buf = <SID>Screen_Yank()
+  if strlen(s:cl_esc)
+    let l:screen_buf = escape(l:screen_buf, s:cl_esc)
+  endif
+  return substitute(l:screen_buf, "\<C-J>", s:cl_eol, 'g')
+endfunction
+
+" Function: Screen_ClConfig configures cmdline insertion {{{1
+" variables configured here and used by Screen_CPut function:
+" global:
+" g:screen_clmode     cmdline behaviour
+" internal:
+" s:cl_eol            eol-conversion
+" s:cl_esc            character group pattern to be escaped
+" s:esc_info          displays escaped characters
+" s:eol_info          displays eol-conversion
+function! s:Screen_ClConfig(mod, msg)
+  if a:mod !~# '^\%(s\%(earch\|ub\)\|noesc\)$'
+    echohl WarningMsg
+    echon "`" a:mod "': invalid value for screen_clmode\n"
+          \ "use one of: search | sub | noesc"
+    echohl None
+    return ""
+  endif
+  let g:screen_clmode = a:mod
+  " call version dependent function to assign escapes
+  call <SID>Screen_ClEscape()
+  if a:msg
+    echon "set '" g:screen_clmode "' "
+          \ "for Screen buffer insertion in cmdline:\n"
+          \ "eol-conversion to literal " s:eol_info "\n"
+          \ "escaped characters        " s:esc_info
+  endif
+endfunction
+" }}}1
+" ============================================================================
+" Vim7 Functions: subroutines, Screen_CPut (command detection) {{{1
+" ============================================================================
+" functions and helpers making use of Vim7 features
+if v:version >= 700
+
+  " Function: Screen_ReadBuf returns Screen buffer as text {{{2
+  function! s:Screen_ReadBuf(screen_tmpfile)
+    try
+      return join(readfile(a:screen_tmpfile, "b"), "\n")
+    catch /^Vim\%((\a\+)\)\=:E484/
+      " Screen buffer empty, no tmpfile created
+      return ""
+    endtry
+  endfunction
+
+  " Function: Screen_ClEscape chars to be escaped in cmdline {{{2
+  " initialize dict vars
+  let s:cl_esc_dict = {
+        \ "search": {0: s:esc_search_noma, 1: s:esc_search_ma},
+        \ "sub":    {0: s:esc_sub_noma,    1: s:esc_sub_ma   },
+        \ "noesc":  {0: '',                1: ''             }
+        \ }
+  let s:cl_info_dict = {
+        \ "search": {0: s:info_search_noma, 1: s:info_search_ma},
+        \ "sub"   : {0: s:info_sub_noma,    1: s:info_sub_ma   },
+        \ "noesc" : {0: 'none',             1: 'none'          }
+        \ }
+  let s:eol_conv_dict =
+        \ {"search": '\\n', "sub": '\\r', "noesc": '\\n'}
+  let s:eol_info_dict =
+        \ {"search": '\n', "sub": '\r', "noesc": '\n'}
+
+  function! s:Screen_ClEscape()
+    let s:cl_esc   =   s:cl_esc_dict[g:screen_clmode][&magic]
+    let s:esc_info =  s:cl_info_dict[g:screen_clmode][&magic]
+    let s:cl_eol   = s:eol_conv_dict[g:screen_clmode]
+    let s:eol_info = s:eol_info_dict[g:screen_clmode]
+  endfunction
+
+  " Function: Screen_CPut writes converted Screen buffer to cmdline {{{2
+  " Screen call needed for :insert and :append commands in Screen_CPut
+  " using slowpaste avoids need for manual redraw
+  let s:screen_slowpaste =
+        \ g:screen_executable." -X slowpaste 10;".
+        \ g:screen_executable." -X paste .;".
+        \ g:screen_executable." -X slowpaste 0"
+
+  function! s:Screen_CPut()
+    " automatically adapt 'screen_clmode' to cmdtype if possible
+    " or instant paste in case of :insert or :append
+    let l:cmdtype = getcmdtype()
+    if l:cmdtype == '-' && exists("$STY")
+      " :insert, :append inside Screen session
+      call system(s:screen_slowpaste)
+      return ""
+    endif
+    " store current cmdline behaviour
+    let l:save_clmode = g:screen_clmode
+    " detect cmdtype if not 'noesc'
+    if g:screen_clmode != "noesc"
+      if l:cmdtype =~ '[/?]'
+        " search: always call config to adapt to 'magic'
+        call <SID>Screen_ClConfig("search", 0)
+      elseif l:cmdtype =~ '[@-]'
+        " input() or :insert, :append outside Screen session
+        call <SID>Screen_ClConfig("noesc", 0)
+      else
+        " search, sub: always call config to adapt to 'magic'
+        call <SID>Screen_ClConfig(g:screen_clmode, 0)
+      endif
+    endif
+    let l:screen_buf = <SID>Screen_BufEscape()
+    " restore global 'screen_clmode' if changed
+    if l:save_clmode != g:screen_clmode
+      call <SID>Screen_ClConfig(l:save_clmode, 0)
+    endif
+    return l:screen_buf
+  endfunction
+
+" }}}1
+" ============================================================================
+" Vim6 Functions: subroutines, Screen_CPut (w/o command detection) {{{1
+" (see Vim7 for more comments)
+else
+
+  " Function: Screen_ReadBuf returns Screen buffer as text {{{2
+  function! s:Screen_ReadBuf(screen_tmpfile)
+    let l:store_quote = @"
+    let l:store_null  = @0
+    let l:lz = &lazyredraw
+    silent execute "1 sview" a:screen_tmpfile
+    silent % yank
+    quit!
+    let &lazyredraw = l:lz
+    " remove closing newline to mimic reading in binary mode
+    " otherwise always a linewise register
+    let l:screen_buf = substitute(@0, '\n\%$', '', 'e')
+    let @" = l:store_quote
+    let @0 = l:store_null
+    return l:screen_buf
+  endfunction
+
+  " Function: Screen_ClEscape assigns chars to be escaped in cmdline {{{2
+  function! s:Screen_ClEscape()
+    if &magic && g:screen_clmode == "search"
+      let s:cl_esc   = s:esc_search_ma
+      let s:esc_info = s:info_search_ma
+    elseif &magic && g:screen_clmode == "sub"
+      let s:cl_esc   = s:esc_sub_ma
+      let s:esc_info = s:info_sub_ma
+    elseif g:screen_clmode == "search"
+      let s:cl_esc   = s:esc_search_noma
+      let s:esc_info = s:info_search_noma
+    elseif g:screen_clmode == "sub"
+      let s:cl_esc   = s:esc_sub_noma
+      let s:esc_info = s:info_sub_noma
+    else " "noesc"
+      let s:cl_esc   = ''
+      let s:esc_info = "none"
+    endif
+    if g:screen_clmode != "sub"
+      let s:cl_eol   = '\\n'
+      let s:eol_info = '\n'
+    else
+      let s:cl_eol   = '\\r'
+      let s:eol_info = '\r'
+    endif
+  endfunction
+
+  " Function: Screen_CPut writes converted Screen buffer to cmdline {{{2
+  " no detection of cmdtype
+  function! s:Screen_CPut()
+    if g:screen_clmode != "noesc"
+      " catch eventual change of &magic
+      call <SID>Screen_ClConfig(g:screen_clmode, 0)
+    endif
+    return <SID>Screen_BufEscape()
+  endfunction
+
+endif
+
+" }}}1
+" ============================================================================
+" Function: Screen_Yank snatches current Screen buffer {{{1
+function! s:Screen_Yank(...)
+  let l:screen_tmpfile = tempname()
+  call system(g:screen_executable." -X writebuf ".l:screen_tmpfile)
+  if !a:0
+    return <SID>Screen_ReadBuf(l:screen_tmpfile)
+  else
+    let l:screen_buf = <SID>Screen_ReadBuf(l:screen_tmpfile)
+    if strlen(l:screen_buf)
+      if strlen(a:1)
+        call setreg(a:1, l:screen_buf)
+      else
+        call setreg(g:screen_register, l:screen_buf)
+      endif
+      return 1
+    elseif g:screen_register =~ '\u'
+      " do nothing
+      return 1
+    else
+      echohl WarningMsg
+      echo "Screen buffer is empty"
+      echohl None
+      return 0
+    endif
+  endif
+endfunction
+
+" Function: Screen_NPut pastes in normal mode {{{1
+function! s:Screen_NPut(p)
+  if <SID>Screen_Yank(g:screen_register)
+    execute 'normal! "'.g:screen_register.a:p
+  endif
+endfunction
+
+" Function: Screen_IPut pastes in insert mode {{{1
+" Function: Screen_TwRestore restores 'paste' {{{2
+" helper function, only called right after Screen_IPut
+" because Screen_IPut must return result before
+" being able to restore paste its previous value
+function! s:Screen_TwRestore()
+  let &paste = s:curr_paste
+  return ""
+endfunction
+" }}}2
+function! s:Screen_IPut()
+  let s:curr_paste = &paste
+  let &paste = 1
+  let l:screen_buf = <SID>Screen_Yank()
+  return l:screen_buf
+endfunction
+
+" Function: Screen_VPut pastes in visual mode {{{1
+function! s:Screen_VPut(go)
+  if <SID>Screen_Yank(g:screen_register)
+    if g:screen_register =~ '["@]'
+      " we have to use another register because
+      " visual selection is deleted into unnamed register
+      let l:store_reg = @z
+      let @z = @"
+      let g:screen_register = "z"
+    endif
+    execute 'normal! gv"'.g:screen_register.a:go.'p'
+    if g:screen_visualselect
+      execute "normal! `[".visualmode()."`]"
+    endif
+    if exists("l:store_reg")
+      let g:screen_register = '"'
+      let @0 = @z
+      let @z = l:store_reg
+    endif
+  else
+    " reset visual after showing message for 3 secs
+    sleep 3
+    execute "normal! gv"
+  endif
+endfunction
+
+" Function: Screen_PutCommand is called from :ScreenPut {{{1
+function! s:Screen_PutCommand(line, bang, reg)
+  if !strlen(a:reg)
+    let l:reg = g:screen_register
+  else
+    let l:reg = a:reg
+  endif
+  if <SID>Screen_Yank(l:reg)
+    if a:line
+      execute a:line "put".a:bang l:reg
+    else
+      execute "put".a:bang l:reg
+    endif
+  endif
+endfunction
+
+" Finale: restore 'compatible' settings {{{1
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+finish
+" }}}1
+" ============================================================================
+" Section: inline documentation (self-installing) {{{1
+" to read the docs from this file with proper syntax coloring, type
+" :set ft=help
+
+=== START_DOC
+*screenpaste.txt* Paste/insert GNU Screen buffer in (almost) any mode #version#
+
+Author:        Christian Ebert <blacktrash@gmx.net>
+
+
+               SCREENPASTE REFERENCE MANUAL~
+
+*screenpaste* *screenpaste.vim*
+
+==============================================================================
+
+1. Contents                                            *screenpaste-toc*
+
+       Screen Paste Plugin                             |screenpaste-intro|
+       Activation                                      |screenpaste-activate|
+       Usage                                           |screenpaste-usage|
+       Options                                         |screenpaste-options|
+       Changing Mappings                               |screenpaste-mappings|
+       Commands                                        |screenpaste-commands|
+       Bugs and Limitations                            |screenpaste-bugs|
+       Credits                                         |screenpaste-credits|
+
+==============================================================================
+
+2. Screen Paste Plugin                                 *screenpaste-intro*
+
+The terminal window manager Screen http://www.gnu.org/software/screen
+offers the capability to copy and paste between windows.
+
+In principle you can just do "C-a ]" (default) to paste the current Screen
+buffer into a vim buffer. However this gives unexpected results when 'paste'
+is not set or in Vim's command-line.
+
+This script provides mappings and commands to get correct results.
+
+As an additional feature the current Screen buffer is available in any Vim
+instance, even those /outside/ the current Screen session.
+
+When pasting into command-line in Vim7 many commands are autodetected and the
+behaviour adapts automatically (|getcmdtype()|).
+
+The underlying mechanism of screenpaste consists in getting hold of the
+current Screen buffer via calling to Screen to write it to a temporary file.
+At this point Vim takes over, reads the contents of the file, and puts them to
+use either directly (in Insert, Replace or Command-line mode) or, in Normal
+and Visual mode, by writing to a register and, most often, putting the
+contents of the register into the Vim buffer.  Which is why the default
+keybindings mimic |p|, |P|, |gp|, |gP|, with the |mapleader| prepended, as
+well as |:ScreenPut| and |:ScreenYank| behave almost like |:put| and |:yank|
+respectively.
+
+==============================================================================
+
+3. Activation                                          *screenpaste-activate*
+
+Either copy screenpaste.vim to your plugin directory (|add-global-plugin|),
+or to your macros directory and source it (manually or from |vimrc|): >
+       :runtime macros/screenpaste.vim
+or >
+       :source $HOME/.vim/macros/screenpaste.vim
+
+The Vim Help documentation installs itself when you restart Vim.
+
+The GNU Screen executable has to be in $PATH. Otherwise screenpaste bails out
+giving an error message.
+
+==============================================================================
+
+4. Usage                                               *screenpaste-usage*
+
+Think of the current Screen buffer as of a register at your disposal via the
+|screenpaste| mappings and commands.
+
+                                                       *screenpaste-put*
+When you type the plugin's Ex command
+>
+       :ScreenPut
+
+this works like executing |:put| with the current Screen buffer as register.
+It puts the text after the current line.  Like |:put| it accepts a prepended
+number as parameter designating the target line as well as an appended bang
+to put the text before the indicated line and an optional register argument
+which defaults to |screen_register| when omitted.
+
+|:ScreenPut| differs from |:put| as the register is not only written into the
+buffer but filled with the current Screen buffer beforehand.
+
+                                                       *screenpaste-yank*
+If you want to just get hold of the current Screen buffer for further
+processing, type
+>
+       :ScreenYank
+>
+and the Screen buffer is at your disposal in the |screen_register|.  Similar
+to |:yank| you can also execute the command with an explicit register
+argument.
+
+Note: Screen's copy mechanism discards spaces at the end and the beginning of
+a selection in case there are printable characters in the same line.  In Vim
+terms one could consider this like selecting 'exclusive', and to get a
+|linewise| "yank" the selection has to span visually more than one line, the
+newline at the end of a visually selected single line is not included.
+
+
+All other commands configure the treatment of the current Screen buffer when
+it is pasted into the command-line.  Please refer to |screen_clmode| and
+|screenpaste-commands| for further information.
+
+
+Mappings:~
+
+In |Insert|, |Replace|, and |Command-line| modes (by default) simply type: >
+       \p
+to paste the current Screen buffer.  In these modes the |screen_register| is
+not changed.
+
+Note: mappings are ignored in Insert mode while |'paste'| is set. But in that
+case Screen's "paste" command (bound to "C-a]" by default) works just fine and
+there's no need to work around this via |'pastetoggle'|.
+
+
+The plugin's mappings for |Normal| and |Visual| mode emulate the non-Ex
+commands |p|, |P|, |gp|, and |gP|:  They put the text of the current Screen
+buffer after or before the cursor, or replace the visual selection with it,
+just as if the unnamed register would contain the current Screen buffer (see
+|screen_register|).
+
+If the Screen buffer is empty they do nothing, the registers stay untouched,
+and only a corresponding message is displayed in the menu.
+
+Note however that the optional initial [count] argument to the original non-Ex
+commands will not work with these mappings (|screenpaste-bugs|).
+
+In their default state the |Normal| and |Visual| mode mappings consist of the
+same letters as the corresponding non-Ex commands with the |mapleader|
+prepended: >
+
+       <Leader>p
+       <Leader>P       (not in Visual)
+       <Leader>gp
+       <Leader>gP      (not in Visual)
+
+For simplicity we use the default |screenpaste-mappings| and the default
+|<Leader>| "\" in the following description.
+
+                                                       *screenpaste-p*
+\p                     Put current Screen buffer after the cursor.
+
+                                                       *screenpaste-P*
+\P                     Put current Screen buffer before the cursor.
+                       Not available in Visual mode.
+
+                                                       *screenpaste-gp*
+\gp                    Like "\p" but leave the cursor after the pasted text.
+
+                                                       *screenpaste-gP*
+\gP                    Like "\P" but leave the cursor after the pasted text.
+                       Not available in Visual mode.
+
+In |Visual| mode we do not need "\P" and "\gP" as "\p" and "\P" have the same
+effect of replacing the Visual selected text with the current Screen buffer.
+
+
+To summarize, supposing the default |<Leader>| "\" and the default
+|screenpaste-mappings| you can type:
+>
+       \p  in Normal mode to put Screen buffer after cursor
+       \gp in Normal mode to put Screen buffer after cursor and leave cursor
+               after the end of new text
+       \P  in Normal mode to put Screen buffer before cursor
+       \gP in Normal mode to put Screen buffer before cursor and leave cursor
+               after the end of new text
+       \p  in Visual mode to replace visual selection with Screen buffer
+       \gp in Visual mode to put Screen buffer after cursor and leave cursor
+               after the end of new text
+       \p  in Insert and Replace mode to paste Screen buffer
+       \p  in Command-line-mode to put Screen buffer in command line
+
+==============================================================================
+
+5. Options                                             *screenpaste-options*
+
+g:loaded_screenpaste                                   *loaded_screenpaste*
+
+       This option normally is set by screenpaste to avoid loading the script
+       more than once. But you can use it to get the current script version: >
+               :echo loaded_screenpaste
+<
+       If you want to disable screenpaste, put the following line in your
+       |vimrc|: >
+               let g:loaded_screenpaste = 1
+
+g:screen_executable                                    *screen_executable*
+
+Type           String
+Default Value  'screen'
+
+       Set this option if the name of your GNU Screen executable differs from
+       "screen", or if you like to specify it's full path: >
+               let g:screen_executable = "/usr/local/bin/screen"
+
+g:screen_visualselect                                  *screen_visualselect*
+Type           Boolean
+Default Value  0
+
+        If set to 1 and in Visual mode the text from the Screen buffer is
+        visually selected after the put operation.
+
+g:screen_register                                      *screen_register*
+
+Type           String
+Valid Values   "a-z0-9A-Z
+Default Value  '"'
+
+       The non-Ex put "commands" (mappings) act in a twofold operation when
+       executed in Normal or Visual mode: they yank the Screen buffer into a
+       register in the background, and then put the register into the buffer
+       or command-line.  This variable controls the register that is used for
+       the first part of the operation.  It defaults to the unnamed register
+       "" (|quotequote|).
+
+       Normally you should be fine with the default setting.  But if you
+       prefer to reserve a register of your choice for the Screen buffer you
+       can do so with this option.  Besides the default "", you may choose
+       any named (|quote_alpha|) or numbered (|quote_number|) register.
+       Consult |registers| about their behaviour.
+
+       For a one time operation with a special register the use of
+       |ScreenPut| ex-command and its register argument is recommended.
+
+       Note: Due to the mechanics of the script even a numbered register has
+       to be passed as string, ie. it has to quoted when you set it; eg. >
+               :let g:screen_register = "8"
+<      Note as well that specifying an uppercase letter means that the
+       contents of the Screen buffer will be appended to the register named
+       with the corresponding lowercase character (|quote_alpha|).
+
+g:screen_clmode                                                *screen_clmode*
+
+Type           String
+Valid Values   'search', 'sub', 'noesc'
+Default Value   'search'
+
+       This setting controls how the Screen buffer is treated when pasted in
+       the command line.
+
+       You can change the setting at startup in your |vimrc|: >
+               let g:screen_clmode = "sub"
+<
+       To change its value in a vim session you might want to use one of the
+       |:ScreenCmdlineConf|, |:ScreenSearch|, |:ScreenSub|, |:ScreenNoEsc|
+       commands as they also give a short informative message on how the mode
+       of your choice will act, and prevent you from setting an invalid value.
+
+       Information on the current value and the resulting behaviour is also
+       available via the |:ScreenCmdlineInfo| command.
+
+Modes and their behaviour:
+                                                       *screenpaste-search*
+'search' ~
+       Converts end-of-line to literal '\n'.
+       Escapes characters according to the current setting of 'magic':
+       magic:    [ ] / \ ^ * . ~ $
+       nomagic:    ] / \ ^       $
+
+       Use this mode to search for occurrences of current Screen buffer.
+       Example as typed using default mapleader: >
+               :ScreenSearch
+               :%s/\p/repl/g
+<      If the current Screen buffer is `[hello world.]' and 'magic' is set,
+       the above becomes: >
+               :%s/\[hello world\.\]/repl/g
+<                                                      *screenpaste-sub*
+'sub' ~
+       Converts end-of-line to literal '\r'.
+       Escapes characters according to the current setting of 'magic':
+       magic:    /  \  ~  &
+       nomagic:  /  \
+
+       Use this mode to substitute a pattern with current Screen buffer.
+       Example as typed using default mapleader: >
+               :ScreenSub
+               :%s/pattern/\p/g
+<      If the current Screen buffer is `http://www.vim.org', the above
+       becomes: >
+               :%s/pattern/http:\/\/www.vim.org/g
+<                                                      *screenpaste-noesc*
+'noesc' ~
+       Converts end-of-line to literal '\n'.
+
+       Use this mode to paste current Screen buffer literally into command
+       line.
+
+Vim7:
+       |/|, |?|, |input()|, |:insert|, and |:append| commands are
+       autodetected when not in 'noesc' |screen_clmode|. This means that even
+       when you are in 'sub' mode you can type: >
+               /\p
+<      and this becomes (using above example for 'search'): >
+               /\[hello world\.\]
+<
+       Note: If you paste a Screen buffer containing newlines while in an
+       |:insert| or |:append| but outside a running Screen session the
+       newlines are escaped because we cannot call Screen's paste mechanism
+       without clobbering a parallel Screen session, and Vim would insert
+       <Nul> characters instead (see |NL-used-for-Nul|).
+
+Vim6:
+       For |:insert| and |:append| commands use Screen's "C-a ]"
+
+==============================================================================
+
+6. Changing Mappings                                   *screenpaste-mappings*
+                                                       *ScreenpastePut*
+                                                       *ScreenpasteGPut*
+                                                       *ScreenpastePutBefore*
+                                                       *ScreenpasteGPutBefore*
+
+The right-hand-side |{rhs}| mappings provided by this plugin and the modes in
+which to apply them are: >
+
+       <Plug>ScreenpastePut            Normal, Visual, Insert, Command-line
+       <Plug>ScreenpasteGPut           Normal, Visual
+       <Plug>ScreenpastePutBefore      Normal
+       <Plug>ScreenpasteGPutBefore     Normal
+<
+Use these to customize the default mappings <Leader>p, <Leader>gp, <Leader>P,
+and <Leader>gP to your taste (see |using-<Plug>| and |:map-modes|).
+
+The default mappings would look like this in a |vimrc|:
+
+map  <Leader>p  <Plug>ScreenpastePut           " Normal, Visual mode
+map! <Leader>p  <Plug>ScreenpastePut           " Insert, Command-line mode
+map  <Leader>gp <Plug>ScreenpasteGPut          " Normal, Visual mode
+nmap <Leader>P  <Plug>ScreenpastePutBefore     " Normal mode
+nmap <Leader>gP <Plug>ScreenpasteGPutBefore    " Normal mode
+
+You can tweak them by changing their left-hand-side |{lhs}|.
+
+Normal (put after cursor) and Visual mode:
+                                                       default
+:map   {lhs}   <Plug>ScreenpastePut                      \p
+:map   {lhs}   <Plug>ScreenpasteGPut                     \gp
+
+       Vimrc example: >
+               map  <Leader>P <Plug>ScreenpastePut
+
+Normal mode (put before cursor):
+
+:nmap  {lhs}   <Plug>ScreenpastePutBefore                \P
+:nmap  {lhs}   <Plug>ScreenpasteGPutBefore               \gP
+
+       Vimrc example: >
+               nmap <Leader>I <Plug>ScreenpastePutBefore
+
+Insert and Command-line mode:
+
+:map!  {lhs}   <Plug>ScreenpastePut                      \p
+
+       Vimrc example, to avoid character mappings when inserting: >
+               map! <F7> <Plug>ScreenpastePut
+
+==============================================================================
+
+7. Commands                                            *screenpaste-commands*
+
+                                                       *:ScreenYank*
+:ScreenYank [x]                Yank current Screen buffer into register [x] (default
+                       |screen_register|).
+
+                                                       *:ScreenPut*
+:[line]ScreenPut [x]   Put the text from current Screen buffer after [line]
+                       (default current line) using register [x] (default
+                       |screen_register|).
+
+       You can use this command for instance to append the contents of the
+       Screen buffer to a named register and then paste in one go: >
+               :3 ScreenPut A
+<      puts the contents of register "a and the Screen buffer after line 3.
+
+:[line]ScreenPut! [x]  Put the text from current Screen buffer before [line]
+                       (default current line) using register [x] (default
+                       |screen_register|).
+
+                                                       *:ScreenCmdlineConf*
+:ScreenCmdlineConf {mode}
+                       Tell screenpaste to convert the current Screen
+                       buffer in command-line-mode according to {mode}.
+                       Takes one argument of: "search", "sub", "noesc" (w/o
+                       quotes).
+                       Changes |screen_clmode| accordingly.
+       Example: >
+               :ScreenCmdlineConf noesc
+<
+                                                       *:ScreenCmdlineInfo*
+:ScreenComdlineInfo    Display information on current command-line-mode
+                       behaviour, ie. current |screen_clmode| and what it
+                       does.
+
+                                                       *:ScreenSearch*
+:ScreenSearch          Set |screen_clmode| to 'search'.
+       Equivalent to: >
+               :ScreenCmdlineConf search
+<
+                                                       *:ScreenSub*
+:ScreenSub             Set |screen_clmode| to 'sub'.
+       Equivalent to: >
+               :ScreenCmdlineConf sub
+<
+                                                       *:ScreenNoEsc*
+:ScreenNoEsc           Set |screen_clmode| to 'noesc'.
+       Equivalent to: >
+               :ScreenCmdlineConf noesc
+
+==============================================================================
+
+8. Bugs and Limitations                                        *screenpaste-bugs*
+
+Found no way (yet?) to make optional initial [count] argument work with
+(Normal mode) mappings.
+
+Screen's copy mechanism treats spaces (including newlines) at the beginning or
+the end of a selection in a different manner than Vim's visual yank does.
+
+Screen expands tabs, expect incorrect results if the Screen buffer contains
+tabs.
+
+==============================================================================
+
+Credits                                                        *screenpaste-credits*
+
+Mathieu Clabaut, Guo-Peng Wen  let me steal and tweak the inline
+                               self-install code for this Help document.
+
+==============================================================================
+=== END_DOC
+
+" EOF vim600: set foldmethod=marker:
diff --git a/vim/plugin/securemodelines.vim b/vim/plugin/securemodelines.vim
new file mode 100644 (file)
index 0000000..bb4b60f
--- /dev/null
@@ -0,0 +1,154 @@
+" vim: set sw=4 sts=4 et ft=vim :
+" Script:           securemodelines.vim
+" Version:          20070518
+" Author:           Ciaran McCreesh <ciaranm@ciaranm.org>
+" Homepage:         http://ciaranm.org/tag/securemodelines
+" Requires:         Vim 7
+" License:          Redistribute under the same terms as Vim itself
+" Purpose:          A secure alternative to modelines
+
+if &compatible || v:version < 700
+    finish
+endif
+
+if exists("g:loaded_securemodelines")
+    finish
+endif
+let g:loaded_securemodelines = 1
+
+if (! exists("g:secure_modelines_allowed_items"))
+    let g:secure_modelines_allowed_items = [
+                \ "textwidth",   "tw",
+                \ "softtabstop", "sts",
+                \ "tabstop",     "ts",
+                \ "shiftwidth",  "sw",
+                \ "expandtab",   "et",   "noexpandtab", "noet",
+                \ "filetype",    "ft",
+                \ "foldmethod",  "fdm",
+                \ "readonly",    "ro",   "noreadonly", "noro",
+                \ "rightleft",   "rl",   "norightleft", "norl",
+                \ "spell",
+                \ "spelllang"
+                \ ]
+endif
+
+if (! exists("g:secure_modelines_verbose"))
+    let g:secure_modelines_verbose = 0
+endif
+
+if (! exists("g:secure_modelines_modelines"))
+    let g:secure_modelines_modelines=5
+endif
+
+if (! exists("g:secure_modelines_leave_modeline"))
+    if &modeline
+        set nomodeline
+        if g:secure_modelines_verbose
+            echohl WarningMsg
+            echomsg "Forcibly disabling internal modelines for securemodelines.vim"
+            echohl None
+        endif
+    endif
+endif
+
+fun! <SID>IsInList(list, i) abort
+    for l:item in a:list
+        if a:i == l:item
+            return 1
+        endif
+    endfor
+    return 0
+endfun
+
+fun! <SID>DoOne(item) abort
+    let l:matches = matchlist(a:item, '^\([a-z]\+\)\%(=[a-zA-Z0-9_\-.]\+\)\?$')
+    if len(l:matches) > 0
+        if <SID>IsInList(g:secure_modelines_allowed_items, l:matches[1])
+            exec "setlocal " . a:item
+        elseif g:secure_modelines_verbose
+            echohl WarningMsg
+            echomsg "Ignoring '" . a:item . "' in modeline"
+            echohl None
+        endif
+    endif
+endfun
+
+fun! <SID>DoNoSetModeline(line) abort
+    for l:item in split(a:line, '[ \t:]')
+        call <SID>DoOne(l:item)
+    endfor
+endfun
+
+fun! <SID>DoSetModeline(line) abort
+    for l:item in split(a:line)
+        call <SID>DoOne(l:item)
+    endfor
+endfun
+
+fun! <SID>CheckVersion(op, ver) abort
+    if a:op == "="
+        return v:version != a:ver
+    elseif a:op == "<"
+        return v:version < a:ver
+    elseif a:op == ">"
+        return v:version >= a:ver
+    else
+        return 0
+    endif
+endfun
+
+fun! <SID>DoModeline(line) abort
+    let l:matches = matchlist(a:line, '\%(\S\@<!\%(vi\|vim\([<>=]\?\)\([0-9]\+\)\?\)\|\sex\):\s*set\?\s\+\([^:]\+\):\S\@!')
+    if len(l:matches) > 0
+        let l:operator = ">"
+        if len(l:matches[1]) > 0
+            let l:operator = l:matches[1]
+        endif
+        if len(l:matches[2]) > 0
+            if <SID>CheckVersion(l:operator, l:matches[2]) ? 0 : 1
+                return
+            endif
+        endif
+        return <SID>DoSetModeline(l:matches[3])
+    endif
+
+    let l:matches = matchlist(a:line, '\%(\S\@<!\%(vi\|vim\([<>=]\?\)\([0-9]\+\)\?\)\|\sex\):\(.\+\)')
+    if len(l:matches) > 0
+        let l:operator = ">"
+        if len(l:matches[1]) > 0
+            let l:operator = l:matches[1]
+        endif
+        if len(l:matches[2]) > 0
+            if <SID>CheckVersion(l:operator, l:matches[2]) ? 0 : 1
+                return
+            endif
+        endif
+        return <SID>DoNoSetModeline(l:matches[3])
+    endif
+endfun
+
+fun! <SID>DoModelines() abort
+    if line("$") > g:secure_modelines_modelines
+        let l:lines={ }
+        call map(filter(getline(1, g:secure_modelines_modelines) +
+                    \ getline(line("$") - g:secure_modelines_modelines, "$"),
+                    \ 'v:val =~ ":"'), 'extend(l:lines, { v:val : 0 } )')
+        for l:line in keys(l:lines)
+            call <SID>DoModeline(l:line)
+        endfor
+    else
+        for l:line in getline(1, "$")
+            call <SID>DoModeline(l:line)
+        endfor
+    endif
+endfun
+
+fun! SecureModelines_DoModelines() abort
+    call <SID>DoModelines()
+endfun
+
+aug SecureModeLines
+    au!
+    au BufRead * :call <SID>DoModelines()
+aug END
+
diff --git a/vim/plugin/surround.vim b/vim/plugin/surround.vim
new file mode 100644 (file)
index 0000000..182cdee
--- /dev/null
@@ -0,0 +1,628 @@
+" surround.vim - Surroundings
+" Author:       Tim Pope <vimNOSPAM@tpope.info>
+" GetLatestVimScripts: 1697 1 :AutoInstall: surround.vim
+" $Id: surround.vim,v 1.34 2008-02-15 21:43:42 tpope Exp $
+"
+" See surround.txt for help.  This can be accessed by doing
+"
+" :helptags ~/.vim/doc
+" :help surround
+"
+" Licensed under the same terms as Vim itself.
+
+" ============================================================================
+
+" Exit quickly when:
+" - this plugin was already loaded or disabled
+" - when 'compatible' is set
+if (exists("g:loaded_surround") && g:loaded_surround) || &cp
+    finish
+endif
+let g:loaded_surround = 1
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" Input functions {{{1
+
+function! s:getchar()
+    let c = getchar()
+    if c =~ '^\d\+$'
+        let c = nr2char(c)
+    endif
+    return c
+endfunction
+
+function! s:inputtarget()
+    let c = s:getchar()
+    while c =~ '^\d\+$'
+        let c = c . s:getchar()
+    endwhile
+    if c == " "
+        let c = c . s:getchar()
+    endif
+    if c =~ "\<Esc>\|\<C-C>\|\0"
+        return ""
+    else
+        return c
+    endif
+endfunction
+
+function! s:inputreplacement()
+    "echo '-- SURROUND --'
+    let c = s:getchar()
+    if c == " "
+        let c = c . s:getchar()
+    endif
+    if c =~ "\<Esc>" || c =~ "\<C-C>"
+        return ""
+    else
+        return c
+    endif
+endfunction
+
+function! s:beep()
+    exe "norm! \<Esc>"
+    return ""
+endfunction
+
+function! s:redraw()
+    redraw
+    return ""
+endfunction
+
+" }}}1
+
+" Wrapping functions {{{1
+
+function! s:extractbefore(str)
+    if a:str =~ '\r'
+        return matchstr(a:str,'.*\ze\r')
+    else
+        return matchstr(a:str,'.*\ze\n')
+    endif
+endfunction
+
+function! s:extractafter(str)
+    if a:str =~ '\r'
+        return matchstr(a:str,'\r\zs.*')
+    else
+        return matchstr(a:str,'\n\zs.*')
+    endif
+endfunction
+
+function! s:repeat(str,count)
+    let cnt = a:count
+    let str = ""
+    while cnt > 0
+        let str = str . a:str
+        let cnt = cnt - 1
+    endwhile
+    return str
+endfunction
+
+function! s:fixindent(str,spc)
+    let str = substitute(a:str,'\t',s:repeat(' ',&sw),'g')
+    let spc = substitute(a:spc,'\t',s:repeat(' ',&sw),'g')
+    let str = substitute(str,'\(\n\|\%^\).\@=','\1'.spc,'g')
+    if ! &et
+        let str = substitute(str,'\s\{'.&ts.'\}',"\t",'g')
+    endif
+    return str
+endfunction
+
+function! s:process(string)
+    let i = 0
+    while i < 7
+        let i = i + 1
+        let repl_{i} = ''
+        let m = matchstr(a:string,nr2char(i).'.\{-\}\ze'.nr2char(i))
+        if m != ''
+            let m = substitute(strpart(m,1),'\r.*','','')
+            let repl_{i} = input(substitute(m,':\s*$','','').': ')
+        endif
+    endwhile
+    let s = ""
+    let i = 0
+    while i < strlen(a:string)
+        let char = strpart(a:string,i,1)
+        if char2nr(char) < 8
+            let next = stridx(a:string,char,i+1)
+            if next == -1
+                let s = s . char
+            else
+                let insertion = repl_{char2nr(char)}
+                let subs = strpart(a:string,i+1,next-i-1)
+                let subs = matchstr(subs,'\r.*')
+                while subs =~ '^\r.*\r'
+                    let sub = matchstr(subs,"^\r\\zs[^\r]*\r[^\r]*")
+                    let subs = strpart(subs,strlen(sub)+1)
+                    let r = stridx(sub,"\r")
+                    let insertion = substitute(insertion,strpart(sub,0,r),strpart(sub,r+1),'')
+                endwhile
+                let s = s . insertion
+                let i = next
+            endif
+        else
+            let s = s . char
+        endif
+        let i = i + 1
+    endwhile
+    return s
+endfunction
+
+function! s:wrap(string,char,type,...)
+    let keeper = a:string
+    let newchar = a:char
+    let type = a:type
+    let linemode = type ==# 'V' ? 1 : 0
+    let special = a:0 ? a:1 : 0
+    let before = ""
+    let after  = ""
+    if type == "V"
+        let initspaces = matchstr(keeper,'\%^\s*')
+    else
+        let initspaces = matchstr(getline('.'),'\%^\s*')
+    endif
+    " Duplicate b's are just placeholders (removed)
+    let pairs = "b()B{}r[]a<>"
+    let extraspace = ""
+    if newchar =~ '^ '
+        let newchar = strpart(newchar,1)
+        let extraspace = ' '
+    endif
+    let idx = stridx(pairs,newchar)
+    if newchar == ' '
+        let before = ''
+        let after  = ''
+    elseif exists("b:surround_".char2nr(newchar))
+        let all    = s:process(b:surround_{char2nr(newchar)})
+        let before = s:extractbefore(all)
+        let after  =  s:extractafter(all)
+    elseif exists("g:surround_".char2nr(newchar))
+        let all    = s:process(g:surround_{char2nr(newchar)})
+        let before = s:extractbefore(all)
+        let after  =  s:extractafter(all)
+    elseif newchar ==# "p"
+        let before = "\n"
+        let after  = "\n\n"
+    elseif newchar =~# "[tT\<C-T><,]"
+        let dounmapp = 0
+        let dounmapb = 0
+        if !maparg(">","c")
+            let dounmapb= 1
+            " Hide from AsNeeded
+            exe "cn"."oremap > <CR>"
+            exe "cn"."oremap % %<C-V>"
+            "cm ap > <C-R>=getcmdline() =~ '^[^%?].*[%?]$' ? "\026\076" : "\026\076\015"<CR>
+        endif
+        let default = ""
+        if !maparg("%","c")
+            " This is to help when typing things like
+            " <a href="/images/<%= @image.filename %>">
+            " The downside is it breaks backspace, so lets disable it for now
+            "let dounmapp= 1
+            "exe "cn"."oremap % %<C-V>"
+        endif
+        if newchar ==# "T"
+            if !exists("s:lastdel")
+                let s:lastdel = ""
+            endif
+            let default = matchstr(s:lastdel,'<\zs.\{-\}\ze>')
+        endif
+        let tag = input("<",default)
+        echo "<".substitute(tag,'>*$','>','')
+        "if dounmapr
+            "silent! cunmap <CR>
+        "endif
+        if dounmapb
+            silent! cunmap >
+        endif
+        if dounmapp
+            silent! cunmap %
+        endif
+        if tag != ""
+            let tag = substitute(tag,'>*$','','')
+            let before = '<'.tag.'>'
+            if tag =~ '/$'
+                let after = ''
+            else
+                let after  = '</'.substitute(tag,' .*','','').'>'
+            endif
+            if newchar == "\<C-T>" || newchar == ","
+                if type ==# "v" || type ==# "V"
+                    let before = before . "\n\t"
+                endif
+                if type ==# "v"
+                    let after  = "\n". after
+                endif
+            endif
+        endif
+    elseif newchar ==# 'l' || newchar == '\'
+        " LaTeX
+        let env = input('\begin{')
+        let env = '{' . env
+        let env = env . s:closematch(env)
+        echo '\begin'.env
+        if env != ""
+            let before = '\begin'.env
+            let after  = '\end'.matchstr(env,'[^}]*').'}'
+        endif
+        "if type ==# 'v' || type ==# 'V'
+            "let before = before ."\n\t"
+        "endif
+        "if type ==# 'v'
+            "let after  = "\n".initspaces.after
+        "endif
+    elseif newchar ==# 'f' || newchar ==# 'F'
+        let fnc = input('function: ')
+        if fnc != ""
+            let before = substitute(fnc,'($','','').'('
+            let after  = ')'
+            if newchar ==# 'F'
+                let before = before . ' '
+                let after  = ' ' . after
+            endif
+        endif
+    elseif idx >= 0
+        let spc = (idx % 3) == 1 ? " " : ""
+        let idx = idx / 3 * 3
+        let before = strpart(pairs,idx+1,1) . spc
+        let after  = spc . strpart(pairs,idx+2,1)
+    elseif newchar == "\<C-[>" || newchar == "\<C-]>"
+        let before = "{\n\t"
+        let after  = "\n}"
+    elseif newchar !~ '\a'
+        let before = newchar
+        let after  = newchar
+    else
+        let before = ''
+        let after  = ''
+    endif
+    "let before = substitute(before,'\n','\n'.initspaces,'g')
+    let after  = substitute(after ,'\n','\n'.initspaces,'g')
+    "let after  = substitute(after,"\n\\s*\<C-U>\\s*",'\n','g')
+    if type ==# 'V' || (special && type ==# "v")
+        let before = substitute(before,' \+$','','')
+        let after  = substitute(after ,'^ \+','','')
+        if after !~ '^\n'
+            let after  = initspaces.after
+        endif
+        if keeper !~ '\n$' && after !~ '^\n'
+            let keeper = keeper . "\n"
+        elseif keeper =~ '\n$' && after =~ '^\n'
+            let after = strpart(after,1)
+        endif
+        if before !~ '\n\s*$'
+            let before = before . "\n"
+            if special
+                let before = before . "\t"
+            endif
+        endif
+    endif
+    if type ==# 'V'
+        let before = initspaces.before
+    endif
+    if before =~ '\n\s*\%$'
+        if type ==# 'v'
+            let keeper = initspaces.keeper
+        endif
+        let padding = matchstr(before,'\n\zs\s\+\%$')
+        let before  = substitute(before,'\n\s\+\%$','\n','')
+        let keeper = s:fixindent(keeper,padding)
+    endif
+    if type ==# 'V'
+        let keeper = before.keeper.after
+    elseif type =~ "^\<C-V>"
+        " Really we should be iterating over the buffer
+        let repl = substitute(before,'[\\~]','\\&','g').'\1'.substitute(after,'[\\~]','\\&','g')
+        let repl = substitute(repl,'\n',' ','g')
+        let keeper = substitute(keeper."\n",'\(.\{-\}\)\('.(special ? '\s\{-\}' : '').'\n\)',repl.'\n','g')
+        let keeper = substitute(keeper,'\n\%$','','')
+    else
+        let keeper = before.extraspace.keeper.extraspace.after
+    endif
+    return keeper
+endfunction
+
+function! s:wrapreg(reg,char,...)
+    let orig = getreg(a:reg)
+    let type = substitute(getregtype(a:reg),'\d\+$','','')
+    let special = a:0 ? a:1 : 0
+    let new = s:wrap(orig,a:char,type,special)
+    call setreg(a:reg,new,type)
+endfunction
+" }}}1
+
+function! s:insert(...) " {{{1
+    " Optional argument causes the result to appear on 3 lines, not 1
+    "call inputsave()
+    let linemode = a:0 ? a:1 : 0
+    let char = s:inputreplacement()
+    while char == "\<CR>" || char == "\<C-S>"
+        " TODO: use total count for additional blank lines
+        let linemode = linemode + 1
+        let char = s:inputreplacement()
+    endwhile
+    "call inputrestore()
+    if char == ""
+        return ""
+    endif
+    "call inputsave()
+    let cb_save = &clipboard
+    let reg_save = @@
+    call setreg('"',"\r",'v')
+    call s:wrapreg('"',char,linemode)
+    " If line mode is used and the surrounding consists solely of a suffix,
+    " remove the initial newline.  This fits a use case of mine but is a
+    " little inconsistent.  Is there anyone that would prefer the simpler
+    " behavior of just inserting the newline?
+    if linemode && match(getreg('"'),'^\n\s*\zs.*') == 0
+        call setreg('"',matchstr(getreg('"'),'^\n\s*\zs.*'),getregtype('"'))
+    endif
+    " This can be used to append a placeholder to the end
+    if exists("g:surround_insert_tail")
+        call setreg('"',g:surround_insert_tail,"a".getregtype('"'))
+    endif
+    "if linemode
+        "call setreg('"',substitute(getreg('"'),'^\s\+','',''),'c')
+    "endif
+    if col('.') >= col('$')
+        norm! ""p
+    else
+        norm! ""P
+    endif
+    if linemode
+        call s:reindent()
+    endif
+    norm! `]
+    call search('\r','bW')
+    let @@ = reg_save
+    let &clipboard = cb_save
+    return "\<Del>"
+endfunction " }}}1
+
+function! s:reindent() " {{{1
+    if exists("b:surround_indent") ? b:surround_indent : (exists("g:surround_indent") && g:surround_indent)
+        silent norm! '[=']
+    endif
+endfunction " }}}1
+
+function! s:dosurround(...) " {{{1
+    let scount = v:count1
+    let char = (a:0 ? a:1 : s:inputtarget())
+    let spc = ""
+    if char =~ '^\d\+'
+        let scount = scount * matchstr(char,'^\d\+')
+        let char = substitute(char,'^\d\+','','')
+    endif
+    if char =~ '^ '
+        let char = strpart(char,1)
+        let spc = 1
+    endif
+    if char == 'a'
+        let char = '>'
+    endif
+    if char == 'r'
+        let char = ']'
+    endif
+    let newchar = ""
+    if a:0 > 1
+        let newchar = a:2
+        if newchar == "\<Esc>" || newchar == "\<C-C>" || newchar == ""
+            return s:beep()
+        endif
+    endif
+    let cb_save = &clipboard
+    set clipboard-=unnamed
+    let append = ""
+    let original = getreg('"')
+    let otype = getregtype('"')
+    call setreg('"',"")
+    let strcount = (scount == 1 ? "" : scount)
+    if char == '/'
+        exe 'norm '.strcount.'[/d'.strcount.']/'
+    else
+        exe 'norm d'.strcount.'i'.char
+    endif
+    let keeper = getreg('"')
+    let okeeper = keeper " for reindent below
+    if keeper == ""
+        call setreg('"',original,otype)
+        let &clipboard = cb_save
+        return ""
+    endif
+    let oldline = getline('.')
+    let oldlnum = line('.')
+    if char ==# "p"
+        call setreg('"','','V')
+    elseif char ==# "s" || char ==# "w" || char ==# "W"
+        " Do nothing
+        call setreg('"','')
+    elseif char =~ "[\"'`]"
+        exe "norm! i \<Esc>d2i".char
+        call setreg('"',substitute(getreg('"'),' ','',''))
+    elseif char == '/'
+        norm! "_x
+        call setreg('"','/**/',"c")
+        let keeper = substitute(substitute(keeper,'^/\*\s\=','',''),'\s\=\*$','','')
+    else
+        " One character backwards
+        call search('.','bW')
+        exe "norm da".char
+    endif
+    let removed = getreg('"')
+    let rem2 = substitute(removed,'\n.*','','')
+    let oldhead = strpart(oldline,0,strlen(oldline)-strlen(rem2))
+    let oldtail = strpart(oldline,  strlen(oldline)-strlen(rem2))
+    let regtype = getregtype('"')
+    if char =~# '[\[({<T]' || spc
+        let keeper = substitute(keeper,'^\s\+','','')
+        let keeper = substitute(keeper,'\s\+$','','')
+    endif
+    if col("']") == col("$") && col('.') + 1 == col('$')
+        if oldhead =~# '^\s*$' && a:0 < 2
+            let keeper = substitute(keeper,'\%^\n'.oldhead.'\(\s*.\{-\}\)\n\s*\%$','\1','')
+        endif
+        let pcmd = "p"
+    else
+        let pcmd = "P"
+    endif
+    if line('.') < oldlnum && regtype ==# "V"
+        let pcmd = "p"
+    endif
+    call setreg('"',keeper,regtype)
+    if newchar != ""
+        call s:wrapreg('"',newchar)
+    endif
+    silent exe 'norm! ""'.pcmd.'`['
+    if removed =~ '\n' || okeeper =~ '\n' || getreg('"') =~ '\n'
+        call s:reindent()
+    endif
+    if getline('.') =~ '^\s\+$' && keeper =~ '^\s*\n'
+        silent norm! cc
+    endif
+    call setreg('"',removed,regtype)
+    let s:lastdel = removed
+    let &clipboard = cb_save
+    if newchar == ""
+        silent! call repeat#set("\<Plug>Dsurround".char,scount)
+    else
+        silent! call repeat#set("\<Plug>Csurround".char.newchar,scount)
+    endif
+endfunction " }}}1
+
+function! s:changesurround() " {{{1
+    let a = s:inputtarget()
+    if a == ""
+        return s:beep()
+    endif
+    let b = s:inputreplacement()
+    if b == ""
+        return s:beep()
+    endif
+    call s:dosurround(a,b)
+endfunction " }}}1
+
+function! s:opfunc(type,...) " {{{1
+    let char = s:inputreplacement()
+    if char == ""
+        return s:beep()
+    endif
+    let reg = '"'
+    let sel_save = &selection
+    let &selection = "inclusive"
+    let cb_save  = &clipboard
+    set clipboard-=unnamed
+    let reg_save = getreg(reg)
+    let reg_type = getregtype(reg)
+    "call setreg(reg,"\n","c")
+    let type = a:type
+    if a:type == "char"
+        silent exe 'norm! v`[o`]"'.reg.'y'
+        let type = 'v'
+    elseif a:type == "line"
+        silent exe 'norm! `[V`]"'.reg.'y'
+        let type = 'V'
+    elseif a:type ==# "v" || a:type ==# "V" || a:type ==# "\<C-V>"
+        silent exe 'norm! gv"'.reg.'y'
+    elseif a:type =~ '^\d\+$'
+        let type = 'v'
+        silent exe 'norm! ^v'.a:type.'$h"'.reg.'y'
+        if mode() == 'v'
+            norm! v
+            return s:beep()
+        endif
+    else
+        let &selection = sel_save
+        let &clipboard = cb_save
+        return s:beep()
+    endif
+    let keeper = getreg(reg)
+    if type == "v" && a:type != "v"
+        let append = matchstr(keeper,'\_s\@<!\s*$')
+        let keeper = substitute(keeper,'\_s\@<!\s*$','','')
+    endif
+    call setreg(reg,keeper,type)
+    call s:wrapreg(reg,char,a:0)
+    if type == "v" && a:type != "v" && append != ""
+        call setreg(reg,append,"ac")
+    endif
+    silent exe 'norm! gv'.(reg == '"' ? '' : '"' . reg).'p`['
+    if type == 'V' || (getreg(reg) =~ '\n' && type == 'v')
+        call s:reindent()
+    endif
+    call setreg(reg,reg_save,reg_type)
+    let &selection = sel_save
+    let &clipboard = cb_save
+    if a:type =~ '^\d\+$'
+        silent! call repeat#set("\<Plug>Y".(a:0 ? "S" : "s")."surround".char,a:type)
+    endif
+endfunction
+
+function! s:opfunc2(arg)
+    call s:opfunc(a:arg,1)
+endfunction " }}}1
+
+function! s:closematch(str) " {{{1
+    " Close an open (, {, [, or < on the command line.
+    let tail = matchstr(a:str,'.[^\[\](){}<>]*$')
+    if tail =~ '^\[.\+'
+        return "]"
+    elseif tail =~ '^(.\+'
+        return ")"
+    elseif tail =~ '^{.\+'
+        return "}"
+    elseif tail =~ '^<.+'
+        return ">"
+    else
+        return ""
+    endif
+endfunction " }}}1
+
+nnoremap <silent> <Plug>Dsurround  :<C-U>call <SID>dosurround(<SID>inputtarget())<CR>
+nnoremap <silent> <Plug>Csurround  :<C-U>call <SID>changesurround()<CR>
+nnoremap <silent> <Plug>Yssurround :<C-U>call <SID>opfunc(v:count1)<CR>
+nnoremap <silent> <Plug>YSsurround :<C-U>call <SID>opfunc2(v:count1)<CR>
+" <C-U> discards the numerical argument but there's not much we can do with it
+nnoremap <silent> <Plug>Ysurround  :<C-U>set opfunc=<SID>opfunc<CR>g@
+nnoremap <silent> <Plug>YSurround  :<C-U>set opfunc=<SID>opfunc2<CR>g@
+vnoremap <silent> <Plug>Vsurround  :<C-U>call <SID>opfunc(visualmode())<CR>
+vnoremap <silent> <Plug>VSurround  :<C-U>call <SID>opfunc2(visualmode())<CR>
+inoremap <silent> <Plug>Isurround  <C-R>=<SID>insert()<CR>
+inoremap <silent> <Plug>ISurround  <C-R>=<SID>insert(1)<CR>
+
+if !exists("g:surround_no_mappings") || ! g:surround_no_mappings
+    nmap          ds   <Plug>Dsurround
+    nmap          cs   <Plug>Csurround
+    nmap          ys   <Plug>Ysurround
+    nmap          yS   <Plug>YSurround
+    nmap          yss  <Plug>Yssurround
+    nmap          ySs  <Plug>YSsurround
+    nmap          ySS  <Plug>YSsurround
+    if !hasmapto("<Plug>Vsurround","v")
+        if exists(":xmap")
+            xmap  s    <Plug>Vsurround
+        else
+            vmap  s    <Plug>Vsurround
+        endif
+    endif
+    if !hasmapto("<Plug>VSurround","v")
+        if exists(":xmap")
+            xmap  S    <Plug>VSurround
+        else
+            vmap  S    <Plug>VSurround
+        endif
+    endif
+    if !hasmapto("<Plug>Isurround","i") && "" == mapcheck("<C-S>","i")
+        imap     <C-S> <Plug>Isurround
+    endif
+    imap        <C-G>s <Plug>Isurround
+    imap        <C-G>S <Plug>ISurround
+    "Implemented internally instead
+    "imap     <C-S><C-S> <Plug>ISurround
+endif
+
+let &cpo = s:cpo_save
+
+" vim:set ft=vim sw=4 sts=4 et:
diff --git a/vim/syntax/asciidoc.vim b/vim/syntax/asciidoc.vim
new file mode 100644 (file)
index 0000000..0bf51f0
--- /dev/null
@@ -0,0 +1,166 @@
+" Vim syntax file
+" Language:     AsciiDoc
+" Author:       Stuart Rackham <srackham@gmail.com> (inspired by Felix
+"               Obenhuber's original asciidoc.vim script).
+" URL:          http://www.methods.co.nz/asciidoc/
+" Licence:      GPL (http://www.gnu.org)
+" Remarks:      Vim 6 or greater
+" Limitations:  See 'Appendix E: Vim Syntax Highlighter' in the AsciiDoc 'User
+"               Guide'.
+
+if exists("b:current_syntax")
+  finish
+endif
+
+syn clear
+syn sync fromstart
+syn sync linebreaks=1
+
+" Run :help syn-priority to review syntax matching priority.
+syn keyword asciidocToDo TODO FIXME XXX ZZZ
+syn match asciidocBackslash /\\/
+syn region asciidocIdMarker start=/^\$Id:\s/ end=/\s\$$/
+syn match asciidocCallout /\\\@<!<\d\{1,2}>/
+syn match asciidocListBlockDelimiter /^--$/
+syn match asciidocLineBreak /[ \t]+$/
+syn match asciidocRuler /^'\{3,}$/
+syn match asciidocPagebreak /^<\{3,}$/
+syn match asciidocEntityRef /\\\@<!&[#a-zA-Z]\S\{-};/
+" The tricky part is not triggering on indented list items that are also
+" preceeded by blank line, handles only bulleted items (see 'Limitations' above
+" for workarounds).
+syn region asciidocLiteralParagraph start=/^\n[ \t]\+\(\([^-*. \t] \)\|\(\S\S\)\)/ end=/\(^+\?\s*$\)\@=/
+syn match asciidocURL /\\\@<!\<\(http\|https\|ftp\|file\|irc\):\/\/[^| \t]*\(\w\|\/\)/
+syn match asciidocEmail /\\\@<!\(\<\|<\)\w\(\w\|[.-]\)*@\(\w\|[.-]\)*\w>\?[0-9A-Za-z_.]\@!/
+syn match asciidocAttributeRef /\\\@<!{\w\(\w\|-\)*\([=!@#$%?:].*\)\?}/
+syn match asciidocAdmonition /^\u\{3,15}:\(\s\+.*\)\@=/
+
+" As a damage control measure quoted patterns always terminate at a  blank
+" line (see 'Limitations' above).
+syn match asciidocQuotedSubscript /\\\@<!\~\S\_.\{-}\(\~\|\n\s*\n\)/
+syn match asciidocQuotedSuperscript /\\\@<!\^\S\_.\{-}\(\^\|\n\s*\n\)/
+syn match asciidocQuotedMonospaced /\(^\|[| \t([.,=\]]\)\@<=+\([ )\n]\)\@!\_.\{-}\S\(+\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+syn match asciidocQuotedMonospaced2 /\(^\|[| \t([.,=]\)\@<=`\([ )\n]\)\@!\_.\{-}\S\(`\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+syn match asciidocQuotedUnconstrainedMonospaced /\\\@<!++\S\_.\{-}\(++\|\n\s*\n\)/
+syn match asciidocQuotedEmphasized /\(^\|[| \t([.,=\]]\)\@<=_\([ )\n]\)\@!\_.\{-}\S\(_\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+syn match asciidocQuotedEmphasized2 /\(^\|[| \t([.,=\]]\)\@<='\([ )\n]\)\@!\_.\{-}\S\('\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+syn match asciidocQuotedUnconstrainedEmphasized /\\\@<!__\S\_.\{-}\(__\|\n\s*\n\)/
+syn match asciidocQuotedBold /\(^\|[| \t([.,=\]]\)\@<=\*\([ )\n]\)\@!\_.\{-}\S\(\*\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+syn match asciidocQuotedUnconstrainedBold /\\\@<!\*\*\S\_.\{-}\(\*\*\|\n\s*\n\)/
+"syn match asciidocQuotedSingleQuoted /\(^\|[| \t([.,=]\)\@<=`\([ )\n]\)\@!\_.\{-}\S\('\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+" Don't allow ` in single quoted (a kludge to stop confusion with `monospaced`).
+syn match asciidocQuotedSingleQuoted /\(^\|[| \t([.,=]\)\@<=`\([ )\n]\)\@!\([^`]\|\n\)\{-}[^`\s]\('\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+syn match asciidocQuotedDoubleQuoted /\(^\|[| \t([.,=]\)\@<=``\([ )\n]\)\@!\_.\{-}\S\(''\([| \t)[\],.?!;:=]\|$\)\@=\|\n\s*\n\)/
+
+syn match asciidocDoubleDollarPassthrough /\\\@<!\(^\|[^0-9a-zA-Z$]\)\@<=\$\$..\{-}\(\$\$\([^0-9a-zA-Z$]\|$\)\@=\|^$\)/
+syn match asciidocTriplePlusPassthrough /\\\@<!\(^\|[^0-9a-zA-Z$]\)\@<=+++..\{-}\(+++\([^0-9a-zA-Z$]\|$\)\@=\|^$\)/
+
+syn match asciidocListBullet /^\s*\zs\(-\|\*\{1,5}\)\ze\s/
+syn match asciidocListNumber /^\s*\zs\(\(\d\+\.\)\|\.\{1,5}\|\(\a\.\)\|\([ivxIVX]\+)\)\)\ze\s\+/
+
+syn region asciidocTable_OLD start=/^\([`.']\d*[-~_]*\)\+[-~_]\+\d*$/ end=/^$/
+syn match asciidocBlockTitle /^\.[^. \t].*[^-~_]$/ contains=asciidocQuoted.*,asciidocAttributeRef
+syn match asciidocOneLineTitle /^=\{1,5}\s\+\S.*$/ contains=asciidocQuoted.*,asciidocAttributeRef
+
+syn match asciidocTitleUnderline /[-=~^+]\{2,}$/ transparent contained contains=NONE
+syn match asciidocTwoLineTitle /^[^. +/].*[^.:]\n[-=~^+]\{2,}$/ contains=asciidocQuoted.*,asciidocAttributeRef,asciidocTitleUnderline
+
+syn match asciidocAttributeList /^\[[^[ \t].*\]$/
+syn match asciidocQuoteBlockDelimiter /^_\{4,}$/
+syn match asciidocExampleBlockDelimiter /^=\{4,}$/
+syn match asciidocSidebarDelimiter /^*\{4,}$/
+
+"See http://vimdoc.sourceforge.net/htmldoc/usr_44.html for excluding region
+"contents from highlighting.
+syn match asciidocTablePrefix /\(\S\@<!\(\([0-9.]\+\)\([*+]\)\)\?\([<\^>.]\{,3}\)\?\([a-z]\)\?\)\?|/ containedin=asciidocTableBlock contained
+syn region asciidocTableBlock matchgroup=asciidocTableDelimiter start=/^|=\{3,}$/ end=/^|=\{3,}$/ keepend contains=ALL
+syn match asciidocTablePrefix /\(\S\@<!\(\([0-9.]\+\)\([*+]\)\)\?\([<\^>.]\{,3}\)\?\([a-z]\)\?\)\?!/ containedin=asciidocTableBlock contained
+syn region asciidocTableBlock2 matchgroup=asciidocTableDelimiter2 start=/^!=\{3,}$/ end=/^!=\{3,}$/ keepend contains=ALL
+
+syn match asciidocListContinuation /^+$/
+syn region asciidocLiteralBlock start=/^\.\{4,}$/ end=/^\.\{4,}$/ contains=asciidocCallout keepend
+syn region asciidocOpenBlock start=/^-\{4,}$/ end=/^-\{4,}$/ contains=asciidocCallout keepend
+syn region asciidocCommentBlock start="^/\{4,}$" end="^/\{4,}$" contains=asciidocToDo
+syn region asciidocPassthroughBlock start="^+\{4,}$" end="^+\{4,}$"
+" Allowing leading \w characters in the filter delimiter is to accomodate
+" the pre version 8.2.7 syntax and may be removed in future releases.
+syn region asciidocFilterBlock start=/^\w*\~\{4,}$/ end=/^\w*\~\{4,}$/
+
+syn region asciidocMacroAttributes matchgroup=asciidocRefMacro start=/\\\@<!<<"\{-}\w\(\w\|-\)*"\?,\?/ end=/\(>>\)\|^$/ contains=asciidocQuoted.* keepend
+syn region asciidocMacroAttributes matchgroup=asciidocAnchorMacro start=/\\\@<!\[\{2}\(\w\|-\)\+,\?/ end=/\]\{2}/ keepend
+syn region asciidocMacroAttributes matchgroup=asciidocAnchorMacro start=/\\\@<!\[\{3}\(\w\|-\)\+/ end=/\]\{3}/ keepend
+syn region asciidocMacroAttributes matchgroup=asciidocMacro start=/[\\0-9a-zA-Z]\@<!\w\(\w\|-\)*:\S\{-}\[/ skip=/\\\]/ end=/\]\|^$/ contains=asciidocQuoted.* keepend
+syn region asciidocMacroAttributes matchgroup=asciidocIndexTerm start=/\\\@<!(\{2,3}/ end=/)\{2,3}/ contains=asciidocQuoted.* keepend
+syn region asciidocMacroAttributes matchgroup=asciidocAttributeMacro start=/\({\(\w\|-\)\+}\)\@<=\[/ skip=/\\\]/ end=/\]/ keepend
+
+syn match asciidocCommentLine "^//\([^/].*\|\)$" contains=asciidocToDo
+
+syn region asciidocVLabel start=/^\s*/ end=/\(::\|;;\)$/ oneline contains=asciidocQuoted.*,asciidocMacroAttributes keepend
+syn region asciidocHLabel start=/^\s*/ end=/\(::\|;;\)\(\s\+\|\\$\)/ oneline contains=asciidocQuoted.*,asciidocMacroAttributes keepend
+
+syn region asciidocAttributeEntry start=/^:\w/ end=/:\(\s\|$\)/ oneline
+
+highlight link asciidocMacroAttributes Label
+highlight link asciidocIdMarker Special
+highlight link asciidocDoubleDollarPassthrough Special
+highlight link asciidocTriplePlusPassthrough Special
+highlight link asciidocQuotedSubscript Type
+highlight link asciidocQuotedSuperscript Type
+highlight link asciidocOneLineTitle Title
+highlight link asciidocTwoLineTitle Title
+highlight link asciidocBlockTitle Title
+highlight link asciidocRefMacro Macro
+highlight link asciidocIndexTerm Macro
+highlight link asciidocMacro Macro
+highlight link asciidocAttributeMacro Macro
+highlight link asciidocAnchorMacro Macro
+highlight link asciidocEmail Macro
+highlight link asciidocListBullet Label
+highlight link asciidocListNumber Label
+highlight link asciidocVLabel Label
+highlight link asciidocHLabel Label
+highlight link asciidocTable_OLD Type
+highlight link asciidocTableDelimiter Label
+highlight link asciidocTableBlock NONE
+highlight link asciidocTablePrefix Label
+highlight link asciidocTableDelimiter2 Label
+highlight link asciidocTableBlock2 NONE
+highlight link asciidocTablePrefix2 Label
+highlight link asciidocListBlockDelimiter Label
+highlight link asciidocListContinuation Label
+highlight link asciidocLiteralParagraph Identifier
+highlight link asciidocQuoteBlockDelimiter Type
+highlight link asciidocExampleBlockDelimiter Type
+highlight link asciidocSidebarDelimiter Type
+highlight link asciidocLiteralBlock Identifier
+highlight link asciidocOpenBlock Identifier
+highlight link asciidocPassthroughBlock Identifier
+highlight link asciidocCommentBlock Comment
+highlight link asciidocFilterBlock Type
+highlight link asciidocQuotedBold Special
+highlight link asciidocQuotedUnconstrainedBold Special
+highlight link asciidocQuotedEmphasized Type
+highlight link asciidocQuotedEmphasized2 Type
+highlight link asciidocQuotedUnconstrainedEmphasized Type
+highlight link asciidocQuotedMonospaced Identifier
+highlight link asciidocQuotedMonospaced2 Identifier
+highlight link asciidocQuotedUnconstrainedMonospaced Identifier
+highlight link asciidocQuotedSingleQuoted Label
+highlight link asciidocQuotedDoubleQuoted Label
+highlight link asciidocToDo Todo
+highlight link asciidocCommentLine Comment
+highlight link asciidocAdmonition Special
+highlight link asciidocAttributeRef Special
+highlight link asciidocAttributeList Special
+highlight link asciidocAttributeEntry Special
+highlight link asciidocBackslash Special
+highlight link asciidocEntityRef Special
+highlight link asciidocCallout Label
+highlight link asciidocLineBreak Special
+highlight link asciidocRuler Type
+highlight link asciidocPagebreak Type
+highlight link asciidocURL Macro
+
+let b:current_syntax = "asciidoc"
+
+" vim: wrap et sw=2 sts=2:
diff --git a/vim/syntax/deb.vim b/vim/syntax/deb.vim
new file mode 100644 (file)
index 0000000..4ad6af1
--- /dev/null
@@ -0,0 +1,28 @@
+" Vim syntax file for browsing debian package.
+" copyright (C) 2007, arno renevier <arenevier@fdn.fr>
+" Distributed under the GNU General Public License (version 2 or above)
+" Last Change: 2007 December 07
+"
+" Latest version of that file can be found at
+" http://www.fdn.fr/~arenevier/vim/syntax/deb.vim
+" It should also be available at
+" http://www.vim.org/scripts/script.php?script_id=1970
+
+if exists("b:current_syntax")
+ finish
+endif
+
+syn match debComment '^".*'
+syn match debInfoFilename '^\* \.\/.*'
+syn match debDataFilename '^\.\/.*[^/]$'
+syn match debDirname '^\..*\/$'
+syn match debSymlink '^\.\/.* -> .*$' contains=debSymlinkTarget,debSymlinkArrow,debSymlinkName
+syn match debSymlinkName '^\S*' contained
+syn match debSymlinkTarget '\S*$' contained
+syn match debSymlinkArrow '->' contained
+
+hi def link debComment Comment
+hi def link debInfoFilename Type
+hi def link debDataFilename PreProc
+hi def link debSymlinkName Identifier
+hi def link debSymlinkTarget PreProc
diff --git a/vim/syntax/getmailrc.vim b/vim/syntax/getmailrc.vim
new file mode 100644 (file)
index 0000000..541e22f
--- /dev/null
@@ -0,0 +1,130 @@
+" Vim syntax file
+" Language:    getmailrc - configuration file for getmail version 4
+" Maintainer:  Nikolai Nespor <nikolai.nespor@utanet.at>
+" URL:         http://www.unet.univie.ac.at/~a9600989/vim/getmailrc.vim
+" Last Change: 2005 02 22
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" string, ints and comments
+syn match gmComment     /#.*$/
+syn match gmInt         /\<\d\+\>/
+syn region gmDbQuoteStr start=+"+ skip=+\\"+ end=+"+
+syn region gmQuoteStr   start=+'+ skip=+\\'+ end=+'+
+
+" booleans are case insensitive
+syn case ignore
+  syn keyword gmTrue 1 true yes on
+  syn keyword gmFalse 0 false no off
+syn case match
+
+syn match gmParam       /^\s*\w\+\s*=/ contains=gmKeywd
+syn match gmSection     /^\s*\[\(retriever\|destination\|options\)\]\s*$/
+syn match gmFilterSec   /^\s*\[filter-\w\+\]\s*$/
+
+syn keyword gmType type contained
+
+" retriever section
+"
+
+" retriever type
+syn match gmRetType /^\s*type\s*=\s*[a-zA-Z3]\+\s*$/ contains=gmRetTypes,gmType
+syn keyword gmRetTypes BrokenUIDLPOP3Retriver contained 
+syn keyword gmRetTypes SimplePOP3Retriever SimpleIMAPRetriever contained 
+syn keyword gmRetTypes SimplePOP3SSLRetriever SimpleIMAPSSLRetriever contained 
+syn keyword gmRetTypes MultidropPOP3Retriever MultidropPOP3SSLRetriever contained 
+syn keyword gmRetTypes MultidropSPDSRetriever MultidropIMAPRetriever contained 
+syn keyword gmRetTypes MultidropIMAPSSLRetriever contained 
+
+" common retriever options
+syn keyword gmKeywd password port server username contained 
+" POP3
+syn keyword gmKeywd use_apop contained 
+" IMAP
+syn keyword gmKeywd mailboxes move_on_delete contained 
+" SSL
+syn keyword gmKeywd certfile keyfile contained 
+" multidrop
+syn keyword gmKeywd envelope_recipient contained 
+" timeout
+syn keyword gmKeywd timeout contained 
+
+" destination section
+"
+
+" destination type
+syn match gmDestType /^\s*type\s*=\s*\(Maildir\|Mboxrd\|MDA_external\|MultiDestination\|MultiGuesser\|MultiSorter\|MDA_qmaillocal\)\s*$/ contains=gmDestTypes,gmType
+syn keyword gmDestTypes Maildir Mboxrd MDA_external MultiDestination contained 
+syn keyword gmDestTypes MultiGuesser MultiSorter MDA_qmaillocal contained 
+
+" Maildir, Mboxrd and MDA_external common options
+syn keyword gmKeywd path contained 
+" MDA_external
+syn keyword gmKeywd allow_root_commands arguments group contained 
+syn keyword gmKeywd unixfrom user contained 
+" MultiSorter
+syn keyword gmKeywd default locals contained 
+" MDA_qmaillocal plus allow_root_command, group and user from
+" MDA_external
+syn keyword gmKeywd conf-break defaultdelivery homedir contained 
+syn keyword gmKeywd localdomain localpart_translate qmaillocal contained 
+syn keyword gmKeywd strip_delivered_to contained 
+
+" option section
+"
+syn keyword gmKeywd delete delete_after delivered_to contained 
+syn keyword gmKeywd max_messages_per_session max_message_size contained 
+syn keyword gmKeywd message_log message_log_syslog read_all received contained 
+syn keyword gmKeywd verbose contained 
+
+" filter section
+"
+
+" filter type
+syn match gmFilterType /^\s*type\s*=\s*\(Filter_classifier\|Filter_external\|Filter_TMDA\)\s*$/ contains=gmFilterTypes,gmType
+syn keyword gmFilterTypes Filter_classifier Filter_external Filter_TMDA contained
+
+" filter options
+syn keyword gmKeywd allow_root_commands arguments exitcodes_drop contained 
+syn keyword gmKeywd exitcodes_keep group path unixfrom user contained 
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_getmail_syn_inits")
+  if version < 508
+    let did_getmail_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+  HiLink gmComment      Comment
+  HiLink gmInt          Identifier
+  HiLink gmDbQuoteStr   String
+  HiLink gmQuoteStr     String
+  
+  HiLink gmTrue         Identifier
+  HiLink gmFalse        Constant
+  
+  HiLink gmParam        Normal
+  HiLink gmSection      Statement
+  HiLink gmFilterSec    Statement
+
+  HiLink gmKeywd        Type
+  HiLink gmType         Type
+
+  HiLink gmRetTypes     PreProc
+  HiLink gmDestTypes    PreProc
+  HiLink gmFilterTypes  PreProc
+  delcommand HiLink
+endif
+
+let b:current_syntax = "getmail"
+
+" vim: ts=8
diff --git a/vim/syntax/mkd.vim b/vim/syntax/mkd.vim
new file mode 100644 (file)
index 0000000..6c23415
--- /dev/null
@@ -0,0 +1,86 @@
+" Vim syntax file
+" Language:    Markdown
+" Maintainer:  Ben Williams <benw@plasticboy.com>
+" URL:         http://plasticboy.com/markdown-vim-mode/
+" Version:     8
+" Last Change:  2008 April 29 
+" Remark:      Uses HTML syntax file
+" Remark:      I don't do anything with angle brackets (<>) because that would too easily
+"              easily conflict with HTML syntax
+" TODO:        Do something appropriate with image syntax
+" TODO:        Handle stuff contained within stuff (e.g. headings within blockquotes)
+
+
+" Read the HTML syntax to start with
+if version < 600
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" don't use standard HiLink, it will not work with included syntax files
+if version < 508
+  command! -nargs=+ HtmlHiLink hi link <args>
+else
+  command! -nargs=+ HtmlHiLink hi def link <args>
+endif
+
+syn spell toplevel
+syn case ignore
+syn sync linebreaks=1
+
+"additions to HTML groups
+syn region htmlBold     start=/\(^\|\s\)\*\@<!\*\*\*\@!/     end=/\*\@<!\*\*\*\@!\($\|\s\)/   contains=@Spell,htmlItalic
+syn region htmlItalic   start=/\(^\|\s\)\*\@<!\*\*\@!/       end=/\*\@<!\*\*\@!\($\|\s\)/      contains=htmlBold,@Spell
+syn region htmlBold     start=/\(^\|\s\)_\@<!___\@!/         end=/_\@<!___\@!\($\|\s\)/       contains=htmlItalic,@Spell
+syn region htmlItalic   start=/\(^\|\s\)_\@<!__\@!/          end=/_\@<!__\@!\($\|\s\)/        contains=htmlBold,@Spell
+syn region htmlString   start="]("ms=s+2             end=")"me=e-1
+syn region htmlLink     start="\["ms=s+1            end="\]"me=e-1 contains=@Spell
+syn region htmlString   start="\(\[.*]: *\)\@<=.*"  end="$"
+
+"define Markdown groups
+syn match  mkdLineContinue ".$" contained
+syn match  mkdRule      /^\s*\*\s\{0,1}\*\s\{0,1}\*$/
+syn match  mkdRule      /^\s*-\s\{0,1}-\s\{0,1}-$/
+syn match  mkdRule      /^\s*_\s\{0,1}_\s\{0,1}_$/
+syn match  mkdRule      /^\s*-\{3,}$/
+syn match  mkdRule      /^\s*\*\{3,5}$/
+syn match  mkdListItem  "^\s*[-*+]\s\+"
+syn match  mkdListItem  "^\s*\d\+\.\s\+"
+syn match  mkdCode      /^\s*\n\(\(\s\{4,}\|[\t]\+\)[^*-+ ].*\n\)\+/
+syn region mkdCode      start=/`/                   end=/`/
+syn region mkdCode      start=/\s*``[^`]*/          end=/[^`]*``\s*/
+syn region mkdBlockquote start=/^\s*>/              end=/$/                 contains=mkdLineContinue,@Spell
+syn region mkdCode      start="<pre[^>]*>"         end="</pre>"
+syn region mkdCode      start="<code[^>]*>"        end="</code>"
+
+"HTML headings
+syn region htmlH1       start="^\s*#"                   end="\($\|#\+\)" contains=@Spell
+syn region htmlH2       start="^\s*##"                  end="\($\|#\+\)" contains=@Spell
+syn region htmlH3       start="^\s*###"                 end="\($\|#\+\)" contains=@Spell
+syn region htmlH4       start="^\s*####"                end="\($\|#\+\)" contains=@Spell
+syn region htmlH5       start="^\s*#####"               end="\($\|#\+\)" contains=@Spell
+syn region htmlH6       start="^\s*######"              end="\($\|#\+\)" contains=@Spell
+syn match  htmlH1       /^.\+\n=\+$/ contains=@Spell
+syn match  htmlH2       /^.\+\n-\+$/ contains=@Spell
+
+"highlighting for Markdown groups
+HtmlHiLink mkdString       String
+HtmlHiLink mkdCode          String
+HtmlHiLink mkdBlockquote    Comment
+HtmlHiLink mkdLineContinue  Comment
+HtmlHiLink mkdListItem      Identifier
+HtmlHiLink mkdRule          Identifier
+
+
+let b:current_syntax = "mkd"
+
+delcommand HtmlHiLink
+" vim: ts=8
diff --git a/vim/syntax/perl.vim b/vim/syntax/perl.vim
new file mode 100644 (file)
index 0000000..8c41d28
--- /dev/null
@@ -0,0 +1,565 @@
+" Vim syntax file
+" Language:    Perl
+" Maintainer:  Nick Hibma <nick@van-laarhoven.org>
+" Last Change: 2007 March 13
+" Location:    http://www.van-laarhoven.org/vim/syntax/perl.vim
+"
+" Please download most recent version first before mailing
+" any comments.
+" See also the file perl.vim.regression.pl to check whether your
+" modifications work in the most odd cases
+" http://www.van-laarhoven.org/vim/syntax/perl.vim.regression.pl
+"
+" Original version: Sonia Heimann <niania@netsurf.org>
+" Thanks to many people for their contribution.
+
+" The following parameters are available for tuning the
+" perl syntax highlighting, with defaults given:
+"
+" unlet perl_include_pod
+" unlet perl_want_scope_in_variables
+" unlet perl_extended_vars
+" unlet perl_string_as_statement
+" unlet perl_no_sync_on_sub
+" unlet perl_no_sync_on_global_var
+" let perl_sync_dist = 100
+" unlet perl_fold
+" unlet perl_fold_blocks
+" let perl_nofold_packages = 1
+" let perl_nofold_subs = 1
+
+" Remove any old syntax stuff that was loaded (5.x) or quit when a syntax file
+" was already loaded (6.x).
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Unset perl_fold if it set but vim doesn't support it.
+if version < 600 && exists("perl_fold")
+  unlet perl_fold
+endif
+
+
+" POD starts with ^=<word> and ends with ^=cut
+
+if exists("perl_include_pod")
+  " Include a while extra syntax file
+  syn include @Pod syntax/pod.vim
+  unlet b:current_syntax
+  if exists("perl_fold")
+    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend fold
+    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend fold
+  else
+    syn region perlPOD start="^=[a-z]" end="^=cut" contains=@Pod,@Spell,perlTodo keepend
+    syn region perlPOD start="^=cut" end="^=cut" contains=perlTodo keepend
+  endif
+else
+  " Use only the bare minimum of rules
+  if exists("perl_fold")
+    syn region perlPOD start="^=[a-z]" end="^=cut" fold
+  else
+    syn region perlPOD start="^=[a-z]" end="^=cut"
+  endif
+endif
+
+
+" All keywords
+"
+if exists("perl_fold") && exists("perl_fold_blocks")
+  syn match perlConditional            "\<if\>"
+  syn match perlConditional            "\<elsif\>"
+  syn match perlConditional            "\<unless\>"
+  syn match perlConditional            "\<else\>" nextgroup=perlElseIfError skipwhite skipnl skipempty
+else
+  syn keyword perlConditional          if elsif unless
+  syn keyword perlConditional          else nextgroup=perlElseIfError skipwhite skipnl skipempty
+endif
+syn keyword perlConditional            switch eq ne gt lt ge le cmp not and or xor err
+if exists("perl_fold") && exists("perl_fold_blocks")
+  syn match perlRepeat                 "\<while\>"
+  syn match perlRepeat                 "\<for\>"
+  syn match perlRepeat                 "\<foreach\>"
+  syn match perlRepeat                 "\<do\>"
+  syn match perlRepeat                 "\<until\>"
+  syn match perlRepeat                 "\<continue\>"
+else
+  syn keyword perlRepeat               while for foreach do until continue
+endif
+syn keyword perlOperator               defined undef and or not bless ref
+if exists("perl_fold")
+  " if BEGIN/END would be a keyword the perlBEGINENDFold does not work
+  syn match perlControl                        "\<BEGIN\|CHECK\|INIT\|END\>" contained
+else
+  syn keyword perlControl              BEGIN END CHECK INIT
+endif
+
+syn keyword perlStatementStorage       my local our
+syn keyword perlStatementControl       goto return last next redo
+syn keyword perlStatementScalar                chomp chop chr crypt index lc lcfirst length ord pack reverse rindex sprintf substr uc ucfirst
+syn keyword perlStatementRegexp                pos quotemeta split study
+syn keyword perlStatementNumeric       abs atan2 cos exp hex int log oct rand sin sqrt srand
+syn keyword perlStatementList          splice unshift shift push pop split join reverse grep map sort unpack
+syn keyword perlStatementHash          each exists keys values tie tied untie
+syn keyword perlStatementIOfunc                carp confess croak dbmclose dbmopen die syscall
+syn keyword perlStatementFiledesc      binmode close closedir eof fileno getc lstat print printf readdir readline readpipe rewinddir select stat tell telldir write nextgroup=perlFiledescStatementNocomma skipwhite
+syn keyword perlStatementFiledesc      fcntl flock ioctl open opendir read seek seekdir sysopen sysread sysseek syswrite truncate nextgroup=perlFiledescStatementComma skipwhite
+syn keyword perlStatementVector                pack vec
+syn keyword perlStatementFiles         chdir chmod chown chroot glob link mkdir readlink rename rmdir symlink umask unlink utime
+syn match   perlStatementFiles         "-[rwxoRWXOezsfdlpSbctugkTBMAC]\>"
+syn keyword perlStatementFlow          caller die dump eval exit wantarray
+syn keyword perlStatementInclude       require
+syn match   perlStatementInclude       "\<\(use\|no\)\s\+\(\(integer\|strict\|lib\|sigtrap\|subs\|vars\|warnings\|utf8\|byte\|base\|fields\)\>\)\="
+syn keyword perlStatementScope         import
+syn keyword perlStatementProc          alarm exec fork getpgrp getppid getpriority kill pipe setpgrp setpriority sleep system times wait waitpid
+syn keyword perlStatementSocket                accept bind connect getpeername getsockname getsockopt listen recv send setsockopt shutdown socket socketpair
+syn keyword perlStatementIPC           msgctl msgget msgrcv msgsnd semctl semget semop shmctl shmget shmread shmwrite
+syn keyword perlStatementNetwork       endhostent endnetent endprotoent endservent gethostbyaddr gethostbyname gethostent getnetbyaddr getnetbyname getnetent getprotobyname getprotobynumber getprotoent getservbyname getservbyport getservent sethostent setnetent setprotoent setservent
+syn keyword perlStatementPword         getpwuid getpwnam getpwent setpwent endpwent getgrent getgrgid getlogin getgrnam setgrent endgrent
+syn keyword perlStatementTime          gmtime localtime time times
+
+syn keyword perlStatementMisc          warn formline reset scalar delete prototype lock
+syn keyword perlStatementNew           new
+
+syn keyword perlTodo                   TODO TBD FIXME XXX contained
+
+" Perl Identifiers.
+"
+" Should be cleaned up to better handle identifiers in particular situations
+" (in hash keys for example)
+"
+" Plain identifiers: $foo, @foo, $#foo, %foo, &foo and dereferences $$foo, @$foo, etc.
+" We do not process complex things such as @{${"foo"}}. Too complicated, and
+" too slow. And what is after the -> is *not* considered as part of the
+" variable - there again, too complicated and too slow.
+
+" Special variables first ($^A, ...) and ($|, $', ...)
+syn match  perlVarPlain                 "$^[ADEFHILMOPSTWX]\="
+syn match  perlVarPlain                 "$[\\\"\[\]'&`+*.,;=%~!?@#$<>(-]"
+syn match  perlVarPlain                 "$\(0\|[1-9][0-9]*\)"
+" Same as above, but avoids confusion in $::foo (equivalent to $main::foo)
+syn match  perlVarPlain                 "$:[^:]"
+" These variables are not recognized within matches.
+syn match  perlVarNotInMatches  "$[|)]"
+" This variable is not recognized within matches delimited by m//.
+syn match  perlVarSlash                 "$/"
+
+" And plain identifiers
+syn match  perlPackageRef       "\(\h\w*\)\=\(::\|'\)\I"me=e-1 contained
+
+" To highlight packages in variables as a scope reference - i.e. in $pack::var,
+" pack:: is a scope, just set "perl_want_scope_in_variables"
+" If you *want* complex things like @{${"foo"}} to be processed,
+" just set the variable "perl_extended_vars"...
+
+" FIXME value between {} should be marked as string. is treated as such by Perl.
+" At the moment it is marked as something greyish instead of read. Probably todo
+" with transparency. Or maybe we should handle the bare word in that case. or make it into
+
+if exists("perl_want_scope_in_variables")
+  syn match  perlVarPlain      "\\\=\([@$]\|\$#\)\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlVarPlain2     "\\\=%\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlFunctionName  "\\\=&\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" contains=perlPackageRef nextgroup=perlVarMember,perlVarSimpleMember
+else
+  syn match  perlVarPlain      "\\\=\([@$]\|\$#\)\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlVarPlain2     "\\\=%\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember,perlVarSimpleMember,perlMethod
+  syn match  perlFunctionName  "\\\=&\$*\(\I\i*\)\=\(\(::\|'\)\I\i*\)*\>" nextgroup=perlVarMember,perlVarSimpleMember
+endif
+
+if exists("perl_extended_vars")
+  syn cluster perlExpr         contains=perlStatementScalar,perlStatementRegexp,perlStatementNumeric,perlStatementList,perlStatementHash,perlStatementFiles,perlStatementTime,perlStatementMisc,perlVarPlain,perlVarPlain2,perlVarNotInMatches,perlVarSlash,perlVarBlock,perlShellCommand,perlFloat,perlNumber,perlStringUnexpanded,perlString,perlQQ
+  syn region perlVarBlock      matchgroup=perlVarPlain start="\($#\|[@%$]\)\$*{" skip="\\}" end="}" contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember
+  syn region perlVarBlock      matchgroup=perlVarPlain start="&\$*{" skip="\\}" end="}" contains=@perlExpr
+  syn match  perlVarPlain      "\\\=\(\$#\|[@%&$]\)\$*{\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember
+  syn region perlVarMember     matchgroup=perlVarPlain start="\(->\)\={" skip="\\}" end="}" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember
+  syn match  perlVarSimpleMember       "\(->\)\={\I\i*}" nextgroup=perlVarMember,perlVarSimpleMember contains=perlVarSimpleMemberName contained
+  syn match  perlVarSimpleMemberName   "\I\i*" contained
+  syn region perlVarMember     matchgroup=perlVarPlain start="\(->\)\=\[" skip="\\]" end="]" contained contains=@perlExpr nextgroup=perlVarMember,perlVarSimpleMember
+  syn match  perlMethod                "\(->\)\I\i*" contained
+endif
+
+" File Descriptors
+syn match  perlFiledescRead    "[<]\h\w\+[>]"
+
+syn match  perlFiledescStatementComma  "(\=\s*\u\w*\s*,"me=e-1 transparent contained contains=perlFiledescStatement
+syn match  perlFiledescStatementNocomma "(\=\s*\u\w*\s*[^, \t]"me=e-1 transparent contained contains=perlFiledescStatement
+
+syn match  perlFiledescStatement       "\u\w*" contained
+
+" Special characters in strings and matches
+syn match  perlSpecialString   "\\\(\d\+\|[xX]\x\+\|c\u\|.\)" contained
+syn match  perlSpecialStringU  "\\['\\]" contained
+syn match  perlSpecialMatch    "{\d\+\(,\(\d\+\)\=\)\=}" contained
+syn match  perlSpecialMatch    "\[\(\]\|-\)\=[^\[\]]*\(\[\|\-\)\=\]" contained
+syn match  perlSpecialMatch    "[+*()?.]" contained
+syn match  perlSpecialMatch    "(?[#:=!]" contained
+syn match  perlSpecialMatch    "(?[imsx]\+)" contained
+" FIXME the line below does not work. It should mark end of line and
+" begin of line as perlSpecial.
+" syn match perlSpecialBEOM    "^\^\|\$$" contained
+
+" Possible errors
+"
+" Highlight lines with only whitespace (only in blank delimited here documents) as errors
+syn match  perlNotEmptyLine    "^\s\+$" contained
+" Highlight '} else if (...) {', it should be '} else { if (...) { ' or
+" '} elsif (...) {'.
+"syn keyword perlElseIfError   if contained
+
+" Variable interpolation
+"
+" These items are interpolated inside "" strings and similar constructs.
+syn cluster perlInterpDQ       contains=perlSpecialString,perlVarPlain,perlVarNotInMatches,perlVarSlash,perlVarBlock,@Spell
+" These items are interpolated inside '' strings and similar constructs.
+syn cluster perlInterpSQ       contains=perlSpecialStringU,@Spell
+" These items are interpolated inside m// matches and s/// substitutions.
+syn cluster perlInterpSlash    contains=perlSpecialString,perlSpecialMatch,perlVarPlain,perlVarBlock,perlSpecialBEOM,@Spell
+" These items are interpolated inside m## matches and s### substitutions.
+syn cluster perlInterpMatch    contains=@perlInterpSlash,perlVarSlash,@Spell
+
+" Shell commands
+syn region  perlShellCommand   matchgroup=perlMatchStartEnd start="`" end="`" contains=@perlInterpDQ
+
+" Constants
+"
+" Numbers
+syn match  perlNumber  "[-+]\=\(\<\d[[:digit:]_]*L\=\>\|0[xX]\x[[:xdigit:]_]*\>\)"
+syn match  perlFloat   "[-+]\=\<\d[[:digit:]_]*[eE][\-+]\=\d\+"
+syn match  perlFloat   "[-+]\=\<\d[[:digit:]_]*\.[[:digit:]_]*\([eE][\-+]\=\d\+\)\="
+syn match  perlFloat   "[-+]\=\<\.[[:digit:]_]\+\([eE][\-+]\=\d\+\)\="
+
+
+" Simple version of searches and matches
+" caters for m//, m##, m{} and m[] (and the !/ variant)
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+[m!]/+ end=+/[cgimosx]*+ contains=@perlInterpSlash
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+[m!]#+ end=+#[cgimosx]*+ contains=@perlInterpMatch
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+[m!]{+ end=+}[cgimosx]*+ contains=@perlInterpMatch
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+[m!]\[+ end=+\][cgimosx]*+ contains=@perlInterpMatch
+
+" A special case for m!!x which allows for comments and extra whitespace in the pattern
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+[m!]!+ end=+![cgimosx]*+ contains=@perlInterpSlash,perlComment
+
+" Below some hacks to recognise the // variant. This is virtually impossible to catch in all
+" cases as the / is used in so many other ways, but these should be the most obvious ones.
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+^split /+lc=5 start=+[^$@%]\<split /+lc=6 start=+^while /+lc=5 start=+[^$@%]\<while /+lc=6 start=+^if /+lc=2 start=+[^$@%]\<if /+lc=3 start=+[!=]\~\s*/+lc=2 start=+[(~]/+lc=1 start=+\.\./+lc=2 start=+\s/[^= \t0-9$@%]+lc=1,me=e-1,rs=e-1 start=+^/+ skip=+\\/+ end=+/[cgimosx]*+ contains=@perlInterpSlash
+
+
+" Substitutions
+" caters for s///, s### and s[][]
+" perlMatch is the first part, perlSubstitution* is the substitution part
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s'+  end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlSubstitutionSQ
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s"+  end=+"+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionDQ
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s/+  end=+/+me=e-1 contains=@perlInterpSlash nextgroup=perlSubstitutionSlash
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s#+  end=+#+me=e-1 contains=@perlInterpMatch nextgroup=perlSubstitutionHash
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s\[+ end=+\]+ contains=@perlInterpMatch nextgroup=perlSubstitutionBracket skipwhite skipempty skipnl
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s{+ end=+}+ contains=@perlInterpMatch nextgroup=perlSubstitutionCurly skipwhite skipempty skipnl
+syn region perlSubstitutionSQ          matchgroup=perlMatchStartEnd start=+'+  end=+'[ecgimosx]*+ contained contains=@perlInterpSQ
+syn region perlSubstitutionDQ          matchgroup=perlMatchStartEnd start=+"+  end=+"[ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionSlash       matchgroup=perlMatchStartEnd start=+/+  end=+/[ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionHash                matchgroup=perlMatchStartEnd start=+#+  end=+#[ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionBracket     matchgroup=perlMatchStartEnd start=+\[+ end=+\][ecgimosx]*+ contained contains=@perlInterpDQ
+syn region perlSubstitutionCurly       matchgroup=perlMatchStartEnd start=+{+  end=+}[ecgimosx]*+ contained contains=@perlInterpDQ
+
+" A special case for m!!x which allows for comments and extra whitespace in the pattern
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<s!+ end=+!+me=e-1 contains=@perlInterpSlash,perlComment nextgroup=perlSubstitutionPling
+syn region perlSubstitutionPling       matchgroup=perlMatchStartEnd start=+!+ end=+![ecgimosx]*+ contained contains=@perlInterpDQ
+
+" Substitutions
+" caters for tr///, tr### and tr[][]
+" perlMatch is the first part, perlTranslation* is the second, translator part.
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)'+ end=+'+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationSQ
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)"+ end=+"+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationDQ
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)/+ end=+/+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationSlash
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)#+ end=+#+me=e-1 contains=@perlInterpSQ nextgroup=perlTranslationHash
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<\(tr\|y\)\[+ end=+\]+ contains=@perlInterpSQ nextgroup=perlTranslationBracket skipwhite skipempty skipnl
+syn region perlMatch   matchgroup=perlMatchStartEnd start=+\<\(tr\|y\){+ end=+}+ contains=@perlInterpSQ nextgroup=perlTranslationCurly skipwhite skipempty skipnl
+syn region perlTranslationSQ           matchgroup=perlMatchStartEnd start=+'+ end=+'[cds]*+ contained
+syn region perlTranslationDQ           matchgroup=perlMatchStartEnd start=+"+ end=+"[cds]*+ contained
+syn region perlTranslationSlash                matchgroup=perlMatchStartEnd start=+/+ end=+/[cds]*+ contained
+syn region perlTranslationHash         matchgroup=perlMatchStartEnd start=+#+ end=+#[cds]*+ contained
+syn region perlTranslationBracket      matchgroup=perlMatchStartEnd start=+\[+ end=+\][cds]*+ contained
+syn region perlTranslationCurly                matchgroup=perlMatchStartEnd start=+{+ end=+}[cds]*+ contained
+
+
+" The => operator forces a bareword to the left of it to be interpreted as
+" a string
+syn match  perlString "\<\I\i*\s*=>"me=e-2
+
+" Strings and q, qq, qw and qr expressions
+
+" Brackets in qq()
+syn region perlBrackets        start=+(+ end=+)+ contained transparent contains=perlBrackets,@perlStringSQ
+
+syn region perlStringUnexpanded        matchgroup=perlStringStartEnd start="'" end="'" contains=@perlInterpSQ
+syn region perlString          matchgroup=perlStringStartEnd start=+"+  end=+"+ contains=@perlInterpDQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q#+ end=+#+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q|+ end=+|+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q(+ end=+)+ contains=@perlInterpSQ,perlBrackets
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q{+ end=+}+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q/+ end=+/+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q[qx]#+ end=+#+ contains=@perlInterpDQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q[qx]|+ end=+|+ contains=@perlInterpDQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q[qx](+ end=+)+ contains=@perlInterpDQ,perlBrackets
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q[qx]{+ end=+}+ contains=@perlInterpDQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<q[qx]/+ end=+/+ contains=@perlInterpDQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qw#+  end=+#+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qw|+  end=+|+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qw(+  end=+)+ contains=@perlInterpSQ,perlBrackets
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qw{+  end=+}+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qw/+  end=+/+ contains=@perlInterpSQ
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qr#+  end=+#[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qr|+  end=+|[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qr(+  end=+)[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qr{+  end=+}[imosx]*+ contains=@perlInterpMatch
+syn region perlQQ              matchgroup=perlStringStartEnd start=+\<qr/+  end=+/[imosx]*+ contains=@perlInterpSlash
+
+" Constructs such as print <<EOF [...] EOF, 'here' documents
+"
+if version >= 600
+  " XXX Any statements after the identifier are in perlString colour (i.e.
+  " 'if $a' in 'print <<EOF if $a'). This is almost impossible to get right it
+  " seems due to the 'auto-extending nature' of regions.
+  if exists("perl_fold")
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\z(\I\i*\).*+    end=+^\z1$+ contains=@perlInterpDQ fold
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*"\z(.\{-}\)"+ end=+^\z1$+ contains=@perlInterpDQ fold
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*'\z(.\{-}\)'+ end=+^\z1$+ contains=@perlInterpSQ fold
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*""+           end=+^$+    contains=@perlInterpDQ,perlNotEmptyLine fold
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*''+           end=+^$+    contains=@perlInterpSQ,perlNotEmptyLine fold
+    syn region perlAutoload    matchgroup=perlStringStartEnd start=+<<['"]\z(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)['"]+ end=+^\z1$+ contains=ALL fold
+  else
+    syn region perlHereDoc1    matchgroup=perlStringStartEnd start=+<<\z(\I\i*\)+      end=+^\z1$+ contains=perlhereDocRestOfLine keepend
+    syn region perlhereDocRestOfLine   start=+.+ end=+$+ nextgroup=perlHereDocDocument
+    syn region perlHereDocDocument     start=+.+ end=+.+ contains=@perlInterpDQ
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*"\z(.\{-}\)"+ end=+^\z1$+ contains=@perlInterpDQ
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*'\z(.\{-}\)'+ end=+^\z1$+ contains=@perlInterpSQ
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*""+           end=+^$+    contains=@perlInterpDQ,perlNotEmptyLine
+    syn region perlHereDoc     matchgroup=perlStringStartEnd start=+<<\s*''+           end=+^$+    contains=@perlInterpSQ,perlNotEmptyLine
+    syn region perlAutoload    matchgroup=perlStringStartEnd start=+<<\(['"]\|\)\z(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)\1+ end=+^\z1$+ contains=ALL
+  endif
+else
+  syn match perlUntilEOFStart  "<<EOF.*"lc=5 nextgroup=perlUntilEOFDQ skipnl transparent
+  syn match perlUntilEOFStart  "<<\s*\"EOF\".*" nextgroup=perlUntilEOFDQ skipnl transparent
+  syn match perlUntilEOFStart  "<<\s*'EOF'.*" nextgroup=perlUntilEOFSQ skipnl transparent
+  syn match perlUntilEOFStart  "<<\s*\"\".*" nextgroup=perlUntilEmptyDQ skipnl transparent
+  syn match perlUntilEOFStart  "<<\s*''.*" nextgroup=perlUntilEmptySQ skipnl transparent
+  syn region perlUntilEOFDQ    matchgroup=perlStringStartEnd start=++ end="^EOF$" contains=@perlInterpDQ contained
+  syn region perlUntilEOFSQ    matchgroup=perlStringStartEnd start=++ end="^EOF$" contains=@perlInterpSQ contained
+  syn region perlUntilEmptySQ  matchgroup=perlStringStartEnd start=++ end="^$" contains=@perlInterpDQ,perlNotEmptyLine contained
+  syn region perlUntilEmptyDQ  matchgroup=perlStringStartEnd start=++ end="^$" contains=@perlInterpSQ,perlNotEmptyLine contained
+  syn match perlHereIdentifier "<<EOF"
+  syn region perlAutoload      matchgroup=perlStringStartEnd start=+<<\(['"]\|\)\(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)\1+ end=+^\(END_\(SUB\|OF_FUNC\|OF_AUTOLOAD\)\)$+ contains=ALL
+endif
+
+
+" Class declarations
+"
+syn match  perlPackageDecl     "^\s*\<package\s\+\S\+" contains=perlStatementPackage
+syn keyword perlStatementPackage       package contained
+
+" Functions
+"       sub [name] [(prototype)] {
+"
+syn region perlFunction                start="\s*\<sub\>" end="[;{]"he=e-1 contains=perlStatementSub,perlFunctionPrototype,perlFunctionPRef,perlFunctionName,perlComment
+syn keyword perlStatementSub   sub contained
+
+syn match  perlFunctionPrototype       "([^)]*)" contained
+if exists("perl_want_scope_in_variables")
+   syn match  perlFunctionPRef "\h\w*::" contained
+   syn match  perlFunctionName "\h\w*[^:]" contained
+else
+   syn match  perlFunctionName "\h[[:alnum:]_:]*" contained
+endif
+
+" All other # are comments, except ^#!
+syn match  perlComment         "#.*" contains=perlTodo,@Spell
+syn match  perlSharpBang       "^#!.*"
+
+" Formats
+syn region perlFormat          matchgroup=perlStatementIOFunc start="^\s*\<format\s\+\k\+\s*=\s*$"rs=s+6 end="^\s*\.\s*$" contains=perlFormatName,perlFormatField,perlVarPlain,perlVarPlain2
+syn match  perlFormatName      "format\s\+\k\+\s*="lc=7,me=e-1 contained
+syn match  perlFormatField     "[@^][|<>~]\+\(\.\.\.\)\=" contained
+syn match  perlFormatField     "[@^]#[#.]*" contained
+syn match  perlFormatField     "@\*" contained
+syn match  perlFormatField     "@[^A-Za-z_|<>~#*]"me=e-1 contained
+syn match  perlFormatField     "@$" contained
+
+" __END__ and __DATA__ clauses
+if exists("perl_fold")
+  syntax region perlDATA               start="^__\(DATA\|END\)__$" skip="." end="." contains=perlPOD,@perlDATA fold
+else
+  syntax region perlDATA               start="^__\(DATA\|END\)__$" skip="." end="." contains=perlPOD,@perlDATA
+endif
+
+
+"
+" Folding
+
+if exists("perl_fold")
+  if !exists("perl_nofold_packages")
+    syn region perlPackageFold start="^package \S\+;\s*\(#.*\)\=$" end="^1;\s*\(#.*\)\=$" end="\n\+package"me=s-1 transparent fold keepend
+  endif
+  if !exists("perl_nofold_subs")
+    syn region perlSubFold     start="^\z(\s*\)\<sub\>.*[^};]$" end="^\z1}\s*\(#.*\)\=$" transparent fold keepend
+    syn region perlSubFold start="^\z(\s*\)\<\(BEGIN\|END\|CHECK\|INIT\)\>.*[^};]$" end="^\z1}\s*$" transparent fold keepend
+  endif
+
+  if exists("perl_fold_blocks")
+    syn region perlBlockFold start="^\z(\s*\)\(if\|elsif\|unless\|for\|while\|until\)\s*(.*)\(\s*{\)\=\s*\(#.*\)\=$" start="^\z(\s*\)foreach\s*\(\(my\|our\)\=\s*\S\+\s*\)\=(.*)\(\s*{\)\=\s*\(#.*\)\=$" end="^\z1}\s*;\=\(#.*\)\=$" transparent fold keepend
+    syn region perlBlockFold start="^\z(\s*\)\(do\|else\)\(\s*{\)\=\s*\(#.*\)\=$" end="^\z1}\s*while" end="^\z1}\s*;\=\(#.*\)\=$" transparent fold keepend
+  endif
+
+  setlocal foldmethod=syntax
+  syn sync fromstart
+else
+  " fromstart above seems to set minlines even if perl_fold is not set.
+  syn sync minlines=0
+endif
+
+
+if version >= 508 || !exists("did_perl_syn_inits")
+  if version < 508
+    let did_perl_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  " The default highlighting.
+  HiLink perlSharpBang         PreProc
+  HiLink perlControl           PreProc
+  HiLink perlInclude           Include
+  HiLink perlSpecial           Special
+  HiLink perlString            String
+  HiLink perlCharacter         Character
+  HiLink perlNumber            Number
+  HiLink perlFloat             Float
+  HiLink perlType              Type
+  HiLink perlIdentifier                Identifier
+  HiLink perlLabel             Label
+  HiLink perlStatement         Statement
+  HiLink perlConditional       Conditional
+  HiLink perlRepeat            Repeat
+  HiLink perlOperator          Operator
+  HiLink perlFunction          Function
+  HiLink perlFunctionPrototype perlFunction
+  HiLink perlComment           Comment
+  HiLink perlTodo              Todo
+  if exists("perl_string_as_statement")
+    HiLink perlStringStartEnd  perlStatement
+  else
+    HiLink perlStringStartEnd  perlString
+  endif
+  HiLink perlList              perlStatement
+  HiLink perlMisc              perlStatement
+  HiLink perlVarPlain          perlIdentifier
+  HiLink perlVarPlain2         perlIdentifier
+  HiLink perlFiledescRead      perlIdentifier
+  HiLink perlFiledescStatement perlIdentifier
+  HiLink perlVarSimpleMember   perlIdentifier
+  HiLink perlVarSimpleMemberName perlString
+  HiLink perlVarNotInMatches   perlIdentifier
+  HiLink perlVarSlash          perlIdentifier
+  HiLink perlQQ                        perlString
+  if version >= 600
+    HiLink perlHereDoc         perlString
+  else
+    HiLink perlHereIdentifier  perlStringStartEnd
+    HiLink perlUntilEOFDQ      perlString
+    HiLink perlUntilEOFSQ      perlString
+    HiLink perlUntilEmptyDQ    perlString
+    HiLink perlUntilEmptySQ    perlString
+    HiLink perlUntilEOF                perlString
+  endif
+  HiLink perlStringUnexpanded  perlString
+  HiLink perlSubstitutionSQ    perlString
+  HiLink perlSubstitutionDQ    perlString
+  HiLink perlSubstitutionSlash perlString
+  HiLink perlSubstitutionHash  perlString
+  HiLink perlSubstitutionBracket perlString
+  HiLink perlSubstitutionCurly         perlString
+  HiLink perlSubstitutionPling perlString
+  HiLink perlTranslationSlash  perlString
+  HiLink perlTranslationHash   perlString
+  HiLink perlTranslationBracket        perlString
+  HiLink perlTranslationCurly  perlString
+  HiLink perlMatch             perlString
+  HiLink perlMatchStartEnd     perlStatement
+  HiLink perlFormatName                perlIdentifier
+  HiLink perlFormatField       perlString
+  HiLink perlPackageDecl       perlType
+  HiLink perlStorageClass      perlType
+  HiLink perlPackageRef                perlType
+  HiLink perlStatementPackage  perlStatement
+  HiLink perlStatementSub      perlStatement
+  HiLink perlStatementStorage  perlStatement
+  HiLink perlStatementControl  perlStatement
+  HiLink perlStatementScalar   perlStatement
+  HiLink perlStatementRegexp   perlStatement
+  HiLink perlStatementNumeric  perlStatement
+  HiLink perlStatementList     perlStatement
+  HiLink perlStatementHash     perlStatement
+  HiLink perlStatementIOfunc   perlStatement
+  HiLink perlStatementFiledesc perlStatement
+  HiLink perlStatementVector   perlStatement
+  HiLink perlStatementFiles    perlStatement
+  HiLink perlStatementFlow     perlStatement
+  HiLink perlStatementScope    perlStatement
+  HiLink perlStatementInclude  perlStatement
+  HiLink perlStatementProc     perlStatement
+  HiLink perlStatementSocket   perlStatement
+  HiLink perlStatementIPC      perlStatement
+  HiLink perlStatementNetwork  perlStatement
+  HiLink perlStatementPword    perlStatement
+  HiLink perlStatementTime     perlStatement
+  HiLink perlStatementMisc     perlStatement
+  HiLink perlStatementNew      perlStatement
+  HiLink perlFunctionName      perlIdentifier
+  HiLink perlMethod            perlIdentifier
+  HiLink perlFunctionPRef      perlType
+  HiLink perlPOD               perlComment
+  HiLink perlShellCommand      perlString
+  HiLink perlSpecialAscii      perlSpecial
+  HiLink perlSpecialDollar     perlSpecial
+  HiLink perlSpecialString     perlSpecial
+  HiLink perlSpecialStringU    perlSpecial
+  HiLink perlSpecialMatch      perlSpecial
+  HiLink perlSpecialBEOM       perlSpecial
+  HiLink perlDATA              perlComment
+
+  HiLink perlBrackets          Error
+
+  " Possible errors
+  HiLink perlNotEmptyLine      Error
+  HiLink perlElseIfError       Error
+
+  delcommand HiLink
+endif
+
+" Syncing to speed up processing
+"
+if !exists("perl_no_sync_on_sub")
+  syn sync match perlSync      grouphere NONE "^\s*\<package\s"
+  syn sync match perlSync      grouphere perlFunction "^\s*\<sub\s"
+  syn sync match perlSync      grouphere NONE "^}"
+endif
+
+if !exists("perl_no_sync_on_global_var")
+  syn sync match perlSync      grouphere NONE "^$\I[[:alnum:]_:]+\s*=\s*{"
+  syn sync match perlSync      grouphere NONE "^[@%]\I[[:alnum:]_:]+\s*=\s*("
+endif
+
+if exists("perl_sync_dist")
+  execute "syn sync maxlines=" . perl_sync_dist
+else
+  syn sync maxlines=100
+endif
+
+syn sync match perlSyncPOD     grouphere perlPOD "^=pod"
+syn sync match perlSyncPOD     grouphere perlPOD "^=head"
+syn sync match perlSyncPOD     grouphere perlPOD "^=item"
+syn sync match perlSyncPOD     grouphere NONE "^=cut"
+
+let b:current_syntax = "perl"
+
+" vim: ts=8
diff --git a/vim/syntax/php.vim b/vim/syntax/php.vim
new file mode 100644 (file)
index 0000000..5dc442b
--- /dev/null
@@ -0,0 +1,3625 @@
+" Vim syntax file
+" Language:     PHP 4/5
+" Maintainer:   Peter Hodge <toomuchphp-vim@yahoo.com>
+" Last Change:  May 7, 2008
+"
+" URL:      http://www.vim.org/scripts/script.php?script_id=1571
+" Version:  0.9.7
+"
+" ================================================================
+"
+" Note: If you are having speed issues loading or editting PHP files, try
+"       disabling some of the options.  In your .vimrc, try adding:
+"         :let php_folding = 0
+"         :let php_strict_blocks = 0
+"
+"       Also, there is a 'large file' mode which can disable certain options
+"       if a PHP file is too big (see php_large_file below).
+"
+" ================================================================
+"
+" Note: If you are using a colour terminal with a dark background, you will
+"       probably find the 'elflord' colorscheme will give you the most
+"       distinctive colors.
+"
+" ================================================================
+"
+" OPTIONS:
+"
+"    Many of these default to 1 (On), so you would need to set
+"       them to 0 to turn them off. E.g., in your .vimrc file:
+"      let php_special_vars = 0
+"      let php_special_functions = 0
+"      let php_alt_comparisons = 0
+"      etc.
+"    If the variables do not exist, the default value will be used.
+"
+"
+"    All options can be set globally or on a per-file basis by using
+"    global or buffer-local variables.  For example, you could turn on
+"    automatic folding for all PHP scripts in your .vimrc:
+"      let g:php_folding = 3
+"
+"    Then you could turn it off in only one file using this command:
+"
+"      :let b:php_folding = 0 | setfiletype php
+"
+"
+"   -- PHP FEATURES --
+"
+"         let php_sql_query = 1/0  [default 0]
+"             ... for SQL syntax highlighting inside strings
+"
+"         let php_htmlInStrings = 1/0  [default 0]
+"             ... for HTML syntax highlighting inside strings
+"
+"         let php_baselib = 1/0  [default 0]
+"             ... for highlighting baselib functions
+"
+"         let php_special_vars = 1/0  [default 1]
+"             ... to highlight superglobals like $_GET, $_SERVER, etc.
+"               * always on if using php_oldStyle
+"
+"         let php_special_functions = 1/0  [default 1]
+"             ... to highlight functions with special behaviour
+"                 e.g., unset(), extract()
+"
+"         let php_alt_comparisons = 1/0  [default 1]
+"             ... to highlight comparison operators in an alternate colour
+"               * always on if using php_oldStyle
+"
+"         let php_alt_assignByReference = 1/0  [default 1]
+"             ... to highlight '=&' in '$foo =& $bar' in an alternate colour.
+"                 This also applies to a function which returns by-reference,
+"                 as well as a function argument which is by-reference.
+"
+"         let php_smart_members = 1/0  [default 0]
+"             ... syntax works out whether -> indicates a property or method.
+"                 Otherwise method colours may be used on properties, for
+"                 example:
+"                   $object->__get[] = true;
+"                 '__get' would be highlighted as a special method, even
+"                 thought it is clearly a property in this context.
+"                 Note: turning this OFF can improve the highlighting speed on
+"                 object-oriented code
+"
+"         let php_alt_properties = 1/0  [default 0]
+"             ... use a different color for '->' based on whether it is used
+"                 for property access, method access, or dynamic access (using
+"                 '->{...}')
+"               * requires php_smart_members
+"
+"         let php_highlight_quotes = 1/0  [default 0]
+"             ... makes quote characters the same colour as the string
+"                 contents, like in C syntax.
+"
+"         let php_show_semicolon = 1/0  [default 1]
+"             ... to make the semicolon (;) more visible
+"
+"         let php_smart_semicolon = 1/0  [default 1]
+"             ... semicolon adopts the color of a 'return' or 'break' keyword
+"               * requires php_show_semicolon
+"                 Note: this also includes the ':' or ';' which follows a
+"                 'case' or 'default' inside a switch
+"
+"         let php_alt_blocks = 1/0  [default 1]
+"             ... colorize { and } around class/function/try/catch bodies
+"                 according to the type of code block.
+"               * requires php_strict_blocks
+"
+"         let php_alt_arrays = 0/1/2  [default 1]
+"             ... to colorize ( and ) around an array body, as well as '=>'
+"               * requires php_strict_blocks
+"                 Setting this to '2' will highlighting the commas as well.
+"                 Commas are not highlighted by default because it's too much
+"                 color.
+"
+"         let php_alt_construct_parents = 0/1  [default 0]
+"             ... to colorize the ( and ) around an if, while, foreach, or switch
+"                 body.
+"               * requires ... what?
+"                 TODO: work out dependencies, code them correctly
+"
+"         let php_show_spl = 1/0  [default 1]
+"             .. to colorize methods which are defined by PHP default interfaces
+"                TODO: work out what these interfaces are part of: SPL or just
+"                PHP
+"
+"         let php_show_pcre = 1/0  [default 1]
+"                 (was: 'php_show_preg')
+"             ... to highlight regular expression patterns inside calls
+"                 to preg_match(), preg_replace(), etc.
+"
+"
+"   -- FINDING ERRORS --
+"
+"         let php_parent_error_close = 1/0  [default 1]
+"             ... for highlighting parent error ] or ) or }
+"               * requires php_strict_blocks
+"
+"         let php_parent_error_open = ?
+"             ... for skipping a php end tag, if there exists an
+"                 open ( or [ without a closing one
+"                 Note: this option is now enabled permanently (unless
+"                 php_strict_blocks is disabled).
+"               * requires php_strict_blocks
+"
+"         let php_empty_construct_error = 0/1  [default 1]
+"             ... highlights ';' as an error if it comes immediately after
+"                 an if/else/while/for/foreach/switch statement (the
+"                 logical constructs should have a body).
+"               * requires php_strict_blocks
+
+"         let php_show_semicolon_error = 1/0  [default 1]
+"             ... highlights certain cases when ';' is followed by an
+"                 operator such as '+'.
+"               * requires php_show_semicolon
+"
+"         let php_nested_functions = 0/1  [default 0]
+"             ... Whether or not to allow contiaining one function inside
+"                 another.  This option is mostly for speeding up syntax
+"                 highlighting - { } blocks can by inserted much faster while
+"                 editting a large class.
+"                 Note: this is the only option which might break valid PHP
+"                 code, although only if you define one function inside
+"                 another, which is usually discouraged.
+"               * only relevant when using php_strict_blocks
+"
+"   -- OTHER OPTIONS --
+"
+"         let php_large_file = 0/?  [ default 3000 ]
+"             ... If a PHP script has more lines than this limit (e.g., more
+"                 than 3000 lines), some options are automatically turned off
+"                 to help it load faster.  These options are:
+"                   php_strict_blocks = 0
+"                   php_smart_members = 0
+"                   php_smart_semicolon = 0
+"                   php_show_pcre = 0
+"                   php_folding = 0
+"                 Note: If you set this option to '0', then this feature will
+"                 be disabled; thus you can use:
+"                   :let b:php_large_file = 0 | setfiletype php
+"                 to reload the current file with the disabled syntax options
+"                 re-activated.
+"
+"         let php_strict_blocks = 1/0  [default 1]
+"             ... to match together all {} () and [] blocks correctly. This is
+"                 required by some of the other options for finding errors and
+"                 applying correct colors to { } blocks, etc.  However, it may
+"                 cause Vim to slow down on large files.
+"
+"         let php_asp_tags = 1/0  [default 0]
+"             ... for highlighting ASP-style short tags: <% %>
+"
+"         let php_noShortTags = 1/0  [default 0]
+"             ... don't sync <? ?> as php
+"               * This has been deprecated in favour of php_short_tags (which
+"                 has the opposite meaning)
+"
+"         let php_short_tags = 1/0  [default 1]
+"             ... highlight <?...?> blocks as php. If this is OFF, you need to
+"                 use the longer <?php...?>
+"
+"         let php_oldStyle = 1
+"             ... for using old colorstyle
+"
+"         let php_folding = 1/2/3  [default 0]
+"             ... 1: for folding classes and functions
+"                 2: for folding all { } regions
+"                 3: for folding only functions
+"                 TODO: documentation for php_folding_manual
+"
+"         let php_fold_arrays = 0/1  [default 0]
+"             ... To fold arrays as well.
+"               * requires php_folding, php_strict_blocks, php_alt_arrays
+"
+"         let php_fold_heredoc = 0/1  [default 0]
+"             ... Fold heredoc blocks ($string = <<<ENDOFSTRING)
+"               * requires php_folding
+"
+"         let php_sync_method = x
+"             ... x = -1 to sync by search (default)
+"                 x > 0  to sync at least x lines backwards
+"                 x = 0  to sync from start
+"
+"
+" ================================================================
+"
+" TODO LIST:
+"
+" PRIORITY:
+"   - document the phpControlParent feature, make sure it works fully, or not
+"     at all
+"   - what to do about 'iskeyword' containing '$'?
+"   - test syntax against older Vims (6.4, 6.0, 5.7)
+"   - concat rid of lines beginning with '\'
+"   - allow turning off all semicolon errors
+"   - fix bug in highlighting of pattern: /[\\\]/ and /[\\]]/
+"   - fix bug in highlighting of pattern: "/\$/" should make the '$' match the
+"     end-of-pattern
+"   - case/default syntax items don't work inside a switch/endswitch
+"     although it's still OK using {...}
+"
+" PHP Syntax:
+"   - review support for PHP built-in superglobals:
+"     - ensure all PHP 5.2 superglobals are recognized
+"   - review support for PHP built-in constants, make sure I've got them all
+"   - make support for PHP built-in class methods optional.
+"   - review highlight links to ensure maximum readability on GUI
+"     and color terminal using colorschemes 'elflord' and 'default'
+"   - new group phpReservedFunction, because some parts of
+"     phpSpecialFunction can be used as a method name.
+"   - what is php_oldStyle? is it still needed?
+"   - use 'nextgroup' to highlight errors when a ']' or ')' is followed by
+"     a constant/variable or function call.  This will also help find when
+"     a closing ')' is missing.
+"   - Review syncing searches, see if there is anything we can add to help the
+"     syncing process.
+"   - make ';' on the end of a while() NOT a problem unless it is followed by
+"     a '{'
+"
+" PCRE Syntax:
+"   - fix problem: in regex "/(...)\1/", '\1' does NOT refer to a backreference!
+"     this is caused by incorrect matching of escape sequences in
+"     double-quoted strings where the double-quote escape sequences should
+"     take precedence
+"   - fix problem: this line breaks folding
+"              preg_match("#^require MODULES_PATH \. (['\"])main\.inc\.php\\1;$#m", '', $m))
+"
+"   - decide on terminology: 'PCRE' or 'PREG'
+"   - Review effects of paired delimiters when combined with other
+"     PCRE complex atoms using those symbols
+"   - decide on better colors for the
+"     (?(?=lookahead/lookbehind)conditional|sub-pattern)
+"
+"
+" Future Plans:
+"   - option to choose PHP4 or PHP5 compatibility
+"   - differentiate between an interface block and a class block
+"   - add ability to highlight user-defined functions and keywords
+"     using any of the following means:
+"       1) a comma-separated string of user functions
+"       2) a file containing user functions
+"       3) using names from the tags file(s)
+"           (this may be better as a separate plugin)
+"   - add support for phpDocumentor comment blocks and tags
+"   - add support for POSIX Regex patterns
+"   - allow easy embedding of the PHP syntax using 'contains=@phpClTop' or
+"     'syn region phpRegion ...'
+"   - automatically select best colors by examining the colorscheme
+"   - check to see if 'baselib' needs to be highlighted still
+"   - Add support 2nd parameter to preg_replace and highlight
+"     "\1" and other confusing sequences as errors ("\1" is "\x01")
+"   - Add support for class constants (foo::bar)
+"
+" Difficult To Implement:
+"   - Highlight expressions without operators or commas, such as:
+"       echo $a $b;
+"     These expressions are *really* difficult to find efficiently.
+"   - Folding around 'case' blocks.
+"
+"
+"
+" ================================================================
+"
+" Note:
+" - syntax case is 'ignore' unless explicitly set to 'match'
+"   for a single item.
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syn clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if !exists("main_syntax")
+  let main_syntax = 'php'
+endif
+
+" TODO: what's all this about?
+if version < 600
+  unlet! php_folding
+  if exists("php_sync_method") && !php_sync_method
+    let php_sync_method=-1
+  endif
+  so <sfile>:p:h/html.vim
+else
+  runtime! syntax/html.vim
+  unlet b:current_syntax
+endif
+
+" accept old options
+if !exists("php_sync_method")
+  if exists("php_minlines")
+    let php_sync_method=php_minlines
+  else
+    let php_sync_method=-1
+  endif
+endif
+
+function! s:ChooseValue(name, default)
+  if exists('b:' . a:name)
+    return b:{a:name}
+  elseif exists('g:' . a:name)
+    return g:{a:name}
+  else
+    return a:default
+  endif
+endfunction
+
+" set up variables based on global or buffer variables {{{1
+  " Is it a large file? (s:large_file) {{{2
+  let s:large_file_limit = s:ChooseValue('php_large_file', 3000)
+  let s:large_file = (s:large_file_limit == 0) ? 0 : (line('$') >= s:large_file_limit)
+
+  if s:large_file
+    echohl WarningMsg
+    echomsg printf('WARNING: Large PHP File (%d lines); some syntax options have been disabled.', line('$'))
+    echohl None
+  endif
+
+  " Strict Blocks (s:strict_blocks) {{{2
+  let s:strict_blocks = s:large_file ? 0 : s:ChooseValue('php_strict_blocks', 1)
+
+  " Fold Level (s:folding) {{{2
+  let s:folding = s:large_file ? 0 : s:ChooseValue('php_folding', 0)
+
+  " Fold manually (s:fold_manual) {{{2
+  let s:fold_manual = s:large_file ? 0 : s:ChooseValue('php_fold_manual', s:folding ? 1 : 0)
+
+  " Fold arrays (s:fold_arrays) {{{2
+  let s:fold_arrays = (s:folding && s:ChooseValue('php_fold_arrays', 0))
+
+  " Fold heredoc strings (s:fold_heredoc) {{{2
+  let s:fold_heredoc = (s:folding && s:ChooseValue('php_fold_heredoc', 0))
+
+  " Allow nested functions (s:nested_functions) {{{2
+  let s:nested_functions = s:ChooseValue('php_nested_functions', 1)
+
+  " Allow ASP-style <% %> tags (s:asp_tags) {{{2
+  let s:asp_tags = s:ChooseValue('php_asp_tags', 0)
+
+  " Only allow long tags '<?php' (s:long_tags) {{{2
+  let s:long_tags = !s:ChooseValue('php_short_tags', !s:ChooseValue('php_noShortTags', 0))
+
+  " SQL in strings (s:show_sql) {{{2
+  let s:show_sql = s:ChooseValue('php_sql_query', 0)
+
+  " HTML in strings (s:show_html_in_strings) {{{2
+  let s:show_html_in_strings = s:ChooseValue('php_htmlInStrings', 0)
+
+  " Highlight the PHP baselib (s:show_baselib) {{{2
+  let s:show_baselib = s:ChooseValue('php_baselib', 0)
+
+  " Highlight superglobals (s:special_vars) {{{2
+  let s:special_vars = s:ChooseValue('php_special_vars', s:ChooseValue('php_special_variables', s:ChooseValue('php_oldStyle', 1)))
+
+  " Highlight special functions (s:special_functions) {{{2
+  let s:special_functions = s:ChooseValue('php_special_functions', 1)
+
+  " Highlight quotes around strings (s:show_quotes) {{{2
+  let s:show_quotes = s:ChooseValue('php_highlight_quotes', 0)
+
+  " Highlight PCRE patterns (s:show_pcre) {{{2
+  let s:show_pcre = s:large_file ? 0 : s:ChooseValue('php_show_pcre', s:ChooseValue('php_show_preg', 1))
+
+  " Highlight ';' (s:show_semicolon) {{{2
+  let s:show_semicolon = s:ChooseValue('php_show_semicolon', 1)
+
+  " Highlight ';' errors (s:show_semicolon_error) {{{2
+  let s:show_semicolon_error = (s:show_semicolon && s:ChooseValue('php_show_semicolon_error', 1))
+
+  " Highlight parent error ) ] or } (s:parent_error_close) {{{2
+  let s:parent_error_close = (s:strict_blocks && s:ChooseValue('php_parent_error_close', 1))
+
+  " Highlight invalid ';' after if/while/foreach (s:no_empty_construct) {{{2
+  let s:no_empty_construct = (s:strict_blocks && s:ChooseValue('php_empty_construct_error', 1))
+
+  " Alt colors for {} around class/func/try/catch blocks (s:alt_blocks) {{{2
+  let s:alt_blocks = (s:strict_blocks && s:ChooseValue('php_alt_blocks', 1))
+
+  " Alt color for by-reference operators (s:alt_refs) {{{2
+  let s:alt_refs = s:ChooseValue('php_alt_assignByReference', 1)
+
+  " Alt color for control structure parents (s:alt_control_parents) {{{2
+  let s:alt_control_parents = s:ChooseValue('php_alt_construct_parents', 0)
+
+  " Alt color for array syntax (s:alt_arrays) {{{2
+  " * requires strict_blocks
+  let s:alt_arrays = (s:strict_blocks ? s:ChooseValue('php_alt_arrays', 1) : 0)
+
+  " Alt color for comparisons (s:alt_comparisons) {{{2
+  let s:alt_comparisons = s:ChooseValue('php_alt_comparisons', s:ChooseValue('php_oldStyle', 1))
+
+  " Alt colors for ';' after return/break (s:smart_semicolon) {{{2
+  let s:smart_semicolon = s:large_file ? 0 : (s:show_semicolon && s:ChooseValue('php_smart_semicolon', 1))
+
+  " Alt colors for '->' (s:smart_members / s:alt_properties) {{{2
+  let s:smart_members = s:large_file ? 0 : s:ChooseValue('php_smart_members', 0)
+  let s:alt_properties = (s:smart_members && s:ChooseValue('php_alt_properties', 0))
+
+  " Syncing method (s:sync) {{{2
+  let s:sync = s:ChooseValue('php_sync_method', -1)
+
+" }}}1
+
+delfunction s:ChooseValue
+
+syn cluster htmlPreproc add=phpRegion,phpRegionAsp,phpRegionSc
+
+" need to source the SQL syntax file in case we encounter
+" heredoc containing SQL
+if version < 600
+  syn include @sqlTop <sfile>:p:h/sql.vim
+else
+  syn include @sqlTop syntax/sql.vim
+endif
+
+syn sync clear
+unlet b:current_syntax
+syn cluster sqlTop remove=sqlString,sqlComment
+if s:show_sql
+  syn cluster phpClShowInStrings contains=@sqlTop
+endif
+
+if s:show_html_in_strings
+  syn cluster phpClShowInStrings add=@htmlTop
+endif
+
+" NOTE: syntax case should be 'ignore' for all items (in keeping
+" with PHP's case insensitive behaviour).  If an item MUST be case
+" sensitive, 'syntax case match' should precede that item and
+" 'syntax case ignore' must follow IMMEDIATELY after so that there
+" can be no confusion over the value of 'syntax case' for most items
+" syntax matches and regions may use '\C' to utilize case sensitivity
+syn case ignore
+
+" PHP syntax: clusters {{{1
+
+  " these represent a single value in PHP
+  syn cluster phpClValues add=@phpClConstants
+
+  syn cluster phpClValues add=phpIdentifier,phpIdentifierComplex,phpMethodsVar
+
+  " TODO: add class constants (foo::BAR)
+
+  " these can go anywhere an expression is valid inside PHP code
+  syn cluster phpClExpressions add=@phpClValues
+  syn cluster phpClExpressions add=phpRelation,phpList
+  syn cluster phpClExpressions add=phpParent,phpParentError
+  syn cluster phpClExpressions add=phpObjectOperator
+
+  " these are the control statements - they shouldn't contain each other
+  syn cluster phpClCode add=@phpClExpressions
+  syn cluster phpClCode add=phpLabel
+  syn cluster phpClCode add=phpFoldTry,phpFoldCatch
+
+  " TODO: what is phpStorageClass class exactly? it needs a more descriptive
+  " name so I know where to include it.  Maybe it should be broken up
+  syn cluster phpClCode add=phpStorageClass
+
+  " code which is inside a function/method/class or global scope
+  syn cluster phpClInFunction add=@phpClCode
+  syn cluster phpClInMethod add=@phpClCode
+  syn cluster phpClInClass add=@phpClValues,phpAssign,phpSemicolon
+  syn cluster phpClTop add=@phpClCode
+
+  " This cluster contains matches to find where an expression follows another
+  " expression without a comma or operator inbetween
+  " TODO: is this even possible to do?
+  syn cluster phpClExprNotSeparated add=NONE
+
+  " Note: there is one cluster here each for:
+  "  - constants
+  "  - functions
+  "  - classes
+  "  - interfaces
+  "  - structures (classes and interfaces combined)
+  "  - methods
+  "  - properties
+  "  - members (things which are a method and a property)
+  syn cluster phpClConstants add=NONE
+  syn cluster phpClFunctions add=NONE
+
+  syn cluster phpClClasses add=NONE
+  syn cluster phpClInterfaces add=NONE
+  syn cluster phpClStructures add=@phpClClasses,@phpClInterfaces
+
+  syn cluster phpClMethods add=@phpClMembers
+  syn cluster phpClProperties add=@phpClMembers
+  syn cluster phpClMembers add=NONE
+
+  " these are the things which can be matched inside an identifier
+  syn cluster phpClIdentifier add=NONE
+
+  " Note: the next clusters contains all the regions or matches that can
+  " contain a class or interface name
+  syn cluster phpClClassHere add=phpStructureHere
+  syn cluster phpClInterfaceHere add=phpStructureHere
+  syn cluster phpClStructureHere add=@phpClClassHere,@phpClStructureHere
+
+  syn cluster phpClMethodHere add=phpMemberHere,phpMethodHere
+  syn cluster phpClPropertyHere add=phpMemberHere,phpPropertyHere
+  syn cluster phpClMemberHere add=@phpClMethodHere,@phpClPropertyHere
+
+  " also, some very basic matches for these place-holders
+  syn match phpStructureHere /\h\w*/ contained display
+  syn match phpMemberHere /\h\w*/ contained display
+  syn match phpMethodHere /\h\w*/ contained display
+  syn match phpPropertyHere /\h\w*/ contained display
+
+  " what to include at the top level?
+  if ! s:strict_blocks
+    " if not strict blocks, we must also allow matching of things from inside
+    " functions/methods/classes
+    syn cluster phpClTop add=@phpClInFunction,@phpClInMethod,@phpClInClass
+  endif
+  
+  " Note: these are the old clusters ... they are deprecated now, but still
+  " here just in case someone is using them elsewhere
+  syn cluster phpClInside add=@phpClExpressions
+  syn cluster phpClConst add=@phpClExpressions
+  syn cluster phpClFunction add=@phpClCode
+
+" PHP syntax: comments {{{1
+
+  syn cluster phpClValues add=phpComment
+  syn cluster phpClInClass add=phpComment
+
+  syn region phpComment start="/\*" end="\*/" contained extend contains=@Spell
+  if version >= 600
+    syn match phpComment "#.\{-}\(?>\|$\)\@="  contained extend contains=@Spell
+    syn match phpComment "//.\{-}\(?>\|$\)\@=" contained extend contains=@Spell
+  else
+    syn match phpComment "#.\{-}$"         contained
+    syn match phpComment "#.\{-}?>"me=e-2  contained
+    syn match phpComment "//.\{-}$"        contained
+    syn match phpComment "//.\{-}?>"me=e-2 contained
+  endif
+
+" PHP syntax: Operators: + - * / && || (etc) {{{1
+
+  " NOTE: these need to come before the numbers (so that floats work)
+  syn cluster phpClExpressions add=phpAssign
+  syn match phpAssign /==\@!/ contained display
+  hi link phpAssign phpOperator
+
+  syn cluster phpClExpressions add=phpOperator
+  syn match   phpOperator contained display /[%^|*!.~]/
+  " & can't be preceded by a '=' or ',' or '('
+  syn match   phpOperator contained display /\%([=,(]\_s*\)\@<!&/
+  " + can't be followed by a number or '.'
+  " - can't be followed by a number or '.' or '>'
+  syn match   phpOperator contained display /+[.0-9]\@!/
+  syn match   phpOperator contained display /-[.>0-9]\@!/
+  syn match   phpOperator contained display /[-+*/%^&|.]=/
+  syn match   phpOperator contained display /\/[*/]\@!/
+  syn match   phpOperator contained display /&&/
+  syn match   phpOperator contained display /||/
+  syn match   phpOperator contained display />>/
+  " Note: how the shift-left operator can't be followed by another '<' (that
+  " would make it a Heredoc syntax)
+  syn match   phpOperator contained display /<<<\@!/
+  syn keyword phpOperator      contained and or xor
+
+  " allow a ':' on its own - this may be after an 'else:' or something like that
+  syn match phpOperator contained display /::\@!/
+
+  syn cluster phpClExpressions add=phpTernaryRegion
+  syn region phpTernaryRegion matchgroup=phpOperator start=/?/ end=/::\@!/
+        \ transparent keepend extend display
+        \ contained matchgroup=Error end=/[;)\]}]/
+
+
+" PHP syntax: null/true/false/numbers {{{1
+
+  syn cluster phpClValues add=phpNull
+  syn keyword phpNull contained null
+
+  syn cluster phpClValues add=phpBoolean
+  syn keyword phpBoolean contained true false
+
+  syn cluster phpClValues add=phpNumber
+  syn match phpNumber contained display /\<[1-9]\d*\>/
+  syn match phpNumber contained display /-[1-9]\d*\>/
+  syn match phpNumber contained display /+[1-9]\d*\>/
+  syn match phpNumber contained display /\<0x\x\{1,8}\>/
+  syn match phpNumber contained display /\<0\d*\>/ contains=phpOctalError
+  syn match phpOctalError contained display /[89]/
+
+  " Note: I've split float into 3 matches which each have a fixed starting
+  " character
+  syn cluster phpClValues add=phpFloat
+  syn match phpFloat contained display /\.\d\+\>/
+  syn match phpFloat contained display /\<\d\+\.\d\+\>/
+  syn match phpFloat contained display /-\d*\.\d\+\>/
+  syn match phpFloat contained display /+\d*\.\d\+\>/
+
+" PHP syntax: dynamic strings {{{1
+
+  " single-quoted strings are always the same
+  " TODO: work out a good name for an option which will add 'display' option
+  " to these strings
+  syn cluster phpClValues add=phpStringSingle
+  syn region phpStringSingle matchgroup=phpQuoteSingle   start=/'/ skip=/\\./ end=/'/
+        \ contained keepend extend contains=@phpClShowInStrings,@Spell
+
+  " Note: this next version of the php double-quoted string can't contain
+  " variables, because a few parts of PHP code require strings without
+  " variables.  There is another string match later which takes precedence
+  " over this one in most circumstances where a string containing variables IS
+  " allowed
+  syn cluster phpClValues add=phpStringDoubleConstant
+  syn region phpStringDoubleConstant contained keepend extend
+        \ matchgroup=phpQuoteSingle start=/"/ end=/"/ skip=/\\./
+        \ contains=@phpClShowInStrings,phpSpecialChar,@Spell
+
+  " Note: this version of the double-quoted string also contains
+  " @phpClStringIdentifiers, which means variables can go inside the string
+  syn cluster phpClExpressions add=phpStringDouble
+  syn region phpStringDouble matchgroup=phpQuoteDouble   start=/"/ skip=/\\./ end=/"/
+        \ contained keepend extend
+        \ contains=@phpClShowInStrings,phpSpecialChar,@phpClStringIdentifiers,@Spell
+
+  " backticks
+  syn cluster phpClExpressions add=phpBacktick
+  syn region phpBacktick matchgroup=phpQuoteBacktick start=/`/ skip=/\\./ end=/`/
+        \ contained keepend extend
+        \ contains=phpSpecialChar,@phpClStringIdentifiers,@Spell
+
+  " this cluster contains only strings which accept things like \n or \x32
+  " inside them
+  syn cluster phpClStringsWithSpecials add=phpStringDoubleConstant,@phpClStringsWithIdentifiers
+
+  " this cluster contains strings which accept things like {$foo} inside them
+  syn cluster phpClStringsWithIdentifiers add=phpStringDouble,phpBacktick,phpHereDoc
+
+  " HereDoc {{{
+  if version >= 600
+    syn cluster phpClExpressions add=phpHereDoc
+    syn case match
+"    syn keyword phpHereDoc contained foobar
+    if s:folding && s:fold_heredoc
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/<<<\s*\z(\h\w*\)$/
+            \ contains=phpSpecialChar
+            \ fold
+
+      " always match special Heredocs which state what type of content they have
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/\c<<<\s*\z(\%(\h\w*\)\=html\)$/
+            \ contains=@htmlTop,phpSpecialChar
+            \ fold
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/\c<<<\s*\z(\%(\h\w*\)\=sql\)$/
+            \ contains=@sqlTop,phpSpecialChar
+            \ fold
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/\c<<<\s*\z(\%(\h\w*\)\=javascript\)$/
+            \ contains=@htmlJavascript,phpSpecialChar
+            \fold
+    else
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/<<<\s*\z(\h\w*\)$/
+            \ contains=phpSpecialChar
+
+      " always match special Heredocs which state what type of content they have
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/\c<<<\s*\z(\%(\h\w*\)\=html\)$/
+            \ contains=@htmlTop,phpSpecialChar
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/\c<<<\s*\z(\%(\h\w*\)\=sql\)$/
+            \ contains=@sqlTop,phpSpecialChar
+      syn region phpHereDoc keepend extend contained
+            \ matchgroup=phpHereDocDelimiter end=/^\z1\%(;\=$\)\@=/
+            \ start=/\c<<<\s*\z(\%(\h\w*\)\=javascript\)$/
+            \ contains=@htmlJavascript,phpSpecialChar
+    endif
+
+    syn case ignore
+  endif " }}}
+
+
+" PHP syntax: strings: special sequences {{{1
+
+  " match an escaped backslash inside any type of string
+  syn match phpStringLiteral /\\\\/ contained display
+        \ containedin=phpStringSingle,@phpClStringsWithSpecials
+
+  " match an escaped quote in each type of string
+  syn match phpStringLiteral /\\`/ contained display containedin=phpBacktick
+  syn match phpStringLiteral /\\'/ contained display containedin=phpStringSingle
+  syn match phpStringLiteral /\\"/ contained display
+        \ containedin=phpStringDouble,phpStringDoubleConstant
+
+  " highlighting for an escaped '\$' inside a double-quoted string
+  syn match phpStringLiteral /\\\$/ contained display containedin=@phpClStringsWithSpecials
+
+  " match \{ as regular string content so that it stops \{$var} from
+  " highlighting the { } region
+  syn match phpStringRegular /\\{/ contained display containedin=@phpClStringsWithSpecials
+  hi link phpStringRegular phpStringDouble
+
+  " match an \r\n\t or hex or octal sequence
+  " TODO: these should also be available in PCRE pattern strings
+  " TODO: what were all these extra escape sequences???
+  syn match phpSpecialChar contained display /\\[nrt]/
+  syn match phpSpecialChar contained display /\\\o\{1,3}/
+  syn match phpSpecialChar contained display /\\x\x\x\=/
+
+  " create an identifier match for inside strings:
+  syn match phpIdentifierInString /\$\h\w*/ contained display
+        \ nextgroup=phpPropertyInString,phpPropertyInStringError,@phpClIdentifierIndexInString
+        \ contains=phpIdentifier
+        \ containedin=@phpClStringsWithIdentifiers
+
+  " match an index [bar] [0] [$key] after a variable inside a string {{{2
+
+    " First: match the [ and ] which would appear in the index (they're
+    " contained int the following items)
+    syn match phpBracketInString /[[\]]/ contained display
+    hi link phpBracketInString phpSpecialChar
+
+    " Second: match a single '[' as an error
+    syn cluster phpClIdentifierIndexInString add=phpBracketInStringFalseStart
+    syn match phpBracketInStringFalseStart /\[\]\=/ contained display
+    hi link phpBracketInStringFalseStart Error
+
+    " Third: match any other [] region which is completed, but doesn't have a
+    " valid key
+    syn cluster phpClIdentifierIndexInString add=phpIdentifierIndexInString
+    syn match phpIdentifierIndexInString /\[[^"]\{-1,}\]/
+          \ contains=phpBracketInString,phpIdentifierIndexInStringError
+          \ contained display
+
+      " error on a bracket which is inside another bracket
+      syn match phpIdentifierIndexInStringError /\[[$_a-z0-9]*\[/ contained display
+      hi link phpIdentifierIndexInStringError Error
+
+      " any character which isn't a valid index character
+      syn match phpIdentifierIndexInStringError /[^$a-z0-9_[\]]\+/ contained display
+
+      " a number *must not* be preceded by the '[' and followed by a \w
+      syn match phpIdentifierIndexInStringError /\[\@<=\d\+\w\@=/ contained display
+
+      " a dollar sign *must* be preceded by the '['
+      syn match phpIdentifierIndexInStringError /\[\@<!\$/ contained display
+            \ containedin=phpIdentifierIndexInStringError
+
+    " Fourth: match a complete '[]' region properly
+
+      " 1) an index containing a number
+      syn match phpIdentifierIndexInString /\[\d\+\]/ contained display
+            \ contains=phpBracketInString
+
+      " 2) a word or variable
+      syn match phpIdentifierIndexInString /\[\$\=\h\w*\]/ contained display
+            \ contains=phpBracketInString,phpVarSelector
+      hi link phpIdentifierIndexInString Identifier
+
+  " }}}2
+
+  " match an property after a variable inside a string
+  syn cluster phpClPropertyHere add=phpPropertyInString
+  syn match phpPropertyInString /->\h\w*/ contained display extend
+        \ contains=phpPropertySelector,@phpClProperties
+
+  " it's sometimes easy to get it wrong
+  syn match phpPropertyInStringError contained display /->\%([^a-z0-9_"\\]\|\\.\)/
+        \ contains=phpPropertySelector
+  syn match phpPropertyInStringError contained display /->"\@=/
+  hi! link phpPropertyInStringError Error
+
+  syn region phpIdentifierInStringComplex matchgroup=phpSpecialChar
+        \ start=/{\$\@=/ start=/\${\w\@!/ end=/}/
+        \ contained extend keepend contains=@phpClExpressions
+        \ containedin=@phpClStringsWithIdentifiers
+
+  syn region phpIdentifierInStringErratic contained extend
+        \ matchgroup=phpSpecialChar start=/\${\w\@=/ end=/}/
+        \ containedin=@phpClStringsWithIdentifiers
+        \ contains=phpIdentifierErratic
+
+  syn match phpIdentifierErratic /{\@<=\h\w*/ contained
+        \ nextgroup=phpErraticBracketRegion
+        \ nextgroup=phpIdentifierInStringErraticError skipwhite skipempty
+  syn region phpErraticBracketRegion contained keepend extend contains=@phpClExpressions
+        \ matchgroup=phpParent start=/\[/ end=/\]/ display
+        \ matchgroup=Error end=/;/
+        \ nextgroup=phpIdentifierInStringErraticError skipwhite skipempty
+
+  syn match phpIdentifierInStringErraticError contained /[^ \t\r\n}]\+/
+        \ nextgroup=phpIdentifierInStringErraticError skipwhite skipempty
+  hi link phpIdentifierInStringErraticError Error
+
+
+" PHP syntax: variables/identifiers ($foo) {{{1
+
+  " one $
+  syn match phpVarSelector      contained display /\$/
+  " two $$
+  syn match phpVarSelectorDeref contained display /\$\$/
+  syn match phpVarSelectorError contained display /\$\$\$\+/
+
+  " match a regular variable
+  syn cluster phpClExpressions add=phpIdentifier
+  syn match phpIdentifier /\$\h\w*/ contained display
+        \ contains=phpVarSelector,@phpClIdentifier
+
+  " match a dereference-variable ($$variable)
+  syn match phpIdentifier /\$\$\+\h\w*/ contained display
+        \ contains=@phpClIdentifier,phpVarSelectorDeref,phpVarSelectorError,phpDerefInvalid
+
+  " you can't dereference these variables:
+  syn match phpDerefInvalid contained display
+        \ /\C\$\$\ze\%(this\|arg[cv]\|GLOBALS\)\>/
+  syn match phpDerefInvalid contained display
+        \ /\C\$\$\ze_\%(GET\|POST\|REQUEST\|COOKIE\|SESSION\|SERVER\|ENV\)\>/
+  hi link phpDerefInvalid Error
+
+  if s:special_vars
+
+    syn case match
+
+    " Superglobals: {{{2
+    syn cluster phpClIdentifier add=phpSuperglobal
+    syn match phpSuperglobal contained display /\$\@<=GLOBALS\>/
+    syn match phpSuperglobal contained display /\$\@<=_GET\>/
+    syn match phpSuperglobal contained display /\$\@<=_POST\>/
+    syn match phpSuperglobal contained display /\$\@<=_COOKIE\>/
+    syn match phpSuperglobal contained display /\$\@<=_REQUEST\>/
+    syn match phpSuperglobal contained display /\$\@<=_FILES\>/
+    syn match phpSuperglobal contained display /\$\@<=_SESSION\>/
+    syn match phpSuperglobal contained display /\$\@<=_SERVER\>/
+    syn match phpSuperglobal contained display /\$\@<=_ENV\>/
+    syn match phpSuperglobal contained display /\$\@<=this\>/
+
+    " Built In Variables: {{{2
+    syn cluster phpClIdentifier add=phpBuiltinVar
+    syn match phpBuiltinVar    contained display /\$\@<=argc\>/
+    syn match phpBuiltinVar    contained display /\$\@<=argv\>/
+    syn match phpBuiltinVar    contained display /\$\@<=php_errormsg\>/
+
+    " Long Arrays: {{{2
+    syn cluster phpClIdentifier add=phpLongVar
+    syn match phpLongVar contained display /\$\@<=HTTP_GET_VARS\>/
+    syn match phpLongVar contained display /\$\@<=HTTP_POST_VARS\>/
+    syn match phpLongVar contained display /\$\@<=HTTP_POST_FILES\>/
+    syn match phpLongVar contained display /\$\@<=HTTP_COOKIE_VARS\>/
+    syn match phpLongVar contained display /\$\@<=HTTP_SESSION_VARS\>/
+    syn match phpLongVar contained display /\$\@<=HTTP_SERVER_VARS\>/
+    syn match phpLongVar contained display /\$\@<=HTTP_ENV_VARS\>/
+
+    " Server Variables: {{{2
+    " TODO: check these against the latest PHP manual
+    syn cluster phpClIdentifier add=phpEnvVar
+    syn match phpEnvVar contained display /\C\$\@<=GATEWAY_INTERFACE\>/
+    syn match phpEnvVar contained display /\C\$\@<=SERVER_NAME\>/
+    syn match phpEnvVar contained display /\C\$\@<=SERVER_SOFTWARE\>/
+    syn match phpEnvVar contained display /\C\$\@<=SERVER_PROTOCOL\>/
+    syn match phpEnvVar contained display /\C\$\@<=REQUEST_METHOD\>/
+    syn match phpEnvVar contained display /\C\$\@<=QUERY_STRING\>/
+    syn match phpEnvVar contained display /\C\$\@<=DOCUMENT_ROOT\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_ACCEPT\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_ACCEPT_CHARSET\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_ENCODING\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_ACCEPT_LANGUAGE\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_CONNECTION\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_HOST\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_REFERER\>/
+    syn match phpEnvVar contained display /\C\$\@<=HTTP_USER_AGENT\>/
+    syn match phpEnvVar contained display /\C\$\@<=REMOTE_ADDR\>/
+    syn match phpEnvVar contained display /\C\$\@<=REMOTE_PORT\>/
+    syn match phpEnvVar contained display /\C\$\@<=SCRIPT_FILENAME\>/
+    syn match phpEnvVar contained display /\C\$\@<=SERVER_ADMIN\>/
+    syn match phpEnvVar contained display /\C\$\@<=SERVER_PORT\>/
+    syn match phpEnvVar contained display /\C\$\@<=SERVER_SIGNATURE\>/
+    syn match phpEnvVar contained display /\C\$\@<=PATH_TRANSLATED\>/
+    syn match phpEnvVar contained display /\C\$\@<=SCRIPT_NAME\>/
+    syn match phpEnvVar contained display /\C\$\@<=REQUEST_URI\>/
+  endif
+
+  " }}}2
+
+" PHP Syntax: type-casting: (string)$foo {{{1
+
+  syn cluster phpClValues add=phpType
+  syn keyword phpType contained null bool boolean int integer real double float string object
+  " only match 'array' as a type when it *isn't* followed by '('
+  syn match phpType contained /\<array\>\%(\_s*(\)\@!/
+
+" PHP Syntax: function/static calls: {{{1
+
+  " Note: I could have forced function calls to be matched only when a '('
+  " follows, but I think users would want PHP functions highlighted in more
+  " places, rather than less, so I have just added the :\@! to make sure it is
+  " not part of a static method call
+  " Note: this didn't work properly ... if the match didn't include the
+  " '(...)', then functions in @phpClFunctions can't have a nextgroup on them
+  syn cluster phpClExpressions add=@phpClFunctions
+"  syn cluster phpClExpressions add=phpFunctionCall
+"  syn match phpFunctionCall contained /\<\%(\h\w*\)(\_.*)/
+"        \ contains=@phpClFunctions
+
+  " Also, a match when a word is part of a :: reference:
+  syn cluster phpClValues add=phpStaticUsage
+  syn cluster phpClExpressions add=phpStaticUsage
+  syn cluster phpClStructureHere add=phpStaticUsage
+  syn match phpStaticUsage contained display /\<\%(\h\w*\)\@>\%(\_s*::\)\@=/
+        \ transparent contains=@phpClClasses
+
+
+  " a match for a static function call
+  syn cluster phpClValues add=phpStaticAccess
+  syn cluster phpClExpressions add=phpStaticVariable,phpStaticCall
+  syn cluster phpClPropertyHere add=phpStaticAccess
+  syn cluster phpClMethodHere add=phpStaticCall
+
+  " also allowed in function prototypes
+  syn cluster phpClDefineFuncProtoArgs add=phpStaticAccess
+
+  syn match phpStaticAccess contained extend display /::\_s*\%(\h\w*\|\%#\)/ contains=phpDoubleColon
+  syn match phpStaticCall contained extend display /::\_s*\h\w*\ze\_s*(/
+        \ contains=phpDoubleColon,@phpClMethods
+
+  " a match for a static variable usage
+  syn match phpStaticVariable contained display /::\_s*\$\h\w*/ extend
+        \ contains=phpDoubleColon,phpIdentifier
+
+  " a match for a static constant usage
+
+  syn match phpDoubleColon contained display /::/
+  hi link phpDoubleColon phpDefine
+
+
+" PHP Syntax: magic classes (self/parent): {{{1
+
+  syn cluster phpClClasses add=phpMagicClass
+  syn keyword phpMagicClass contained self parent
+
+  " Note: 'self' and 'parent' are also matched in other places because they
+  " could be confusing otherwise ...
+  syn cluster phpClValues add=phpMagicClass
+
+" PHP Syntax: control structures: {{{1
+
+  syn cluster phpClCode add=phpConditional
+  syn keyword phpConditional contained declare enddeclare if else elseif endif
+
+  syn cluster phpClCode add=phpRepeat
+  syn keyword phpRepeat contained foreach endforeach
+        \ do while endwhile for endfor
+        \ switch endswitch
+
+  " override 'foreach' if we need use a special colour for the '(...)' region
+  if s:alt_arrays || s:alt_control_parents
+    syn keyword phpRepeat contained foreach nextgroup=phpForeachRegion skipwhite skipempty
+    syn keyword phpAs contained as containedin=phpForeachRegion
+    hi link phpAs phpRepeat
+  else
+    " otherwise, allow 'as' anywhere
+    syn cluster phpClExpressions add=phpAs
+    syn keyword phpAs contained as
+  endif
+
+  if s:strict_blocks
+    " need an alternate parenthesis block for 'for' structure
+    " when using strict blocks
+    syn keyword phpRepeat contained for nextgroup=phpForRegion skipwhite skipempty
+
+    " if looking for errors with semicolons, add the other 'nextgroups' as well
+    if s:no_empty_construct
+      syn keyword phpRepeat contained while nextgroup=phpConstructRegion skipwhite skipempty
+      syn keyword phpRepeat contained switch nextgroup=phpSwitchConstructRegion skipwhite skipempty
+      syn keyword phpConditional contained if elseif nextgroup=phpConstructRegion skipwhite skipempty
+      syn keyword phpConditional contained else nextgroup=phpSemicolonNotAllowedHere skipwhite skipempty
+      syn keyword phpRepeat contained do nextgroup=phpDoBlock,phpSemicolonNotAllowedHere skipwhite skipempty
+      if s:folding == 2
+        syn region phpDoBlock matchgroup=phpBrace start=/{/ end=/}/ keepend extend
+              \ contained transparent
+              \ nextgroup=phpDoWhile skipwhite skipempty
+"              \ matchgroup=phpHTMLError end=/?>/
+              \ fold
+        syn region phpSwitchBlock matchgroup=phpBrace start=/{/ end=/}/ keepend extend
+              \ contained contains=@phpClInSwitch,@phpClCode
+              \ fold
+      else
+        syn region phpDoBlock matchgroup=phpBrace start=/{/ end=/}/ keepend extend
+              \ contained transparent
+              \ nextgroup=phpDoWhile skipwhite skipempty
+"              \ matchgroup=phpHTMLError end=/?>/
+        syn region phpSwitchBlock matchgroup=phpBrace start=/{/ end=/}/ keepend extend
+              \ contained contains=@phpClInSwitch,@phpClCode
+
+        " TODO: thoroughly test this feature ...
+        if s:fold_manual
+          syn region phpDoBlock matchgroup=phpBrace start='{\ze\s*//\s*fold\s*$\c' end='}' keepend extend
+                \ contained transparent
+                \ nextgroup=phpDoWhile skipwhite skipempty
+"               \ matchgroup=phpHTMLError end=/?>/
+                \ fold
+          syn region phpSwitchBlock matchgroup=phpBrace start='{\ze\s*//\s*fold\s*$\c' end='}' keepend extend
+                \ contained contains=@phpClInSwitch,@phpClCode
+                \ fold
+        endif
+      endif
+      syn keyword phpDoWhile contained while nextgroup=phpDoWhileConstructRegion skipwhite skipempty
+      hi link phpDoWhile phpRepeat
+    endif
+  endif
+
+
+" PHP Syntax: statements: {{{1
+
+  " if we are not using smart semicolons, we can implement these using
+  " keywords
+  if ! s:smart_semicolon
+    syn cluster phpClCode add=phpStatement
+    syn keyword phpStatement contained return break continue exit die throw
+
+    syn cluster phpClInSwitch add=phpCase
+    syn keyword phpCase contained case default
+
+  else
+    " if we *are* using smart semicolons, we'll need to use regions instead
+    syn cluster phpClCode add=phpStatementRegion
+    syn cluster phpClInSwitch add=phpCaseRegion
+
+    " with or without error on mis-matched /})]/ at end?
+    " Note: by containing phpSemicolonError, the semicolon error is
+    " automatically taken care of by the phpSemicolonError item
+
+    " return/break/continue/exit/die: {{{2
+    " Note: having an error ending at 'private/var/final' etc, makes things much
+    " much faster for writing classes.
+    if s:strict_blocks
+      syn region phpStatementRegion extend keepend contained
+            \ contains=@phpClExpressions,phpSemicolonError
+            \ matchgroup=phpStatement end=/;/ end=/\ze?>/
+            \ start=/\$\@<!\<return\>/
+            \ start=/\$\@<!\<break\>/
+            \ start=/\$\@<!\<continue\>/
+            \ start=/\$\@<!\<exit\>/
+            \ start=/\$\@<!\<die\>/
+            \ start=/\$\@<!\<throw\>/
+            \ matchgroup=Error
+              \ end=/[$>]\@<!\<\%(protected\|public\|private\|var\|final\|abstract\|static\)\>/
+              \ end=/}/ end=/)/ end=/\]/
+              \ end=/,/
+"              \ end=/;\_s*\%([.*\^|&,:!=<>]\|?>\@!\|\/[/*]\@!\|++\@!\|--\@!\)/
+    else
+      syn region phpStatementRegion extend keepend contained
+            \ contains=@phpClExpressions,phpSemicolonError
+            \ matchgroup=phpStatement end=/;/
+            \ start=/\$\@<!\<return\>/
+            \ start=/\$\@<!\<break\>/
+            \ start=/\$\@<!\<continue\>/
+            \ start=/\$\@<!\<exit\>/
+            \ start=/\$\@<!\<die\>/
+            \ start=/\$\@<!\<throw\>/
+"              \ end=/;\_s*\%([.*\^|&,:!=<>]\|?>\@!\|\/[/*]\@!\|++\@!\|--\@!\)/
+    endif " }}}2
+    " case: {{{2
+    if s:strict_blocks
+      syn region phpCaseRegion extend keepend contained display
+            \ contains=@phpClExpressions,phpSemicolonError,phpColonError
+            \ matchgroup=phpCase start=/\$\@<!\<case\>/ end=/[;:]/ skip=/::/
+            \ matchgroup=Error
+              \ end=/}/ end=/)/ end=/\]/
+"              \ end=/;\_s*\%([.*\^|&,:!=<>]\|?>\@!\|\/[/*]\@!\|++\@!\|--\@!\)/
+    else
+      syn region phpCaseRegion extend keepend contained display
+            \ contains=@phpClExpressions,phpSemicolonError,phpColonError
+            \ matchgroup=phpCase start=/\$\@<!\<case\>/ end=/[;:]/
+    endif " }}}2
+    " default: {{{2
+    if s:strict_blocks
+      syn region phpCaseRegion extend keepend contained display
+            \ contains=phpComment,phpSemicolonError,phpColonError
+            \ matchgroup=phpCase start=/\$\@<!\<default\>/ end=/[;:]/
+            \ matchgroup=Error end=/}/ end=/)/ end=/\]/
+"              \ end=/;\_s*\%([.*\^|&,:!=<>]\|?>\@!\|\/[/*]\@!\|++\@!\|--\@!\)/
+    else
+      syn region phpCaseRegion extend keepend contained display
+            \ contains=phpComment,phpSemicolonError,phpColonError
+            \ matchgroup=phpCase start=/\$\@<!\<default\>/ end=/[;:]/
+    endif " }}}2
+
+  endif
+
+  " if we *aren't* using strict blocks, allow a 'case' or 'default'
+  " anywhere in regular code
+  if ! s:strict_blocks
+    syn cluster phpClCode add=@phpClInSwitch
+  endif
+
+
+" PHP Syntax: semicolons: {{{1
+
+  if s:show_semicolon
+    " highlight the semicolon anywhere it appears in regular code
+    syn cluster phpClExpressions add=phpSemicolon
+    syn match phpSemicolon /;/ contained display contains=phpSemicolonError
+
+    " match a semicolon or colon which is followed by one of:
+    "   = ! . +-*/ &|^ < > , ? :
+    if s:show_semicolon_error
+      " match a semicolon or colon which is followed by one of:
+      "   = ! . +-*/ &|^ < > , ? :
+      syn match phpSemicolonError contained display extend
+            \ ";\_s*\%(\%(\%(//.*$\|#.*$\|/\*\_.\{-}\*/\)\_s*\)*\)\@>\%([.*/\^|&,:!=<>]\|?>\@!\|++\@!\|--\@!\)"
+      syn match phpColonError contained display extend
+            \ "::\@!\_s*\%(\%(\%(//.*$\|#.*$\|/\*\_.\{-}\*/\)\_s*\)*\)\@>\%([.*/\^|&,:!=<>]\|?>\@!\|++\@!\|--\@!\)"
+    endif
+    hi link phpSemicolonError Error
+    hi link phpColonError Error
+
+    " need to sync back one or two linebreaks to capture the semicolon
+    " error properly
+    syn sync linebreaks=2
+  endif
+
+  " a special match for when a semicolon is not allowed here
+  " Note: this is contained/nextgrouped by other items, not included
+  " directly
+  if s:no_empty_construct
+    syn match phpSemicolonNotAllowedHere /;/ contained display
+  endif
+
+
+" PHP Syntax: constants: {{{1
+
+  " Magic Constants {{{2
+    syn cluster phpClConstants add=phpMagicConstant
+    syn case match
+    syn keyword        phpMagicConstant contained __LINE__ __FILE__ __FUNCTION__ __METHOD__ __CLASS__
+    syn case ignore
+  " }}}2
+
+  " Built-in Constants {{{2
+  " TODO: check these against the latest PHP manual
+    syn cluster phpClConstants add=phpCoreConstant
+    syn case match
+    syn keyword phpCoreConstant contained ASSERT_ACTIVE ASSERT_BAIL ASSERT_CALLBACK ASSERT_QUIET_EVAL ASSERT_WARNING
+    syn keyword phpCoreConstant contained CAL_DOW_DAYNO CAL_DOW_LONG CAL_DOW_SHORT CAL_EASTER_ALWAYS_GREGORIAN CAL_EASTER_ALWAYS_JULIAN CAL_EASTER_DEFAULT CAL_EASTER_ROMAN CAL_FRENCH CAL_GREGORIAN CAL_JULIAN CAL_NUM_CALS CAL_JEWISH CAL_JEWISH_ADD_ALAFIM CAL_JEWISH_ADD_ALAFIM_GERESH CAL_JEWISH_ADD_GERESHAYIM CAL_MONTH_FRENCH CAL_MONTH_GREGORIAN_LONG CAL_MONTH_GREGORIAN_SHORT CAL_MONTH_JEWISH CAL_MONTH_JULIAN_LONG CAL_MONTH_JULIAN_SHORT
+    syn keyword phpCoreConstant contained CASE_LOWER CASE_UPPER CHAR_MAX
+    syn keyword phpCoreConstant contained CLSCTX_ALL CLSCTX_INPROC_HANDLER CLSCTX_INPROC_SERVER CLSCTX_LOCAL_SERVER CLSCTX_REMOTE_SERVER CLSCTX_SERVER
+    syn keyword phpCoreConstant contained CONNECTION_ABORTED CONNECTION_NORMAL CONNECTION_TIMEOUT
+    syn keyword phpCoreConstant contained COUNT_NORMAL COUNT_RECURSIVE
+    syn keyword phpCoreConstant contained CP_ACP CP_MACCP CP_OEMCP CP_SYMBOL CP_THREAD_ACP CP_UTF7 CP_UTF8
+    syn keyword phpCoreConstant contained CREDITS_ALL CREDITS_DOCS CREDITS_FULLPAGE CREDITS_GENERAL CREDITS_GROUP CREDITS_MODULES CREDITS_QA CREDITS_SAPI
+    syn keyword phpCoreConstant contained CRYPT_BLOWFISH CRYPT_EXT_DES CRYPT_MD5 CRYPT_SALT_LENGTH CRYPT_STD_DES
+    syn keyword phpCoreConstant contained DATE_ATOM DATE_COOKIE DATE_ISO8601 DATE_RFC1036 DATE_RFC1123 DATE_RFC2822 DATE_RFC822 DATE_RFC850 DATE_RSS DATE_W3C
+    syn keyword phpCoreConstant contained DEFAULT_INCLUDE_PATH DIRECTORY_SEPARATOR
+    syn keyword phpCoreConstant contained DISP_E_BADINDEX DISP_E_DIVBYZERO DISP_E_OVERFLOW
+    syn keyword phpCoreConstant contained DOMSTRING_SIZE_ERR
+    syn keyword phpCoreConstant contained DOM_HIERARCHY_REQUEST_ERR DOM_INDEX_SIZE_ERR DOM_INUSE_ATTRIBUTE_ERR DOM_INVALID_ACCESS_ERR DOM_INVALID_CHARACTER_ERR DOM_INVALID_MODIFICATION_ERR
+    syn keyword phpCoreConstant contained DOM_INVALID_STATE_ERR DOM_NAMESPACE_ERR DOM_NOT_FOUND_ERR DOM_NOT_SUPPORTED_ERR DOM_NO_DATA_ALLOWED_ERR DOM_NO_MODIFICATION_ALLOWED_ERR DOM_PHP_ERR
+    syn keyword phpCoreConstant contained DOM_SYNTAX_ERR DOM_VALIDATION_ERR DOM_WRONG_DOCUMENT_ERR
+    syn keyword phpCoreConstant contained ENT_COMPAT ENT_NOQUOTES ENT_QUOTES
+    syn keyword phpCoreConstant contained EXTR_IF_EXISTS EXTR_OVERWRITE EXTR_PREFIX_ALL EXTR_PREFIX_IF_EXISTS EXTR_PREFIX_INVALID EXTR_PREFIX_SAME EXTR_REFS EXTR_SKIP
+    syn keyword phpCoreConstant contained E_ERROR E_WARNING E_PARSE E_NOTICE E_STRICT E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_ALL
+    syn keyword phpCoreConstant contained FILE_APPEND FILE_IGNORE_NEW_LINES FILE_NO_DEFAULT_CONTEXT FILE_SKIP_EMPTY_LINES FILE_USE_INCLUDE_PATH
+    syn keyword phpCoreConstant contained FORCE_DEFLATE FORCE_GZIP
+    syn keyword phpCoreConstant contained FTP_ASCII FTP_AUTORESUME FTP_AUTOSEEK FTP_BINARY FTP_FAILED FTP_FINISHED FTP_IMAGE FTP_MOREDATA FTP_TEXT FTP_TIMEOUT_SEC
+    syn keyword phpCoreConstant contained GLOB_BRACE GLOB_ERR GLOB_MARK GLOB_NOCHECK GLOB_NOESCAPE GLOB_NOSORT GLOB_ONLYDIR
+    syn keyword phpCoreConstant contained HTML_ENTITIES HTML_SPECIALCHARS
+    syn keyword phpCoreConstant contained ICONV_IMPL ICONV_MIME_DECODE_CONTINUE_ON_ERROR ICONV_MIME_DECODE_STRICT ICONV_VERSION
+    syn keyword phpCoreConstant contained IMAGETYPE_BMP IMAGETYPE_GIF IMAGETYPE_IFF IMAGETYPE_JB2 IMAGETYPE_JP2 IMAGETYPE_JPC IMAGETYPE_JPEG IMAGETYPE_JPEG2000
+    syn keyword phpCoreConstant contained IMAGETYPE_JPX IMAGETYPE_PNG IMAGETYPE_PSD IMAGETYPE_SWC IMAGETYPE_SWF IMAGETYPE_TIFF_II IMAGETYPE_TIFF_MM IMAGETYPE_WBMP IMAGETYPE_XBM
+    syn keyword phpCoreConstant contained INF
+    syn keyword phpCoreConstant contained INFO_ALL INFO_CONFIGURATION INFO_CREDITS INFO_ENVIRONMENT INFO_GENERAL INFO_LICENSE INFO_MODULES INFO_VARIABLES
+    syn keyword phpCoreConstant contained INI_ALL INI_PERDIR INI_SYSTEM INI_USER
+    syn keyword phpCoreConstant contained LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME
+    syn keyword phpCoreConstant contained LIBXML_COMPACT LIBXML_DOTTED_VERSION LIBXML_DTDATTR LIBXML_DTDLOAD LIBXML_DTDVALID LIBXML_ERR_ERROR LIBXML_ERR_FATAL LIBXML_ERR_NONE
+    syn keyword phpCoreConstant contained LIBXML_ERR_WARNING LIBXML_NOBLANKS LIBXML_NOCDATA LIBXML_NOEMPTYTAG LIBXML_NOENT LIBXML_NOERROR LIBXML_NONET LIBXML_NOWARNING
+    syn keyword phpCoreConstant contained LIBXML_NOXMLDECL LIBXML_NSCLEAN LIBXML_VERSION LIBXML_XINCLUDE
+    syn keyword phpCoreConstant contained LOCK_EX LOCK_NB LOCK_SH LOCK_UN
+    syn keyword phpCoreConstant contained LOG_ALERT LOG_AUTH LOG_AUTHPRIV LOG_CONS LOG_CRIT LOG_CRON LOG_DAEMON LOG_DEBUG
+    syn keyword phpCoreConstant contained LOG_EMERG LOG_ERR LOG_INFO LOG_KERN LOG_LPR LOG_MAIL LOG_NDELAY LOG_NEWS
+    syn keyword phpCoreConstant contained LOG_NOTICE LOG_NOWAIT LOG_ODELAY LOG_PERROR LOG_PID LOG_SYSLOG LOG_USER LOG_UUCP LOG_WARNING
+    syn keyword phpCoreConstant contained MK_E_UNAVAILABLE
+    syn keyword phpCoreConstant contained MYSQL_ASSOC MYSQL_BOTH MYSQL_CLIENT_COMPRESS MYSQL_CLIENT_IGNORE_SPACE MYSQL_CLIENT_INTERACTIVE MYSQL_CLIENT_SSL MYSQL_NUM
+    syn keyword phpCoreConstant contained M_1_PI M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2 M_LOG10E M_LOG2E M_PI M_PI_2 M_PI_4 M_SQRT1_2 M_SQRT2
+    syn keyword phpCoreConstant contained NAN
+    syn keyword phpCoreConstant contained NORM_IGNORECASE NORM_IGNOREKANATYPE NORM_IGNORENONSPACE NORM_IGNORESYMBOLS NORM_IGNOREWIDTH
+    syn keyword phpCoreConstant contained ODBC_BINMODE_CONVERT ODBC_BINMODE_PASSTHRU ODBC_BINMODE_RETURN ODBC_TYPE
+    syn keyword phpCoreConstant contained PATHINFO_BASENAME PATHINFO_DIRNAME PATHINFO_EXTENSION
+    syn keyword phpCoreConstant contained PATH_SEPARATOR
+    syn keyword phpCoreConstant contained PEAR_INSTALL_DIR PEAR_EXTENSION_DIR
+    syn keyword phpCoreConstant contained PHP_PREFIX PHP_BINDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_DATADIR PHP_EXTENSION_DIR PHP_LIBDIR PHP_LOCALSTATEDIR PHP_SYSCONFDIR PHP_SHLIB_SUFFIX
+    syn keyword phpCoreConstant contained PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_END PHP_OUTPUT_HANDLER_START
+    syn keyword phpCoreConstant contained PHP_URL_FRAGMENT PHP_URL_HOST PHP_URL_PASS PHP_URL_PATH PHP_URL_PORT PHP_URL_QUERY PHP_URL_SCHEME PHP_URL_USER
+    syn keyword phpCoreConstant contained PHP_VERSION PHP_OS PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_SIZE
+    syn keyword phpCoreConstant contained PREG_GREP_INVERT PREG_OFFSET_CAPTURE PREG_PATTERN_ORDER PREG_SET_ORDER PREG_SPLIT_DELIM_CAPTURE PREG_SPLIT_NO_EMPTY PREG_SPLIT_OFFSET_CAPTURE
+    syn keyword phpCoreConstant contained PSFS_ERR_FATAL PSFS_FEED_ME PSFS_FLAG_FLUSH_CLOSE PSFS_FLAG_FLUSH_INC PSFS_FLAG_NORMAL PSFS_PASS_ON
+    syn keyword phpCoreConstant contained SEEK_CUR SEEK_END SEEK_SET
+    syn keyword phpCoreConstant contained SORT_ASC SORT_DESC SORT_LOCALE_STRING SORT_NUMERIC SORT_REGULAR SORT_STRING
+    syn keyword phpCoreConstant contained SQL_BIGINT SQL_BINARY SQL_BIT SQL_CHAR SQL_CONCURRENCY SQL_CONCUR_LOCK SQL_CONCUR_READ_ONLY SQL_CONCUR_ROWVER SQL_CONCUR_VALUES
+    syn keyword phpCoreConstant contained SQL_CURSOR_DYNAMIC SQL_CURSOR_FORWARD_ONLY SQL_CURSOR_KEYSET_DRIVEN SQL_CURSOR_STATIC SQL_CURSOR_TYPE SQL_CUR_USE_DRIVER SQL_CUR_USE_IF_NEEDED SQL_CUR_USE_ODBC
+    syn keyword phpCoreConstant contained SQL_DATE SQL_DECIMAL SQL_DOUBLE SQL_FETCH_FIRST SQL_FETCH_NEXT SQL_FLOAT SQL_INTEGER SQL_KEYSET_SIZE
+    syn keyword phpCoreConstant contained SQL_LONGVARBINARY SQL_LONGVARCHAR SQL_NUMERIC SQL_ODBC_CURSORS SQL_REAL SQL_SMALLINT SQL_TIME SQL_TIMESTAMP SQL_TINYINT SQL_VARBINARY SQL_VARCHAR
+    syn keyword phpCoreConstant contained STDERR STDIN STDOUT
+    syn keyword phpCoreConstant contained STREAM_CLIENT_ASYNC_CONNECT STREAM_CLIENT_CONNECT STREAM_CLIENT_PERSISTENT
+    syn keyword phpCoreConstant contained STREAM_CRYPTO_METHOD_SSLv23_CLIENT STREAM_CRYPTO_METHOD_SSLv23_SERVER STREAM_CRYPTO_METHOD_SSLv2_CLIENT STREAM_CRYPTO_METHOD_SSLv2_SERVER STREAM_CRYPTO_METHOD_SSLv3_CLIENT STREAM_CRYPTO_METHOD_SSLv3_SERVER STREAM_CRYPTO_METHOD_TLS_CLIENT STREAM_CRYPTO_METHOD_TLS_SERVER
+    syn keyword phpCoreConstant contained STREAM_ENFORCE_SAFE_MODE STREAM_FILTER_ALL STREAM_FILTER_READ STREAM_FILTER_WRITE STREAM_IGNORE_URL
+    syn keyword phpCoreConstant contained STREAM_IPPROTO_ICMP STREAM_IPPROTO_IP STREAM_IPPROTO_RAW STREAM_IPPROTO_TCP STREAM_IPPROTO_UDP STREAM_MKDIR_RECURSIVE STREAM_MUST_SEEK
+    syn keyword phpCoreConstant contained STREAM_NOTIFY_AUTH_REQUIRED STREAM_NOTIFY_AUTH_RESULT STREAM_NOTIFY_COMPLETED STREAM_NOTIFY_CONNECT STREAM_NOTIFY_FAILURE STREAM_NOTIFY_FILE_SIZE_IS STREAM_NOTIFY_MIME_TYPE_IS
+    syn keyword phpCoreConstant contained STREAM_NOTIFY_PROGRESS STREAM_NOTIFY_REDIRECTED STREAM_NOTIFY_RESOLVE STREAM_NOTIFY_SEVERITY_ERR STREAM_NOTIFY_SEVERITY_INFO STREAM_NOTIFY_SEVERITY_WARN
+    syn keyword phpCoreConstant contained STREAM_OOB STREAM_PEEK STREAM_PF_INET STREAM_PF_INET6 STREAM_PF_UNIX STREAM_REPORT_ERRORS STREAM_SERVER_BIND STREAM_SERVER_LISTEN
+    syn keyword phpCoreConstant contained STREAM_SOCK_DGRAM STREAM_SOCK_RAW STREAM_SOCK_RDM STREAM_SOCK_SEQPACKET STREAM_SOCK_STREAM STREAM_URL_STAT_LINK STREAM_URL_STAT_QUIET STREAM_USE_PATH
+    syn keyword phpCoreConstant contained STR_PAD_BOTH STR_PAD_LEFT STR_PAD_RIGHT
+    syn keyword phpCoreConstant contained SUNFUNCS_RET_DOUBLE SUNFUNCS_RET_STRING SUNFUNCS_RET_TIMESTAMP
+    syn keyword phpCoreConstant contained T_ABSTRACT T_AND_EQUAL T_ARRAY T_ARRAY_CAST T_AS T_BAD_CHARACTER T_BOOLEAN_AND T_BOOLEAN_OR T_BOOL_CAST T_BREAK T_CASE T_CATCH
+    syn keyword phpCoreConstant contained T_CHARACTER T_CLASS T_CLASS_C T_CLONE T_CLOSE_TAG T_COMMENT T_CONCAT_EQUAL T_CONST T_CONSTANT_ENCAPSED_STRING T_CONTINUE
+    syn keyword phpCoreConstant contained T_CURLY_OPEN T_DEC T_DECLARE T_DEFAULT T_DIV_EQUAL T_DNUMBER T_DO T_DOC_COMMENT T_DOLLAR_OPEN_CURLY_BRACES T_DOUBLE_ARROW
+    syn keyword phpCoreConstant contained T_DOUBLE_CAST T_DOUBLE_COLON T_ECHO T_ELSE T_ELSEIF T_EMPTY T_ENCAPSED_AND_WHITESPACE T_ENDDECLARE T_ENDFOR T_ENDFOREACH
+    syn keyword phpCoreConstant contained T_ENDIF T_ENDSWITCH T_ENDWHILE T_END_HEREDOC T_EVAL T_EXIT T_EXTENDS T_FILE T_FINAL T_FOR T_FOREACH T_FUNCTION T_FUNC_C
+    syn keyword phpCoreConstant contained T_GLOBAL T_HALT_COMPILER T_IF T_IMPLEMENTS T_INC T_INCLUDE T_INCLUDE_ONCE T_INLINE_HTML T_INSTANCEOF T_INTERFACE T_INT_CAST
+    syn keyword phpCoreConstant contained T_ISSET T_IS_EQUAL T_IS_GREATER_OR_EQUAL T_IS_IDENTICAL T_IS_NOT_EQUAL T_IS_NOT_IDENTICAL T_IS_SMALLER_OR_EQUAL T_LINE T_LIST
+    syn keyword phpCoreConstant contained T_LNUMBER T_LOGICAL_AND T_LOGICAL_OR T_LOGICAL_XOR T_METHOD_C T_MINUS_EQUAL T_MOD_EQUAL T_MUL_EQUAL T_NEW T_NUM_STRING T_OBJECT_CAST
+    syn keyword phpCoreConstant contained T_OBJECT_OPERATOR T_OPEN_TAG T_OPEN_TAG_WITH_ECHO T_OR_EQUAL T_PAAMAYIM_NEKUDOTAYIM T_PLUS_EQUAL T_PRINT T_PRIVATE T_PROTECTED T_PUBLIC
+    syn keyword phpCoreConstant contained T_REQUIRE T_REQUIRE_ONCE T_RETURN T_SL T_SL_EQUAL T_SR T_SR_EQUAL T_START_HEREDOC T_STATIC T_STRING T_STRING_CAST T_STRING_VARNAME
+    syn keyword phpCoreConstant contained T_SWITCH T_THROW T_TRY T_UNSET T_UNSET_CAST T_USE T_VAR T_VARIABLE T_WHILE T_WHITESPACE T_XOR_EQUAL
+    syn keyword phpCoreConstant contained UPLOAD_ERR_CANT_WRITE UPLOAD_ERR_FORM_SIZE UPLOAD_ERR_INI_SIZE UPLOAD_ERR_NO_FILE UPLOAD_ERR_NO_TMP_DIR UPLOAD_ERR_OK UPLOAD_ERR_PARTIAL
+    syn keyword phpCoreConstant contained VARCMP_EQ VARCMP_GT VARCMP_LT VARCMP_NULL
+    syn keyword phpCoreConstant contained VT_ARRAY VT_BOOL VT_BSTR VT_BYREF VT_CY VT_DATE VT_DECIMAL VT_DISPATCH VT_EMPTY VT_ERROR VT_I1 VT_I2 VT_I4 VT_INT VT_NULL VT_R4 VT_R8 VT_UI1 VT_UI2 VT_UI4 VT_UINT VT_UNKNOWN VT_VARIANT
+    syn keyword phpCoreConstant contained XML_ATTRIBUTE_CDATA XML_ATTRIBUTE_DECL_NODE XML_ATTRIBUTE_ENTITY XML_ATTRIBUTE_ENUMERATION XML_ATTRIBUTE_ID XML_ATTRIBUTE_IDREF
+    syn keyword phpCoreConstant contained XML_ATTRIBUTE_IDREFS XML_ATTRIBUTE_NMTOKEN XML_ATTRIBUTE_NMTOKENS XML_ATTRIBUTE_NODE XML_ATTRIBUTE_NOTATION XML_CDATA_SECTION_NODE
+    syn keyword phpCoreConstant contained XML_COMMENT_NODE XML_DOCUMENT_FRAG_NODE XML_DOCUMENT_NODE XML_DOCUMENT_TYPE_NODE XML_DTD_NODE XML_ELEMENT_DECL_NODE XML_ELEMENT_NODE
+    syn keyword phpCoreConstant contained XML_ENTITY_DECL_NODE XML_ENTITY_NODE XML_ENTITY_REF_NODE XML_ERROR_ASYNC_ENTITY XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF XML_ERROR_BAD_CHAR_REF
+    syn keyword phpCoreConstant contained XML_ERROR_BINARY_ENTITY_REF XML_ERROR_DUPLICATE_ATTRIBUTE XML_ERROR_EXTERNAL_ENTITY_HANDLING XML_ERROR_INCORRECT_ENCODING XML_ERROR_INVALID_TOKEN
+    syn keyword phpCoreConstant contained XML_ERROR_JUNK_AFTER_DOC_ELEMENT XML_ERROR_MISPLACED_XML_PI XML_ERROR_NONE XML_ERROR_NO_ELEMENTS XML_ERROR_NO_MEMORY XML_ERROR_PARAM_ENTITY_REF
+    syn keyword phpCoreConstant contained XML_ERROR_PARTIAL_CHAR XML_ERROR_RECURSIVE_ENTITY_REF XML_ERROR_SYNTAX XML_ERROR_TAG_MISMATCH XML_ERROR_UNCLOSED_CDATA_SECTION
+    syn keyword phpCoreConstant contained XML_ERROR_UNCLOSED_TOKEN XML_ERROR_UNDEFINED_ENTITY XML_ERROR_UNKNOWN_ENCODING XML_HTML_DOCUMENT_NODE XML_LOCAL_NAMESPACE
+    syn keyword phpCoreConstant contained XML_NAMESPACE_DECL_NODE XML_NOTATION_NODE XML_OPTION_CASE_FOLDING XML_OPTION_SKIP_TAGSTART XML_OPTION_SKIP_WHITE XML_OPTION_TARGET_ENCODING
+    syn keyword phpCoreConstant contained XML_PI_NODE XML_SAX_IMPL XML_TEXT_NODE
+    syn keyword phpCoreConstant contained ZEND_THREAD_SAFE
+    syn case ignore
+  " }}}2
+
+" PHP Syntax: functions {{{1
+
+  " TODO: move constants out of here - they need to be case-sensitive
+
+  " Function and Methods ripped from php_manual_de.tar.gz Jan 2003 {{{2
+  " TODO: check these against the latest PHP manual
+  syn cluster phpClFunctions add=phpFunctions
+
+  " Apache
+  syn keyword phpFunctions contained apache_child_terminate apache_get_modules apache_get_version apache_getenv apache_lookup_uri apache_note apache_request_headers apache_reset_timeout apache_response_headers apache_setenv ascii2ebcdic ebcdic2ascii getallheaders virtual
+
+  " APC Alternative PHP Cache
+  syn keyword phpFunctions contained apc_add apc_cache_info apc_clear_cache apc_compile_file apc_define_constants apc_delete apc_fetch apc_load_constants apc_sma_info apc_store
+
+  " APD Advanced PHP Debugger
+  syn keyword phpCoreConstant contained FUNCTION_TRACE ARGS_TRACE ASSIGNMENT_TRACE STATEMENT_TRACE MEMORY_TRACE TIMING_TRACE SUMMARY_TRACE ERROR_TRACE PROF_TRACE APD_VERSION
+  syn keyword phpFunctions contained apd_breakpoint apd_callstack apd_clunk apd_continue apd_croak apd_dump_function_table apd_dump_persistent_resources apd_dump_regular_resources apd_echo apd_get_active_symbols apd_set_pprof_trace apd_set_session_trace apd_set_session apd_set_socket_session_trace override_function rename_function
+
+  " array functions
+  syn keyword phpCoreConstant contained CASE_LOWER CASE_UPPER SORT_ASC SORT_DESC SORT_REGULAR SORT_NUMERIC SORT_STRING SORT_LOCALE_STRING COUNT_NORMAL COUNT_RECURSIVE EXTR_OVERWRITE EXTR_SKIP EXTR_PREFIX_SAME EXTR_PREFIX_ALL EXTR_PREFIX_INVALID EXTR_PREFIX_IF_EXISTS EXTR_IF_EXISTS EXTR_REFS
+  syn keyword phpFunctions contained array_change_key_case array_chunk array_combine array_count_values array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_diff array_fill_keys array_fill array_filter array_flip array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey array_intersect array_key_exists array_keys array_map array_merge_recursive array_merge array_multisort array_pad array_pop array_product array_push array_rand array_reduce array_reverse array_search array_shift array_slice array_splice array_sum array_udiff_assoc array_udiff_uassoc array_udiff array_uintersect_assoc array_uintersect_uassoc array_uintersect array_unique array_unshift array_values array_walk_recursive array_walk arsort asort compact count current each end extract in_array key krsort ksort natcasesort natsort next pos prev range reset rsort shuffle sizeof sort uasort uksort usort
+
+  " NOTE: aspell is deprecated as of PHP 4.3.0
+  " syn keyword        phpFunctions    aspell_check aspell_new aspell_suggest  contained
+
+  " BBCode
+  syn keyword phpCoreConstant contained BBCODE_TYPE_NOARG BBCODE_TYPE_SINGLE BBCODE_TYPE_ARG BBCODE_TYPE_OPTARG BBCODE_TYPE_ROOT BBCODE_FLAGS_ARG_PARSING BBCODE_FLAGS_CDATA_NOT_ALLOWED BBCODE_FLAGS_SMILEYS_ON BBCODE_FLAGS_SMILEYS_OFF BBCODE_FLAGS_ONE_OPEN_PER_LEVEL BBCODE_FLAGS_REMOVE_IF_EMPTY BBCODE_FLAGS_DENY_REOPEN_CHILD BBCODE_ARG_DOUBLE_QUOTE BBCODE_ARG_SINGLE_QUOTE BBCODE_ARG_HTML_QUOTE BBCODE_AUTO_CORRECT BBCODE_CORRECT_REOPEN_TAGS BBCODE_DISABLE_TREE_BUILD BBCODE_DEFAULT_SMILEYS_ON BBCODE_DEFAULT_SMILEYS_OFF BBCODE_FORCE_SMILEYS_OFF BBCODE_SMILEYS_CASE_INSENSITIVE BBCODE_SET_FLAGS_SET BBCODE_SET_FLAGS_ADD BBCODE_SET_FLAGS_REMOVE
+  syn keyword phpFunctions contained bbcode_add_element bbcode_add_smiley bbcode_create bbcode_destroy bbcode_parse bbcode_set_arg_parser bbcode_set_flags
+
+  " BC Math
+  syn keyword phpFunctions contained bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub
+
+  " BZip2
+  syn keyword phpFunctions contained bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite
+
+  " Calendar functions
+  syn keyword phpCoreConstant contained CAL_GREGORIAN CAL_JULIAN CAL_JEWISH CAL_FRENCH CAL_NUM_CALS CAL_DOW_DAYNO CAL_DOW_SHORT CAL_DOW_LONG CAL_MONTH_GREGORIAN_SHORT CAL_MONTH_GREGORIAN_LONG CAL_MONTH_JULIAN_SHORT CAL_MONTH_JULIAN_LONG CAL_MONTH_JEWISH CAL_MONTH_FRENCH CAL_EASTER_DEFAULT CAL_EASTER_ROMAN CAL_EASTER_ALWAYS_GREGORIAN CAL_EASTER_ALWAYS_JULIAN CAL_JEWISH_ADD_ALAFIM_GERESH CAL_JEWISH_ADD_ALAFIM CAL_JEWISH_ADD_GERESHAYIM
+  syn keyword phpFunctions contained cal_days_in_month cal_from_jd cal_info cal_to_jd easter_date easter_days FrenchToJD GregorianToJD JDDayOfWeek JDMonthName JDToFrench JDToGregorian jdtojewish JDToJulian jdtounix JewishToJD JulianToJD unixtojd
+
+  " NOTE: CCVS has been deprecated as of PHP 4.3.0
+  " syn keyword        phpFunctions    ccvs_add ccvs_auth ccvs_command ccvs_count ccvs_delete ccvs_done ccvs_init ccvs_lookup ccvs_new ccvs_report ccvs_return ccvs_reverse ccvs_sale ccvs_status ccvs_textvalue ccvs_void     contained
+
+  " Classes / Objects
+  " NOTE: call_user_method_array() and call_user_method() are both deprecated ...
+  syn keyword phpFunctions contained class_exists get_class_methods get_class_vars get_class get_declared_classes get_declared_interfaces get_object_vars get_parent_class interface_exists is_a is_subclass_of method_exists property_exists
+
+  " COM
+  syn keyword phpCoreConstant contained CLSCTX_INPROC_SERVER CLSCTX_INPROC_HANDLER CLSCTX_LOCAL_SERVER CLSCTX_REMOTE_SERVER CLSCTX_SERVER CLSCTX_ALL VT_NULL VT_EMPTY VT_UI1 VT_I2 VT_I4 VT_R4 VT_R8 VT_BOOL VT_ERROR VT_CY VT_DATE VT_BSTR VT_DECIMAL VT_UNKNOWN VT_DISPATCH VT_VARIANT VT_I1 VT_UI2 VT_UI4 VT_INT VT_UINT VT_ARRAY VT_BYREF CP_ACP CP_MACCP CP_OEMCP CP_UTF7 CP_UTF8 CP_SYMBOL CP_THREAD_ACP VARCMP_LT VARCMP_EQ VARCMP_GT VARCMP_NULL NORM_IGNORECASE NORM_IGNORENONSPACE NORM_IGNORESYMBOLS NORM_IGNOREWIDTH NORM_IGNOREKANATYPE NORM_IGNOREKASHIDA DISP_E_DIVBYZERO DISP_E_OVERFLOW MK_E_UNAVAILABLE
+  syn keyword phpClasses contained COM DOTNET VARIANT
+  syn keyword phpFunctions contained com_addref com_create_guid com_event_sink com_get_active_object com_get com_invoke com_isenum com_load_typelib com_load com_message_pump com_print_typeinfo com_propget com_propput com_propset com_release com_set variant_abs variant_add variant_and variant_cast variant_cat variant_cmp variant_date_from_timestamp variant_date_to_timestamp variant_div variant_eqv variant_fix variant_get_type variant_idiv variant_imp variant_int variant_mod variant_mul variant_neg variant_not variant_or variant_pow variant_round variant_set_type variant_set variant_sub variant_xor
+
+  " Crack functions
+  syn keyword phpFunctions contained crack_check crack_closedict crack_getlastmessage crack_opendict
+
+  " Character type functions
+  syn keyword phpFunctions contained ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_graph ctype_lower ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit
+
+  " cURL
+  syn keyword phpCoreConstant contained CURLOPT_AUTOREFERER CURLOPT_COOKIESESSION CURLOPT_DNS_USE_GLOBAL_CACHE CURLOPT_DNS_CACHE_TIMEOUT CURLOPT_FTP_SSL CURLFTPSSL_TRY CURLFTPSSL_ALL CURLFTPSSL_CONTROL CURLFTPSSL_NONE CURLOPT_PRIVATE CURLOPT_FTPSSLAUTH CURLOPT_PORT CURLOPT_FILE CURLOPT_INFILE CURLOPT_INFILESIZE CURLOPT_URL CURLOPT_PROXY CURLOPT_VERBOSE CURLOPT_HEADER CURLOPT_HTTPHEADER CURLOPT_NOPROGRESS CURLOPT_NOBODY CURLOPT_FAILONERROR CURLOPT_UPLOAD CURLOPT_POST CURLOPT_FTPLISTONLY CURLOPT_FTPAPPEND CURLOPT_FTP_CREATE_MISSING_DIRS CURLOPT_NETRC CURLOPT_FOLLOWLOCATION CURLOPT_FTPASCII CURLOPT_PUT CURLOPT_MUTE CURLOPT_USERPWD CURLOPT_PROXYUSERPWD CURLOPT_RANGE CURLOPT_TIMEOUT CURLOPT_TIMEOUT_MS CURLOPT_TCP_NODELAY CURLOPT_POSTFIELDS CURLOPT_REFERER CURLOPT_USERAGENT CURLOPT_FTPPORT CURLOPT_FTP_USE_EPSV CURLOPT_LOW_SPEED_LIMIT CURLOPT_LOW_SPEED_TIME CURLOPT_RESUME_FROM CURLOPT_COOKIE CURLOPT_SSLCERT CURLOPT_SSLCERTPASSWD CURLOPT_WRITEHEADER CURLOPT_SSL_VERIFYHOST CURLOPT_COOKIEFILE CURLOPT_SSLVERSION CURLOPT_TIMECONDITION CURLOPT_TIMEVALUE CURLOPT_CUSTOMREQUEST CURLOPT_STDERR CURLOPT_TRANSFERTEXT CURLOPT_RETURNTRANSFER CURLOPT_QUOTE CURLOPT_POSTQUOTE CURLOPT_INTERFACE CURLOPT_KRB4LEVEL CURLOPT_HTTPPROXYTUNNEL CURLOPT_FILETIME CURLOPT_WRITEFUNCTION CURLOPT_READFUNCTION CURLOPT_PASSWDFUNCTION CURLOPT_HEADERFUNCTION CURLOPT_MAXREDIRS CURLOPT_MAXCONNECTS CURLOPT_CLOSEPOLICY CURLOPT_FRESH_CONNECT CURLOPT_FORBID_REUSE CURLOPT_RANDOM_FILE CURLOPT_EGDSOCKET CURLOPT_CONNECTTIMEOUT CURLOPT_CONNECTTIMEOUT_MS CURLOPT_SSL_VERIFYPEER CURLOPT_CAINFO CURLOPT_CAPATH CURLOPT_COOKIEJAR CURLOPT_SSL_CIPHER_LIST CURLOPT_BINARYTRANSFER CURLOPT_NOSIGNAL CURLOPT_PROXYTYPE CURLOPT_BUFFERSIZE CURLOPT_HTTPGET CURLOPT_HTTP_VERSION CURLOPT_SSLKEY CURLOPT_SSLKEYTYPE CURLOPT_SSLKEYPASSWD CURLOPT_SSLENGINE CURLOPT_SSLENGINE_DEFAULT CURLOPT_SSLCERTTYPE CURLOPT_CRLF CURLOPT_ENCODING CURLOPT_PROXYPORT CURLOPT_UNRESTRICTED_AUTH CURLOPT_FTP_USE_EPRT CURLOPT_HTTP200ALIASES CURLOPT_HTTPAUTH CURLAUTH_BASIC
+  syn keyword phpCoreConstant contained CURLAUTH_DIGEST CURLAUTH_GSSNEGOTIATE CURLAUTH_NTLM CURLAUTH_ANY CURLAUTH_ANYSAFE CURLOPT_PROXYAUTH CURLCLOSEPOLICY_LEAST_RECENTLY_USED CURLCLOSEPOLICY_LEAST_TRAFFIC CURLCLOSEPOLICY_SLOWEST CURLCLOSEPOLICY_CALLBACK CURLCLOSEPOLICY_OLDEST CURLINFO_PRIVATE CURLINFO_EFFECTIVE_URL CURLINFO_HTTP_CODE CURLINFO_HEADER_OUT CURLINFO_HEADER_SIZE CURLINFO_REQUEST_SIZE CURLINFO_TOTAL_TIME CURLINFO_NAMELOOKUP_TIME CURLINFO_CONNECT_TIME CURLINFO_PRETRANSFER_TIME CURLINFO_SIZE_UPLOAD CURLINFO_SIZE_DOWNLOAD CURLINFO_SPEED_DOWNLOAD CURLINFO_SPEED_UPLOAD CURLINFO_FILETIME CURLINFO_SSL_VERIFYRESULT CURLINFO_CONTENT_LENGTH_DOWNLOAD CURLINFO_CONTENT_LENGTH_UPLOAD CURLINFO_STARTTRANSFER_TIME CURLINFO_CONTENT_TYPE CURLINFO_REDIRECT_TIME CURLINFO_REDIRECT_COUNT CURL_TIMECOND_IFMODSINCE CURL_TIMECOND_IFUNMODSINCE CURL_TIMECOND_LASTMOD CURL_VERSION_IPV6 CURL_VERSION_KERBEROS4 CURL_VERSION_SSL CURL_VERSION_LIBZ CURLVERSION_NOW CURLE_OK CURLE_UNSUPPORTED_PROTOCOL CURLE_FAILED_INIT CURLE_URL_MALFORMAT CURLE_URL_MALFORMAT_USER CURLE_COULDNT_RESOLVE_PROXY CURLE_COULDNT_RESOLVE_HOST CURLE_COULDNT_CONNECT CURLE_FTP_WEIRD_SERVER_REPLY CURLE_FTP_ACCESS_DENIED CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_FTP_WEIRD_PASS_REPLY CURLE_FTP_WEIRD_USER_REPLY CURLE_FTP_WEIRD_PASV_REPLY CURLE_FTP_WEIRD_227_FORMAT CURLE_FTP_CANT_GET_HOST CURLE_FTP_CANT_RECONNECT CURLE_FTP_COULDNT_SET_BINARY CURLE_PARTIAL_FILE CURLE_FTP_COULDNT_RETR_FILE CURLE_FTP_WRITE_ERROR CURLE_FTP_QUOTE_ERROR CURLE_HTTP_NOT_FOUND CURLE_WRITE_ERROR CURLE_MALFORMAT_USER CURLE_FTP_COULDNT_STOR_FILE CURLE_READ_ERROR CURLE_OUT_OF_MEMORY CURLE_OPERATION_TIMEOUTED CURLE_FTP_COULDNT_SET_ASCII CURLE_FTP_PORT_FAILED CURLE_FTP_COULDNT_USE_REST CURLE_FTP_COULDNT_GET_SIZE CURLE_HTTP_RANGE_ERROR CURLE_HTTP_POST_ERROR CURLE_SSL_CONNECT_ERROR CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_FILE_COULDNT_READ_FILE CURLE_LDAP_CANNOT_BIND CURLE_LDAP_SEARCH_FAILED CURLE_LIBRARY_NOT_FOUND CURLE_FUNCTION_NOT_FOUND CURLE_ABORTED_BY_CALLBACK CURLE_BAD_FUNCTION_ARGUMENT CURLE_BAD_CALLING_ORDER CURLE_HTTP_PORT_FAILED CURLE_BAD_PASSWORD_ENTERED CURLE_TOO_MANY_REDIRECTS CURLE_UNKNOWN_TELNET_OPTION CURLE_TELNET_OPTION_SYNTAX CURLE_OBSOLETE CURLE_SSL_PEER_CERTIFICATE CURLE_GOT_NOTHING CURLE_SSL_ENGINE_NOTFOUND CURLE_SSL_ENGINE_SETFAILED CURLE_SEND_ERROR CURLE_RECV_ERROR CURLE_SHARE_IN_USE CURLE_SSL_CERTPROBLEM CURLE_SSL_CIPHER CURLE_SSL_CACERT CURLE_BAD_CONTENT_ENCODING CURLE_LDAP_INVALID_URL CURLE_FILESIZE_EXCEEDED CURLE_FTP_SSL_FAILED CURLFTPAUTH_DEFAULT CURLFTPAUTH_SSL CURLFTPAUTH_TLS CURLPROXY_HTTP CURLPROXY_SOCKS5 CURL_NETRC_OPTIONAL CURL_NETRC_IGNORED CURL_NETRC_REQUIRED CURL_HTTP_VERSION_NONE CURL_HTTP_VERSION_1_0 CURL_HTTP_VERSION_1_1 CURLM_CALL_MULTI_PERFORM CURLM_OK CURLM_BAD_HANDLE CURLM_BAD_EASY_HANDLE CURLM_OUT_OF_MEMORY CURLM_INTERNAL_ERROR CURLMSG_DONE
+  syn keyword phpFunctions contained curl_close curl_copy_handle curl_errno curl_error curl_exec curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_setopt_array curl_setopt curl_version
+
+  " Cybercash
+  syn keyword phpFunctions contained cybercash_base64_decode cybercash_base64_encode cybercash_decr cybercash_encr
+
+  " Cybermut
+  syn keyword phpFunctions contained cybermut_creerformulairecm cybermut_creerreponsecm cybermut_testmac
+
+  " Cyrus IMAP administration
+  syn keyword phpCoreConstant contained CYRUS_CONN_NONSYNCLITERAL CYRUS_CONN_INITIALRESPONSE CYRUS_CALLBACK_NUMBERED CYRUS_CALLBACK_NOLITERAL
+  syn keyword phpFunctions contained cyrus_authenticate cyrus_bind cyrus_close cyrus_connect cyrus_query cyrus_unbind
+
+  " Date/Time functions
+  syn keyword phpCoreConstant contained DATE_ATOM DATE_COOKIE DATE_ISO8601 DATE_RFC822 DATE_RFC850 DATE_RFC1036 DATE_RFC1123 DATE_RFC2822 DATE_RFC3339 DATE_RSS DATE_W3C SUNFUNCS_RET_TIMESTAMP SUNFUNCS_RET_STRING SUNFUNCS_RET_DOUBLE
+  syn keyword phpFunctions contained checkdate date_create date_date_set date_default_timezone_get date_default_timezone_set date_format date_isodate_set date_modify date_offset_get date_parse date_sun_info date_sunrise date_sunset date_time_set date_timezone_get date_timezone_set date getdate gettimeofday gmdate gmmktime gmstrftime idate localtime microtime mktime strftime strptime strtotime time timezone_abbreviations_list timezone_identifiers_list timezone_name_from_abbr timezone_name_get timezone_offset_get timezone_open timezone_transitions_get
+  syn keyword phpClasses contained DateTime DateTimeZone
+
+  " Database (dbm-style) Abstraction Layer Functions 
+  syn keyword phpFunctions contained dba_close dba_delete dba_exists dba_fetch dba_firstkey dba_handlers dba_insert dba_key_split dba_list dba_nextkey dba_open dba_optimize dba_popen dba_replace dba_sync
+
+  " dBase functions
+  syn keyword phpFunctions contained dbase_add_record dbase_close dbase_create dbase_delete_record dbase_get_header_info dbase_get_record_with_names dbase_get_record dbase_numfields dbase_numrecords dbase_open dbase_pack dbase_replace_record
+
+  " NOTE: DBM functions are deprecated as of PHP 5.0
+  " syn keyword phpFunctions contained dblist dbmclose dbmdelete dbmexists dbmfetch dbmfirstkey dbminsert dbmnextkey dbmopen dbmreplace
+
+  " DBX Functions
+  syn keyword phpCoreConstant contained DBX_MYSQL DBX_ODBC DBX_PGSQL DBX_MSSQL DBX_FBSQL DBX_OCI8 DBX_SYBASECT DBX_SQLITE DBX_PERSISTENT DBX_RESULT_INFO DBX_RESULT_INDEX DBX_RESULT_ASSOC DBX_RESULT_UNBUFFERED DBX_COLNAMES_UNCHANGED DBX_COLNAMES_UPPERCASE DBX_COLNAMES_LOWERCASE DBX_CMP_NATIVE DBX_CMP_TEXT DBX_CMP_NUMBER DBX_CMP_ASC DBX_CMP_DESC
+  syn keyword phpFunctions contained dbx_close dbx_compare dbx_connect dbx_error dbx_escape_string dbx_fetch_row dbx_query dbx_sort
+
+  " Direct I/O functions
+  " NOTE: this extension also defines the constant 'c', but I am not declaring
+  " it here because most people will never use it ...
+  syn keyword phpCoreConstant contained F_DUPFD F_GETFD F_GETFL F_GETLK F_GETOWN F_RDLCK F_SETFL F_SETLK F_SETLKW F_SETOWN F_UNLCK F_WRLCK O_APPEND O_ASYNC O_CREAT O_EXCL O_NDELAY O_NOCTTY O_NONBLOCK O_RDONLY O_RDWR O_SYNC O_TRUNC O_WRONLY S_IRGRP S_IROTH S_IRUSR S_IRWXG S_IRWXO S_IRWXU S_IWGRP S_IWOTH S_IWUSR S_IXGRP S_IXOTH S_IXUSR
+  syn keyword phpFunctions contained dio_close dio_fcntl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write
+
+  " Directory functions
+  syn keyword phpCoreConstant contained DIRECTORY_SEPARATOR PATH_SEPARATOR
+  syn keyword phpFunctions contained chdir chroot dir closedir getcwd opendir readdir rewinddir scandir
+  syn keyword phpClasses contained Directory
+
+  " DOM functions
+  syn keyword phpClasses contained DOMAttr DOMCharacterData DOMComment DOMDocument DOMDocumentFragment DOMDocumentType DOMElement DOMEntity DOMEntityReference DOMException DOMImplementation DOMNamedNodeMap DOMNode DOMNodeList DOMNotation DOMProcessingInstruction DOMText DOMXPath
+  syn keyword phpCoreConstant contained XML_ELEMENT_NODE XML_ATTRIBUTE_NODE XML_TEXT_NODE XML_CDATA_SECTION_NODE XML_ENTITY_REF_NODE XML_ENTITY_NODE XML_PI_NODE XML_COMMENT_NODE XML_DOCUMENT_NODE XML_DOCUMENT_TYPE_NODE XML_DOCUMENT_FRAG_NODE XML_NOTATION_NODE XML_HTML_DOCUMENT_NODE XML_DTD_NODE XML_ELEMENT_DECL_NODE XML_ATTRIBUTE_DECL_NODE XML_ENTITY_DECL_NODE XML_NAMESPACE_DECL_NODE XML_ATTRIBUTE_CDATA XML_ATTRIBUTE_ID XML_ATTRIBUTE_IDREF XML_ATTRIBUTE_IDREFS XML_ATTRIBUTE_ENTITY XML_ATTRIBUTE_NMTOKEN XML_ATTRIBUTE_NMTOKENS XML_ATTRIBUTE_ENUMERATION XML_ATTRIBUTE_NOTATION DOM_INDEX_SIZE_ERR DOMSTRING_SIZE_ERR DOM_HIERARCHY_REQUEST_ERR DOM_WRONG_DOCUMENT_ERR DOM_INVALID_CHARACTER_ERR DOM_NO_DATA_ALLOWED_ERR DOM_NO_MODIFICATION_ALLOWED_ERR DOM_NOT_FOUND_ERR DOM_NOT_SUPPORTED_ERR DOM_INUSE_ATTRIBUTE_ERR DOM_INVALID_STATE_ERR DOM_SYNTAX_ERR DOM_INVALID_MODIFICATION_ERR DOM_NAMESPACE_ERR DOM_INVALID_ACCESS_ERR DOM_VALIDATION_ERR
+  syn keyword phpFunctions contained dom_import_simplexml
+
+  " DOM XML functions
+  "  NOTE: DOM XML is deprecated in favour of the new 'DOM' extension (they
+  "  appear to contain overlapping functionality)
+  " syn keyword phpCoreConstant contained XML_ELEMENT_NODE XML_ATTRIBUTE_NODE XML_TEXT_NODE XML_CDATA_SECTION_NODE XML_ENTITY_REF_NODE XML_ENTITY_NODE XML_PI_NODE XML_COMMENT_NODE XML_DOCUMENT_NODE XML_DOCUMENT_TYPE_NODE XML_DOCUMENT_FRAG_NODE XML_NOTATION_NODE XML_GLOBAL_NAMESPACE XML_LOCAL_NAMESPACE XML_HTML_DOCUMENT_NODE XML_DTD_NODE XML_ELEMENT_DECL_NODE XML_ATTRIBUTE_DECL_NODE XML_ENTITY_DECL_NODE XML_NAMESPACE_DECL_NODE XML_ATTRIBUTE_CDATA XML_ATTRIBUTE_ID XML_ATTRIBUTE_IDREF XML_ATTRIBUTE_IDREFS XML_ATTRIBUTE_ENTITY XML_ATTRIBUTE_NMTOKEN XML_ATTRIBUTE_NMTOKENS XML_ATTRIBUTE_ENUMERATION XML_ATTRIBUTE_NOTATION XPATH_UNDEFINED XPATH_NODESET XPATH_BOOLEAN XPATH_NUMBER XPATH_STRING XPATH_POINT XPATH_RANGE XPATH_LOCATIONSET XPATH_USERS XPATH_NUMBER
+  " syn keyword phpClasses contained DomAttribute DomCData DomComment DomDocument DomDocumentType DomElement DomEntity DomEntityReference DomProcessingInstruction DomText Parser XPathContext
+  " syn keyword phpFunctions contained domxml_new_doc domxml_open_file domxml_open_mem domxml_version domxml_xmltree domxml_xslt_stylesheet_doc domxml_xslt_stylesheet_file domxml_xslt_stylesheet domxml_xslt_version xpath_eval_expression xpath_eval xpath_new_context xpath_register_ns_auto xpath_register_ns xptr_eval xptr_new_context
+
+  " Enchant functions
+  syn keyword phpFunctions contained enchant_broker_describe enchant_broker_dict_exists enchant_broker_free_dict enchant_broker_free enchant_broker_get_error enchant_broker_init enchant_broker_list_dicts enchant_broker_request_dict enchant_broker_request_pwl_dict enchant_broker_set_ordering enchant_dict_add_to_personal enchant_dict_add_to_session enchant_dict_check enchant_dict_describe enchant_dict_get_error enchant_dict_is_in_session enchant_dict_quick_check enchant_dict_store_replacement enchant_dict_suggest
+
+  " error-handling
+  syn keyword phpCoreConstant contained E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_STRICT E_RECOVERABLE_ERROR E_ALL
+  syn keyword phpFunctions contained debug_backtrace debug_print_backtrace error_get_last error_log error_reporting restore_error_handler restore_exception_handler set_error_handler set_exception_handler trigger_error user_error
+
+  " exif functions
+  syn keyword phpCoreConstant contained EXIF_USE_MBSTRING
+  syn keyword phpCoreConstant contained IMAGETYPE_GIF IMAGETYPE_JPEG IMAGETYPE_PNG IMAGETYPE_SWF IMAGETYPE_PSD IMAGETYPE_BMP IMAGETYPE_TIFF_II IMAGETYPE_TIFF_MM IMAGETYPE_JPC IMAGETYPE_JP2 IMAGETYPE_JPX IMAGETYPE_JB2 IMAGETYPE_SWC IMAGETYPE_IFF IMAGETYPE_WBMP IMAGETYPE_XBM
+  syn keyword phpFunctions contained exif_imagetype exif_read_data exif_tagname exif_thumbnail read_exif_data
+
+  " expect functions
+  syn keyword phpCoreConstant contained EXP_GLOB EXP_EXACT EXP_REGEXP EXP_EOF EXP_TIMEOUT EXP_FULLBUFFER
+  syn keyword phpFunctions contained expect_expectl expect_popen
+
+  " FAM functions
+  syn keyword phpCoreConstant contained FAMChanged FAMDeleted FAMStartExecuting FAMStopExecuting FAMCreated FAMMoved FAMAcknowledge FAMExists FAMEndExist
+  syn keyword phpFunctions contained fam_cancel_monitor fam_close fam_monitor_collection fam_monitor_directory fam_monitor_file fam_next_event fam_open fam_pending fam_resume_monitor fam_suspend_monitor
+
+  " FDF functions
+  syn keyword phpCoreConstant contained FDFValue FDFStatus FDFFile FDFID FDFFf FDFSetFf FDFClearFf FDFFlags FDFSetF FDFClrF FDFAP FDFAS FDFAction FDFAA FDFAPRef FDFIF FDFEnter FDFExit FDFDown FDFUp FDFFormat FDFValidate FDFKeystroke FDFCalculate FDFNormalAP FDFRolloverAP FDFDownAP
+  syn keyword phpFunctions contained fdf_add_doc_javascript fdf_add_template fdf_close fdf_create fdf_enum_values fdf_errno fdf_error fdf_get_ap fdf_get_attachment fdf_get_encoding fdf_get_file fdf_get_flags fdf_get_opt fdf_get_status fdf_get_value fdf_get_version fdf_header fdf_next_field_name fdf_open_string fdf_open fdf_remove_item fdf_save_string fdf_save fdf_set_ap fdf_set_encoding fdf_set_file fdf_set_flags fdf_set_javascript_action fdf_set_on_import_javascript fdf_set_opt fdf_set_status fdf_set_submit_form_action fdf_set_target_frame fdf_set_value fdf_set_version
+
+  " Fileinfo functions
+  syn keyword phpCoreConstant contained FILEINFO_NONE FILEINFO_SYMLINK FILEINFO_MIME FILEINFO_COMPRESS FILEINFO_DEVICES FILEINFO_CONTINUE FILEINFO_PRESERVE_ATIME FILEINFO_RAW
+  syn keyword phpFunctions contained finfo_buffer finfo_close finfo_file finfo_open finfo_set_flags
+
+  " Filepro functions
+  syn keyword phpFunctions contained filepro_fieldcount filepro_fieldname filepro_fieldtype filepro_fieldwidth filepro_retrieve filepro_rowcount filepro
+
+  " Filesystem functions
+  syn keyword phpCoreConstant contained GLOB_BRACE GLOB_ONLYDIR GLOB_MARK GLOB_NOSORT GLOB_NOCHECK GLOB_NOESCAPE PATHINFO_DIRNAME PATHINFO_BASENAME PATHINFO_EXTENSION PATHINFO_FILENAME FILE_USE_INCLUDE_PATH FILE_APPEND FILE_IGNORE_NEW_LINES FILE_SKIP_EMPTY_LINES FILE_BINARY FILE_TEXT
+  syn keyword phpFunctions contained basename chgrp chmod chown clearstatcache copy delete dirname disk_free_space disk_total_space diskfreespace fclose feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents file fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype flock fnmatch fopen fpassthru fputcsv fputs fread fscanf fseek fstat ftell ftruncate fwrite glob is_dir is_executable is_file is_link is_readable is_uploaded_file is_writable is_writeable lchgrp lchown link linkinfo lstat mkdir move_uploaded_file parse_ini_file pathinfo pclose popen readfile readlink realpath rename rewind rmdir set_file_buffer stat symlink tempnam tmpfile touch umask unlink
+
+  " Filter extension
+  syn keyword phpCoreConstant contained INPUT_POST INPUT_GET INPUT_COOKIE INPUT_ENV INPUT_SERVER INPUT_SESSION INPUT_REQUEST FILTER_FLAG_NONE FILTER_REQUIRE_SCALAR FILTER_REQUIRE_ARRAY FILTER_FORCE_ARRAY FILTER_NULL_ON_FAILURE FILTER_VALIDATE_INT FILTER_VALIDATE_BOOLEAN FILTER_VALIDATE_FLOAT FILTER_VALIDATE_REGEXP FILTER_VALIDATE_URL FILTER_VALIDATE_EMAIL FILTER_VALIDATE_IP FILTER_DEFAULT FILTER_UNSAFE_RAW FILTER_SANITIZE_STRING FILTER_SANITIZE_STRIPPED FILTER_SANITIZE_ENCODED FILTER_SANITIZE_SPECIAL_CHARS FILTER_SANITIZE_EMAIL FILTER_SANITIZE_URL FILTER_SANITIZE_NUMBER_INT FILTER_SANITIZE_NUMBER_FLOAT FILTER_SANITIZE_MAGIC_QUOTES FILTER_CALLBACK FILTER_FLAG_ALLOW_OCTAL FILTER_FLAG_ALLOW_HEX FILTER_FLAG_STRIP_LOW FILTER_FLAG_STRIP_HIGH FILTER_FLAG_ENCODE_LOW FILTER_FLAG_ENCODE_HIGH FILTER_FLAG_ENCODE_AMP FILTER_FLAG_NO_ENCODE_QUOTES FILTER_FLAG_EMPTY_STRING_NULL FILTER_FLAG_ALLOW_FRACTION FILTER_FLAG_ALLOW_THOUSAND FILTER_FLAG_ALLOW_SCIENTIFIC FILTER_FLAG_SCHEME_REQUIRED FILTER_FLAG_HOST_REQUIRED FILTER_FLAG_PATH_REQUIRED FILTER_FLAG_QUERY_REQUIRED FILTER_FLAG_IPV4 FILTER_FLAG_IPV6 FILTER_FLAG_NO_RES_RANGE FILTER_FLAG_NO_PRIV_RANGE 
+  syn keyword phpFunctions contained filter_has_var filter_id filter_input_array filter_input filter_list filter_var_array filter_var
+
+  " Firebird / interbase functions
+  syn keyword phpCoreConstant contained IBASE_DEFAULT IBASE_READ IBASE_WRITE IBASE_CONSISTENCY IBASE_CONCURRENCY IBASE_COMMITTED IBASE_WAIT IBASE_NOWAIT IBASE_FETCH_BLOBS IBASE_FETCH_ARRAYS IBASE_UNIXTIME IBASE_BKP_IGNORE_CHECKSUMS IBASE_BKP_IGNORE_LIMBO IBASE_BKP_METADATA_ONLY IBASE_BKP_NO_GARBAGE_COLLECT IBASE_BKP_OLD_DESCRIPTIONS IBASE_BKP_NON_TRANSPORTABLE IBASE_BKP_CONVERT IBASE_RES_DEACTIVATE_IDX IBASE_RES_NO_SHADOW IBASE_RES_NO_VALIDITY IBASE_RES_ONE_AT_A_TIME IBASE_RES_REPLACE IBASE_RES_CREATE IBASE_RES_USE_ALL_SPACE IBASE_PRP_PAGE_BUFFERS IBASE_PRP_SWEEP_INTERVAL IBASE_PRP_SHUTDOWN_DB IBASE_PRP_DENY_NEW_TRANSACTIONS IBASE_PRP_DENY_NEW_ATTACHMENTS IBASE_PRP_RESERVE_SPACE IBASE_PRP_RES_USE_FULL IBASE_PRP_RES IBASE_PRP_WRITE_MODE IBASE_PRP_WM_ASYNC IBASE_PRP_WM_SYNC IBASE_PRP_ACCESS_MODE IBASE_PRP_AM_READONLY IBASE_PRP_AM_READWRITE IBASE_PRP_SET_SQL_DIALECT IBASE_PRP_ACTIVATE IBASE_PRP_DB_ONLINE IBASE_RPR_CHECK_DB IBASE_RPR_IGNORE_CHECKSUM IBASE_RPR_KILL_SHADOWS IBASE_RPR_MEND_DB IBASE_RPR_VALIDATE_DB IBASE_RPR_FULL IBASE_RPR_SWEEP_DB IBASE_STS_DATA_PAGES IBASE_STS_DB_LOG IBASE_STS_HDR_PAGES IBASE_STS_IDX_PAGES IBASE_STS_SYS_RELATIONS IBASE_SVC_SERVER_VERSION IBASE_SVC_IMPLEMENTATION IBASE_SVC_GET_ENV IBASE_SVC_GET_ENV_LOCK IBASE_SVC_GET_ENV_MSG IBASE_SVC_USER_DBPATH IBASE_SVC_SVR_DB_INFO IBASE_SVC_GET_USERS
+  syn keyword phpFunctions contained ibase_add_user ibase_affected_rows ibase_backup ibase_blob_add ibase_blob_cancel ibase_blob_close ibase_blob_create ibase_blob_echo ibase_blob_get ibase_blob_import ibase_blob_info ibase_blob_open ibase_close ibase_commit_ret ibase_commit ibase_connect ibase_db_info ibase_delete_user ibase_drop_db ibase_errcode ibase_errmsg ibase_execute ibase_fetch_assoc ibase_fetch_object ibase_fetch_row ibase_field_info ibase_free_event_handler ibase_free_query ibase_free_result ibase_gen_id ibase_maintain_db ibase_modify_user ibase_name_result ibase_num_fields ibase_num_params ibase_param_info ibase_pconnect ibase_prepare ibase_query ibase_restore ibase_rollback_ret ibase_rollback ibase_server_info ibase_service_attach ibase_service_detach ibase_set_event_handler ibase_timefmt ibase_trans ibase_wait_event
+
+  " FriDiBi functions
+  syn keyword phpCoreConstant contained FRIBIDI_CHARSET_UTF8 FRIBIDI_CHARSET_8859_6 FRIBIDI_CHARSET_8859_8 FRIBIDI_CHARSET_CP1255 FRIBIDI_CHARSET_CP1256 FRIBIDI_CHARSET_ISIRI_3342 FRIBIDI_CHARSET_CAP_RTL FRIBIDI_RTL FRIBIDI_LTR FRIBIDI_AUTO
+  syn keyword phpFunctions contained fribidi_log2vis
+
+  " FrontBase functions
+  syn keyword phpCoreConstant contained FBSQL_ASSOC FBSQL_NUM FBSQL_BOTH FBSQL_LOCK_DEFERRED FBSQL_LOCK_OPTIMISTIC FBSQL_LOCK_PESSIMISTIC FBSQL_ISO_READ_UNCOMMITTED FBSQL_ISO_READ_COMMITTED FBSQL_ISO_REPEATABLE_READ FBSQL_ISO_SERIALIZABLE FBSQL_ISO_VERSIONED FBSQL_UNKNOWN FBSQL_STOPPED FBSQL_STARTING FBSQL_RUNNING FBSQL_STOPPING FBSQL_NOEXEC FBSQL_LOB_DIRECT FBSQL_LOB_HANDLE
+  syn keyword phpFunctions contained fbsql_affected_rows fbsql_autocommit fbsql_blob_size fbsql_change_user fbsql_clob_size fbsql_close fbsql_commit fbsql_connect fbsql_create_blob fbsql_create_clob fbsql_create_db fbsql_data_seek fbsql_database_password fbsql_database fbsql_db_query fbsql_db_status fbsql_drop_db fbsql_errno fbsql_error fbsql_fetch_array fbsql_fetch_assoc fbsql_fetch_field fbsql_fetch_lengths fbsql_fetch_object fbsql_fetch_row fbsql_field_flags fbsql_field_len fbsql_field_name fbsql_field_seek fbsql_field_table fbsql_field_type fbsql_free_result fbsql_get_autostart_info fbsql_hostname fbsql_insert_id fbsql_list_dbs fbsql_list_fields fbsql_list_tables fbsql_next_result fbsql_num_fields fbsql_num_rows fbsql_password fbsql_pconnect fbsql_query fbsql_read_blob fbsql_read_clob fbsql_result fbsql_rollback fbsql_rows_fetched fbsql_select_db fbsql_set_characterset fbsql_set_lob_mode fbsql_set_password fbsql_set_transaction fbsql_start_db fbsql_stop_db fbsql_table_name fbsql_tablename fbsql_username fbsql_warnings
+
+  " FTP functions
+  syn keyword phpCoreConstant contained FTP_ASCII FTP_TEXT FTP_BINARY FTP_IMAGE FTP_TIMEOUT_SEC FTP_AUTOSEEK FTP_AUTORESUME FTP_FAILED FTP_FINISHED FTP_MOREDATA
+  syn keyword phpFunctions contained ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_fget ftp_fput ftp_get_option ftp_get ftp_login ftp_mdtm ftp_mkdir ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put ftp_nlist ftp_pasv ftp_put ftp_pwd ftp_quit ftp_raw ftp_rawlist ftp_rename ftp_rmdir ftp_set_option ftp_site ftp_size ftp_ssl_connect ftp_systype
+
+  " Function Handling Functions
+  syn keyword phpFunctions contained call_user_func_array call_user_func create_function func_get_arg func_get_args func_num_args function_exists get_defined_functions register_shutdown_function register_tick_function unregister_tick_function
+
+  " GeoIP Functions
+  syn keyword phpCoreConstant contained GEOIP_COUNTRY_EDITION GEOIP_REGION_EDITION_REV0 GEOIP_CITY_EDITION_REV0 GEOIP_ORG_EDITION GEOIP_ISP_EDITION GEOIP_CITY_EDITION_REV1 GEOIP_REGION_EDITION_REV1 GEOIP_PROXY_EDITION GEOIP_ASNUM_EDITION GEOIP_NETSPEED_EDITION GEOIP_DOMAIN_EDITION GEOIP_UNKNOWN_SPEED GEOIP_DIALUP_SPEED GEOIP_CABLEDSL_SPEED GEOIP_CORPORATE_SPEED
+  syn keyword phpFunctions contained geoip_country_code_by_name geoip_country_code3_by_name geoip_country_name_by_name geoip_database_info geoip_db_avail geoip_db_filename geoip_db_get_all_info geoip_id_by_name geoip_org_by_name geoip_record_by_name geoip_region_by_name
+
+  " Gettext functions
+  syn keyword phpFunctions contained bind_textdomain_codeset bindtextdomain dcgettext dcngettext dgettext dngettext gettext ngettext textdomain
+
+  " GMP Function
+  syn keyword phpCoreConstant contained GMP_ROUND_ZERO GMP_ROUND_PLUSINF GMP_ROUND_MINUSINF GMP_VERSION
+  syn keyword phpFunctions contained gmp_abs gmp_add gmp_and gmp_clrbit gmp_cmp gmp_com gmp_div_q gmp_div_qr gmp_div_r gmp_div gmp_divexact gmp_fact gmp_gcd gmp_gcdext gmp_hamdist gmp_init gmp_intval gmp_invert gmp_jacobi gmp_legendre gmp_mod gmp_mul gmp_neg gmp_nextprime gmp_or gmp_perfect_square gmp_popcount gmp_pow gmp_powm gmp_prob_prime gmp_random gmp_scan0 gmp_scan1 gmp_setbit gmp_sign gmp_sqrt gmp_sqrtrem gmp_strval gmp_sub gmp_testbit gmp_xor
+
+  " gnupg Functions
+  syn keyword phpCoreConstant contained GNUPG_SIG_MODE_NORMAL GNUPG_SIG_MODE_DETACH GNUPG_SIG_MODE_CLEAR GNUPG_VALIDITY_UNKNOWN GNUPG_VALIDITY_UNDEFINED GNUPG_VALIDITY_NEVER GNUPG_VALIDITY_MARGINAL GNUPG_VALIDITY_FULL GNUPG_VALIDITY_ULTIMATE GNUPG_PROTOCOL_OpenPGP GNUPG_PROTOCOL_CMS GNUPG_SIGSUM_VALID GNUPG_SIGSUM_GREEN GNUPG_SIGSUM_RED GNUPG_SIGSUM_KEY_REVOKED GNUPG_SIGSUM_KEY_EXPIRED GNUPG_SIGSUM_KEY_MISSING GNUPG_SIGSUM_SIG_EXPIRED GNUPG_SIGSUM_CRL_MISSING GNUPG_SIGSUM_CRL_TOO_OLD GNUPG_SIGSUM_BAD_POLICY GNUPG_SIGSUM_SYS_ERROR GNUPG_ERROR_WARNING GNUPG_ERROR_EXCEPTION GNUPG_ERROR_SILENT
+  syn keyword phpFunctions contained gnupg_adddecryptkey gnupg_addencryptkey gnupg_addsignkey gnupg_cleardecryptkeys gnupg_clearencryptkeys gnupg_clearsignkeys gnupg_decrypt gnupg_decryptverify gnupg_encrypt gnupg_encryptsign gnupg_export gnupg_geterror gnupg_getprotocol gnupg_import gnupg_keyinfo gnupg_setarmor gnupg_seterrormode gnupg_setsignmode gnupg_sign gnupg_verify
+
+  " Net_Gopher
+  syn keyword phpCoreConstant contained GOPHER_DOCUMENT GOPHER_DIRECTORY GOPHER_BINHEX GOPHER_DOSBINARY GOPHER_UUENCODED GOPHER_BINARY GOPHER_INFO GOPHER_HTTP GOPHER_UNKNOWN
+  syn keyword phpFunctions contained gopher_parsedir
+
+  " hash functions
+  syn keyword phpCoreConstant contained HASH_HMAC
+  syn keyword phpFunctions contained hash_algos hash_file hash_final hash_hmac_file hash_hmac hash_init hash_update_file hash_update_stream hash_update hash
+
+  " HTTP functions
+  " TODO: I've never seen these classes before ... make sure they work / are available
+  syn keyword phpCoreConstant contained HTTP_SUPPORT HTTP_SUPPORT_REQUESTS HTTP_SUPPORT_MAGICMIME HTTP_SUPPORT_ENCODINGS HTTP_SUPPORT_SSLREQUESTS HTTP_PARAMS_ALLOW_COMMA HTTP_PARAMS_ALLOW_FAILURE HTTP_PARAMS_RAISE_ERROR HTTP_PARAMS_DEFAULT HTTP_COOKIE_PARSE_RAW HTTP_COOKIE_SECURE HTTP_COOKIE_HTTPONLY HTTP_DEFLATE_LEVEL_DEF HTTP_DEFLATE_LEVEL_MIN HTTP_DEFLATE_LEVEL_MAX HTTP_DEFLATE_TYPE_ZLIB HTTP_DEFLATE_TYPE_GZIP HTTP_DEFLATE_TYPE_RAW HTTP_DEFLATE_STRATEGY_DEF HTTP_DEFLATE_STRATEGY_FILT HTTP_DEFLATE_STRATEGY_HUFF HTTP_DEFLATE_STRATEGY_RLE HTTP_DEFLATE_STRATEGY_FIXED HTTP_ENCODING_STREAM_FLUSH_NONE HTTP_ENCODING_STREAM_FLUSH_SYNC HTTP_ENCODING_STREAM_FLUSH_FULL HTTP_E_RUNTIME HTTP_E_INVALID_PARAM HTTP_E_HEADER HTTP_E_MALFORMED_HEADERS HTTP_E_REQUEST_METHOD HTTP_E_MESSAGE_TYPE HTTP_E_ENCODING HTTP_E_REQUEST HTTP_E_REQUEST_POOL HTTP_E_SOCKET HTTP_E_RESPONSE HTTP_E_URL HTTP_E_QUERYSTRING HTTP_MSG_NONE HTTP_MSG_REQUEST HTTP_MSG_RESPONSE HTTP_QUERYSTRING_TYPE_BOOL HTTP_QUERYSTRING_TYPE_INT HTTP_QUERYSTRING_TYPE_FLOAT HTTP_QUERYSTRING_TYPE_STRING
+  syn keyword phpCoreConstant contained HTTP_QUERYSTRING_TYPE_ARRAY HTTP_QUERYSTRING_TYPE_OBJECT HTTP_AUTH_BASIC HTTP_AUTH_DIGEST HTTP_AUTH_NTLM HTTP_AUTH_GSSNEG HTTP_AUTH_ANY HTTP_VERSION_ANY HTTP_VERSION_1_0 HTTP_VERSION_1_1 HTTP_SSL_VERSION_ANY HTTP_SSL_VERSION_TLSv1 HTTP_SSL_VERSION_SSLv3 HTTP_SSL_VERSION_SSLv2 HTTP_PROXY_SOCKS4 HTTP_PROXY_SOCKS5 HTTP_PROXY_HTTP HTTP_IPRESOLVE_V4 HTTP_IPRESOLVE_V6 HTTP_IPRESOLVE_ANY HTTP_METH_GET HTTP_METH_HEAD HTTP_METH_POST HTTP_METH_PUT HTTP_METH_DELETE HTTP_METH_OPTIONS HTTP_METH_TRACE HTTP_METH_CONNECT HTTP_METH_PROPFIND HTTP_METH_PROPPATCH HTTP_METH_MKCOL HTTP_METH_COPY HTTP_METH_MOVE HTTP_METH_LOCK HTTP_METH_UNLOCK HTTP_METH_VERSION_CONTROL HTTP_METH_REPORT HTTP_METH_CHECKOUT HTTP_METH_CHECKIN HTTP_METH_UNCHECKOUT HTTP_METH_MKWORKSPACE HTTP_METH_UPDATE HTTP_METH_LABEL HTTP_METH_MERGE HTTP_METH_BASELINE_CONTROL HTTP_METH_MKACTIVITY HTTP_METH_ACL HTTP_REDIRECT HTTP_REDIRECT_PERM HTTP_REDIRECT_FOUND HTTP_REDIRECT_POST HTTP_REDIRECT_PROXY HTTP_REDIRECT_TEMP HTTP_URL_REPLACE HTTP_URL_JOIN_PATH
+  syn keyword phpCoreConstant contained HTTP_URL_JOIN_QUERY HTTP_URL_STRIP_USER HTTP_URL_STRIP_PASS HTTP_URL_STRIP_AUTH HTTP_URL_STRIP_PORT HTTP_URL_STRIP_PATH HTTP_URL_STRIP_QUERY HTTP_URL_STRIP_FRAGMENT HTTP_URL_STRIP_ALL
+  syn keyword phpClasses contained HttpMessage HttpQueryString HttpDeflateStream HttpInflateStream HttpRequest HttpRequestPool HttpResponse
+  syn keyword phpFunctions contained http_cache_etag http_cache_last_modified http_chunked_decode http_deflate http_inflate http_get_request_body_stream http_get_request_body http_get_request_headers http_date http_support http_match_etag http_match_modified http_match_request_header http_build_cookie http_negotiate_charset http_negotiate_content_type http_negotiate_language ob_deflatehandler ob_etaghandler ob_inflatehandler http_parse_cookie http_parse_headers http_parse_message http_parse_params http_persistent_handles_count http_persistent_handles_ident http_persistent_handles_clean http_get http_head http_post_data http_post_fields http_put_data http_put_file http_put_stream http_request_method_exists http_request_method_name http_request_method_register http_request_method_unregister http_request http_request_body_encode http_redirect http_send_content_disposition http_send_content_type http_send_data http_send_file http_send_last_modified http_send_status http_send_stream http_throttle http_build_str http_build_url
+
+  " Hyperwave functions
+  syn keyword phpCoreConstant contained HW_ATTR_LANG HW_ATTR_NR HW_ATTR_NONE
+  syn keyword phpFunctions contained hw_Array2Objrec hw_changeobject hw_Children hw_ChildrenObj hw_Close hw_Connect hw_connection_info hw_cp hw_Deleteobject hw_DocByAnchor hw_DocByAnchorObj hw_Document_Attributes hw_Document_BodyTag hw_Document_Content hw_Document_SetContent hw_Document_Size hw_dummy hw_EditText hw_Error hw_ErrorMsg hw_Free_Document hw_GetAnchors hw_GetAnchorsObj hw_GetAndLock hw_GetChildColl hw_GetChildCollObj hw_GetChildDocColl hw_GetChildDocCollObj hw_GetObject hw_GetObjectByQuery hw_GetObjectByQueryColl hw_GetObjectByQueryCollObj hw_GetObjectByQueryObj hw_GetParents hw_GetParentsObj hw_getrellink hw_GetRemote hw_getremotechildren hw_GetSrcByDestObj hw_GetText hw_getusername hw_Identify hw_InCollections hw_Info hw_InsColl hw_InsDoc hw_insertanchors hw_InsertDocument hw_InsertObject hw_mapid hw_Modifyobject hw_mv hw_New_Document hw_objrec2array hw_Output_Document hw_pConnect hw_PipeDocument hw_Root hw_setlinkroot hw_stat hw_Unlock hw_Who
+
+  " Hyperwave API
+  syn keyword phpClasses contained HW_API HW_API_Object HW_API_Attribute HW_API_Error HW_API_Content HW_API_Reason 
+  syn keyword phpFunctions contained hw_api_object hw_api_content hwapi_hgcsp hw_api_attribute
+
+  " NOTE: i18n functions are not yet available
+
+  " IBM DB2
+  syn keyword phpCoreConstant contained DB2_BINARY DB2_CONVERT DB2_PASSTHRU DB2_SCROLLABLE DB2_FORWARD_ONLY DB2_PARAM_IN DB2_PARAM_OUT DB2_PARAM_INOUT DB2_PARAM_FILE DB2_AUTOCOMMIT_ON DB2_AUTOCOMMIT_OFF DB2_DOUBLE DB2_LONG DB2_CHAR DB2_CASE_NATURAL DB2_CASE_LOWER DB2_CASE_UPPER DB2_DEFERRED_PREPARE_ON DB2_DEFERRED_PREPARE_OFF
+  syn keyword phpFunctions contained db2_autocommit db2_bind_param db2_client_info db2_close db2_column_privileges db2_columns db2_commit db2_conn_error db2_conn_errormsg db2_connect db2_cursor_type db2_escape_string db2_exec db2_execute db2_fetch_array db2_fetch_assoc db2_fetch_both db2_fetch_object db2_fetch_row db2_field_display_size db2_field_name db2_field_num db2_field_precision db2_field_scale db2_field_type db2_field_width db2_foreign_keys db2_free_result db2_free_stmt db2_get_option db2_lob_read db2_next_result db2_num_fields db2_num_rows db2_pconnect db2_prepare db2_primary_keys db2_procedure_columns db2_procedures db2_result db2_rollback db2_server_info db2_set_option db2_special_columns db2_statistics db2_stmt_error db2_stmt_errormsg db2_table_privileges db2_tables
+
+  " ICONV functions
+  syn keyword phpCoreConstant contained ICONV_IMPL ICONV_VERSION ICONV_MIME_DECODE_STRICT ICONV_MIME_DECODE_CONTINUE_ON_ERROR
+  syn keyword phpFunctions contained iconv_get_encoding iconv_mime_decode_headers iconv_mime_decode iconv_mime_encode iconv_set_encoding iconv_strlen iconv_strpos iconv_strrpos iconv_substr iconv ob_iconv_handler
+
+  " ID3 functions
+  syn keyword phpCoreConstant contained ID3_V1_0 ID3_V1_1 ID3_V2_1 ID3_V2_2 ID3_V2_3 ID3_V2_4 ID3_BEST
+  syn keyword phpFunctions contained id3_get_frame_long_name id3_get_frame_short_name id3_get_genre_id id3_get_genre_list id3_get_genre_name id3_get_tag id3_get_version id3_remove_tag id3_set_tag
+
+  " IIS functions
+  syn keyword phpCoreConstant contained IIS_READ IIS_WRITE IIS_EXECUTE IIS_SCRIPT IIS_ANONYMOUS IIS_BASIC IIS_NTLM IIS_STARTING IIS_STOPPED IIS_PAUSED IIS_RUNNING
+  syn keyword phpFunctions contained iis_add_server iis_get_dir_security iis_get_script_map iis_get_server_by_comment iis_get_server_by_path iis_get_server_rights iis_get_service_state iis_remove_server iis_set_app_settings iis_set_dir_security iis_set_script_map iis_set_server_rights iis_start_server iis_start_service iis_stop_server iis_stop_service
+
+  " Image functions
+  syn keyword phpCoreConstant contained GD_VERSION GD_MAJOR_VERSION GD_MINOR_VERSION GD_RELEASE_VERSION GD_EXTRA_VERSION IMG_GIF IMG_JPG IMG_JPEG IMG_PNG IMG_WBMP IMG_XPM IMG_COLOR_TILED IMG_COLOR_STYLED IMG_COLOR_BRUSHED IMG_COLOR_STYLEDBRUSHED IMG_COLOR_TRANSPARENT IMG_ARC_ROUNDED IMG_ARC_PIE IMG_ARC_CHORD IMG_ARC_NOFILL IMG_ARC_EDGED IMG_GD2_RAW IMG_GD2_COMPRESSED IMG_EFFECT_REPLACE IMG_EFFECT_ALPHABLEND IMG_EFFECT_NORMAL IMG_EFFECT_OVERLAY IMG_FILTER_NEGATE IMG_FILTER_GRAYSCALE IMG_FILTER_BRIGHTNESS IMG_FILTER_CONTRAST IMG_FILTER_COLORIZE IMG_FILTER_EDGEDETECT IMG_FILTER_GAUSSIAN_BLUR IMG_FILTER_SELECTIVE_BLUR IMG_FILTER_EMBOSS IMG_FILTER_MEAN_REMOVAL IMG_FILTER_SMOOTH IMAGETYPE_GIF IMAGETYPE_JPEG IMAGETYPE_PNG IMAGETYPE_SWF IMAGETYPE_PSD IMAGETYPE_BMP IMAGETYPE_WBMP IMAGETYPE_XBM IMAGETYPE_TIFF_II IMAGETYPE_TIFF_MM IMAGETYPE_IFF IMAGETYPE_JB2 IMAGETYPE_JPC IMAGETYPE_JP2 IMAGETYPE_JPX IMAGETYPE_SWC IMAGETYPE_ICO PNG_NO_FILTER PNG_FILTER_NONE PNG_FILTER_SUB PNG_FILTER_UP PNG_FILTER_AVG PNG_FILTER_PAETH PNG_ALL_FILTERS
+  syn keyword phpFunctions contained gd_info getimagesize image_type_to_extension image_type_to_mime_type image2wbmp imagealphablending imageantialias imagearc imagechar imagecharup imagecolorallocate imagecolorallocatealpha imagecolorat imagecolorclosest imagecolorclosestalpha imagecolorclosesthwb imagecolordeallocate imagecolorexact imagecolorexactalpha imagecolormatch imagecolorresolve imagecolorresolvealpha imagecolorset imagecolorsforindex imagecolorstotal imagecolortransparent imageconvolution imagecopy imagecopymerge imagecopymergegray imagecopyresampled imagecopyresized imagecreate imagecreatefromgd2 imagecreatefromgd2part imagecreatefromgd imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromstring imagecreatefromwbmp imagecreatefromxbm imagecreatefromxpm imagecreatetruecolor imagedashedline imagedestroy imageellipse imagefill imagefilledarc imagefilledellipse imagefilledpolygon imagefilledrectangle imagefilltoborder imagefilter imagefontheight
+  syn keyword phpFunctions contained imagefontwidth imageftbbox imagefttext imagegammacorrect imagegd2 imagegd imagegif imagegrabscreen imagegrabwindow imageinterlace imageistruecolor imagejpeg imagelayereffect imageline imageloadfont imagepalettecopy imagepng imagepolygon imagepsbbox imagepsencodefont imagepsextendfont imagepsfreefont imagepsloadfont imagepsslantfont imagepstext imagerectangle imagerotate imagesavealpha imagesetbrush imagesetpixel imagesetstyle imagesetthickness imagesettile imagestring imagestringup imagesx imagesy imagetruecolortopalette imagettfbbox imagettftext imagetypes imagewbmp imagexbm iptcembed iptcparse jpeg2wbmp png2wbmp
+
+  " Imagick Image Library
+  " NOTE: this extension is experimental
+  " syn keyword phpClasses contained Imagick ImagickDraw ImagickPixel ImagickPixelIterator
+
+  " IMAP POP3 and NNTP functions
+  syn keyword phpCoreConstant contained NIL OP_DEBUG OP_READONLY OP_ANONYMOUS OP_SHORTCACHE OP_SILENT OP_PROTOTYPE OP_HALFOPEN OP_EXPUNGE OP_SECURE CL_EXPUNGE FT_UID FT_PEEK FT_NOT FT_INTERNAL FT_PREFETCHTEXT ST_UID ST_SILENT ST_SET CP_UID CP_MOVE SE_UID SE_FREE SE_NOPREFETCH SO_FREE SO_NOSERVER SA_MESSAGES SA_RECENT SA_UNSEEN SA_UIDNEXT SA_UIDVALIDITY SA_ALL LATT_NOINFERIORS LATT_NOSELECT LATT_MARKED LATT_UNMARKED SORTDATE SORTARRIVAL SORTFROM SORTSUBJECT SORTTO SORTCC SORTSIZE TYPETEXT TYPEMULTIPART TYPEMESSAGE TYPEAPPLICATION TYPEAUDIO TYPEIMAGE TYPEVIDEO TYPEOTHER ENC7BIT ENC8BIT ENCBINARY ENCBASE64 ENCQUOTEDPRINTABLE ENCOTHER IMAP_OPENTIMEOUT IMAP_READTIMEOUT IMAP_WRITETIMEOUT IMAP_CLOSETIMEOUT LATT_REFERRAL LATT_HASCHILDREN LATT_HASNOCHILDREN TYPEMODEL
+  syn keyword phpFunctions contained imap_8bit imap_alerts imap_append imap_base64 imap_binary imap_body imap_bodystruct imap_check imap_clearflag_full imap_close imap_createmailbox imap_delete imap_deletemailbox imap_errors imap_expunge imap_fetch_overview imap_fetchbody imap_fetchheader imap_fetchstructure imap_get_quota imap_get_quotaroot imap_getacl imap_getmailboxes imap_getsubscribed imap_header imap_headerinfo imap_headers imap_last_error imap_list imap_listmailbox imap_listscan imap_listsubscribed imap_lsub imap_mail_compose imap_mail_copy imap_mail_move imap_mail imap_mailboxmsginfo imap_mime_header_decode imap_msgno imap_num_msg imap_num_recent imap_open imap_ping imap_qprint imap_renamemailbox imap_reopen imap_rfc822_parse_adrlist imap_rfc822_parse_headers imap_rfc822_write_address imap_savebody imap_scanmailbox imap_search imap_set_quota imap_setacl imap_setflag_full imap_sort imap_status imap_subscribe imap_thread imap_timeout imap_uid imap_undelete imap_unsubscribe imap_utf7_decode imap_utf7_encode imap_utf8
+
+  " Informix functions
+  syn keyword phpCoreConstant contained IFX_SCROLL IFX_HOLD IFX_LO_RDONLY IFX_LO_WRONLY IFX_LO_APPEND IFX_LO_RDWR IFX_LO_BUFFER IFX_LO_NOBUFFER
+  syn keyword phpFunctions contained ifx_affected_rows ifx_blobinfile_mode ifx_byteasvarchar ifx_close ifx_connect ifx_copy_blob ifx_create_blob ifx_create_char ifx_do ifx_error ifx_errormsg ifx_fetch_row ifx_fieldproperties ifx_fieldtypes ifx_free_blob ifx_free_char ifx_free_result ifx_get_blob ifx_get_char ifx_getsqlca ifx_htmltbl_result ifx_nullformat ifx_num_fields ifx_num_rows ifx_pconnect ifx_prepare ifx_query ifx_textasvarchar ifx_update_blob ifx_update_char ifxus_close_slob ifxus_create_slob ifxus_free_slob ifxus_open_slob ifxus_read_slob ifxus_seek_slob ifxus_tell_slob ifxus_write_slob
+
+  " Ingres II Functions
+  syn keyword phpCoreConstant contained INGRES_ASSOC INGRES_NUM INGRES_BOTH INGRES_EXT_VERSION INGRES_API_VERSION INGRES_CURSOR_READONLY INGRES_CURSOR_UPDATE INGRES_DATE_MULTINATIONAL INGRES_DATE_MULTINATIONAL4 INGRES_DATE_FINNISH INGRES_DATE_ISO INGRES_DATE_ISO4 INGRES_DATE_GERMAN INGRES_DATE_MDY INGRES_DATE_DMY INGRES_DATE_YMD INGRES_MONEY_LEADING INGRES_MONEY_TRAILING INGRES_STRUCTURE_BTREE INGRES_STRUCTURE_CBTREE INGRES_STRUCTURE_HASH INGRES_STRUCTURE_CHASH INGRES_STRUCTURE_HEAP INGRES_STRUCTURE_CHEAP INGRES_STRUCTURE_ISAM INGRES_STRUCTURE_CISAM
+  syn keyword phpFunctions contained ingres_autocommit ingres_close ingres_commit ingres_connect ingres_cursor ingres_errno ingres_error ingres_errsqlstate ingres_fetch_array ingres_fetch_object ingres_fetch_row ingres_field_length ingres_field_name ingres_field_nullable ingres_field_precision ingres_field_scale ingres_field_type ingres_num_fields ingres_num_rows ingres_pconnect ingres_query ingres_rollback
+
+  " IRC Gateway functions
+  syn keyword phpFunctions contained ircg_channel_mode ircg_disconnect ircg_eval_ecmascript_params ircg_fetch_error_msg ircg_get_username ircg_html_encode ircg_ignore_add ircg_ignore_del ircg_invite ircg_is_conn_alive ircg_join ircg_kick ircg_list ircg_lookup_format_messages ircg_lusers ircg_msg ircg_names ircg_nick ircg_nickname_escape ircg_nickname_unescape ircg_notice ircg_oper ircg_part ircg_pconnect ircg_register_format_messages ircg_set_current ircg_set_file ircg_set_on_die ircg_topic ircg_who ircg_whois
+
+  " PHP/Java Integration
+  " NOTE: this extension is experimental
+
+  " JSON functions
+  syn keyword phpFunctions contained json_decode json_encode
+
+  " KADM5
+  syn keyword phpCoreConstant contained KRB5_KDB_DISALLOW_POSTDATED KRB5_KDB_DISALLOW_FORWARDABLE KRB5_KDB_DISALLOW_TGT_BASED KRB5_KDB_DISALLOW_RENEWABLE KRB5_KDB_DISALLOW_PROXIABLE KRB5_KDB_DISALLOW_DUP_SKEY KRB5_KDB_DISALLOW_ALL_TIX KRB5_KDB_REQUIRES_PRE_AUTH KRB5_KDB_REQUIRES_HW_AUTH KRB5_KDB_REQUIRES_PWCHANGE KRB5_KDB_DISALLOW_SVR KRB5_KDB_PWCHANGE_SERVER KRB5_KDB_SUPPORT_DESMD5 KRB5_KDB_NEW_PRINC KADM5_PRINCIPAL KADM5_PRINC_EXPIRE_TIME KADM5_LAST_PW_CHANGE KADM5_PW_EXPIRATION KADM5_MAX_LIFE KADM5_MAX_RLIFE KADM5_MOD_NAME KADM5_MOD_TIME KADM5_KVNO KADM5_POLICY KADM5_CLEARPOLICY KADM5_LAST_SUCCESS KADM5_LAST_FAILED KADM5_FAIL_AUTH_COUNT KADM5_RANDKEY KADM5_ATTRIBUTES
+  syn keyword phpFunctions contained kadm5_chpass_principal kadm5_create_principal kadm5_delete_principal kadm5_destroy kadm5_flush kadm5_get_policies kadm5_get_principal kadm5_get_principals kadm5_init_with_password kadm5_modify_principal
+
+  " LDAP functions
+  syn keyword phpCoreConstant contained LDAP_DEREF_NEVER LDAP_DEREF_SEARCHING LDAP_DEREF_FINDING LDAP_DEREF_ALWAYS LDAP_OPT_DEREF LDAP_OPT_SIZELIMIT LDAP_OPT_TIMELIMIT LDAP_OPT_NETWORK_TIMEOUT LDAP_OPT_PROTOCOL_VERSION LDAP_OPT_ERROR_NUMBER LDAP_OPT_REFERRALS LDAP_OPT_RESTART LDAP_OPT_HOST_NAME LDAP_OPT_ERROR_STRING LDAP_OPT_MATCHED_DN LDAP_OPT_SERVER_CONTROLS LDAP_OPT_CLIENT_CONTROLS LDAP_OPT_DEBUG_LEVEL GSLC_SSL_NO_AUTH GSLC_SSL_ONEWAY_AUTH GSLC_SSL_TWOWAY_AUTH
+  syn keyword phpFunctions contained ldap_8859_to_t61 ldap_add ldap_bind ldap_close ldap_compare ldap_connect ldap_count_entries ldap_delete ldap_dn2ufn ldap_err2str ldap_errno ldap_error ldap_explode_dn ldap_first_attribute ldap_first_entry ldap_first_reference ldap_free_result ldap_get_attributes ldap_get_dn ldap_get_entries ldap_get_option ldap_get_values_len ldap_get_values ldap_list ldap_mod_add ldap_mod_del ldap_mod_replace ldap_modify ldap_next_attribute ldap_next_entry ldap_next_reference ldap_parse_reference ldap_parse_result ldap_read ldap_rename ldap_sasl_bind ldap_search ldap_set_option ldap_set_rebind_proc ldap_sort ldap_start_tls ldap_t61_to_8859 ldap_unbind
+
+  " libxml functions
+  syn keyword phpClasses contained LibXMLError
+  syn keyword phpCoreConstant contained LIBXML_COMPACT LIBXML_DTDATTR LIBXML_DTDLOAD LIBXML_DTDVALID LIBXML_NOBLANKS LIBXML_NOCDATA LIBXML_NOEMPTYTAG LIBXML_NOENT LIBXML_NOERROR LIBXML_NONET LIBXML_NOWARNING LIBXML_NOXMLDECL LIBXML_NSCLEAN LIBXML_XINCLUDE LIBXML_ERR_ERROR LIBXML_ERR_FATAL LIBXML_ERR_NONE LIBXML_ERR_WARNING LIBXML_VERSION LIBXML_DOTTED_VERSION
+  syn keyword phpFunctions contained libxml_clear_errors libxml_get_errors libxml_get_last_error libxml_set_streams_context libxml_use_internal_errors
+
+  " Lotus Notes functions
+  " NOTE: experimental, no maintainer
+  " syn keyword phpFunctions contained notes_body notes_copy_db notes_create_db notes_create_note notes_drop_db notes_find_note notes_header_info notes_list_msgs notes_mark_read notes_mark_unread notes_nav_create notes_search notes_unread notes_version
+
+  " LZF functions
+  syn keyword phpFunctions contained lzf_compress lzf_decompress lzf_optimized_for
+
+  " Mail functions
+  syn keyword phpFunctions contained ezmlm_hash mail
+
+  " Mailparse functions
+  syn keyword phpCoreConstant contained MAILPARSE_EXTRACT_OUTPUT MAILPARSE_EXTRACT_STREAM MAILPARSE_EXTRACT_RETURN
+  syn keyword phpFunctions contained mailparse_determine_best_xfer_encoding mailparse_msg_create mailparse_msg_extract_part_file mailparse_msg_extract_part mailparse_msg_extract_whole_part_file mailparse_msg_free mailparse_msg_get_part_data mailparse_msg_get_part mailparse_msg_get_structure mailparse_msg_parse_file mailparse_msg_parse mailparse_rfc822_parse_addresses mailparse_stream_encode mailparse_uudecode_all
+
+  " Mathematical functions
+  syn keyword phpCoreConstant contained M_PI M_E M_LOG2E M_LOG10E M_LN2 M_LN10 M_PI_2 M_PI_4 M_1_PI M_2_PI M_SQRTPI M_2_SQRTPI M_SQRT2 M_SQRT3 M_SQRT1_2 M_LNPI M_EULER
+  syn keyword phpFunctions contained abs acos acosh asin asinh atan2 atan atanh base_convert bindec ceil cos cosh decbin dechex decoct deg2rad exp expm1 floor fmod getrandmax hexdec hypot is_finite is_infinite is_nan lcg_value log10 log1p log max min mt_getrandmax mt_rand mt_srand octdec pi pow rad2deg rand round sin sinh sqrt srand tan tanh
+
+  " MaxDB functions
+  syn keyword phpClasses contained maxdb maxdb_stmt maxdb_result
+  syn keyword phpCoreConstant contained MAXDB_COMPNAME MAXDB_APPLICATION MAXDB_APPVERSION MAXDB_SQLMODE MAXDB_UNICODE MAXDB_TIMEOUT MAXDB_ISOLATIONLEVEL MAXDB_PACKETCOUNT MAXDB_STATEMENTCACHESIZE MAXDB_CURSORPREFIX MAXDB_ASSOC MAXDB_ASSOC_UPPER MAXDB_ASSOC_LOWER MAXDB_BOTH MAXDB_NUM
+  syn keyword phpFunctions contained maxdb_affected_rows maxdb_autocommit maxdb_bind_param maxdb_bind_result maxdb_change_user maxdb_character_set_name maxdb_client_encoding maxdb_close_long_data maxdb_close maxdb_commit maxdb_connect_errno maxdb_connect_error maxdb_connect maxdb_data_seek maxdb_debug maxdb_disable_reads_from_master maxdb_disable_rpl_parse maxdb_dump_debug_info maxdb_embedded_connect maxdb_enable_reads_from_master maxdb_enable_rpl_parse maxdb_errno maxdb_error maxdb_escape_string maxdb_execute maxdb_fetch_array maxdb_fetch_assoc maxdb_fetch_field_direct maxdb_fetch_field maxdb_fetch_fields maxdb_fetch_lengths maxdb_fetch_object maxdb_fetch_row maxdb_fetch maxdb_field_count maxdb_field_seek maxdb_field_tell maxdb_free_result maxdb_get_client_info maxdb_get_client_version maxdb_get_host_info maxdb_get_metadata maxdb_get_proto_info maxdb_get_server_info maxdb_get_server_version maxdb_info maxdb_init maxdb_insert_id maxdb_kill maxdb_master_query maxdb_more_results
+  syn keyword phpFunctions contained maxdb_multi_query maxdb_next_result maxdb_num_fields maxdb_num_rows maxdb_options maxdb_param_count maxdb_ping maxdb_prepare maxdb_query maxdb_real_connect maxdb_real_escape_string maxdb_real_query maxdb_report maxdb_rollback maxdb_rpl_parse_enabled maxdb_rpl_probe maxdb_rpl_query_type maxdb_select_db maxdb_send_long_data maxdb_send_query maxdb_server_end maxdb_server_init maxdb_set_opt maxdb_sqlstate maxdb_ssl_set maxdb_stat maxdb_stmt_affected_rows maxdb_stmt_bind_param maxdb_stmt_bind_result maxdb_stmt_close_long_data maxdb_stmt_close maxdb_stmt_data_seek maxdb_stmt_errno maxdb_stmt_error maxdb_stmt_execute maxdb_stmt_fetch maxdb_stmt_free_result maxdb_stmt_init maxdb_stmt_num_rows maxdb_stmt_param_count maxdb_stmt_prepare maxdb_stmt_reset maxdb_stmt_result_metadata maxdb_stmt_send_long_data maxdb_stmt_sqlstate maxdb_stmt_store_result maxdb_store_result maxdb_thread_id maxdb_thread_safe maxdb_use_result maxdb_warning_count
+
+  " MCAL functions
+  syn keyword phpCoreConstant contained MCAL_SUNDAY MCAL_MONDAY MCAL_TUESDAY MCAL_WEDNESDAY MCAL_THURSDAY MCAL_FRIDAY MCAL_SATURDAY MCAL_JANUARY MCAL_FEBRUARY MCAL_MARCH MCAL_APRIL MCAL_MAY MCAL_JUNE MCAL_JULY MCAL_AUGUST MCAL_SEPTEMBER MCAL_OCTOBER MCAL_NOVEMBER MCAL_DECEMBER MCAL_RECUR_NONE MCAL_RECUR_DAILY MCAL_RECUR_WEEKLY MCAL_RECUR_MONTHLY_MDAY MCAL_RECUR_MONTHLY_WDAY MCAL_RECUR_YEARLY MCAL_M_SUNDAY MCAL_M_MONDAY MCAL_M_TUESDAY MCAL_M_WEDNESDAY MCAL_M_THURSDAY MCAL_M_FRIDAY MCAL_M_SATURDAY MCAL_M_WEEKDAYS MCAL_M_WEEKEND MCAL_M_ALLDAYS
+  syn keyword phpFunctions contained mcal_append_event mcal_close mcal_create_calendar mcal_date_compare mcal_date_valid mcal_day_of_week mcal_day_of_year mcal_days_in_month mcal_delete_calendar mcal_delete_event mcal_event_add_attribute mcal_event_init mcal_event_set_alarm mcal_event_set_category mcal_event_set_class mcal_event_set_description mcal_event_set_end mcal_event_set_recur_daily mcal_event_set_recur_monthly_mday mcal_event_set_recur_monthly_wday mcal_event_set_recur_none mcal_event_set_recur_weekly mcal_event_set_recur_yearly mcal_event_set_start mcal_event_set_title mcal_expunge mcal_fetch_current_stream_event mcal_fetch_event mcal_is_leap_year mcal_list_alarms mcal_list_events mcal_next_recurrence mcal_open mcal_popen mcal_rename_calendar mcal_reopen mcal_snooze mcal_store_event mcal_time_valid mcal_week_of_year
+
+  " Mcrypt Encryption functions
+  syn keyword phpCoreConstant contained MCRYPT_MODE_ECB MCRYPT_MODE_CBC MCRYPT_MODE_CFB MCRYPT_MODE_OFB MCRYPT_MODE_NOFB MCRYPT_MODE_STREAM MCRYPT_ENCRYPT MCRYPT_DECRYPT MCRYPT_DEV_RANDOM MCRYPT_DEV_URANDOM MCRYPT_RAND MCRYPT_3DES MCRYPT_ARCFOUR_IV MCRYPT_ARCFOUR MCRYPT_BLOWFISH MCRYPT_CAST_128 MCRYPT_CAST_256 MCRYPT_CRYPT MCRYPT_DES MCRYPT_DES_COMPAT MCRYPT_ENIGMA MCRYPT_GOST MCRYPT_IDEA MCRYPT_LOKI97 MCRYPT_MARS MCRYPT_PANAMA MCRYPT_RIJNDAEL_128 MCRYPT_RIJNDAEL_192 MCRYPT_RIJNDAEL_256 MCRYPT_RC2 MCRYPT_RC4 MCRYPT_RC6 MCRYPT_RC6_128 MCRYPT_RC6_192 MCRYPT_RC6_256 MCRYPT_SAFER64 MCRYPT_SAFER128 MCRYPT_SAFERPLUS MCRYPT_SERPENT(libmcrypt MCRYPT_SERPENT_128 MCRYPT_SERPENT_192 MCRYPT_SERPENT_256 MCRYPT_SKIPJACK MCRYPT_TEAN MCRYPT_THREEWAY MCRYPT_TRIPLEDES MCRYPT_TWOFISH MCRYPT_TWOFISH128 MCRYPT_TWOFISH192 MCRYPT_TWOFISH256 MCRYPT_WAKE MCRYPT_XTEA
+  syn keyword phpFunctions contained mcrypt_cbc mcrypt_cfb mcrypt_create_iv mcrypt_decrypt mcrypt_ecb mcrypt_enc_get_algorithms_name mcrypt_enc_get_block_size mcrypt_enc_get_iv_size mcrypt_enc_get_key_size mcrypt_enc_get_modes_name mcrypt_enc_get_supported_key_sizes mcrypt_enc_is_block_algorithm_mode mcrypt_enc_is_block_algorithm mcrypt_enc_is_block_mode mcrypt_enc_self_test mcrypt_encrypt mcrypt_generic_deinit mcrypt_generic_end mcrypt_generic_init mcrypt_generic mcrypt_get_block_size mcrypt_get_cipher_name mcrypt_get_iv_size mcrypt_get_key_size mcrypt_list_algorithms mcrypt_list_modes mcrypt_module_close mcrypt_module_get_algo_block_size mcrypt_module_get_algo_key_size mcrypt_module_get_supported_key_sizes mcrypt_module_is_block_algorithm_mode mcrypt_module_is_block_algorithm mcrypt_module_is_block_mode mcrypt_module_open mcrypt_module_self_test mcrypt_ofb mdecrypt_generic
+
+  " MCVE (Monetra) Payment functions
+  syn keyword phpCoreConstant contained M_PENDING M_DONE M_ERROR M_FAIL M_SUCCESS
+  syn keyword phpFunctions contained m_checkstatus m_completeauthorizations m_connect m_connectionerror m_deletetrans m_destroyconn m_destroyengine m_getcell m_getcellbynum m_getcommadelimited m_getheader m_initconn m_initengine m_iscommadelimited m_maxconntimeout m_monitor m_numcolumns m_numrows m_parsecommadelimited m_responsekeys m_responseparam m_returnstatus m_setblocking m_setdropfile m_setip m_setssl_cafile m_setssl_files m_setssl m_settimeout m_sslcert_gen_hash m_transactionssent m_transinqueue m_transkeyval m_transnew m_transsend m_uwait m_validateidentifier m_verifyconnection m_verifysslcert
+
+  " Memcache functions
+  syn keyword phpClasses contained Memcache
+  syn keyword phpCoreConstant contained MEMCACHE_COMPRESSED MEMCACHE_HAVE_SESSION
+  syn keyword phpFunctions contained memcache_add memcache_add_server memcache_close memcache_connect memcache_debug memcache_decrement memcache_delete memcache_flush memcache_get memcache_get_extended_stats memcache_get_server_status memcache_get_stats memcache_get_version memcache_increment memcache_pconnect memcache_replace memcache_set memcache_set_compress_threshold memcache_set_server_params
+
+  " MHash functions
+  syn keyword phpCoreConstant contained MHASH_ADLER32 MHASH_CRC32 MHASH_CRC32B MHASH_GOST MHASH_HAVAL128 MHASH_HAVAL160 MHASH_HAVAL192 MHASH_HAVAL256 MHASH_MD4 MHASH_MD5 MHASH_RIPEMD160 MHASH_SHA1 MHASH_SHA256 MHASH_TIGER MHASH_TIGER128 MHASH_TIGER160 
+  syn keyword phpFunctions contained mhash_count mhash_get_block_size mhash_get_hash_name mhash_keygen_s2k mhash
+
+  " Mimetype functions
+  " NOTE: has been deprecated in favour of the Fileinfo extension
+  " syn keyword phpFunctions contained mime_content_type
+
+  " Ming functions for flash
+  " NOTE: this extension is experimental
+  " syn keyword phpCoreConstant contained MING_NEW MING_ZLIB SWFBUTTON_HIT SWFBUTTON_DOWN SWFBUTTON_OVER SWFBUTTON_UP SWFBUTTON_MOUSEUPOUTSIDE SWFBUTTON_DRAGOVER SWFBUTTON_DRAGOUT SWFBUTTON_MOUSEUP SWFBUTTON_MOUSEDOWN SWFBUTTON_MOUSEOUT SWFBUTTON_MOUSEOVER SWFFILL_RADIAL_GRADIENT SWFFILL_LINEAR_GRADIENT SWFFILL_TILED_BITMAP SWFFILL_CLIPPED_BITMAP SWFTEXTFIELD_HASLENGTH SWFTEXTFIELD_NOEDIT SWFTEXTFIELD_PASSWORD SWFTEXTFIELD_MULTILINE SWFTEXTFIELD_WORDWRAP SWFTEXTFIELD_DRAWBOX SWFTEXTFIELD_NOSELECT SWFTEXTFIELD_HTML SWFTEXTFIELD_ALIGN_LEFT SWFTEXTFIELD_ALIGN_RIGHT SWFTEXTFIELD_ALIGN_CENTER SWFTEXTFIELD_ALIGN_JUSTIFY SWFACTION_ONLOAD SWFACTION_ENTERFRAME SWFACTION_UNLOAD SWFACTION_MOUSEMOVE SWFACTION_MOUSEDOWN SWFACTION_MOUSEUP SWFACTION_KEYDOWN SWFACTION_KEYUP SWFACTION_DATA
+  " syn keyword phpClasses contained SWFAction SWFBitmap SWFButton SWFDisplayItem SWFFill SWFFont SWFFontChar SWFGradient SWFMorph SWFMovie SWFPrebuiltClip SWFShape SWFSound SWFSoundInstance SWFSprite SWFText SWFTextField SWFVideoStream
+  " syn keyword phpFunctions contained ming_keypress ming_setcubicthreshold ming_setscale ming_setswfcompression ming_useconstants ming_useswfversion
+
+  " Miscellaneous functions
+  " NOTE: php_check_syntax was removed after PHP 5.0.4
+  " NOTE: some of the functions like exit() and die() are defined elsewhere
+  syn keyword phpCoreConstant contained CONNECTION_ABORTED CONNECTION_NORMAL CONNECTION_TIMEOUT __COMPILER_HALT_OFFSET__
+  syn keyword phpFunctions contained connection_aborted connection_status connection_timeout constant define defined get_browser highlight_file highlight_string ignore_user_abort pack php_strip_whitespace show_source sleep sys_getloadavg time_nanosleep time_sleep_until uniqid unpack usleep
+
+  " mnoGoSearch functions
+  syn keyword phpCoreConstant contained UDM_FIELD_URLID UDM_FIELD_URL UDM_FIELD_CONTENT UDM_FIELD_TITLE UDM_FIELD_KEYWORDS UDM_FIELD_DESC UDM_FIELD_DESCRIPTION UDM_FIELD_TEXT UDM_FIELD_SIZE UDM_FIELD_RATING UDM_FIELD_SCORE UDM_FIELD_MODIFIED UDM_FIELD_ORDER UDM_FIELD_CRC UDM_FIELD_CATEGORY UDM_FIELD_LANG UDM_FIELD_CHARSET UDM_PARAM_PAGE_SIZE UDM_PARAM_PAGE_NUM UDM_PARAM_SEARCH_MODE UDM_PARAM_CACHE_MODE UDM_PARAM_TRACK_MODE UDM_PARAM_PHRASE_MODE UDM_PARAM_CHARSET UDM_PARAM_LOCAL_CHARSET UDM_PARAM_BROWSER_CHARSET UDM_PARAM_STOPTABLE UDM_PARAM_STOP_TABLE UDM_PARAM_STOPFILE UDM_PARAM_STOP_FILE UDM_PARAM_WEIGHT_FACTOR UDM_PARAM_WORD_MATCH UDM_PARAM_MAX_WORD_LEN UDM_PARAM_MAX_WORDLEN UDM_PARAM_MIN_WORD_LEN UDM_PARAM_MIN_WORDLEN UDM_PARAM_ISPELL_PREFIXES UDM_PARAM_ISPELL_PREFIX UDM_PARAM_PREFIXES UDM_PARAM_PREFIX UDM_PARAM_CROSS_WORDS UDM_PARAM_CROSSWORDS UDM_PARAM_VARDIR UDM_PARAM_DATADIR UDM_PARAM_HLBEG UDM_PARAM_HLEND UDM_PARAM_SYNONYM UDM_PARAM_SEARCHD UDM_PARAM_QSTRING UDM_PARAM_REMOTE_ADDR UDM_LIMIT_CAT UDM_LIMIT_URL UDM_LIMIT_TAG UDM_LIMIT_LANG UDM_LIMIT_DATE UDM_PARAM_FOUND UDM_PARAM_NUM_ROWS UDM_PARAM_WORDINFO UDM_PARAM_WORD_INFO UDM_PARAM_SEARCHTIME UDM_PARAM_SEARCH_TIME UDM_PARAM_FIRST_DOC UDM_PARAM_LAST_DOC UDM_MODE_ALL UDM_MODE_ANY UDM_MODE_BOOL UDM_MODE_PHRASE UDM_CACHE_ENABLED UDM_CACHE_DISABLED UDM_TRACK_ENABLED UDM_TRACK_DISABLED UDM_PHRASE_ENABLED UDM_PHRASE_DISABLED UDM_CROSS_WORDS_ENABLED UDM_CROSSWORDS_ENABLED UDM_CROSS_WORDS_DISABLED UDM_CROSSWORDS_DISABLED UDM_PREFIXES_ENABLED UDM_PREFIX_ENABLED UDM_ISPELL_PREFIXES_ENABLED UDM_ISPELL_PREFIX_ENABLED UDM_PREFIXES_DISABLED UDM_PREFIX_DISABLED UDM_ISPELL_PREFIXES_DISABLED UDM_ISPELL_PREFIX_DISABLED UDM_ISPELL_TYPE_AFFIX UDM_ISPELL_TYPE_SPELL UDM_ISPELL_TYPE_DB UDM_ISPELL_TYPE_SERVER UDM_MATCH_WORD UDM_MATCH_BEGIN UDM_MATCH_SUBSTR UDM_MATCH_END
+  syn keyword phpFunctions contained udm_add_search_limit udm_alloc_agent_array udm_alloc_agent udm_api_version udm_cat_list udm_cat_path udm_check_charset udm_check_stored udm_clear_search_limits udm_close_stored udm_crc32 udm_errno udm_error udm_find udm_free_agent udm_free_ispell_data udm_free_res udm_get_doc_count udm_get_res_field udm_get_res_param udm_hash32 udm_load_ispell_data udm_open_stored udm_set_agent_param
+
+  " Microsoft SQL server functions
+  syn keyword phpCoreConstant contained MSSQL_ASSOC MSSQL_NUM MSSQL_BOTH SQLTEXT SQLVARCHAR SQLCHAR SQLINT1 SQLINT2 SQLINT4 SQLBIT SQLFLT8
+  syn keyword phpFunctions contained mssql_bind mssql_close mssql_connect mssql_data_seek mssql_execute mssql_fetch_array mssql_fetch_assoc mssql_fetch_batch mssql_fetch_field mssql_fetch_object mssql_fetch_row mssql_field_length mssql_field_name mssql_field_seek mssql_field_type mssql_free_result mssql_free_statement mssql_get_last_message mssql_guid_string mssql_init mssql_min_error_severity mssql_min_message_severity mssql_next_result mssql_num_fields mssql_num_rows mssql_pconnect mssql_query mssql_result mssql_rows_affected mssql_select_db
+
+  " Mohawk Software Session Handler Functions
+  syn keyword phpFunctions contained msession_connect msession_count msession_create msession_destroy msession_disconnect msession_find msession_get_array msession_get_data msession_get msession_inc msession_list msession_listvar msession_lock msession_plugin msession_randstr msession_set_array msession_set_data msession_set msession_timeout msession_uniq msession_unlock
+
+  " mSQL functions
+  syn keyword phpCoreConstant contained MSQL_ASSOC MSQL_NUM MSQL_BOTH
+  syn keyword phpFunctions contained msql_affected_rows msql_close msql_connect msql_create_db msql_createdb msql_data_seek msql_db_query msql_dbname msql_drop_db msql_error msql_fetch_array msql_fetch_field msql_fetch_object msql_fetch_row msql_field_flags msql_field_len msql_field_name msql_field_seek msql_field_table msql_field_type msql_fieldflags msql_fieldlen msql_fieldname msql_fieldtable msql_fieldtype msql_free_result msql_list_dbs msql_list_fields msql_list_tables msql_num_fields msql_num_rows msql_numfields msql_numrows msql_pconnect msql_query msql_regcase msql_result msql_select_db msql_tablename msql
+
+  " Multibyte string functions
+  syn keyword phpCoreConstant contained MB_OVERLOAD_MAIL MB_OVERLOAD_STRING MB_OVERLOAD_REGEX MB_CASE_UPPER MB_CASE_LOWER MB_CASE_TITLE
+  syn keyword phpFunctions contained mb_check_encoding mb_convert_case mb_convert_encoding mb_convert_kana mb_convert_variables mb_decode_mimeheader mb_decode_numericentity mb_detect_encoding mb_detect_order mb_encode_mimeheader mb_encode_numericentity mb_ereg_match mb_ereg_replace mb_ereg_search_getpos mb_ereg_search_getregs mb_ereg_search_init mb_ereg_search_pos mb_ereg_search_regs mb_ereg_search_setpos mb_ereg_search mb_ereg mb_eregi_replace mb_eregi mb_get_info mb_http_input mb_http_output mb_internal_encoding mb_language mb_output_handler mb_parse_str mb_preferred_mime_name mb_regex_encoding mb_regex_set_options mb_send_mail mb_split mb_strcut mb_strimwidth mb_stripos mb_stristr mb_strlen mb_strpos mb_strrchr mb_strrichr mb_strripos mb_strrpos mb_strstr mb_strtolower mb_strtoupper mb_strwidth mb_substitute_character mb_substr_count mb_substr
+
+  " muscat functions
+  " NOTE: Experimental, doesn't seem to be necessary any more
+
+  " MySQL functions
+  syn keyword phpCoreConstant contained MYSQL_CLIENT_COMPRESS MYSQL_CLIENT_IGNORE_SPACE MYSQL_CLIENT_INTERACTIVE MYSQL_CLIENT_SSL MYSQL_ASSOC MYSQL_BOTH MYSQL_NUM
+  syn keyword phpFunctions contained mysql_affected_rows mysql_change_user mysql_client_encoding mysql_close mysql_connect mysql_create_db mysql_data_seek mysql_db_name mysql_db_query mysql_drop_db mysql_errno mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek mysql_field_table mysql_field_type mysql_free_result mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes mysql_list_tables mysql_num_fields mysql_num_rows mysql_pconnect mysql_ping mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_set_charset mysql_stat mysql_tablename mysql_thread_id mysql_unbuffered_query
+
+  " MySQL Improved extension
+  syn keyword phpClasses contained mysqli mysqli_stmt mysqli_result
+  syn keyword phpCoreConstant contained MYSQLI_READ_DEFAULT_GROUP MYSQLI_READ_DEFAULT_FILE MYSQLI_OPT_CONNECT_TIMEOUT MYSQLI_OPT_LOCAL_INFILE MYSQLI_INIT_COMMAND MYSQLI_CLIENT_SSL MYSQLI_CLIENT_COMPRESS MYSQLI_CLIENT_INTERACTIVE MYSQLI_CLIENT_IGNORE_SPACE MYSQLI_CLIENT_NO_SCHEMA MYSQLI_CLIENT_MULTI_QUERIES MYSQLI_STORE_RESULT MYSQLI_USE_RESULT MYSQLI_ASSOC MYSQLI_NUM MYSQLI_BOTH MYSQLI_NOT_NULL_FLAG MYSQLI_PRI_KEY_FLAG MYSQLI_UNIQUE_KEY_FLAG MYSQLI_MULTIPLE_KEY_FLAG MYSQLI_BLOB_FLAG MYSQLI_UNSIGNED_FLAG MYSQLI_ZEROFILL_FLAG MYSQLI_AUTO_INCREMENT_FLAG MYSQLI_TIMESTAMP_FLAG MYSQLI_SET_FLAG MYSQLI_NUM_FLAG MYSQLI_PART_KEY_FLAG MYSQLI_GROUP_FLAG MYSQLI_TYPE_DECIMAL MYSQLI_TYPE_NEWDECIMAL MYSQLI_TYPE_BIT MYSQLI_TYPE_TINY MYSQLI_TYPE_SHORT MYSQLI_TYPE_LONG MYSQLI_TYPE_FLOAT MYSQLI_TYPE_DOUBLE MYSQLI_TYPE_NULL MYSQLI_TYPE_TIMESTAMP MYSQLI_TYPE_LONGLONG MYSQLI_TYPE_INT24 MYSQLI_TYPE_DATE MYSQLI_TYPE_TIME MYSQLI_TYPE_DATETIME MYSQLI_TYPE_YEAR MYSQLI_TYPE_NEWDATE MYSQLI_TYPE_ENUM MYSQLI_TYPE_SET MYSQLI_TYPE_TINY_BLOB MYSQLI_TYPE_MEDIUM_BLOB MYSQLI_TYPE_LONG_BLOB MYSQLI_TYPE_BLOB MYSQLI_TYPE_VAR_STRING MYSQLI_TYPE_STRING MYSQLI_TYPE_GEOMETRY MYSQLI_NEED_DATA MYSQLI_NO_DATA MYSQLI_DATA_TRUNCATED
+  syn keyword phpFunctions contained mysqli_affected_rows mysqli_autocommit mysqli_bind_param mysqli_bind_result mysqli_change_user mysqli_character_set_name mysqli_client_encoding mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_disable_reads_from_master mysqli_disable_rpl_parse mysqli_dump_debug_info mysqli_embedded_server_end mysqli_embedded_server_start mysqli_enable_reads_from_master mysqli_enable_rpl_parse mysqli_errno mysqli_error mysqli_escape_string mysqli_execute mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_fetch mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_version mysqli_get_host_info mysqli_get_metadata mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_get_warnings
+  syn keyword phpFunctions contained mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_master_query mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_param_count mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_report mysqli_rollback mysqli_rpl_parse_enabled mysqli_rpl_probe mysqli_rpl_query_type mysqli_select_db mysqli_send_long_data mysqli_send_query mysqli_server_end mysqli_server_init mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_set_opt mysqli_slave_query mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_affected_rows mysqli_stmt_attr_get mysqli_stmt_attr_set mysqli_stmt_bind_param mysqli_stmt_bind_result mysqli_stmt_close mysqli_stmt_data_seek mysqli_stmt_errno mysqli_stmt_error mysqli_stmt_execute mysqli_stmt_fetch mysqli_stmt_field_count mysqli_stmt_free_result mysqli_stmt_get_warnings
+  syn keyword phpFunctions contained mysqli_stmt_init mysqli_stmt_insert_id mysqli_stmt_num_rows mysqli_stmt_param_count mysqli_stmt_prepare mysqli_stmt_reset mysqli_stmt_result_metadata mysqli_stmt_send_long_data mysqli_stmt_sqlstate mysqli_stmt_store_result mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count
+
+  " ncurses extension
+  " NOTE: this extension is experimental
+  syn keyword phpCoreConstant contained NCURSES_ERR NCURSES_COLOR_BLACK NCURSES_COLOR_WHITE NCURSES_COLOR_RED NCURSES_COLOR_GREEN NCURSES_COLOR_YELLOW NCURSES_COLOR_BLUE NCURSES_COLOR_CYAN NCURSES_COLOR_MAGENTA
+  " Keyboard
+  syn match phpCoreConstant contained /\<NCURSES_KEY_F\%(6[0-4]\=\|[1-5][0-9]\|[0-9]\)\>/
+  syn keyword phpCoreConstant contained NCURSES_KEY_DOWN NCURSES_KEY_UP NCURSES_KEY_LEFT NCURSES_KEY_RIGHT NCURSES_KEY_HOME NCURSES_KEY_BACKSPACE NCURSES_KEY_DL NCURSES_KEY_IL NCURSES_KEY_DC NCURSES_KEY_IC NCURSES_KEY_EIC NCURSES_KEY_CLEAR NCURSES_KEY_EOS NCURSES_KEY_EOL NCURSES_KEY_SF NCURSES_KEY_SR NCURSES_KEY_NPAGE NCURSES_KEY_PPAGE NCURSES_KEY_STAB NCURSES_KEY_CTAB NCURSES_KEY_CATAB NCURSES_KEY_SRESET NCURSES_KEY_RESET NCURSES_KEY_PRINT NCURSES_KEY_LL NCURSES_KEY_A1 NCURSES_KEY_A3 NCURSES_KEY_B2 NCURSES_KEY_C1 NCURSES_KEY_C3 NCURSES_KEY_BTAB NCURSES_KEY_BEG NCURSES_KEY_CANCEL NCURSES_KEY_CLOSE NCURSES_KEY_COMMAND NCURSES_KEY_COPY NCURSES_KEY_CREATE NCURSES_KEY_END NCURSES_KEY_EXIT NCURSES_KEY_FIND NCURSES_KEY_HELP NCURSES_KEY_MARK NCURSES_KEY_MESSAGE NCURSES_KEY_MOVE NCURSES_KEY_NEXT NCURSES_KEY_OPEN NCURSES_KEY_OPTIONS NCURSES_KEY_PREVIOUS NCURSES_KEY_REDO NCURSES_KEY_REFERENCE NCURSES_KEY_REFRESH NCURSES_KEY_REPLACE NCURSES_KEY_RESTART NCURSES_KEY_RESUME
+  syn keyword phpCoreConstant contained NCURSES_KEY_SAVE NCURSES_KEY_SBEG NCURSES_KEY_SCANCEL NCURSES_KEY_SCOMMAND NCURSES_KEY_SCOPY NCURSES_KEY_SCREATE NCURSES_KEY_SDC NCURSES_KEY_SDL NCURSES_KEY_SELECT NCURSES_KEY_SEND NCURSES_KEY_SEOL NCURSES_KEY_SEXIT NCURSES_KEY_SFIND NCURSES_KEY_SHELP NCURSES_KEY_SHOME NCURSES_KEY_SIC NCURSES_KEY_SLEFT NCURSES_KEY_SMESSAGE NCURSES_KEY_SMOVE NCURSES_KEY_SNEXT NCURSES_KEY_SOPTIONS NCURSES_KEY_SPREVIOUS NCURSES_KEY_SPRINT NCURSES_KEY_SREDO NCURSES_KEY_SREPLACE NCURSES_KEY_SRIGHT NCURSES_KEY_SRSUME NCURSES_KEY_SSAVE NCURSES_KEY_SSUSPEND NCURSES_KEY_UNDO NCURSES_KEY_MOUSE NCURSES_KEY_MAX
+  " Mouse
+  syn keyword phpCoreConstant contained NCURSES_BUTTON1_RELEASED NCURSES_BUTTON2_RELEASED NCURSES_BUTTON3_RELEASED NCURSES_BUTTON4_RELEASED NCURSES_BUTTON1_PRESSED NCURSES_BUTTON2_PRESSED NCURSES_BUTTON3_PRESSED NCURSES_BUTTON4_PRESSED NCURSES_BUTTON1_CLICKED NCURSES_BUTTON2_CLICKED NCURSES_BUTTON3_CLICKED NCURSES_BUTTON4_CLICKED NCURSES_BUTTON1_DOUBLE_CLICKED NCURSES_BUTTON2_DOUBLE_CLICKED NCURSES_BUTTON3_DOUBLE_CLICKED NCURSES_BUTTON4_DOUBLE_CLICKED NCURSES_BUTTON1_TRIPLE_CLICKED NCURSES_BUTTON2_TRIPLE_CLICKED NCURSES_BUTTON3_TRIPLE_CLICKED NCURSES_BUTTON4_TRIPLE_CLICKED NCURSES_BUTTON_CTRL NCURSES_BUTTON_SHIFT NCURSES_BUTTON_ALT NCURSES_ALL_MOUSE_EVENTS NCURSES_REPORT_MOUSE_POSITION
+  " Functions
+  syn keyword phpFunctions contained ncurses_addch ncurses_addchnstr ncurses_addchstr ncurses_addnstr ncurses_addstr ncurses_assume_default_colors ncurses_attroff ncurses_attron ncurses_attrset ncurses_baudrate ncurses_beep ncurses_bkgd ncurses_bkgdset ncurses_border ncurses_bottom_panel ncurses_can_change_color ncurses_cbreak ncurses_clear ncurses_clrtobot ncurses_clrtoeol ncurses_color_content ncurses_color_set ncurses_curs_set ncurses_def_prog_mode ncurses_def_shell_mode ncurses_define_key ncurses_del_panel ncurses_delay_output ncurses_delch ncurses_deleteln ncurses_delwin ncurses_doupdate ncurses_echo ncurses_echochar ncurses_end ncurses_erase ncurses_erasechar ncurses_filter ncurses_flash ncurses_flushinp ncurses_getch ncurses_getmaxyx ncurses_getmouse ncurses_getyx ncurses_halfdelay ncurses_has_colors ncurses_has_ic ncurses_has_il ncurses_has_key ncurses_hide_panel ncurses_hline ncurses_inch ncurses_init_color ncurses_init_pair
+  syn keyword phpFunctions contained ncurses_init ncurses_insch ncurses_insdelln ncurses_insertln ncurses_insstr ncurses_instr ncurses_isendwin ncurses_keyok ncurses_keypad ncurses_killchar ncurses_longname ncurses_meta ncurses_mouse_trafo ncurses_mouseinterval ncurses_mousemask ncurses_move_panel ncurses_move ncurses_mvaddch ncurses_mvaddchnstr ncurses_mvaddchstr ncurses_mvaddnstr ncurses_mvaddstr ncurses_mvcur ncurses_mvdelch ncurses_mvgetch ncurses_mvhline ncurses_mvinch ncurses_mvvline ncurses_mvwaddstr ncurses_napms ncurses_new_panel ncurses_newpad ncurses_newwin ncurses_nl ncurses_nocbreak ncurses_noecho ncurses_nonl ncurses_noqiflush ncurses_noraw ncurses_pair_content ncurses_panel_above ncurses_panel_below ncurses_panel_window ncurses_pnoutrefresh ncurses_prefresh ncurses_putp ncurses_qiflush ncurses_raw ncurses_refresh ncurses_replace_panel ncurses_reset_prog_mode ncurses_reset_shell_mode ncurses_resetty ncurses_savetty
+  syn keyword phpFunctions contained ncurses_scr_dump ncurses_scr_init ncurses_scr_restore ncurses_scr_set ncurses_scrl ncurses_show_panel ncurses_slk_attr ncurses_slk_attroff ncurses_slk_attron ncurses_slk_attrset ncurses_slk_clear ncurses_slk_color ncurses_slk_init ncurses_slk_noutrefresh ncurses_slk_refresh ncurses_slk_restore ncurses_slk_set ncurses_slk_touch ncurses_standend ncurses_standout ncurses_start_color ncurses_termattrs ncurses_termname ncurses_timeout ncurses_top_panel ncurses_typeahead ncurses_ungetch ncurses_ungetmouse ncurses_update_panels ncurses_use_default_colors ncurses_use_env ncurses_use_extended_names ncurses_vidattr ncurses_vline ncurses_waddch ncurses_waddstr ncurses_wattroff ncurses_wattron ncurses_wattrset ncurses_wborder ncurses_wclear ncurses_wcolor_set ncurses_werase ncurses_wgetch ncurses_whline ncurses_wmouse_trafo ncurses_wmove ncurses_wnoutrefresh ncurses_wrefresh ncurses_wstandend ncurses_wstandout ncurses_wvline
+
+  " network functions
+  syn keyword phpCoreConstant contained LOG_CONS LOG_NDELAY LOG_ODELAY LOG_NOWAIT LOG_PERROR LOG_PID LOG_AUTH LOG_AUTHPRIV LOG_CRON LOG_DAEMON LOG_KERN LOG_LOCAL0 LOG_LPR LOG_MAIL LOG_NEWS LOG_SYSLOG LOG_USER LOG_UUCP LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG DNS_A DNS_MX DNS_CNAME DNS_NS DNS_PTR DNS_HINFO DNS_SOA DNS_TXT DNS_ANY DNS_AAAA DNS_ALL
+  syn keyword phpFunctions contained checkdnsrr closelog debugger_off debugger_on define_syslog_variables dns_check_record dns_get_mx dns_get_record fsockopen gethostbyaddr gethostbyname gethostbynamel getmxrr getprotobyname getprotobynumber getservbyname getservbyport header headers_list headers_sent inet_ntop inet_pton ip2long long2ip openlog pfsockopen setcookie setrawcookie socket_get_status socket_set_blocking socket_set_timeout syslog
+
+  " newt functions
+  syn keyword phpCoreConstant contained NEWT_EXIT_HOTKEY NEWT_EXIT_COMPONENT NEWT_EXIT_FDREADY NEWT_EXIT_TIMER NEWT_COLORSET_ROOT NEWT_COLORSET_BORDER NEWT_COLORSET_WINDOW NEWT_COLORSET_SHADOW NEWT_COLORSET_TITLE NEWT_COLORSET_BUTTON NEWT_COLORSET_ACTBUTTON NEWT_COLORSET_CHECKBOX NEWT_COLORSET_ACTCHECKBOX NEWT_COLORSET_ENTRY NEWT_COLORSET_LABEL NEWT_COLORSET_LISTBOX NEWT_COLORSET_ACTLISTBOX NEWT_COLORSET_TEXTBOX NEWT_COLORSET_ACTTEXTBOX NEWT_COLORSET_HELPLINE NEWT_COLORSET_ROOTTEXT NEWT_COLORSET_ROOTTEXT NEWT_COLORSET_EMPTYSCALE NEWT_COLORSET_FULLSCALE NEWT_COLORSET_DISENTRY NEWT_COLORSET_COMPACTBUTTON NEWT_COLORSET_ACTSELLISTBOX NEWT_COLORSET_SELLISTBOX NEWT_FLAGS_SET NEWT_FLAGS_RESET NEWT_FLAGS_TOGGLE NEWT_FLAG_RETURNEXIT NEWT_FLAG_HIDDEN NEWT_FLAG_SCROLL NEWT_FLAG_DISABLED NEWT_FLAG_BORDER NEWT_FLAG_WRAP NEWT_FLAG_NOF12 NEWT_FLAG_MULTIPLE NEWT_FLAG_SELECTED NEWT_FLAG_CHECKBOX NEWT_FLAG_PASSWORD NEWT_FLAG_SHOWCURSOR NEWT_FD_READ NEWT_FD_WRITE NEWT_FD_EXCEPT NEWT_CHECKBOXTREE_UNSELECTABLE
+  syn keyword phpCoreConstant contained NEWT_CHECKBOXTREE_HIDE_BOX NEWT_CHECKBOXTREE_COLLAPSED NEWT_CHECKBOXTREE_EXPANDED NEWT_CHECKBOXTREE_UNSELECTED NEWT_CHECKBOXTREE_SELECTED NEWT_ENTRY_SCROLL NEWT_ENTRY_HIDDEN NEWT_ENTRY_RETURNEXIT NEWT_ENTRY_DISABLED NEWT_LISTBOX_RETURNEXIT NEWT_TEXTBOX_WRAP NEWT_TEXTBOX_SCROLL NEWT_FORM_NOF12 NEWT_KEY_TAB NEWT_KEY_ENTER NEWT_KEY_SUSPEND NEWT_KEY_ESCAPE NEWT_KEY_RETURN NEWT_KEY_EXTRA_BASE NEWT_KEY_UP NEWT_KEY_DOWN NEWT_KEY_LEFT NEWT_KEY_RIGHT NEWT_KEY_BKSPC NEWT_KEY_DELETE NEWT_KEY_HOME NEWT_KEY_END NEWT_KEY_UNTAB NEWT_KEY_PGUP NEWT_KEY_PGDN NEWT_KEY_INSERT NEWT_KEY_F1 NEWT_KEY_F2 NEWT_KEY_F3 NEWT_KEY_F4 NEWT_KEY_F5 NEWT_KEY_F6 NEWT_KEY_F7 NEWT_KEY_F8 NEWT_KEY_F9 NEWT_KEY_F10 NEWT_KEY_F11 NEWT_KEY_F12 NEWT_KEY_RESIZE NEWT_ANCHOR_LEFT NEWT_ANCHOR_RIGHT NEWT_ANCHOR_TOP NEWT_ANCHOR_BOTTOM NEWT_GRID_FLAG_GROWX NEWT_GRID_FLAG_GROWY NEWT_GRID_EMPTY NEWT_GRID_COMPONENT NEWT_GRID_SUBGRID
+  syn keyword phpFunctions contained newt_bell newt_button_bar newt_button newt_centered_window newt_checkbox_get_value newt_checkbox_set_flags newt_checkbox_set_value newt_checkbox_tree_add_item newt_checkbox_tree_find_item newt_checkbox_tree_get_current newt_checkbox_tree_get_entry_value newt_checkbox_tree_get_multi_selection newt_checkbox_tree_get_selection newt_checkbox_tree_multi newt_checkbox_tree_set_current newt_checkbox_tree_set_entry_value newt_checkbox_tree_set_entry newt_checkbox_tree_set_width newt_checkbox_tree newt_checkbox newt_clear_key_buffer newt_cls newt_compact_button newt_component_add_callback newt_component_takes_focus newt_create_grid newt_cursor_off newt_cursor_on newt_delay newt_draw_form newt_draw_root_text newt_entry_get_value newt_entry_set_filter newt_entry_set_flags newt_entry_set newt_entry newt_finished newt_form_add_component newt_form_add_components newt_form_add_hot_key newt_form_destroy newt_form_get_current newt_form_run
+  syn keyword phpFunctions contained newt_form_set_background newt_form_set_height newt_form_set_size newt_form_set_timer newt_form_set_width newt_form_watch_fd newt_form newt_get_screen_size newt_grid_add_components_to_form newt_grid_basic_window newt_grid_free newt_grid_get_size newt_grid_h_close_stacked newt_grid_h_stacked newt_grid_place newt_grid_set_field newt_grid_simple_window newt_grid_v_close_stacked newt_grid_v_stacked newt_grid_wrapped_window_at newt_grid_wrapped_window newt_init newt_label_set_text newt_label newt_listbox_append_entry newt_listbox_clear_selection newt_listbox_clear newt_listbox_delete_entry newt_listbox_get_current newt_listbox_get_selection newt_listbox_insert_entry newt_listbox_item_count newt_listbox_select_item newt_listbox_set_current_by_key newt_listbox_set_current newt_listbox_set_data newt_listbox_set_entry newt_listbox_set_width newt_listbox newt_listitem_get_data newt_listitem_set newt_listitem newt_open_window
+  syn keyword phpFunctions contained newt_pop_help_line newt_pop_window newt_push_help_line newt_radio_get_current newt_radiobutton newt_redraw_help_line newt_reflow_text newt_refresh newt_resize_screen newt_resume newt_run_form newt_scale_set newt_scale newt_scrollbar_set newt_set_help_callback newt_set_suspend_callback newt_suspend newt_textbox_get_num_lines newt_textbox_reflowed newt_textbox_set_height newt_textbox_set_text newt_textbox newt_vertical_scrollbar newt_wait_for_key newt_win_choice newt_win_entries newt_win_menu newt_win_message newt_win_messagev newt_win_ternary
+
+  " NSAPI functions
+  syn keyword phpFunctions contained nsapi_request_headers nsapi_response_headers nsapi_virtual
+  " NOTE: these functions are also implemented by the apache module
+  syn keyword phpCoreConstant contained apache_request_headers apache_response_headers getallheaders virtual
+
+  " object aggregation functions
+  " NOTE: this extension is experimental
+  syn keyword phpFunctions contained aggregate_info aggregate_methods_by_list aggregate_methods_by_regexp aggregate_methods aggregate_properties_by_list aggregate_properties_by_regexp aggregate_properties aggregate aggregation_info deaggregate
+
+  " object overloading functions
+  " NOTE: experimental and no longer needed in PHP 5
+  " syn keyword phpFunctions contained overload
+
+
+
+
+
+  " TODO: review function list from here:
+  syn keyword  phpFunctions    array_change_key_case array_chunk array_combine array_count_values array_diff_assoc array_diff_uassoc array_diff array_fill array_filter array_flip array_intersect_assoc array_intersect array_key_exists array_keys array_map array_merge_recursive array_merge array_multisort array_pad array_pop array_push array_rand array_reduce array_reverse array_search array_shift array_slice array_splice array_sum array_udiff_assoc array_udiff_uassoc array_udiff array_unique array_unshift array_values array_walk arsort asort compact count current each end extract in_array key krsort ksort natcasesort natsort next pos prev range reset rsort shuffle sizeof sort uasort uksort usort        contained
+  syn keyword  phpFunctions    bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub      contained
+  syn keyword  phpFunctions    bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite  contained
+  syn keyword  phpFunctions    cal_days_in_month cal_from_jd cal_info cal_to_jd easter_date easter_days frenchtojd gregoriantojd jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd juliantojd unixtojd        contained
+  syn keyword  phpFunctions    call_user_method_array call_user_method class_exists get_class_methods get_class_vars get_class get_declared_classes get_object_vars get_parent_class is_a is_subclass_of method_exists property_exists contained
+  syn keyword  phpFunctions    com VARIANT com_addref com_get com_invoke com_isenum com_load_typelib com_load com_propget com_propput com_propset com_release com_set  contained
+  syn keyword  phpFunctions    cpdf_add_annotation cpdf_add_outline cpdf_arc cpdf_begin_text cpdf_circle cpdf_clip cpdf_close cpdf_closepath_fill_stroke cpdf_closepath_stroke cpdf_closepath cpdf_continue_text cpdf_curveto cpdf_end_text cpdf_fill_stroke cpdf_fill cpdf_finalize_page cpdf_finalize cpdf_global_set_document_limits cpdf_import_jpeg cpdf_lineto cpdf_moveto cpdf_newpath cpdf_open cpdf_output_buffer cpdf_page_init cpdf_place_inline_image cpdf_rect cpdf_restore cpdf_rlineto cpdf_rmoveto cpdf_rotate_text cpdf_rotate cpdf_save_to_file cpdf_save cpdf_scale cpdf_set_action_url cpdf_set_char_spacing cpdf_set_creator cpdf_set_current_page cpdf_set_font_directories cpdf_set_font_map_file cpdf_set_font cpdf_set_horiz_scaling cpdf_set_keywords cpdf_set_leading cpdf_set_page_animation cpdf_set_subject cpdf_set_text_matrix cpdf_set_text_pos cpdf_set_text_rendering cpdf_set_text_rise cpdf_set_title cpdf_set_viewer_preferences cpdf_set_word_spacing cpdf_setdash cpdf_setflat cpdf_setgray_fill cpdf_setgray_stroke cpdf_setgray cpdf_setlinecap cpdf_setlinejoin cpdf_setlinewidth cpdf_setmiterlimit cpdf_setrgbcolor_fill cpdf_setrgbcolor_stroke cpdf_setrgbcolor cpdf_show_xy cpdf_show cpdf_stringwidth cpdf_stroke cpdf_text cpdf_translate    contained
+  syn keyword  phpFunctions    crack_check crack_closedict crack_getlastmessage crack_opendict contained
+  syn keyword  phpFunctions    ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_graph ctype_lower ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit    contained
+  syn keyword  phpFunctions    curl_close curl_errno curl_error curl_exec curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_setopt curl_version contained
+  syn keyword  phpFunctions    cybercash_base64_decode cybercash_base64_encode cybercash_decr cybercash_encr   contained
+  syn keyword  phpFunctions    cyrus_authenticate cyrus_bind cyrus_close cyrus_connect cyrus_query cyrus_unbind        contained
+  syn keyword  phpFunctions    checkdate date getdate gettimeofday gmdate gmmktime gmstrftime localtime microtime mktime strftime strtotime time       contained
+  syn keyword  phpFunctions    dba_close dba_delete dba_exists dba_fetch dba_firstkey dba_handlers dba_insert dba_key_split dba_list dba_nextkey dba_open dba_optimize dba_popen dba_replace dba_sync  contained
+  syn keyword  phpFunctions    dbase_add_record dbase_close dbase_create dbase_delete_record dbase_get_header_info dbase_get_record_with_names dbase_get_record dbase_numfields dbase_numrecords dbase_open dbase_pack dbase_replace_record    contained
+  syn keyword  phpFunctions    dblist dbmclose dbmdelete dbmexists dbmfetch dbmfirstkey dbminsert dbmnextkey dbmopen dbmreplace        contained
+  syn keyword  phpFunctions    dbplus_add dbplus_aql dbplus_chdir dbplus_close dbplus_curr dbplus_errcode dbplus_errno dbplus_find dbplus_first dbplus_flush dbplus_freealllocks dbplus_freelock dbplus_freerlocks dbplus_getlock dbplus_getunique dbplus_info dbplus_last dbplus_lockrel dbplus_next dbplus_open dbplus_prev dbplus_rchperm dbplus_rcreate dbplus_rcrtexact dbplus_rcrtlike dbplus_resolve dbplus_restorepos dbplus_rkeys dbplus_ropen dbplus_rquery dbplus_rrename dbplus_rsecindex dbplus_runlink dbplus_rzap dbplus_savepos dbplus_setindex dbplus_setindexbynumber dbplus_sql dbplus_tcl dbplus_tremove dbplus_undo dbplus_undoprepare dbplus_unlockrel dbplus_unselect dbplus_update dbplus_xlockrel dbplus_xunlockrel   contained
+  syn keyword  phpFunctions    dbx_close dbx_compare dbx_connect dbx_error dbx_escape_string dbx_fetch_row dbx_query dbx_sort  contained
+  syn keyword  phpFunctions    dio_close dio_fcntl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write    contained
+  syn keyword  phpFunctions    chdir chroot dir closedir getcwd opendir readdir rewinddir scandir      contained
+  syn keyword  phpFunctions    domxml_new_doc domxml_open_file domxml_open_mem domxml_version domxml_xmltree domxml_xslt_stylesheet_doc domxml_xslt_stylesheet_file domxml_xslt_stylesheet xpath_eval_expression xpath_eval xpath_new_context xptr_eval xptr_new_context       contained
+  syn keyword  phpMethods      name specified value create_attribute create_cdata_section create_comment create_element_ns create_element create_entity_reference create_processing_instruction create_text_node doctype document_element dump_file dump_mem get_element_by_id get_elements_by_tagname html_dump_mem xinclude entities internal_subset name notations public_id system_id get_attribute_node get_attribute get_elements_by_tagname has_attribute remove_attribute set_attribute tagname add_namespace append_child append_sibling attributes child_nodes clone_node dump_node first_child get_content has_attributes has_child_nodes insert_before is_blank_node last_child next_sibling node_name node_type node_value owner_document parent_node prefix previous_sibling remove_child replace_child replace_node set_content set_name set_namespace unlink_node data target process result_dump_file result_dump_mem contained
+  syn keyword  phpFunctions    dotnet_load     contained
+  syn keyword  phpFunctions    debug_backtrace debug_print_backtrace error_log error_reporting restore_error_handler set_error_handler trigger_error user_error        contained
+  syn keyword  phpFunctions    escapeshellarg escapeshellcmd exec passthru proc_close proc_get_status proc_nice proc_open proc_terminate shell_exec system     contained
+  syn keyword  phpFunctions    fam_cancel_monitor fam_close fam_monitor_collection fam_monitor_directory fam_monitor_file fam_next_event fam_open fam_pending fam_resume_monitor fam_suspend_monitor   contained
+  syn keyword  phpFunctions    fbsql_affected_rows fbsql_autocommit fbsql_change_user fbsql_close fbsql_commit fbsql_connect fbsql_create_blob fbsql_create_clob fbsql_create_db fbsql_data_seek fbsql_database_password fbsql_database fbsql_db_query fbsql_db_status fbsql_drop_db fbsql_errno fbsql_error fbsql_fetch_array fbsql_fetch_assoc fbsql_fetch_field fbsql_fetch_lengths fbsql_fetch_object fbsql_fetch_row fbsql_field_flags fbsql_field_len fbsql_field_name fbsql_field_seek fbsql_field_table fbsql_field_type fbsql_free_result fbsql_get_autostart_info fbsql_hostname fbsql_insert_id fbsql_list_dbs fbsql_list_fields fbsql_list_tables fbsql_next_result fbsql_num_fields fbsql_num_rows fbsql_password fbsql_pconnect fbsql_query fbsql_read_blob fbsql_read_clob fbsql_result fbsql_rollback fbsql_select_db fbsql_set_lob_mode fbsql_set_transaction fbsql_start_db fbsql_stop_db fbsql_tablename fbsql_username fbsql_warnings      contained
+  syn keyword  phpFunctions    fdf_add_doc_javascript fdf_add_template fdf_close fdf_create fdf_enum_values fdf_errno fdf_error fdf_get_ap fdf_get_attachment fdf_get_encoding fdf_get_file fdf_get_flags fdf_get_opt fdf_get_status fdf_get_value fdf_get_version fdf_header fdf_next_field_name fdf_open_string fdf_open fdf_remove_item fdf_save_string fdf_save fdf_set_ap fdf_set_encoding fdf_set_file fdf_set_flags fdf_set_javascript_action fdf_set_opt fdf_set_status fdf_set_submit_form_action fdf_set_target_frame fdf_set_value fdf_set_version  contained
+  syn keyword  phpFunctions    filepro_fieldcount filepro_fieldname filepro_fieldtype filepro_fieldwidth filepro_retrieve filepro_rowcount filepro     contained
+  syn keyword  phpFunctions    basename chgrp chmod chown clearstatcache copy delete dirname disk_free_space disk_total_space diskfreespace fclose feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents file fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype flock fnmatch fopen fpassthru fputs fread fscanf fseek fstat ftell ftruncate fwrite glob is_dir is_executable is_file is_link is_readable is_uploaded_file is_writable is_writeable link linkinfo lstat mkdir move_uploaded_file parse_ini_file pathinfo pclose popen readfile readlink realpath rename rewind rmdir set_file_buffer stat symlink tempnam tmpfile touch umask unlink    contained
+  syn keyword  phpFunctions    fribidi_log2vis contained
+  syn keyword  phpFunctions    ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_fget ftp_fput ftp_get_option ftp_get ftp_login ftp_mdtm ftp_mkdir ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put ftp_nlist ftp_pasv ftp_put ftp_pwd ftp_quit ftp_raw ftp_rawlist ftp_rename ftp_rmdir ftp_set_option ftp_site ftp_size ftp_ssl_connect ftp_systype  contained
+  syn keyword  phpFunctions    call_user_func_array call_user_func create_function func_get_arg func_get_args func_num_args function_exists get_defined_functions register_shutdown_function register_tick_function unregister_tick_function   contained
+  syn keyword  phpFunctions    bind_textdomain_codeset bindtextdomain dcgettext dcngettext dgettext dngettext gettext ngettext textdomain      contained
+  syn keyword  phpFunctions    gmp_abs gmp_add gmp_and gmp_clrbit gmp_cmp gmp_com gmp_div_q gmp_div_qr gmp_div_r gmp_div gmp_divexact gmp_fact gmp_gcd gmp_gcdext gmp_hamdist gmp_init gmp_intval gmp_invert gmp_jacobi gmp_legendre gmp_mod gmp_mul gmp_neg gmp_or gmp_perfect_square gmp_popcount gmp_pow gmp_powm gmp_prob_prime gmp_random gmp_scan0 gmp_scan1 gmp_setbit gmp_sign gmp_sqrt gmp_sqrtrem gmp_sqrtrm gmp_strval gmp_sub gmp_xor      contained
+  syn keyword  phpFunctions    header headers_list headers_sent setcookie      contained
+  syn keyword  phpFunctions    hw_api_attribute hwapi_hgcsp hw_api_content hw_api_object       contained
+  syn keyword  phpMethods      key langdepvalue value values checkin checkout children mimetype read content copy dbstat dcstat dstanchors dstofsrcanchors count reason find ftstat hwstat identify info insert insertanchor insertcollection insertdocument link lock move assign attreditable count insert remove title value object objectbyanchor parents description type remove replace setcommitedversion srcanchors srcsofdst unlock user userlist     contained
+  syn keyword  phpFunctions    hw_Array2Objrec hw_changeobject hw_Children hw_ChildrenObj hw_Close hw_Connect hw_connection_info hw_cp hw_Deleteobject hw_DocByAnchor hw_DocByAnchorObj hw_Document_Attributes hw_Document_BodyTag hw_Document_Content hw_Document_SetContent hw_Document_Size hw_dummy hw_EditText hw_Error hw_ErrorMsg hw_Free_Document hw_GetAnchors hw_GetAnchorsObj hw_GetAndLock hw_GetChildColl hw_GetChildCollObj hw_GetChildDocColl hw_GetChildDocCollObj hw_GetObject hw_GetObjectByQuery hw_GetObjectByQueryColl hw_GetObjectByQueryCollObj hw_GetObjectByQueryObj hw_GetParents hw_GetParentsObj hw_getrellink hw_GetRemote hw_getremotechildren hw_GetSrcByDestObj hw_GetText hw_getusername hw_Identify hw_InCollections hw_Info hw_InsColl hw_InsDoc hw_insertanchors hw_InsertDocument hw_InsertObject hw_mapid hw_Modifyobject hw_mv hw_New_Document hw_objrec2array hw_Output_Document hw_pConnect hw_PipeDocument hw_Root hw_setlinkroot hw_stat hw_Unlock hw_Who   contained
+  syn keyword  phpFunctions    ibase_add_user ibase_affected_rows ibase_blob_add ibase_blob_cancel ibase_blob_close ibase_blob_create ibase_blob_echo ibase_blob_get ibase_blob_import ibase_blob_info ibase_blob_open ibase_close ibase_commit_ret ibase_commit ibase_connect ibase_delete_user ibase_drop_db ibase_errcode ibase_errmsg ibase_execute ibase_fetch_assoc ibase_fetch_object ibase_fetch_row ibase_field_info ibase_free_event_handler ibase_free_query ibase_free_result ibase_gen_id ibase_modify_user ibase_name_result ibase_num_fields ibase_num_params ibase_param_info ibase_pconnect ibase_prepare ibase_query ibase_rollback_ret ibase_rollback ibase_set_event_handler ibase_timefmt ibase_trans ibase_wait_event    contained
+  syn keyword  phpFunctions    iconv_get_encoding iconv_mime_decode_headers iconv_mime_decode iconv_mime_encode iconv_set_encoding iconv_strlen iconv_strpos iconv_strrpos iconv_substr iconv ob_iconv_handler contained
+  syn keyword  phpFunctions    ifx_affected_rows ifx_blobinfile_mode ifx_byteasvarchar ifx_close ifx_connect ifx_copy_blob ifx_create_blob ifx_create_char ifx_do ifx_error ifx_errormsg ifx_fetch_row ifx_fieldproperties ifx_fieldtypes ifx_free_blob ifx_free_char ifx_free_result ifx_get_blob ifx_get_char ifx_getsqlca ifx_htmltbl_result ifx_nullformat ifx_num_fields ifx_num_rows ifx_pconnect ifx_prepare ifx_query ifx_textasvarchar ifx_update_blob ifx_update_char ifxus_close_slob ifxus_create_slob ifxus_free_slob ifxus_open_slob ifxus_read_slob ifxus_seek_slob ifxus_tell_slob ifxus_write_slob    contained
+  syn keyword  phpFunctions    exif_imagetype exif_read_data exif_thumbnail gd_info getimagesize image_type_to_mime_type image2wbmp imagealphablending imageantialias imagearc imagechar imagecharup imagecolorallocate imagecolorallocatealpha imagecolorat imagecolorclosest imagecolorclosestalpha imagecolorclosesthwb imagecolordeallocate imagecolorexact imagecolorexactalpha imagecolormatch imagecolorresolve imagecolorresolvealpha imagecolorset imagecolorsforindex imagecolorstotal imagecolortransparent imagecopy imagecopymerge imagecopymergegray imagecopyresampled imagecopyresized imagecreate imagecreatefromgd2 imagecreatefromgd2part imagecreatefromgd imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromstring imagecreatefromwbmp imagecreatefromxbm imagecreatefromxpm imagecreatetruecolor imagedashedline imagedestroy imageellipse imagefill imagefilledarc imagefilledellipse imagefilledpolygon imagefilledrectangle imagefilltoborder imagefontheight imagefontwidth imageftbbox imagefttext imagegammacorrect imagegd2 imagegd imagegif imageinterlace imageistruecolor imagejpeg imageline imageloadfont imagepalettecopy imagepng imagepolygon imagepsbbox imagepscopyfont imagepsencodefont imagepsextendfont imagepsfreefont imagepsloadfont imagepsslantfont imagepstext imagerectangle imagerotate imagesavealpha imagesetbrush imagesetpixel imagesetstyle imagesetthickness imagesettile imagestring imagestringup imagesx imagesy imagetruecolortopalette imagettfbbox imagettftext imagetypes imagewbmp iptcembed iptcparse jpeg2wbmp png2wbmp read_exif_data       contained
+  syn keyword  phpFunctions    imap_8bit imap_alerts imap_append imap_base64 imap_binary imap_body imap_bodystruct imap_check imap_clearflag_full imap_close imap_createmailbox imap_delete imap_deletemailbox imap_errors imap_expunge imap_fetch_overview imap_fetchbody imap_fetchheader imap_fetchstructure imap_get_quota imap_get_quotaroot imap_getacl imap_getmailboxes imap_getsubscribed imap_header imap_headerinfo imap_headers imap_last_error imap_list imap_listmailbox imap_listscan imap_listsubscribed imap_lsub imap_mail_compose imap_mail_copy imap_mail_move imap_mail imap_mailboxmsginfo imap_mime_header_decode imap_msgno imap_num_msg imap_num_recent imap_open imap_ping imap_qprint imap_renamemailbox imap_reopen imap_rfc822_parse_adrlist imap_rfc822_parse_headers imap_rfc822_write_address imap_scanmailbox imap_search imap_set_quota imap_setacl imap_setflag_full imap_sort imap_status imap_subscribe imap_thread imap_timeout imap_uid imap_undelete imap_unsubscribe imap_utf7_decode imap_utf7_encode imap_utf8      contained
+  syn keyword  phpFunctions    assert_options assert dl extension_loaded get_cfg_var get_current_user get_defined_constants get_extension_funcs get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime get_required_files getenv getlastmod getmygid getmyinode getmypid getmyuid getopt getrusage ini_alter ini_get_all ini_get ini_restore ini_set main memory_get_usage php_ini_scanned_files php_logo_guid php_sapi_name php_uname phpcredits phpinfo phpversion putenv restore_include_path set_include_path set_magic_quotes_runtime set_time_limit version_compare zend_logo_guid zend_version contained
+  syn keyword  phpFunctions    ingres_autocommit ingres_close ingres_commit ingres_connect ingres_fetch_array ingres_fetch_object ingres_fetch_row ingres_field_length ingres_field_name ingres_field_nullable ingres_field_precision ingres_field_scale ingres_field_type ingres_num_fields ingres_num_rows ingres_pconnect ingres_query ingres_rollback      contained
+  syn keyword  phpFunctions    ircg_channel_mode ircg_disconnect ircg_fetch_error_msg ircg_get_username ircg_html_encode ircg_ignore_add ircg_ignore_del ircg_is_conn_alive ircg_join ircg_kick ircg_lookup_format_messages ircg_msg ircg_nick ircg_nickname_escape ircg_nickname_unescape ircg_notice ircg_part ircg_pconnect ircg_register_format_messages ircg_set_current ircg_set_file ircg_set_on_die ircg_topic ircg_whois      contained
+  syn keyword  phpFunctions    java_last_exception_clear java_last_exception_get       contained
+  syn keyword  phpFunctions    ldap_8859_to_t61 ldap_add ldap_bind ldap_close ldap_compare ldap_connect ldap_count_entries ldap_delete ldap_dn2ufn ldap_err2str ldap_errno ldap_error ldap_explode_dn ldap_first_attribute ldap_first_entry ldap_first_reference ldap_free_result ldap_get_attributes ldap_get_dn ldap_get_entries ldap_get_option ldap_get_values_len ldap_get_values ldap_list ldap_mod_add ldap_mod_del ldap_mod_replace ldap_modify ldap_next_attribute ldap_next_entry ldap_next_reference ldap_parse_reference ldap_parse_result ldap_read ldap_rename ldap_search ldap_set_option ldap_set_rebind_proc ldap_sort ldap_start_tls ldap_t61_to_8859 ldap_unbind    contained
+  syn keyword  phpFunctions    lzf_compress lzf_decompress lzf_optimized_for   contained
+  syn keyword  phpFunctions    ezmlm_hash mail contained
+  syn keyword  phpFunctions    mailparse_determine_best_xfer_encoding mailparse_msg_create mailparse_msg_extract_part_file mailparse_msg_extract_part mailparse_msg_free mailparse_msg_get_part_data mailparse_msg_get_part mailparse_msg_get_structure mailparse_msg_parse_file mailparse_msg_parse mailparse_rfc822_parse_addresses mailparse_stream_encode mailparse_uudecode_all   contained
+  syn keyword  phpFunctions    abs acos acosh asin asinh atan2 atan atanh base_convert bindec ceil cos cosh decbin dechex decoct deg2rad exp expm1 floor fmod getrandmax hexdec hypot is_finite is_infinite is_nan lcg_value log10 log1p log max min mt_getrandmax mt_rand mt_srand octdec pi pow rad2deg rand round sin sinh sqrt srand tan tanh      contained
+  syn keyword  phpFunctions    mb_convert_case mb_convert_encoding mb_convert_kana mb_convert_variables mb_decode_mimeheader mb_decode_numericentity mb_detect_encoding mb_detect_order mb_encode_mimeheader mb_encode_numericentity mb_ereg_match mb_ereg_replace mb_ereg_search_getpos mb_ereg_search_getregs mb_ereg_search_init mb_ereg_search_pos mb_ereg_search_regs mb_ereg_search_setpos mb_ereg_search mb_ereg mb_eregi_replace mb_eregi mb_get_info mb_http_input mb_http_output mb_internal_encoding mb_language mb_output_handler mb_parse_str mb_preferred_mime_name mb_regex_encoding mb_regex_set_options mb_send_mail mb_split mb_strcut mb_strimwidth mb_strlen mb_strpos mb_strrpos mb_strtolower mb_strtoupper mb_strwidth mb_substitute_character mb_substr_count mb_substr        contained
+  syn keyword  phpFunctions    mcal_append_event mcal_close mcal_create_calendar mcal_date_compare mcal_date_valid mcal_day_of_week mcal_day_of_year mcal_days_in_month mcal_delete_calendar mcal_delete_event mcal_event_add_attribute mcal_event_init mcal_event_set_alarm mcal_event_set_category mcal_event_set_class mcal_event_set_description mcal_event_set_end mcal_event_set_recur_daily mcal_event_set_recur_monthly_mday mcal_event_set_recur_monthly_wday mcal_event_set_recur_none mcal_event_set_recur_weekly mcal_event_set_recur_yearly mcal_event_set_start mcal_event_set_title mcal_expunge mcal_fetch_current_stream_event mcal_fetch_event mcal_is_leap_year mcal_list_alarms mcal_list_events mcal_next_recurrence mcal_open mcal_popen mcal_rename_calendar mcal_reopen mcal_snooze mcal_store_event mcal_time_valid mcal_week_of_year contained
+  syn keyword  phpFunctions    mcrypt_cbc mcrypt_cfb mcrypt_create_iv mcrypt_decrypt mcrypt_ecb mcrypt_enc_get_algorithms_name mcrypt_enc_get_block_size mcrypt_enc_get_iv_size mcrypt_enc_get_key_size mcrypt_enc_get_modes_name mcrypt_enc_get_supported_key_sizes mcrypt_enc_is_block_algorithm_mode mcrypt_enc_is_block_algorithm mcrypt_enc_is_block_mode mcrypt_enc_self_test mcrypt_encrypt mcrypt_generic_deinit mcrypt_generic_end mcrypt_generic_init mcrypt_generic mcrypt_get_block_size mcrypt_get_cipher_name mcrypt_get_iv_size mcrypt_get_key_size mcrypt_list_algorithms mcrypt_list_modes mcrypt_module_close mcrypt_module_get_algo_block_size mcrypt_module_get_algo_key_size mcrypt_module_get_supported_key_sizes mcrypt_module_is_block_algorithm_mode mcrypt_module_is_block_algorithm mcrypt_module_is_block_mode mcrypt_module_open mcrypt_module_self_test mcrypt_ofb mdecrypt_generic      contained
+  syn keyword  phpFunctions    mcve_adduser mcve_adduserarg mcve_bt mcve_checkstatus mcve_chkpwd mcve_chngpwd mcve_completeauthorizations mcve_connect mcve_connectionerror mcve_deleteresponse mcve_deletetrans mcve_deleteusersetup mcve_deluser mcve_destroyconn mcve_destroyengine mcve_disableuser mcve_edituser mcve_enableuser mcve_force mcve_getcell mcve_getcellbynum mcve_getcommadelimited mcve_getheader mcve_getuserarg mcve_getuserparam mcve_gft mcve_gl mcve_gut mcve_initconn mcve_initengine mcve_initusersetup mcve_iscommadelimited mcve_liststats mcve_listusers mcve_maxconntimeout mcve_monitor mcve_numcolumns mcve_numrows mcve_override mcve_parsecommadelimited mcve_ping mcve_preauth mcve_preauthcompletion mcve_qc mcve_responseparam mcve_return mcve_returncode mcve_returnstatus mcve_sale mcve_setblocking mcve_setdropfile mcve_setip mcve_setssl_files mcve_setssl mcve_settimeout mcve_settle mcve_text_avs mcve_text_code mcve_text_cv mcve_transactionauth mcve_transactionavs mcve_transactionbatch mcve_transactioncv mcve_transactionid mcve_transactionitem mcve_transactionssent mcve_transactiontext mcve_transinqueue mcve_transnew mcve_transparam mcve_transsend mcve_ub mcve_uwait mcve_verifyconnection mcve_verifysslcert mcve_void        contained
+  syn keyword  phpFunctions    mhash_count mhash_get_block_size mhash_get_hash_name mhash_keygen_s2k mhash     contained
+  syn keyword  phpFunctions    mime_content_type       contained
+  syn keyword  phpFunctions    ming_setcubicthreshold ming_setscale ming_useswfversion SWFAction SWFBitmap swfbutton_keypress SWFbutton SWFDisplayItem SWFFill SWFFont SWFGradient SWFMorph SWFMovie SWFShape SWFSprite SWFText SWFTextField   contained
+  syn keyword  phpMethods      getHeight getWidth addAction addShape setAction setdown setHit setOver setUp addColor move moveTo multColor remove Rotate rotateTo scale scaleTo setDepth setName setRatio skewX skewXTo skewY skewYTo moveTo rotateTo scaleTo skewXTo skewYTo getwidth addEntry getshape1 getshape2 add nextframe output remove save setbackground setdimension setframes setrate streammp3 addFill drawCurve drawCurveTo drawLine drawLineTo movePen movePenTo setLeftFill setLine setRightFill add nextframe remove setframes addString getWidth moveTo setColor setFont setHeight setSpacing addstring align setbounds setcolor setFont setHeight setindentation setLeftMargin setLineSpacing setMargins setname setrightMargin     contained
+  syn keyword  phpFunctions    connection_aborted connection_status connection_timeout constant define defined eval get_browser highlight_file highlight_string ignore_user_abort pack show_source sleep uniqid unpack usleep  contained
+  syn keyword  phpFunctions    udm_add_search_limit udm_alloc_agent udm_api_version udm_cat_list udm_cat_path udm_check_charset udm_check_stored udm_clear_search_limits udm_close_stored udm_crc32 udm_errno udm_error udm_find udm_free_agent udm_free_ispell_data udm_free_res udm_get_doc_count udm_get_res_field udm_get_res_param udm_load_ispell_data udm_open_stored udm_set_agent_param       contained
+  syn keyword  phpFunctions    msession_connect msession_count msession_create msession_destroy msession_disconnect msession_find msession_get_array msession_get msession_getdata msession_inc msession_list msession_listvar msession_lock msession_plugin msession_randstr msession_set_array msession_set msession_setdata msession_timeout msession_uniq msession_unlock  contained
+  syn keyword  phpFunctions    msql_affected_rows msql_close msql_connect msql_create_db msql_createdb msql_data_seek msql_dbname msql_drop_db msql_dropdb msql_error msql_fetch_array msql_fetch_field msql_fetch_object msql_fetch_row msql_field_seek msql_fieldflags msql_fieldlen msql_fieldname msql_fieldtable msql_fieldtype msql_free_result msql_freeresult msql_list_dbs msql_list_fields msql_list_tables msql_listdbs msql_listfields msql_listtables msql_num_fields msql_num_rows msql_numfields msql_numrows msql_pconnect msql_query msql_regcase msql_result msql_select_db msql_selectdb msql_tablename msql        contained
+  syn keyword  phpFunctions    mssql_bind mssql_close mssql_connect mssql_data_seek mssql_execute mssql_fetch_array mssql_fetch_assoc mssql_fetch_batch mssql_fetch_field mssql_fetch_object mssql_fetch_row mssql_field_length mssql_field_name mssql_field_seek mssql_field_type mssql_free_result mssql_free_statement mssql_get_last_message mssql_guid_string mssql_init mssql_min_error_severity mssql_min_message_severity mssql_next_result mssql_num_fields mssql_num_rows mssql_pconnect mssql_query mssql_result mssql_rows_affected mssql_select_db        contained
+  syn keyword  phpFunctions    muscat_close muscat_get muscat_give muscat_setup_net muscat_setup       contained
+  syn keyword  phpFunctions    mysql_affected_rows mysql_change_user mysql_client_encoding mysql_close mysql_connect mysql_create_db mysql_data_seek mysql_db_name mysql_db_query mysql_drop_db mysql_errno mysql_error mysql_escape_string mysql_fetch_array mysql_fetch_assoc mysql_fetch_field mysql_fetch_lengths mysql_fetch_object mysql_fetch_row mysql_field_flags mysql_field_len mysql_field_name mysql_field_seek mysql_field_table mysql_field_type mysql_free_result mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql_insert_id mysql_list_dbs mysql_list_fields mysql_list_processes mysql_list_tables mysql_num_fields mysql_num_rows mysql_pconnect mysql_ping mysql_query mysql_real_escape_string mysql_result mysql_select_db mysql_stat mysql_tablename mysql_thread_id mysql_unbuffered_query        contained
+  syn keyword  phpFunctions    mysqli_affected_rows mysqli_autocommit mysqli_bind_param mysqli_bind_result mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect mysqli_data_seek mysqli_debug mysqli_disable_reads_from_master mysqli_disable_rpl_parse mysqli_dump_debug_info mysqli_enable_reads_from_master mysqli_enable_rpl_parse mysqli_errno mysqli_error mysqli_execute mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_fetch mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_client_info mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_master_query mysqli_num_fields mysqli_num_rows mysqli_options mysqli_param_count mysqli_ping mysqli_prepare_result mysqli_prepare mysqli_profiler mysqli_query mysqli_read_query_result mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reload mysqli_rollback mysqli_rpl_parse_enabled mysqli_rpl_probe mysqli_rpl_query_type mysqli_select_db mysqli_send_long_data mysqli_send_query mysqli_slave_query mysqli_ssl_set mysqli_stat mysqli_stmt_affected_rows mysqli_stmt_close mysqli_stmt_errno mysqli_stmt_error mysqli_stmt_store_result mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count  contained
+  syn keyword  phpFunctions    ncurses_addch ncurses_addchnstr ncurses_addchstr ncurses_addnstr ncurses_addstr ncurses_assume_default_colors ncurses_attroff ncurses_attron ncurses_attrset ncurses_baudrate ncurses_beep ncurses_bkgd ncurses_bkgdset ncurses_border ncurses_bottom_panel ncurses_can_change_color ncurses_cbreak ncurses_clear ncurses_clrtobot ncurses_clrtoeol ncurses_color_content ncurses_color_set ncurses_curs_set ncurses_def_prog_mode ncurses_def_shell_mode ncurses_define_key ncurses_del_panel ncurses_delay_output ncurses_delch ncurses_deleteln ncurses_delwin ncurses_doupdate ncurses_echo ncurses_echochar ncurses_end ncurses_erase ncurses_erasechar ncurses_filter ncurses_flash ncurses_flushinp ncurses_getch ncurses_getmaxyx ncurses_getmouse ncurses_getyx ncurses_halfdelay ncurses_has_colors ncurses_has_ic ncurses_has_il ncurses_has_key ncurses_hide_panel ncurses_hline ncurses_inch ncurses_init_color ncurses_init_pair ncurses_init ncurses_insch ncurses_insdelln ncurses_insertln ncurses_insstr ncurses_instr ncurses_isendwin ncurses_keyok ncurses_keypad ncurses_killchar ncurses_longname ncurses_meta ncurses_mouse_trafo ncurses_mouseinterval ncurses_mousemask ncurses_move_panel ncurses_move ncurses_mvaddch ncurses_mvaddchnstr ncurses_mvaddchstr ncurses_mvaddnstr ncurses_mvaddstr ncurses_mvcur ncurses_mvdelch ncurses_mvgetch ncurses_mvhline ncurses_mvinch ncurses_mvvline ncurses_mvwaddstr ncurses_napms ncurses_new_panel ncurses_newpad ncurses_newwin ncurses_nl ncurses_nocbreak ncurses_noecho ncurses_nonl ncurses_noqiflush ncurses_noraw ncurses_pair_content ncurses_panel_above ncurses_panel_below ncurses_panel_window ncurses_pnoutrefresh ncurses_prefresh ncurses_putp ncurses_qiflush ncurses_raw ncurses_refresh ncurses_replace_panel ncurses_reset_prog_mode ncurses_reset_shell_mode ncurses_resetty ncurses_savetty ncurses_scr_dump ncurses_scr_init ncurses_scr_restore ncurses_scr_set ncurses_scrl ncurses_show_panel ncurses_slk_attr ncurses_slk_attroff ncurses_slk_attron ncurses_slk_attrset ncurses_slk_clear ncurses_slk_color ncurses_slk_init ncurses_slk_noutrefresh ncurses_slk_refresh ncurses_slk_restore ncurses_slk_set ncurses_slk_touch ncurses_standend ncurses_standout ncurses_start_color ncurses_termattrs ncurses_termname ncurses_timeout ncurses_top_panel ncurses_typeahead ncurses_ungetch ncurses_ungetmouse ncurses_update_panels ncurses_use_default_colors ncurses_use_env ncurses_use_extended_names ncurses_vidattr ncurses_vline ncurses_waddch ncurses_waddstr ncurses_wattroff ncurses_wattron ncurses_wattrset ncurses_wborder ncurses_wclear ncurses_wcolor_set ncurses_werase ncurses_wgetch ncurses_whline ncurses_wmouse_trafo ncurses_wmove ncurses_wnoutrefresh ncurses_wrefresh ncurses_wstandend ncurses_wstandout ncurses_wvline contained
+  syn keyword  phpFunctions    checkdnsrr closelog debugger_off debugger_on define_syslog_variables dns_check_record dns_get_mx dns_get_record fsockopen gethostbyaddr gethostbyname gethostbynamel getmxrr getprotobyname getprotobynumber getservbyname getservbyport ip2long long2ip openlog pfsockopen socket_get_status socket_set_blocking socket_set_timeout syslog     contained
+  syn keyword  phpFunctions    yp_all yp_cat yp_err_string yp_errno yp_first yp_get_default_domain yp_master yp_match yp_next yp_order contained
+  syn keyword  phpFunctions    notes_body notes_copy_db notes_create_db notes_create_note notes_drop_db notes_find_note notes_header_info notes_list_msgs notes_mark_read notes_mark_unread notes_nav_create notes_search notes_unread notes_version   contained
+  syn keyword  phpFunctions    nsapi_request_headers nsapi_response_headers nsapi_virtual      contained
+  syn keyword  phpFunctions    aggregate_info aggregate_methods_by_list aggregate_methods_by_regexp aggregate_methods aggregate_properties_by_list aggregate_properties_by_regexp aggregate_properties aggregate aggregation_info deaggregate  contained
+  syn keyword  phpFunctions    ocibindbyname ocicancel ocicloselob ocicollappend ocicollassign ocicollassignelem ocicollgetelem ocicollmax ocicollsize ocicolltrim ocicolumnisnull ocicolumnname ocicolumnprecision ocicolumnscale ocicolumnsize ocicolumntype ocicolumntyperaw ocicommit ocidefinebyname ocierror ociexecute ocifetch ocifetchinto ocifetchstatement ocifreecollection ocifreecursor ocifreedesc ocifreestatement ociinternaldebug ociloadlob ocilogoff ocilogon ocinewcollection ocinewcursor ocinewdescriptor ocinlogon ocinumcols ociparse ociplogon ociresult ocirollback ocirowcount ocisavelob ocisavelobfile ociserverversion ocisetprefetch ocistatementtype ociwritelobtofile ociwritetemporarylob   contained
+  syn keyword  phpFunctions    odbc_autocommit odbc_binmode odbc_close_all odbc_close odbc_columnprivileges odbc_columns odbc_commit odbc_connect odbc_cursor odbc_data_source odbc_do odbc_error odbc_errormsg odbc_exec odbc_execute odbc_fetch_array odbc_fetch_into odbc_fetch_object odbc_fetch_row odbc_field_len odbc_field_name odbc_field_num odbc_field_precision odbc_field_scale odbc_field_type odbc_foreignkeys odbc_free_result odbc_gettypeinfo odbc_longreadlen odbc_next_result odbc_num_fields odbc_num_rows odbc_pconnect odbc_prepare odbc_primarykeys odbc_procedurecolumns odbc_procedures odbc_result_all odbc_result odbc_rollback odbc_setoption odbc_specialcolumns odbc_statistics odbc_tableprivileges odbc_tables        contained
+  syn keyword  phpFunctions    openssl_csr_export_to_file openssl_csr_export openssl_csr_new openssl_csr_sign openssl_error_string openssl_free_key openssl_get_privatekey openssl_get_publickey openssl_open openssl_pkcs7_decrypt openssl_pkcs7_encrypt openssl_pkcs7_sign openssl_pkcs7_verify openssl_pkey_export_to_file openssl_pkey_export openssl_pkey_get_private openssl_pkey_get_public openssl_pkey_new openssl_private_decrypt openssl_private_encrypt openssl_public_decrypt openssl_public_encrypt openssl_seal openssl_sign openssl_verify openssl_x509_check_private_key openssl_x509_checkpurpose openssl_x509_export_to_file openssl_x509_export openssl_x509_free openssl_x509_parse openssl_x509_read     contained
+  syn keyword  phpFunctions    ora_bind ora_close ora_columnname ora_columnsize ora_columntype ora_commit ora_commitoff ora_commiton ora_do ora_error ora_errorcode ora_exec ora_fetch_into ora_fetch ora_getcolumn ora_logoff ora_logon ora_numcols ora_numrows ora_open ora_parse ora_plogon ora_rollback    contained
+  syn keyword  phpFunctions    flush ob_clean ob_end_clean ob_end_flush ob_flush ob_get_clean ob_get_contents ob_get_flush ob_get_length ob_get_level ob_get_status ob_gzhandler ob_implicit_flush ob_list_handlers ob_start output_add_rewrite_var output_reset_rewrite_vars  contained
+  syn keyword  phpFunctions    overload        contained
+  syn keyword  phpFunctions    ovrimos_close ovrimos_commit ovrimos_connect ovrimos_cursor ovrimos_exec ovrimos_execute ovrimos_fetch_into ovrimos_fetch_row ovrimos_field_len ovrimos_field_name ovrimos_field_num ovrimos_field_type ovrimos_free_result ovrimos_longreadlen ovrimos_num_fields ovrimos_num_rows ovrimos_prepare ovrimos_result_all ovrimos_result ovrimos_rollback  contained
+  syn keyword  phpFunctions    pcntl_exec pcntl_fork pcntl_signal pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig     contained
+  syn keyword  phpFunctions    preg_grep preg_match_all preg_match preg_quote preg_replace_callback preg_replace preg_split    contained
+  syn keyword  phpFunctions    pdf_add_annotation pdf_add_bookmark pdf_add_launchlink pdf_add_locallink pdf_add_note pdf_add_outline pdf_add_pdflink pdf_add_thumbnail pdf_add_weblink pdf_arc pdf_arcn pdf_attach_file pdf_begin_page pdf_begin_pattern pdf_begin_template pdf_circle pdf_clip pdf_close_image pdf_close_pdi_page pdf_close_pdi pdf_close pdf_closepath_fill_stroke pdf_closepath_stroke pdf_closepath pdf_concat pdf_continue_text pdf_curveto pdf_delete pdf_end_page pdf_end_pattern pdf_end_template pdf_endpath pdf_fill_stroke pdf_fill pdf_findfont pdf_get_buffer pdf_get_font pdf_get_fontname pdf_get_fontsize pdf_get_image_height pdf_get_image_width pdf_get_majorversion pdf_get_minorversion pdf_get_parameter pdf_get_pdi_parameter pdf_get_pdi_value pdf_get_value pdf_initgraphics pdf_lineto pdf_makespotcolor pdf_moveto pdf_new pdf_open_CCITT pdf_open_file pdf_open_gif pdf_open_image_file pdf_open_image pdf_open_jpeg pdf_open_memory_image pdf_open_pdi_page pdf_open_pdi pdf_open_png pdf_open_tiff pdf_open pdf_place_image pdf_place_pdi_page pdf_rect pdf_restore pdf_rotate pdf_save pdf_scale pdf_set_border_color pdf_set_border_dash pdf_set_border_style pdf_set_char_spacing pdf_set_duration pdf_set_font pdf_set_horiz_scaling pdf_set_info_author pdf_set_info_creator pdf_set_info_keywords pdf_set_info_subject pdf_set_info_title pdf_set_info pdf_set_leading pdf_set_parameter pdf_set_text_matrix pdf_set_text_pos pdf_set_text_rendering pdf_set_text_rise pdf_set_value pdf_set_word_spacing pdf_setcolor pdf_setdash pdf_setflat pdf_setfont pdf_setgray_fill pdf_setgray_stroke pdf_setgray pdf_setlinecap pdf_setlinejoin pdf_setlinewidth pdf_setmatrix pdf_setmiterlimit pdf_setpolydash pdf_setrgbcolor_fill pdf_setrgbcolor_stroke pdf_setrgbcolor pdf_show_boxed pdf_show_xy pdf_show pdf_skew pdf_stringwidth pdf_stroke pdf_translate       contained
+  syn keyword  phpFunctions    pfpro_cleanup pfpro_init pfpro_process_raw pfpro_process pfpro_version  contained
+  syn keyword  phpFunctions    pg_affected_rows pg_cancel_query pg_client_encoding pg_close pg_connect pg_connection_busy pg_connection_reset pg_connection_status pg_convert pg_copy_from pg_copy_to pg_dbname pg_delete pg_end_copy pg_escape_bytea pg_escape_string pg_fetch_all pg_fetch_array pg_fetch_assoc pg_fetch_object pg_fetch_result pg_fetch_row pg_field_is_null pg_field_name pg_field_num pg_field_prtlen pg_field_size pg_field_type pg_free_result pg_get_notify pg_get_pid pg_get_result pg_host pg_insert pg_last_error pg_last_notice pg_last_oid pg_lo_close pg_lo_create pg_lo_export pg_lo_import pg_lo_open pg_lo_read_all pg_lo_read pg_lo_seek pg_lo_tell pg_lo_unlink pg_lo_write pg_meta_data pg_num_fields pg_num_rows pg_options pg_pconnect pg_ping pg_port pg_put_line pg_query pg_result_error pg_result_seek pg_result_status pg_select pg_send_query pg_set_client_encoding pg_trace pg_tty pg_unescape_bytea pg_untrace pg_update        contained
+  syn keyword  phpFunctions    posix_ctermid posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid posix_isatty posix_kill posix_mkfifo posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname contained
+  syn keyword  phpFunctions    printer_abort printer_close printer_create_brush printer_create_dc printer_create_font printer_create_pen printer_delete_brush printer_delete_dc printer_delete_font printer_delete_pen printer_draw_bmp printer_draw_chord printer_draw_elipse printer_draw_line printer_draw_pie printer_draw_rectangle printer_draw_roundrect printer_draw_text printer_end_doc printer_end_page printer_get_option printer_list printer_logical_fontheight printer_open printer_select_brush printer_select_font printer_select_pen printer_set_option printer_start_doc printer_start_page printer_write   contained
+  syn keyword  phpFunctions    pspell_add_to_personal pspell_add_to_session pspell_check pspell_clear_session pspell_config_create pspell_config_ignore pspell_config_mode pspell_config_personal pspell_config_repl pspell_config_runtogether pspell_config_save_repl pspell_new_config pspell_new_personal pspell_new pspell_save_wordlist pspell_store_replacement pspell_suggest   contained
+  syn keyword  phpFunctions    qdom_error qdom_tree    contained
+  syn keyword  phpFunctions    readline_add_history readline_clear_history readline_completion_function readline_info readline_list_history readline_read_history readline_write_history readline      contained
+  syn keyword  phpFunctions    recode_file recode_string recode        contained
+  syn keyword  phpFunctions    ereg_replace ereg eregi_replace eregi split spliti sql_regcase  contained
+  syn keyword  phpFunctions    ftok msg_get_queue msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue sem_acquire sem_get sem_release sem_remove shm_attach shm_detach shm_get_var shm_put_var shm_remove_var shm_remove        contained
+  syn keyword  phpFunctions    sesam_affected_rows sesam_commit sesam_connect sesam_diagnostic sesam_disconnect sesam_errormsg sesam_execimm sesam_fetch_array sesam_fetch_result sesam_fetch_row sesam_field_array sesam_field_name sesam_free_result sesam_num_fields sesam_query sesam_rollback sesam_seek_row sesam_settransaction contained
+  syn keyword  phpFunctions    session_cache_expire session_cache_limiter session_decode session_destroy session_encode session_get_cookie_params session_id session_is_registered session_module_name session_name session_regenerate_id session_register session_save_path session_set_cookie_params session_set_save_handler session_start session_unregister session_unset session_write_close     contained
+  syn keyword  phpFunctions    shmop_close shmop_delete shmop_open shmop_read shmop_size shmop_write   contained
+  syn keyword  phpFunctions    snmp_get_quick_print snmp_set_quick_print snmpget snmprealwalk snmpset snmpwalk snmpwalkoid     contained
+  syn keyword  phpFunctions    socket_accept socket_bind socket_clear_error socket_close socket_connect socket_create_listen socket_create_pair socket_create socket_get_option socket_getpeername socket_getsockname socket_iovec_add socket_iovec_alloc socket_iovec_delete socket_iovec_fetch socket_iovec_free socket_iovec_set socket_last_error socket_listen socket_read socket_readv socket_recv socket_recvfrom socket_recvmsg socket_select socket_send socket_sendmsg socket_sendto socket_set_block socket_set_nonblock socket_set_option socket_shutdown socket_strerror socket_write socket_writev       contained
+  syn keyword  phpFunctions    sqlite_array_query sqlite_busy_timeout sqlite_changes sqlite_close sqlite_column sqlite_create_aggregate sqlite_create_function sqlite_current sqlite_error_string sqlite_escape_string sqlite_fetch_array sqlite_fetch_single sqlite_fetch_string sqlite_field_name sqlite_has_more sqlite_last_error sqlite_last_insert_rowid sqlite_libencoding sqlite_libversion sqlite_next sqlite_num_fields sqlite_num_rows sqlite_open sqlite_popen sqlite_query sqlite_rewind sqlite_seek sqlite_udf_decode_binary sqlite_udf_encode_binary sqlite_unbuffered_query    contained
+  syn keyword  phpFunctions    stream_context_create stream_context_get_options stream_context_set_option stream_context_set_params stream_copy_to_stream stream_filter_append stream_filter_prepend stream_filter_register stream_get_contents stream_get_filters stream_get_line stream_get_meta_data stream_get_transports stream_get_wrappers stream_register_wrapper stream_select stream_set_blocking stream_set_timeout stream_set_write_buffer stream_socket_accept stream_socket_client stream_socket_get_name stream_socket_recvfrom stream_socket_sendto stream_socket_server stream_wrapper_register       contained
+  syn keyword  phpFunctions    addcslashes addslashes bin2hex chop chr chunk_split convert_cyr_string count_chars crc32 crypt explode fprintf get_html_translation_table hebrev hebrevc html_entity_decode htmlentities htmlspecialchars implode join levenshtein localeconv ltrim md5_file md5 metaphone money_format nl_langinfo nl2br number_format ord parse_str print printf quoted_printable_decode quotemeta rtrim setlocale sha1_file sha1 similar_text soundex sprintf sscanf str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count strcasecmp strchr strcmp strcoll strcspn strip_tags stripcslashes stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpos strrchr strrev strripos strrpos strspn strstr strtok strtolower strtoupper strtr substr_compare substr_count substr_replace substr trim ucfirst ucwords vprintf vsprintf wordwrap   contained
+  syn keyword  phpFunctions    swf_actiongeturl swf_actiongotoframe swf_actiongotolabel swf_actionnextframe swf_actionplay swf_actionprevframe swf_actionsettarget swf_actionstop swf_actiontogglequality swf_actionwaitforframe swf_addbuttonrecord swf_addcolor swf_closefile swf_definebitmap swf_definefont swf_defineline swf_definepoly swf_definerect swf_definetext swf_endbutton swf_enddoaction swf_endshape swf_endsymbol swf_fontsize swf_fontslant swf_fonttracking swf_getbitmapinfo swf_getfontinfo swf_getframe swf_labelframe swf_lookat swf_modifyobject swf_mulcolor swf_nextid swf_oncondition swf_openfile swf_ortho2 swf_ortho swf_perspective swf_placeobject swf_polarview swf_popmatrix swf_posround swf_pushmatrix swf_removeobject swf_rotate swf_scale swf_setfont swf_setframe swf_shapearc swf_shapecurveto3 swf_shapecurveto swf_shapefillbitmapclip swf_shapefillbitmaptile swf_shapefilloff swf_shapefillsolid swf_shapelinesolid swf_shapelineto swf_shapemoveto swf_showframe swf_startbutton swf_startdoaction swf_startshape swf_startsymbol swf_textwidth swf_translate swf_viewport     contained
+  syn keyword  phpFunctions    sybase_affected_rows sybase_close sybase_connect sybase_data_seek sybase_deadlock_retry_count sybase_fetch_array sybase_fetch_assoc sybase_fetch_field sybase_fetch_object sybase_fetch_row sybase_field_seek sybase_free_result sybase_get_last_message sybase_min_client_severity sybase_min_error_severity sybase_min_message_severity sybase_min_server_severity sybase_num_fields sybase_num_rows sybase_pconnect sybase_query sybase_result sybase_select_db sybase_set_message_handler sybase_unbuffered_query   contained
+  syn keyword  phpFunctions    tidy_access_count tidy_clean_repair tidy_config_count tidy_diagnose tidy_error_count tidy_get_body tidy_get_config tidy_get_error_buffer tidy_get_head tidy_get_html_ver tidy_get_html tidy_get_output tidy_get_release tidy_get_root tidy_get_status tidy_getopt tidy_is_xhtml tidy_load_config tidy_parse_file tidy_parse_string tidy_repair_file tidy_repair_string tidy_reset_config tidy_save_config tidy_set_encoding tidy_setopt tidy_warning_count      contained
+  syn keyword  phpMethods      attributes children get_attr get_nodes has_children has_siblings is_asp is_comment is_html is_jsp is_jste is_text is_xhtml is_xml next prev tidy_node   contained
+  syn keyword  phpFunctions    token_get_all token_name        contained
+  syn keyword  phpFunctions    base64_decode base64_encode get_meta_tags http_build_query parse_url rawurldecode rawurlencode urldecode urlencode      contained
+  syn keyword  phpFunctions    doubleval empty floatval get_defined_vars get_resource_type gettype import_request_variables intval is_array is_bool is_callable is_double is_float is_int is_integer is_long is_null is_numeric is_object is_real is_resource is_scalar is_string isset print_r serialize settype strval unserialize unset var_dump var_export contained
+  syn keyword  phpFunctions    vpopmail_add_alias_domain_ex vpopmail_add_alias_domain vpopmail_add_domain_ex vpopmail_add_domain vpopmail_add_user vpopmail_alias_add vpopmail_alias_del_domain vpopmail_alias_del vpopmail_alias_get_all vpopmail_alias_get vpopmail_auth_user vpopmail_del_domain_ex vpopmail_del_domain vpopmail_del_user vpopmail_error vpopmail_passwd vpopmail_set_user_quota    contained
+  syn keyword  phpFunctions    w32api_deftype w32api_init_dtype w32api_invoke_function w32api_register_function w32api_set_call_method contained
+  syn keyword  phpFunctions    wddx_add_vars wddx_deserialize wddx_packet_end wddx_packet_start wddx_serialize_value wddx_serialize_vars       contained
+  syn keyword  phpFunctions    utf8_decode utf8_encode xml_error_string xml_get_current_byte_index xml_get_current_column_number xml_get_current_line_number xml_get_error_code xml_parse_into_struct xml_parse xml_parser_create_ns xml_parser_create xml_parser_free xml_parser_get_option xml_parser_set_option xml_set_character_data_handler xml_set_default_handler xml_set_element_handler xml_set_end_namespace_decl_handler xml_set_external_entity_ref_handler xml_set_notation_decl_handler xml_set_object xml_set_processing_instruction_handler xml_set_start_namespace_decl_handler xml_set_unparsed_entity_decl_handler contained
+  syn keyword  phpFunctions    xmlrpc_decode_request xmlrpc_decode xmlrpc_encode_request xmlrpc_encode xmlrpc_get_type xmlrpc_parse_method_descriptions xmlrpc_server_add_introspection_data xmlrpc_server_call_method xmlrpc_server_create xmlrpc_server_destroy xmlrpc_server_register_introspection_callback xmlrpc_server_register_method xmlrpc_set_type  contained
+  syn keyword  phpFunctions    xslt_create xslt_errno xslt_error xslt_free xslt_output_process xslt_set_base xslt_set_encoding xslt_set_error_handler xslt_set_log xslt_set_sax_handler xslt_set_sax_handlers xslt_set_scheme_handler xslt_set_scheme_handlers contained
+  syn keyword  phpFunctions    yaz_addinfo yaz_ccl_conf yaz_ccl_parse yaz_close yaz_connect yaz_database yaz_element yaz_errno yaz_error yaz_es_result yaz_get_option yaz_hits yaz_itemorder yaz_present yaz_range yaz_record yaz_scan_result yaz_scan yaz_schema yaz_search yaz_set_option yaz_sort yaz_syntax yaz_wait       contained
+  syn keyword  phpFunctions    zip_close zip_entry_close zip_entry_compressedsize zip_entry_compressionmethod zip_entry_filesize zip_entry_name zip_entry_open zip_entry_read zip_open zip_read        contained
+  syn keyword  phpFunctions    gzclose gzcompress gzdeflate gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell gzuncompress gzwrite readgzfile zlib_get_coding_type  contained
+  syn keyword  phpFunctions    timezone_offset_get date_create
+  syn keyword phpFunctions     date_default_timezone_set date_default_timezone_get
+  " ext SPL:
+  syn keyword phpFunctions     spl_autoload_call spl_autoload_extensions spl_autoload_functions
+  syn keyword phpFunctions     spl_autoload_register spl_autoload_unregister spl_autoload
+  syn keyword phpFunctions     spl_classes spl_object_hash
+  syn keyword phpFunctions     class_implements class_parents iterator_count iterator_to_array
+  
+  " }}}2
+
+  if s:show_baselib
+    syn keyword        phpMethods      query next_record num_rows affected_rows nf f p np num_fields haltmsg seek link_id query_id metadata table_names nextid connect halt free register unregister is_registered delete url purl self_url pself_url hidden_session add_query padd_query reimport_get_vars reimport_post_vars reimport_cookie_vars set_container set_tokenname release_token put_headers get_id get_id put_id freeze thaw gc reimport_any_vars start url purl login_if is_authenticated auth_preauth auth_loginform auth_validatelogin auth_refreshlogin auth_registerform auth_doregister start check have_perm permsum perm_invalid contained
+    syn keyword        phpFunctions    page_open page_close sess_load sess_save        contained
+  endif
+
+
+" }}}1
+
+" {{{1 REVIEW: }}}1
+
+
+" Keyword
+syn cluster phpClInClass add=phpClassDefine
+syn keyword    phpClassDefine contained var const
+hi link phpClassDefine phpDefine
+
+if s:alt_arrays
+  syn cluster phpClExpressions add=phpArrayRegion
+  syn cluster phpClValues add=phpArrayRegionSimple
+  " TODO: should the error highlighting be optional???
+  if s:fold_arrays
+    syn region phpArrayRegionSimple contained matchgroup=phpArrayParens start=/\<array\_s*(/ end=/)/
+          \ keepend extend contains=@phpClValues,phpArrayPair,phpArrayComma
+          \ matchgroup=Error end=/;/
+          \ fold
+    syn region phpArrayRegion contained matchgroup=phpArrayParens start=/\<array\_s*(/ end=/)/
+          \ keepend extend contains=@phpClExpressions,phpArrayPair,phpArrayComma
+          \ matchgroup=Error end=/;/
+          \ fold
+  else
+    syn region phpArrayRegionSimple contained matchgroup=phpArrayParens start=/\<array\_s*(/ end=/)/
+          \ keepend extend contains=@phpClValues,phpArrayPair,phpArrayComma
+          \ matchgroup=Error end=/;/
+    syn region phpArrayRegion contained matchgroup=phpArrayParens start=/\<array\_s*(/ end=/)/
+          \ keepend extend contains=@phpClExpressions,phpArrayPair,phpArrayComma
+          \ matchgroup=Error end=/;/
+  endif
+  syn match phpArrayComma contained display /,/
+
+  syn cluster phpClExpressions add=phpListRegion
+  " need to make a region for the 'list' keyword as well!!!
+  " TODO: should the error highlighting be optional???
+  " TODO: only allow variables and stuff inside the list() construct
+  syn region phpListRegion contained matchgroup=phpList start=/\<list(/ end=/)/
+        \ keepend extend contains=@phpClExpressions,phpListComma
+        \ matchgroup=Error end=/;/
+  syn match phpListComma contained display /,/
+else
+  " need to use a match instead of keyword here ... to stop it
+  " from blocking a match later on.
+  syn cluster phpClExpressions add=phpArray
+  syn match phpArray contained display /\<array\>/
+
+  syn keyword phpList contained list
+endif
+
+" Operators
+
+
+" Peter Hodge - added support for array-building operator
+" to stop the relations from mixing this up
+if s:alt_arrays
+  " highlight misuse of the '=>' operator
+  syn cluster phpClExpressions add=phpArrayPairError
+  syn match    phpArrayPairError /=>/ contained display
+
+  " the next match is used only in the correct places
+  syn match    phpArrayPair /=>/ contained display
+else
+  syn match phpOperator /=>/ contained display
+endif
+
+" relations
+" Peter Hodge, June 17 2006
+" - altered relations to match strict comparisons (=== and !==)
+" - highlight the 'instanceof' operator as a relation operator
+"   rather than a structure, if comparison support is a priority.
+syn cluster phpClExpressions add=phpRelation
+syn match phpRelation contained display /===\=/
+syn match phpRelation contained display /!==\=/
+syn match phpRelation contained display /<<\@!=\=/
+syn match phpRelation contained display />>\@!=\=/
+
+" 'instanceof' is also a relation, but may have alternate colours
+syn cluster phpClExpressions add=phpInstanceof
+syn keyword phpInstanceof contained instanceof
+      \ nextgroup=@phpClStructures,phpStructureHere skipwhite skipempty
+
+" how to treat '->'?
+
+" Note: this is always needed for inside strings
+syn match phpPropertySelector contained display /->/
+
+if ! s:smart_members
+  " NOTE: this match is for ANY '->' match, however the more specific
+  " phpPropertySelector or phpDynamicSelector may match instead
+  syn cluster phpClExpressions add=phpMemberSelector
+  syn match phpMemberSelector contained display /->/
+        \ nextgroup=@phpClProperties,@phpClMembers,phpMemberHere skipwhite skipempty
+
+else
+  " by default all -> matches are property access
+  syn cluster phpClExpressions add=phpPropertySelector
+
+  " make a match for a whole property name also
+  syn cluster phpClExpressions add=phpPropertyAccess
+  syn match phpPropertyAccess contained display /->\_s*\h\w*/
+        \ contains=phpPropertySelector,@phpClProperties,phpPropertyHere
+
+  " try match them as method calls first though
+  " NOTE: have taken out phpMethods (because it just wasn't accurate)
+  " but have added phpSpecialMethods because they are always special
+  syn cluster phpClExpressions add=phpMethodCall
+  syn cluster phpClMethodHere add=phpMethodCall
+  syn match phpMethodCall contained display /->\_s*\h\w*\_s*(\@=/
+        \ contained display contains=phpMemberSelector,@phpClMethods
+  syn match phpMethodCall contained display /->\_s*\$\h\w*\_s*(\@=/
+        \ contained display contains=phpIdentifier,phpMemberSelector
+  syn match phpMemberSelector contained display /->/
+
+  " for a dynamic {} property/method
+  if s:alt_properties
+    syn cluster phpClExpressions add=phpDynamicSelectorRegion
+    syn region phpDynamicSelectorRegion contained keepend extend
+          \ matchgroup=phpDynamicSelector start=/->\_s*{/ end=/}/
+          \ contains=@phpClExpressions
+  endif
+
+"  " highlight incorrect use of -> as an error
+"  syn cluster phpClExpressions add=phpMemberError
+"  syn match phpMemberError /->\%#\@!\%(\_s*\)\@>[a-z{_$]\@!/ contained display
+
+endif
+
+syn region phpIdentifierComplex contained display matchgroup=phpVarSelector start=/\${/ end=/}/
+      \ keepend extend
+      \ contains=@phpClExpressions
+
+" create an identifier match for double-quoted strings:
+
+" Methoden
+
+" Peter Hodge - added 'clone' keyword here
+" Define
+syn cluster phpClExpressions add=phpObjectOperator
+syn keyword    phpObjectOperator contained new
+      \ nextgroup=@phpClClasses,@phpClInterfaces,phpStructureHere skipwhite skipempty
+syn keyword    phpObjectOperator contained clone
+
+" Todo
+syn keyword    phpTodo contained todo fixme xxx containedin=phpComment
+
+" Parent
+if s:strict_blocks
+  syn cluster phpClExpressions add=phpBlockRegion
+  if s:folding == 2
+      syn region phpBlockRegion matchgroup=phpBrace start=/{/ end=/}/ keepend extend
+            \ transparent contained
+            \ fold
+  else
+      syn region phpBlockRegion matchgroup=phpBrace start=/{/ end=/}/ keepend extend
+            \ transparent contained
+      if s:fold_manual
+        syn region phpBlockRegion matchgroup=phpBrace start='{\ze\s*//\s*fold\s*$\c' end='}' keepend extend
+              \ transparent contained
+              \ fold
+      endif
+  endif
+
+  " parenthesis for a foreach() block, not found automatically
+  " (is triggered by a nextgroup=phpForeachRegion)
+  " Note: the 'display' option on a foreach region (the part inside the '()')
+  " would be bad, because it is possible for that to be spread over several
+  " lines (well, I do it myself)
+  if s:alt_arrays || s:alt_control_parents
+    syn region phpForeachRegion matchgroup=phpControlParent start=/(/ end=/)/ keepend extend
+            \ contained contains=@phpClExpressions,phpArrayPair
+            \ nextgroup=phpSemicolonNotAllowedHere skipwhite skipempty
+  endif
+
+  " parenthesis for a for() block, not found automatically
+  " (is triggered by a nextgroup=phpForRegion)
+  if s:alt_arrays || s:alt_control_parents
+    syn region phpForRegion matchgroup=phpControlParent
+            \ start=/(/ end=/)/ keepend extend display
+            \ contained contains=@phpClExpressions,phpForSemicolon
+            \ nextgroup=phpSemicolonNotAllowedHere skipwhite skipempty
+    syn match phpForSemicolon contained display /[,;]/
+    hi! link phpForSemicolon phpConditional
+  endif
+
+  " special parent regions for 'if/while' blocks so we can catch a semicolon
+  " which shouldn't be at the end
+  " Note: having endings on those keywords helps speed things up alot.
+  if s:no_empty_construct
+    syn region phpConstructRegion keepend extend contained contains=@phpClExpressions
+          \ nextgroup=phpSemicolonNotAllowedHere skipwhite skipempty
+          \ matchgroup=phpControlParent start=/(/ end=/)/
+          \ matchgroup=Error end=/}/ end=/\]/
+            \ end=/\$\@<!\<\%(protected\|public\|private\)\>/
+            \ end=/\$\@<!\<\%(final\|abstract\|static\|global\)\>/
+            \ end=/\$\@<!\<\%(class\|function\|interface\|extends\)\>/
+            \ end=/\$\@<!\<\%(return\|break\|continue\|case\|default\|echo\)\>/
+    syn region phpSwitchConstructRegion keepend extend contained contains=@phpClExpressions
+          \ nextgroup=phpSemicolonNotAllowedHere,phpSwitchBlock skipwhite skipempty
+          \ matchgroup=phpControlParent start=/(/ end=/)/
+          \ matchgroup=Error end=/}/ end=/\]/
+            \ end=/\$\@<!\<\%(protected\|public\|private\)\>/
+            \ end=/\$\@<!\<\%(final\|abstract\|static\|global\)\>/
+            \ end=/\$\@<!\<\%(class\|function\|interface\|extends\)\>/
+            \ end=/\$\@<!\<\%(return\|break\|continue\|case\|default\|echo\)\>/
+    syn region phpDoWhileConstructRegion keepend extend contained contains=@phpClExpressions
+          \ matchgroup=phpControlParent start=/(/ end=/)\_s*;/
+          \ matchgroup=Error end=/}/ end=/\]/ end=/;/
+            \ end=/\$\@<!\<\%(protected\|public\|private\)\>/
+            \ end=/\$\@<!\<\%(final\|abstract\|static\|global\)\>/
+            \ end=/\$\@<!\<\%(class\|function\|interface\|extends\)\>/
+            \ end=/\$\@<!\<\%(return\|break\|continue\|case\|default\|echo\)\>/
+  endif
+
+  " match up ( and ), as well as [ and ]
+  syn cluster phpClExpressions add=phpParentRegion,phpBracketRegion
+  syn region phpParentRegion contained keepend extend contains=@phpClExpressions
+        \ matchgroup=phpParent start=/(/ end=/)/
+        \ matchgroup=Error end=/;/ end=/}/ end=/\]/
+  " NOTE: the 'dispay' option on a [] region isn't so dangerous, as they are
+  " normally only one line
+  " TODO: does the 'display' option break folding for php_fold_arrays? The
+  " answer is YES
+  syn region phpBracketRegion contained keepend extend contains=@phpClExpressions
+        \ matchgroup=phpParent start=/\[/ end=/\]/
+        \ matchgroup=Error end=/;/
+
+  " when a closing }, ) or ] is out of place ...
+  if s:parent_error_close
+    syn cluster phpClValues add=phpBraceError,phpParentError
+    syn match phpBraceError  contained display /}/
+    syn match phpParentError contained display /)/
+    syn match phpParentError contained display /\]/
+  endif
+
+else
+  syn match phpParent contained display /{/
+  syn match phpParent contained display /}/
+  syn match phpParent contained display /\[/
+  syn match phpParent contained display /\]/
+  syn match phpParent contained display /(/
+  syn match phpParent contained display /)/
+endif
+
+syn cluster    phpClTop      add=phpFoldFunction,phpFoldClass,phpFoldInterface
+
+" PHP Region
+if s:long_tags
+  syn region phpRegion matchgroup=phpRegionDelimiter start=/<?php\w\@!/ end=/?>/
+        \ keepend extend contains=@phpClTop
+else
+  syn region phpRegion matchgroup=phpRegionDelimiter start=/<?\(php\w\@!\|=\)\=/ end=/?>/
+        \ keepend extend contains=@phpClTop
+endif
+
+syn region phpRegionSc matchgroup=phpRegionDelimiter
+      \ start=#<script language="php"># end=#</script>#
+      \ contains=@phpClTop keepend extend
+
+if s:asp_tags
+  syn region phpRegionAsp matchgroup=phpRegionDelimiter start=/<%=\=/ end=/%>/
+        \ keepend extend contains=@phpClTop
+endif
+
+if s:strict_blocks
+  syn cluster phpClValues add=phpHTMLError
+  syn match phpHTMLError /?>/ contained
+endif
+
+" if using strict blocks, need to look out for HTML inside
+" blocks
+if s:strict_blocks
+  " only allow in base-level code (not inside () or [])
+  syn cluster phpClCode add=htmlRegion
+  if s:long_tags
+    " only match full php tags
+    syn region htmlRegion contained contains=TOP matchgroup=phpRegionDelimiter
+          \ start=/?>/ end=/<?php\w\@!/ keepend extend
+  else
+    " match any php tags
+    syn region htmlRegion contained contains=TOP matchgroup=phpRegionDelimiter
+          \ start=/?>/ end=/<?\%(php\w\@!\|=\)\=/ keepend extend
+  endif
+
+  if s:asp_tags
+    syn region htmlRegion contained contains=TOP matchgroup=phpRegionDelimiter
+          \ start=/%>/ end=/<%=\=/ keepend extend
+  endif
+endif
+
+" if strict curly-braces matching is enabled, then match braces
+" properly
+if s:strict_blocks
+  " DEFINITIONS FOR:
+  "   function ...() {
+  "   class ... {
+  "     method ...() {
+  " these need to be done piece-by-piece so that we can use 'nextgroups'
+  " to match the { } code blocks - we want to use special colors for them!
+  " {{{1
+
+  " Match the 'final' and 'abstract' keywords first, they can be inside the
+  " global scope or inside a class declaration
+  syn cluster phpClTop add=phpStructureType
+  syn cluster phpClInClass add=phpStructureType
+  syn keyword phpStructureType contained abstract final
+
+  " the phpStructure keywords (class/interface) can be found anywhere in
+  " global scope
+  syn cluster phpClTop add=phpStructure
+
+  " CLASSES: class myFoo extends baseFoo implements foo, Iterator { }: {{{2
+  " I MATCH: <class myFoo> extends baseFoo implements foo, Iterator { }: {{{3
+  
+    " 2: match the start of the class declaration
+    syn keyword phpStructure contained class
+          \ nextgroup=phpDefineClassName skipwhite skipempty
+
+    " 3: an empty placeholder for any class name (which in turn can contain
+    " any of the known PHP class names)
+    " NOTE: allow matching the class block immediately after the class name
+    syn cluster phpClClassHere add=phpDefineClassName
+    syn match phpDefineClassName /\h\w*/ contained contains=@phpClStructures
+          \ nextgroup=@phpClDefineClassBlock skipwhite skipempty
+
+  " II MATCH: class myFoo <extends baseFoo> implements foo, Iterator { }: {{{3
+
+      " match the 'extends' keyword and follow it by the match
+      " for class names in a declaration (as above)
+      syn keyword phpStructure contained extends
+            \ nextgroup=phpDefineClassName skipwhite skipempty
+
+  " III MATCH: class myFoo extends baseFoo <implements foo, Iterator> { }: {{{3
+
+      " 1: match the 'implements' keyword and follow it by the match
+      " for class names in a declaration (as above)
+      syn keyword phpStructure contained implements
+            \ nextgroup=@phpClDefineClassImplements skipwhite skipempty
+
+      " 2: define a place-holding for interfaces which matches any valid
+      " interface name and also contains the recognized names
+      syn cluster phpClDefineClassImplements add=phpDefineClassImplementsName
+      syn cluster phpClInterfaceHere add=phpDefineClassImplementsName
+      syn cluster phpClClassHere add=phpDefineClassImplementsName
+      syn match phpDefineClassImplementsName /\h\w*/ contained contains=@phpClStructures
+            \ nextgroup=@phpClDefineClassImplements skipwhite skipempty
+
+      " 3: allow a comma in the list
+      syn cluster phpClDefineClassImplements add=phpDefineClassImplementsComma
+      syn match phpDefineClassImplementsComma /,/ contained
+            \ nextgroup=@phpClDefineClassImplements skipwhite skipempty
+
+      " 4: there might be a '#' or '//'-style comment in-between!
+      syn cluster phpClDefineClassImplements add=phpDefineClassImplementsCommentOneLine
+      syn region phpDefineClassImplementsCommentOneLine
+            \ start=/#/ start=,//, end=/$/ end=/.\ze?>/ oneline
+            \ contained contains=phpComment
+            \ nextgroup=@phpClDefineClassImplements skipwhite skipempty
+
+      " 5: there might a C-style comment (/*...*/) in-between
+      syn cluster phpClDefineClassImplements add=phpDefineClassImplementsCommentCStyle
+      syn region phpDefineClassImplementsCommentCStyle start=,/\*, end=,\*/, keepend
+            \ contained contains=@Spell
+            \ nextgroup=@phpClDefineClassImplements skipwhite skipempty
+      hi link phpDefineClassImplementsCommentCStyle phpComment
+
+      " 6: add the block to the list so it can match here also
+      syn cluster phpClDefineClassImplements add=phpClassBlock
+
+  " IV MATCH: class myFoo extends baseFoo implements foo, Iterator <{ }>: {{{3
+
+    " 1: there might be a '#' or '//'-style comment in-between!
+    syn cluster phpClDefineClassBlock add=phpDefineClassBlockCommentOneline
+    syn region phpDefineClassBlockCommentOneline start=/#/ start=,//, end=/$/ end=/.\ze?>/ oneline
+          \ contained contains=phpComment
+          \ nextgroup=@phpClDefineClassBlock skipwhite skipempty
+
+    " 2: there might a C-style comment (/*...*/) in-between
+    syn cluster phpClDefineClassBlock add=phpDefineClassBlockCommentCStyle
+    syn region phpDefineClassBlockCommentCStyle start=,/\*, end=,\*/, keepend
+          \ contained contains=@Spell
+          \ nextgroup=@phpClDefineClassBlock skipwhite skipempty
+    hi link phpDefineClassBlockCommentCStyle phpComment
+
+    " 3: look for the actual { } block
+    syn cluster phpClDefineClassBlock add=phpClassBlock
+    if (s:folding == 1) || (s:folding == 2)
+      syn region phpClassBlock matchgroup=phpBraceClass start=/{/ end=/}/ keepend extend
+            \ contained contains=@phpClInClass
+            \ matchgroup=phpHTMLError end=/?>/
+            \ fold
+    else
+      syn region phpClassBlock matchgroup=phpBraceClass start=/{/ end=/}/ keepend extend
+            \ contained contains=@phpClInClass
+            \ matchgroup=phpHTMLError end=/?>/
+      if s:fold_manual
+        syn region phpClassBlock matchgroup=phpBraceClass start='{\ze\s*//\s*fold\s*$\c' end='}' keepend extend
+              \ contained contains=@phpClInClass
+              \ matchgroup=phpHTMLError end=/?>/
+              \ fold
+      endif
+    endif
+
+
+  " }}}2
+
+  " INTERFACES: interface myFoo extends baseFoo { }: {{{2
+  " I MATCH: <interface myFoo> extends baseFoo { }: {{{3
+  
+    " 1: match the start of the interface declaration
+    syn keyword phpStructure contained interface
+          \ nextgroup=phpDefineInterfaceName skipwhite skipempty
+
+    " 2: an empty placeholder for any interface name (which in turn can contain
+    " any of the known PHP class names)
+    " NOTE: allow matching the class block immediately after the class name
+    " NOTE: maybe one day will make a separate block for interface bodies
+    syn cluster phpClClassHere add=phpDefineInterfaceName
+    syn cluster phpClInterfaceHere add=phpDefineInterfaceName
+    syn match phpDefineInterfaceName /\h\w*/ contained contains=@phpClStructures
+          \ nextgroup=@phpClDefineClassBlock skipwhite skipempty
+
+  " II MATCH: interface myFoo <extends baseFoo> { }: {{{3
+
+    " NOTE: this is handled in the class syntax handling above
+
+  " IV MATCH: class myFoo extends baseFoo implements foo, Iterator <{ }>: {{{3
+
+    " NOTE: this is handled in the class syntax handling above
+
+  " }}}2
+
+  " FUNCTIONS: function & somefunc($a = 0, &$b) { }: {{{2
+  " I MATCH: <function> & somefunc($a = 0, &$b) { }: {{{3
+
+    " if we are finding functions anywhere, allow this match only
+    syn cluster phpClCode add=phpDefine
+
+    syn keyword phpDefine function contained
+          \ nextgroup=@phpClDefineFuncName,phpDefineFuncByRef
+          \ skipwhite skipempty
+
+  " II MATCH: function <&> somefunc($a = 0, &$b) { }: {{{3
+
+    " second, there might be a '&' return-by-reference option, so add
+    " a match for that.
+    syn match phpDefineFuncByRef /&/ contained nextgroup=@phpClDefineFuncName skipwhite skipnl
+    hi link phpDefineFuncByRef phpAssignByRef
+
+
+  " III MATCH: function & <somefunc>($a = 0, &$b) { }: {{{3
+
+    " what can go inside a function name? Anything that does will need
+    " a 'nextgroup=phpDefineFuncProto' argument!
+
+    " first up, an empty placeholder to match any valid function name.
+    "     It should contain the special user-defineable function names.
+    syn cluster phpClDefineFuncName add=phpDefineFuncName
+    syn cluster phpClFunctionHere add=phpDefineFuncName
+    syn match phpDefineFuncName /\h\w*/ contained
+          \ contains=@phpClFunctions
+          \ nextgroup=phpDefineFuncProto
+          \ skipwhite skipempty
+    " TODO: allow adding comments between 'function' and 'someFunc'
+
+
+  " IV MATCH: function & somefunc<(>$a = 0, &$b<)> { }: {{{3
+  " match the parenthesis surrounding the function arguments
+  if s:folding
+    syn region phpDefineFuncProto contained contains=@phpClDefineFuncProtoArgs
+          \ matchgroup=phpParent start=/(/ end=/)/ keepend extend
+          \ nextgroup=@phpClDefineFuncBlock
+          \ skipwhite skipempty
+          \ fold
+  else
+    syn region phpDefineFuncProto contained contains=@phpClDefineFuncProtoArgs
+          \ matchgroup=phpParent start=/(/ end=/)/ keepend extend
+          \ nextgroup=@phpClDefineFuncBlock
+          \ skipwhite skipempty
+  endif
+  " TODO: allow comments in this cluster
+
+
+  " V MATCH: function & somefunc(<stdClass> $a = 0, &$b) { }: {{{3
+  " first: any valid class name
+  syn cluster phpClDefineFuncProtoArgs add=@phpClClasses,@phpClInterfaces
+
+  " we still need to match an 'array' keyword, because it can be used for
+  " parameter type-requirements
+  syn cluster phpClDefineFuncProtoArgs add=phpProtoArrayCheck
+  syn match phpProtoArrayCheck /\<array\>/ contained
+  hi link phpProtoArrayCheck phpArray
+
+  " VI MATCH: function & somefunc(stdClass <$a => 0, <&$b>) { }: {{{3
+
+    " 1: match the by-ref '&'
+    syn cluster phpClDefineFuncProtoArgs add=phpProtoArgByRef
+    syn match phpProtoArgByRef /&/ display contained
+    hi link phpProtoArgByRef phpAssignByRef
+
+    " 2: match a valid identifier
+    syn cluster phpClDefineFuncProtoArgs add=phpIdentifier,phpAssign
+
+  " VII MATCH: function & somefunc(stdClass $a = <0>, &$b) { }: {{{3
+  " What about other items? numbers? strings? arrays()?
+  syn cluster phpClDefineFuncProtoArgs add=@phpClProtoValues
+
+    " 1: simple types (null, boolean)
+    syn cluster phpClProtoValues add=phpNull
+    syn cluster phpClProtoValues add=phpBoolean
+
+    " 2: numbers and strings and constants
+    syn cluster phpClProtoValues add=phpNumber,phpFloat
+    syn cluster phpClProtoValues add=phpStringSingle,phpStringDouble
+    syn cluster phpClProtoValues add=@phpClConstants
+
+    " 3: arrays must be done separately to ensure ( and ) match correctly
+    " (but only if using alt colors for arrays)
+    if s:alt_arrays
+      syn cluster phpClProtoValues add=phpProtoArray
+      syn region phpProtoArray matchgroup=phpArrayParens start=/\<array\_s*(/ end=/)/ keepend extend
+          \ contained contains=@phpClProtoValues,phpArrayPair
+
+      " don't allow arbitrary parenthesis here!!
+      syn cluster phpClProtoValues add=phpProtoParentError
+      syn match phpProtoParentError /(/ contained display
+      hi link phpProtoParentError phpParentError
+    else
+      syn cluster phpClProtoValues add=phpArray
+
+      " need to allow arbitrary parenthesis for arrays
+      syn cluster phpClProtoValues add=phpParentRegion
+    endif
+
+    " 4: comments
+    syn cluster phpClProtoValues add=phpComment
+
+
+  " VIII MATCH: function & somefunc(</* foo */>) { }: {{{3
+  " What about comment items?
+  syn cluster phpClDefineFuncProtoArgs add=phpComment
+
+  " IX MATCH: function & somefunc(stdclass $a = 0, &$b) <{ }>: {{{3
+
+    " 1: there might be a '#' or '//'-style comment in-between!
+    syn cluster phpClDefineFuncBlock add=phpDefineFuncBlockCommentOneline
+    syn region phpDefineFuncBlockCommentOneline start=/#/ start=,//, end=/$/ end=/.\ze?>/ oneline
+          \ contained contains=phpComment
+          \ nextgroup=@phpClDefineFuncBlock skipwhite skipempty
+
+    " 2: there might a C-style comment (/*...*/) in-between
+    syn cluster phpClDefineFuncBlock add=phpDefineFuncBlockCommentCStyle
+    syn region phpDefineFuncBlockCommentCStyle start=,/\*, end=,\*/, keepend
+          \ contained contains=@Spell
+          \ nextgroup=@phpClDefineFuncBlock skipwhite skipempty
+    hi link phpDefineFuncBlockCommentCStyle phpComment
+
+    " 3: look for the actual { } block
+    "    NOTE: how the function block will end at the next function
+    "    declaration: this helps stop the region extending indefinitely,
+    "    forcing the recalculation of all { } blocks for the rest of the file.
+    "    Otherwise, inserting an open-brace will 
+    "    NOTE: that the error can't happen on a 'final', 'abstract', 'class',
+    "    or 'interface' keyword because they can't be contained in a function
+    syn cluster phpClDefineFuncBlock add=phpFuncBlock
+
+    let s:foldHere = s:folding ? 'fold' : ''
+    let s:endEarly = s:nested_functions ? '' : 'matchgroup=Error end=/\%(^\|\s\)function\>/'
+
+"    if s:folding
+"      if s:nested_functions
+"        syn region phpFuncBlock keepend extend matchgroup=phpBraceFunc start=/{/ end=/}/
+"              \ matchgroup=Error end=/\%(^\|\s\)\%(public\|private\|protected\)\>/
+"              \ contained contains=@phpClInFunction
+"              \ fold
+"      else
+"        syn region phpFuncBlock keepend extend matchgroup=phpBraceFunc start=/{/ end=/}/
+"              \ matchgroup=Error end=/\%(^\|\s\)function\>/
+"              \ matchgroup=Error end=/\%(^\|\s\)\%(public\|private\|protected\)\>/
+"              \ contained contains=@phpClInFunction
+"              \ fold
+"      endif
+"    else
+"      if s:nested_functions
+"        syn region phpFuncBlock keepend extend matchgroup=phpBraceFunc start=/{/ end=/}/
+"              \ matchgroup=Error end=/\%(^\|\s\)\%(public\|private\|protected\)\>/
+"              \ contained contains=@phpClInFunction
+"      else
+"        syn region phpFuncBlock keepend extend matchgroup=phpBraceFunc start=/{/ end=/}/
+"              \ matchgroup=Error end=/\%(^\|\s\)function\>/
+"              \ matchgroup=Error end=/\%(^\|\s\)p\%(ublic\|rivate\|rotected\)\>/
+"              \ contained contains=@phpClInFunction
+"      endif
+"    endif
+
+        execute 'syn region phpFuncBlock keepend extend matchgroup=phpBraceFunc'
+              \ 'end=/}/ start=/{/'
+              \ 'matchgroup=Error end=/\%(^\|\s\)\%(public\|private\|protected\)\>/'
+              \ s:endEarly
+              \ 'contained contains=@phpClInFunction'
+              \ s:foldHere
+        " for manual folding, we use an alternate start
+        if s:fold_manual
+          execute 'syn region phpFuncBlock keepend extend matchgroup=phpBraceFunc'
+                \ 'start=#{\ze\s*//\s*fold\s*$\c# end=/}/'
+                \ 'matchgroup=Error end=/\%(^\|\s\)\%(public\|private\|protected\)\>/'
+                \ s:endEarly
+                \ 'contained contains=@phpClInFunction'
+                \ s:foldHere
+        endif
+    unlet s:foldHere s:endEarly
+
+  " }}}2
+
+  " METHODS: protected function & somefunc($a = 0, &$b) { }: {{{2
+  " I MATCH: <protected function> somefunc($a = 0, &$b) { }: {{{3
+
+    " 1: match the final / abstract / private keywords at start
+    " TODO: rename 'phpStorageClass' to Typedef (for global and static keywords)
+    " and rename 'phpStorageClass2' to 'phpStorageClass'
+    syn cluster phpClInClass add=phpStorageClass2
+    syn keyword phpStorageClass2 contained private protected public static final abstract
+    hi link phpStorageClass2 phpStorageClass
+
+    syn keyword phpDefineMethod function contained containedin=phpClassBlock
+          \ nextgroup=@phpClDefineMethodName,phpDefineMethodByRef
+          \ skipwhite skipempty
+    " TODO: add phpDefineFunction in the proper place
+    hi link phpDefineFunction phpDefine
+    hi link phpDefineMethod phpDefineFunction
+
+  " II MATCH: protected function <&> somefunc($a = 0, &$b) { }: {{{3
+  " second, there might be a '&' return-by-reference option, so add
+  " a match for that.
+  syn match phpDefineMethodByRef /&/ contained
+        \ nextgroup=@phpClDefineMethodName skipwhite skipnl
+  hi link phpDefineMethodByRef phpDefineFuncByRef
+
+  " III MATCH: protected function & <somefunc>($a = 0, &$b) { }: {{{3
+  " what can go inside a method name? Anything that does will need
+  " a 'nextgroup=phpDefineMethodProto' argument!
+
+    " An empty placeholder to match any valid method name.
+    " It should contain the special user-defineable method names.
+    " NOTE: how we are just re-using 'function' block instead of
+    " making more stuff to have a special 'method' block also.
+    " I don't think it would be worthwhile at this stage.
+    " NOTE: phpSpecialFunction must be included as well, because
+    " that's a reserved function name and will break things.
+    " TODO: cater for a new group, phpReservedFunction
+    syn cluster phpClDefineMethodName add=phpDefineMethodName
+    syn cluster phpClMethodHere add=phpDefineMethodName
+    syn match phpDefineMethodName /\h\w*/ contained
+          \ contains=phpSpecialFunction,@phpClMethods
+          \ nextgroup=phpDefineFuncProto
+          \ skipwhite skipempty
+    " TODO: allow adding comments between 'function' and 'someFunc'
+
+  " }}}2
+
+  " EXCEPTIONS: try/catch { } {{{2
+
+    syn cluster phpClCode add=phpException
+  
+    " 1: match the start of a try block
+    syn keyword phpException try contained nextgroup=@phpClTryBlock skipwhite skipnl
+
+    " TODO: 2: allow having comments preceding the { } block?
+  
+    " 3: match the try block
+    syn cluster phpClTryBlock add=phpTryBlock
+    " TODO: manual folding from here (search for \<fold\>)
+    if s:folding == 2
+      syn region phpTryBlock matchgroup=phpBraceException start=/{/ end=/}/ keepend extend
+            \ contained transparent
+            \ fold
+    else
+      syn region phpTryBlock matchgroup=phpBraceException start=/{/ end=/}/ keepend extend
+            \ contained transparent
+    endif
+
+    " 3: match the start of the catch block
+    syn keyword phpException catch contained nextgroup=phpCatchRegion skipwhite skipnl
+    syn region phpCatchRegion matchgroup=phpParent start=/(/ end=/)/ keepend extend
+          \ contained contains=@phpClExpressions
+          \ nextgroup=@phpClCatchBlock skipwhite skipnl
+
+    " TODO: 4: allow having comments preceding the { } block?
+
+    " 5: match the catch block
+    syn cluster phpClCatchBlock add=phpCatchBlock
+    if s:folding == 2
+      syn region phpCatchBlock matchgroup=phpBraceException start=/{/ end=/}/ keepend extend
+            \ contained transparent
+            \ fold
+    else
+      syn region phpCatchBlock matchgroup=phpBraceException start=/{/ end=/}/ keepend extend
+            \ contained transparent
+    endif
+
+  " }}}2
+
+  " }}}1
+
+  " make sure 'static' and 'global' work inside a function block
+  " TODO: refactor this?
+  syn keyword phpStorageClass static global contained
+
+  " set foldmethod if folding
+  if s:folding
+    set foldmethod=syntax
+  endif
+else
+  " Fold
+  if s:folding == 1 " {{{1
+  " match one line constructs here and skip them at folding
+    syn keyword        phpSCKeyword    abstract final private protected public static  contained
+    syn keyword        phpFCKeyword    function        contained
+    syn keyword        phpStorageClass global  contained
+    syn match  phpDefine       "\(\s\|^\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\(\s\+.*[;}]\)\@="    contained contains=phpSCKeyword
+    syn match  phpStructure    "\(\s\|^\)\(abstract\s\+\|final\s\+\)*class\(\s\+.*}\)\@="      contained
+    syn match  phpStructure    "\(\s\|^\)interface\(\s\+.*}\)\@="      contained
+    syn match  phpException    "\(\s\|^\)try\(\s\+.*}\)\@="    contained
+    syn match  phpException    "\(\s\|^\)catch\(\s\+.*}\)\@="  contained
+
+    set foldmethod=syntax
+    syn region phpFoldHtmlInside contained transparent contains=@htmlTop
+          \ matchgroup=phpRegionDelimiter start="?>" end="<?\(php\w\@!\)\="
+    syn region phpFoldFunction contained transparent fold extend
+          \ matchgroup=StorageClass
+          \ start="^\z(\s*\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\s\([^};]*$\)\@="rs=e-9
+          \ matchgroup=Delimiter end="^\z1}"
+          \ contains=@phpClInFunction,phpFoldHtmlInside,phpFCKeyword
+    syn region phpFoldFunction matchgroup=Define start="^function\s\([^};]*$\)\@="
+          \ matchgroup=Delimiter end="^}"
+          \ contains=@phpClInFunction,phpFoldHtmlInside contained transparent fold extend
+    syn region phpFoldClass    matchgroup=Structure start="^\z(\s*\)\(abstract\s\+\|final\s\+\)*class\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}"
+          \ contains=@phpClInFunction,phpFoldFunction,phpSCKeyword contained transparent fold extend
+    syn region phpFoldInterface        matchgroup=Structure start="^\z(\s*\)interface\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
+    syn region phpFoldCatch    matchgroup=Exception start="^\z(\s*\)catch\%([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
+    syn region phpFoldTry      matchgroup=Exception start="^\z(\s*\)try\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent fold extend
+
+  elseif s:folding == 2 " {{{1
+    syn keyword        phpDefine       function        contained
+    syn keyword        phpStructure    abstract class interface        contained
+    syn keyword        phpException    catch throw try contained
+    syn keyword        phpStorageClass final global private protected public static    contained
+
+    set foldmethod=syntax
+    syn region phpFoldHtmlInside       matchgroup=phpRegionDelimiter start="?>" end="<?\(php\w\@!\)\=" contained transparent contains=@htmlTop
+    syn region phpParent       matchgroup=Delimiter start="{" end="}" keepend extend contained contains=@phpClFunction,phpFoldHtmlInside transparent fold
+
+  elseif s:folding == 3 " {{{1
+    " match one line constructs here and skip them at folding
+    syn keyword        phpSCKeyword    abstract final private protected public static  contained
+    syn keyword        phpFCKeyword    function        contained
+    syn keyword        phpStorageClass global static contained
+    syn keyword        phpException    catch throw try contained
+
+    syn match  phpDefine       "\(\s\|^\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\(\s\+.*[;}]\)\@="    contained contains=phpSCKeyword
+    syn match  phpStructure    "\(\s\|^\)\(abstract\s\+\|final\s\+\)*class\(\s\+.*}\)\@="      contained
+    syn match  phpStructure    "\(\s\|^\)interface\(\s\+.*}\)\@="      contained
+    syn match  phpException    "\(\s\|^\)try\(\s\+.*}\)\@="    contained
+    syn match  phpException    "\(\s\|^\)catch\(\s\+.*}\)\@="  contained
+
+    " fold these:
+    set foldmethod=syntax
+    syn region phpFoldFunction matchgroup=StorageClass start="^\z(\s*\)\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function\s\([^};]*$\)\@="rs=e-9 matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldHtmlInside,phpFCKeyword contained transparent fold extend
+    syn region phpFoldFunction matchgroup=Define start="^function\s\([^};]*$\)\@=" matchgroup=Delimiter end="^}" contains=@phpClFunction,phpFoldHtmlInside contained transparent fold extend
+
+    " don't fold these:
+    syn region phpFoldHtmlInside       matchgroup=phpRegionDelimiter start="?>" end="<?\(php\w\@!\)\=" contained transparent contains=@htmlTop
+    syn region phpFoldClass    matchgroup=Structure start="^\z(\s*\)\(abstract\s\+\|final\s\+\)*class\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction,phpSCKeyword contained transparent extend
+    syn region phpFoldInterface        matchgroup=Structure start="^\z(\s*\)interface\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent extend
+    syn region phpFoldCatch    matchgroup=Exception start="^\z(\s*\)catch\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent extend
+    syn region phpFoldTry      matchgroup=Exception start="^\z(\s*\)try\s\+\([^}]*$\)\@=" matchgroup=Delimiter end="^\z1}" contains=@phpClFunction,phpFoldFunction contained transparent extend
+
+  else " {{{1
+    syn keyword        phpDefine       contained function
+    syn keyword        phpStructure    contained abstract class interface
+    syn keyword        phpException    contained catch throw try
+    syn keyword        phpStorageClass contained final global private protected public static
+  endif " }}} 1
+
+  " always need these
+  syn keyword phpStructure contained extends implements
+endif
+
+" ================================================================
+" Peter Hodge - June 9, 2006
+" Some of these changes (highlighting isset/unset/echo etc) are not so
+" critical, but they make things more colourful. :-)
+
+
+" different syntax highlighting for 'echo', 'print', 'switch', 'die' and 'list' keywords
+" to better indicate what they are.
+" TODO: convert 'echo' and 'include' to regions so that it cannot contain other control
+" structures
+"syn cluster phpClCode add=phpEcho
+"syn keyword phpEcho contained echo
+syn cluster phpClCode add=phpEchoRegion
+if s:strict_blocks
+  syn region phpEchoRegion contained keepend extend contains=@phpClExpressions,phpEchoComma
+        \ matchgroup=phpEcho start=/\$\@<!\<echo\>/ end=/;/ end=/\ze?>/
+        \ matchgroup=Error end=/[})\]]/
+else
+  syn cluster phpClCode add=phpEcho
+  syn keyword phpEcho contained echo
+endif
+
+syn match phpEchoComma contained display /,/
+hi! link phpEchoComma phpEcho
+
+syn cluster phpClExpressions add=phpPrint,phpInclude
+syn keyword phpPrint contained print
+syn keyword    phpInclude contained include require include_once require_once
+
+" match when a '(type)' is used to cast the type of something
+
+" Highlighting for PHP5's user-definable magic class methods
+syn cluster phpClMethods add=phpSpecialMethods
+syn keyword phpSpecialMethods contained containedin=phpRegion
+    \ __construct __destruct __sleep __wakeup __clone __set_state __toString
+    \ __set __get __unset __isset __call
+
+" these methods are used by the SPL Interfaces
+syn cluster phpClMethods add=phpSPLMethods
+" Serializable
+syn keyword phpSPLMethods contained serialize unserialize
+" ArrayAccess
+syn keyword phpSPLMethods contained offsetSet offsetGet offsetExists offsetUnset
+" Iterator
+syn keyword phpSPLMethods contained current next key valid rewind
+" IteratorAggregate
+syn keyword phpSPLMethods contained getIterator
+" RecursiveIterator
+syn keyword phpSPLMethods contained hasChildren getChildren current next key valid rewind
+" OuterIterator
+syn keyword phpSPLMethods contained getInnerIterator current next key valid rewind
+" SeekableIterator
+syn keyword phpSPLMethods contained seek current next key valid rewind 
+" Countable
+syn keyword phpSPLMethods contained count 
+" SplObserver
+syn keyword phpSPLMethods contained update
+" SplSubject
+syn keyword phpSPLMethods contained attach detach notify 
+" Reflector
+syn keyword phpSPLMethods contained export
+hi link phpSPLMethods phpSpecialMethods
+
+syn keyword phpSpecialFunction contained __autoload
+
+" Highlighting for PHP5's built-in classes
+" - built-in classes harvested from get_declared_classes() in 5.1.4
+syn cluster phpClClasses add=phpClasses
+syn keyword phpClasses contained containedin=phpRegion
+       \ stdClass __PHP_Incomplete_Class php_user_filter Directory ArrayObject
+       \ Exception ErrorException LogicException BadFunctionCallException BadMethodCallException DomainException
+       \ RecursiveIteratorIterator IteratorIterator FilterIterator RecursiveFilterIterator ParentIterator LimitIterator
+       \ CachingIterator RecursiveCachingIterator NoRewindIterator AppendIterator InfiniteIterator EmptyIterator
+       \ ArrayIterator RecursiveArrayIterator DirectoryIterator RecursiveDirectoryIterator
+       \ InvalidArgumentException LengthException OutOfRangeException RuntimeException OutOfBoundsException
+       \ OverflowException RangeException UnderflowException UnexpectedValueException
+       \ PDO PDOException PDOStatement PDORow
+       \ Reflection ReflectionFunction ReflectionParameter ReflectionMethod ReflectionClass
+       \ ReflectionObject ReflectionProperty ReflectionExtension ReflectionException
+       \ SplFileInfo SplFileObject SplTempFileObject SplObjectStorage
+       \ XMLWriter LibXMLError XMLReader SimpleXMLElement SimpleXMLIterator
+       \ DOMException DOMStringList DOMNameList DOMDomError DOMErrorHandler
+       \ DOMImplementation DOMImplementationList DOMImplementationSource
+       \ DOMNode DOMNameSpaceNode DOMDocumentFragment DOMDocument DOMNodeList DOMNamedNodeMap
+       \ DOMCharacterData DOMAttr DOMElement DOMText DOMComment DOMTypeinfo DOMUserDataHandler
+       \ DOMLocator DOMConfiguration DOMCdataSection DOMDocumentType DOMNotation DOMEntity
+       \ DOMEntityReference DOMProcessingInstruction DOMStringExtend DOMXPath
+  \ DateTime DateTimeZone
+
+" Highlighting for PHP5's built-in interfaces
+" - built-in classes harvested from get_declared_interfaces() in 5.1.4
+syn cluster phpClInterfaces add=phpInterfaces
+syn keyword phpInterfaces contained
+       \ Iterator IteratorAggregate RecursiveIterator OuterIterator SeekableIterator
+       \ Traversable ArrayAccess Serializable Countable SplObserver SplSubject Reflector
+"
+" add php_errormsg as a special variable
+
+
+"syn cluster phpClExpressions add=phpProperty
+"syn match phpProperty /->\_s*\%(\$\=\h\w*\)\@>\ze\_s*(\@!/ display extend
+"      \ contained contains=phpPropertySelector,phpIdentifier,@phpClProperties
+"syn match phpPropertySelector /->/ contained display
+
+" for going in string where can be followed by () without making it a method
+" call
+"syn match phpPropertySelectorInString /->/ contained display
+"hi link phpPropertySelectorInString phpPropertySelector
+
+if s:special_functions
+  " Highlighting for PHP built-in functions which exhibit special behaviours
+  " - isset()/unset()/empty() are not real functions.
+  " - compact()/extract() directly manipulate variables in the local scope where
+  "   regular functions would not be able to.
+  " - eval() and assert()
+  " - user_error()/trigger_error() can be overloaded by set_error_handler and also
+  "   have the capacity to terminate your script when type is E_USER_ERROR.
+  syn cluster phpClFunctions add=phpSpecialFunction
+  syn keyword phpSpecialFunction contained
+        \ user_error trigger_error isset unset empty eval assert extract compact __halt_compiler
+endif
+
+" special highlighting for '=&' operator
+syn cluster phpClExpressions add=phpAssignByRef
+syn match phpAssignByRef /=\_s*&/ contained display
+
+" call-time pass-by-reference
+syn match phpAssignByRef /&\$\@=/      contained display
+
+" highlighting for the '@' error-supressing operator
+syn cluster phpClExpressions add=phpSupressErrors
+syn match phpSupressErrors /@/ contained display
+
+" ================================================================
+
+" Sync
+if s:sync == -1
+"  syn sync match phpSyncKeyword grouphere phpRegion /\ze\$\@<!\<class\>/
+"  syn sync match phpSyncKeyword grouphere phpRegion /\ze\$\@<!\<interface\>/
+
+  " best things to look for are the class/interface keywords or
+  " private/protected/public keywords, as we can be 100% confident where we
+  " are when we find them
+  if s:strict_blocks
+    syn sync match phpClassStart grouphere phpClassBlock
+          \ /\$\@<!\<class\%(\%(\s\+\w\+\)\+\)\@>\s*{/
+    " Note: the 'var' and 'const' sync methods have been causing Vim to miss
+    " out the '?>' at the end of a file, so I had to drop them out.  I'm not
+    " sure if it syncs faster
+"    syn sync match phpSyncKeyword grouphere phpClassBlock /\ze\$\@<!\<var\>/
+"    syn sync match phpSyncKeyword grouphere phpClassBlock /\ze\$\@<!\<const\>/
+"    syn sync match phpSyncKeyword grouphere phpClassBlock
+"          \ /\$\@<!\<p\%(rivate\|rotected\|ublic\)\>/
+  endif
+
+  syn sync match phpSyncStartOfFile grouphere NONE /\%^/
+
+  " watch out for strings and comments in syncing process
+  " TODO: make sure this actually works
+  syn sync region phpSyncComment start=/\/\// start=/#/ end=/$/
+  syn sync region phpSyncString start=/\z(['"]\)/ skip=/\\./ end=/\z1/
+
+  if s:long_tags
+    syn sync match phpRegionSync grouphere phpRegion "^\s*<?php\s*$"
+  else
+    syn sync match phpRegionSync grouphere phpRegion "^\s*<?\(php\w\@!\)\=\s*$"
+  endif
+"  syn sync match phpRegionSync grouphere phpRegionSc +^\s*<script language="php">\s*$+
+"  if s:asp_tags
+"    syn sync match phpRegionSync grouphere phpRegionAsp "^\s*<%\(=\)\=\s*$"
+"  endif
+"  syn sync match phpRegionSync grouphere NONE "^\s*?>\s*$"
+"  syn sync match phpRegionSync grouphere NONE "^\s*%>\s*$"
+"  syn sync match phpRegionSync grouphere phpRegion "function\s.*(.*\$"
+"  "syn sync match phpRegionSync grouphere NONE "/\i*>\s*$"
+
+" Sync backwards a certain number of lines?
+"elseif s:sync > 0
+"  exec "syn sync minlines=" . s:sync
+
+else
+  syn sync fromstart
+endif
+
+" Define the default highlighting.
+" For version 5.7 and earlier: only when not done already
+" For version 5.8 and later: only when an item doesn't have highlighting yet
+if version >= 508 || !exists("did_php_syn_inits")
+  if version < 508
+    let did_php_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    "command -nargs=+ HiLink hi def link <args>
+    command -nargs=+ HiLink hi link <args>
+  endif
+
+  " Peter Hodge, June 17 2006
+  " - I'm optimizing these highlight links for the default
+  "   colorscheme, or 'elflord' when it would make a major
+  "   difference.
+  "   After most HiLinks I have noted which color the group
+  "   will revert back to under default or elflord.
+
+  " TODO: remove this testing
+  let s:is_elflord = (exists('g:colors_name') && g:colors_name == 'elflord')
+
+  if exists("php_oldStyle")
+    hi phpOperator guifg=SeaGreen ctermfg=DarkGreen
+    hi phpIdentifier guifg=DarkGray ctermfg=Brown
+"   hi phpIdentifierSimply guifg=DarkGray ctermfg=Brown
+    hi phpVarSelector guifg=SeaGreen ctermfg=DarkGreen
+
+    hi phpRelation guifg=SeaGreen ctermfg=DarkGreen
+
+    hi phpSuperglobal guifg=Red ctermfg=DarkRed
+  else
+    HiLink phpOperator          Operator    " => Statement(Yellow) / Operator(Red)
+    HiLink phpIdentifier        Identifier  " => Identifier(Cyan)
+    HiLink phpIdentifierErratic        phpIdentifier
+
+    HiLink phpVarSelector       Operator
+    HiLink phpVarSelectorDeref  PreProc
+    HiLink phpVarSelectorError  Error
+
+    HiLink phpType              Type
+
+    " list() / arrays
+    HiLink phpList              phpType
+    HiLink phpArray             phpType
+    if s:alt_arrays
+      HiLink phpArrayParens phpArray
+      HiLink phpArrayPair phpArray
+
+      if s:alt_arrays == 2
+        HiLink phpArrayComma phpArrayParens
+      endif
+    else
+      HiLink phpArrayParens phpParent
+      HiLink phpArrayPair phpOperator
+    endif
+    HiLink phpListComma phpArrayComma
+    HiLink phpArrayPairError Error
+
+    if s:alt_comparisons
+      if s:is_elflord
+        HiLink phpRelation     Statement " => Yellow
+      else
+        HiLink phpRelation     Constant  " => Constant (SlateBlue)
+      endif
+    else
+      HiLink phpRelation     phpOperator
+    endif
+
+    " special variables support:
+    if s:special_vars
+      " NOTE: this is better highlighted using the 'Operator' colour ...
+      HiLink phpSuperglobal Operator         " => Special (orange/red)
+    else
+      HiLink phpSuperglobal phpIdentifier
+    endif
+  endif
+
+  " support for other variables
+  HiLink phpBuiltinVar phpSuperglobal
+  HiLink phpLongVar    phpSuperglobal
+  HiLink phpEnvVar     phpSuperglobal
+
+  " language:
+  HiLink phpComment       Comment       " Slateblue
+
+  HiLink phpSemicolon      Macro        " => PreProc (LightMagenta)
+  HiLink phpSemicolonNotAllowedHere Error
+
+  HiLink phpDefine         Define       " => PreProc (LightMagenta)
+  HiLink phpObjectOperator phpDefine
+  HiLink phpInclude        Include      " => PreProc (LightMagenta)
+
+  HiLink phpEcho           Macro        " => PreProc (LightMagenta)
+  HiLink phpPrint          phpEcho
+
+  HiLink phpParent        Delimiter     " => Special (Red)
+  if s:alt_control_parents
+    HiLink phpControlParent phpConditional
+  else
+    HiLink phpControlParent phpParent
+  endif
+  HiLink phpBrace         phpParent     " => Special (Red)
+  HiLink phpBraceError    Error         " => Error
+
+  if s:alt_blocks
+    HiLink phpBraceFunc      phpDefine
+    HiLink phpBraceClass     phpStructure
+    HiLink phpBraceException phpException
+  else
+    HiLink phpBraceFunc      phpBrace
+    HiLink phpBraceClass     phpBrace
+    HiLink phpBraceException phpBrace
+  endif
+
+  " other operations
+  HiLink phpSupressErrors     PreProc   " LightMagenta
+
+  if s:alt_refs
+    HiLink phpAssignByRef     Type      " Green
+  else
+    HiLink phpAssignByRef     Operator  " Red
+  endif
+
+  HiLink phpMemberSelector    Structure " => Type (Green)
+  if s:alt_properties
+    HiLink phpPropertySelector  Function  " => Identifier (Cyan) / (White)
+    HiLink phpDynamicSelector   Operator  " => Operator (Red) / (White)
+  else
+    HiLink phpPropertySelector  phpMemberSelector
+    HiLink phpDynamicSelector   phpMemberSelector
+  endif
+
+
+  " execution control structures
+  HiLink phpConditional   Conditional   " => Statement (Yellow) / Repeat (White)
+  HiLink phpRepeat        Repeat        " => Statement (Yellow) / Repeat (White)
+  HiLink phpStatement     Statement     " (Yellow / Brown)
+  HiLink phpCase          Label         " => Statement (Yellow / Brown)
+  HiLink phpException     Exception     " => Statement (Yellow)
+
+  " constants
+  HiLink phpMagicConstant Constant      " Pink / Magenta
+  HiLink phpCoreConstant  Constant      " Pink / Magenta
+  HiLink phpNumber        Number        " => Constant (Pink)
+  HiLink phpFloat         Float         " => Constant (Pink)
+  HiLink phpBoolean       phpType
+  HiLink phpNull          phpType
+
+  HiLink phpStringSingle         String
+  HiLink phpStringDouble         phpStringSingle
+  HiLink phpStringDoubleConstant phpStringSingle
+  HiLink phpBacktick             phpStringSingle
+
+  HiLink phpStringLiteral SpecialChar
+
+  HiLink phpSpecialChar   SpecialChar   " => Special (Orange / Red)
+
+  " keywords (mainly class / function definitions)
+  HiLink phpStorageClass  StorageClass  " => Type (Green)
+  HiLink phpSCKeyword     phpStorageClass
+
+  HiLink phpStructure     Structure     " => Type (Green)
+  HiLink phpStructureType phpStructure
+
+  HiLink phpFCKeyword     phpDefine
+  HiLink phpMagicClass    StorageClass
+  if s:alt_comparisons
+    HiLink phpInstanceof  phpRelation
+  else
+    HiLink phpInstanceof  phpMagicClass
+  endif
+
+  if s:show_quotes
+    HiLink phpQuoteSingle   String
+    HiLink phpQuoteDouble   String
+  else
+    HiLink phpQuoteSingle   Normal
+    HiLink phpQuoteDouble   Normal
+  endif
+
+  " always highlight backtick quotes like an operator
+  " (seeing as it executes stuff)
+  HiLink phpQuoteBacktick phpOperator
+
+  " built-in langauge functions / classes
+  HiLink phpFunctions       Function        " => Identifier (Cyan) / Function (White)
+  HiLink phpClasses         phpFunctions
+  HiLink phpMethods         phpFunctions
+  HiLink phpInterfaces      phpCoreConstant
+  HiLink phpSpecialFunction SpecialComment  " => Special (Orange / Red)
+  HiLink phpSpecialMethods  phpSpecialFunction
+
+  " other items
+  HiLink phpMemberError     Error
+  HiLink phpParentError     Error
+  HiLink phpHTMLError       Error
+  HiLink phpOctalError      Error
+  HiLink phpTodo            Todo
+
+  " Peter Hodge June 17, 2006:
+  " changed matchgroup for phpRegion from Delimiter to phpRegionDelimiter
+  HiLink phpRegionDelimiter   Debug               " => Special (Orange / Red)
+
+  " changed matchgroup for phpHereDoc to phpHereDocDelimiter
+  HiLink phpHereDocDelimiter  phpRegionDelimiter  " => Special (Orange / Red)
+
+  delcommand HiLink
+endif
+
+" optional support for PCRE extension (preg_* functions)
+if s:show_pcre
+    " ===================================================
+    " Note: I have deliberately neglected to support the '\cx' functionality
+    "       - it would do more harm than good by complicating this already-
+    "       mind-numbing syntax file when nobody really needs this feature in
+    "       PHP.
+    " TODO: add support for '\cx' sequences (I changed my mind)
+
+    " 1) Allow for dropping out of SQ and concatenating a variable {{{
+
+      " flag a lone quote as an error!
+      syn match pregError /'/ display contained containedin=pregPattern_S
+      syn match pregError /"/ display contained containedin=pregPattern_D
+
+      " find real concatenations (overrides the errors)
+      syn region pregConcat matchgroup=phpQuoteSingle start=#'\ze\%(\%(\_s*\|\/\*.\{-}\*\/\|\/\/.*\n\)*\)\@>\.# end=/'/
+        \ skip=/\['.\{-}'\]\|('.\{-}'[,)]/
+        \ keepend extend
+        \ contained containedin=pregPattern_S
+        \ contains=@phpClExpressions
+      syn region pregConcat matchgroup=phpQuoteDouble start=/"/ end=/"/
+        \ skip=/\[".\{-}"\]\|(".\{-}"[,)]/
+        \ keepend extend
+        \ contained containedin=pregPattern_D
+        \ contains=@phpClExpressions
+    " }}}
+
+    " 2) look for special characters {{{
+
+      " TODO: re-examine how \$ is going to fit into a double-quoted string ...
+      syn match pregSpecial /\$/ contained containedin=pregPattern_S display
+      syn match pregSpecial /\$/ contained containedin=pregPattern_D display
+        \ contains=phpIdentifierInString,phpIdentifierInStringComplex
+      syn match pregSpecial /\^/ contained containedin=@pregPattern_Q display
+      syn match pregSpecial /|/  contained containedin=@pregPattern_Q display
+      syn match pregDot     /\./ contained containedin=@pregPattern_Q display
+
+      " TODO: move these things out of here???
+      " find a ] character at the start of a character range ...
+      syn match pregClassIncStartBracket /\]/ contained display containedin=@pregClassIncStart_Q
+      syn match pregClassExcStartBracket /\]/ contained display containedin=@pregClassExcStart_Q
+      hi link pregClassIncStartBracket pregClassInc
+      hi link pregClassExcStartBracket pregClassExc
+    " }}}
+
+    " 3) look for escape sequences {{{
+
+      " look for any escape sequence inside the pattern and mark them as errors
+      " by default, all escape sequences are errors
+      " NOTE: adding 'display' to this next one can break the highlighting
+      " (because it contains sequences such as \" which aren't supposed to end
+      " the string)
+      syn match pregEscapeUnknown /\\./ contained containedin=@pregPattern_Q
+
+      " TODO: when \$ is encountered, the \ is a PHP escape and prevents
+      " variable expansion, but the '$' becomes the end-of-line wildcard.
+      " \\$ will match a literal '$', but the '$' might be part of a variable
+      " name also. \\\$ is the proper way to match
+
+      " TODO: deprecate these clusters?
+      " TODO: deprecate pregClass_any
+      syn cluster pregClass_any add=@pregClassInc,pregClassExc
+      syn cluster pregClassRange_any_S add=pregClassIncRange_S,pregClassExcRange_S
+      syn cluster pregClassRange_any_D add=pregClassIncRange_D,pregClassExcRange_D
+
+      syn match pregClassEscapeUnknown /\\[^\^\-\]]/ contained containedin=@pregClass_any_Q display
+      syn match pregClassEscape /\\[^a-zA-Z0-9]/ contained containedin=@pregClass_any_Q display extend
+
+      " known escape sequences:
+      syn match pregClassIncEscapeKnown /\C\\[abtnfret]/ contained display
+            \ containedin=@pregClassInc_Q,@pregClassIncRange_Q
+      syn match pregClassIncEscapeRange /\\[dsw]/ contained display
+            \ containedin=@pregClassInc_Q,@pregClassIncRange_Q
+      syn match pregClassExcEscapeKnown /\C\\[abtnfret]/ contained display
+            \ containedin=@pregClassExc_Q,@pregClassExcRange_Q
+      syn match pregClassExcEscapeRange /\\[dsw]/ contained display
+            \ containedin=@pregClassExc_Q,@pregClassExcRange_Q
+
+      " ... including hex sequences
+      syn match pregClassIncEscapeKnown /\C\\x\x\{0,2}/ contained display
+        \ containedin=@pregClassInc_Q,@pregClassIncRange_Q
+      syn match pregClassExcEscapeKnown /\C\\x\x\{0,2}/ contained display
+        \ containedin=@pregClassExc_Q,@pregClassExcRange_Q
+
+      " ... and octal sequences
+      syn match pregClassIncEscapeKnown /\\\o\{1,3}/ contained display
+        \ containedin=@pregClassInc_Q,@pregClassIncRange_Q
+      syn match pregClassExcEscapeKnown /\\\o\{1,3}/ contained display
+        \ containedin=@pregClassExc_Q,@pregClassExcRange_Q
+
+      syn match pregClassEscapeMainQuote /\\'/ contained transparent display contains=pregEscapePHP 
+        \ containedin=@pregClass_any_S,@pregClassRange_any_S
+      syn match pregClassEscapeMainQuote /\\"/ contained transparent display contains=pregEscapePHP 
+        \ containedin=@pregClass_any_D,@pregClassRange_any_D
+
+      syn match pregClassEscape /\\\\\ze\\'/ contained display
+        \ containedin=@pregClass_any_S contains=pregEscapePHP
+        \ nextgroup=pregClassEscapeMainQuote
+      syn match pregClassEscape /\\\\\ze\\"/ contained display
+        \ containedin=@pregClass_any_D contains=pregEscapePHP
+        \ nextgroup=pregClassEscapeMainQuote
+
+      syn match pregClassEscapeDouble1 /\\\\\ze\\\\/ contained containedin=@pregClass_any_Q display
+        \ contains=pregEscapePHP
+        \ nextgroup=pregClassEscapeDouble2
+      syn match pregClassEscapeDouble2 /\\\\/ contained transparent display
+        \ containedin=@pregClassRange_any_S,@pregClassRange_any_D
+        \ contains=pregEscapePHP
+      hi link pregClassEscapeDouble1 pregClassEscape
+
+      " in the unknown escapes, match those that make a special character
+      " take on its literal meaning (except for <single-quote> which is covered next)
+      " NOTE: am changing these from being contained inside pregEscapeUnknown
+      " to being in the main scope to make SQ and DQ containment easier
+      syn match pregEscapeLiteral /\\[^A-Za-z0-9]/ contained containedin=@pregPattern_Q display
+      syn match pregEscapeLiteral /\\\{4}/ contained containedin=@pregPattern_Q display
+
+      " for single-quoted strings
+      syn match pregEscapeLiteral /\\"/ contained containedin=pregPattern_S display
+      syn match pregEscapeLiteral /\\\\\\'/ contained containedin=pregPattern_S display contains=pregEscapePHP
+
+      " for double-quoted strings
+      syn match pregEscapeLiteral /\\'/ contained containedin=pregPattern_D display
+      syn match pregEscapeLiteral /\\\\\\"/ contained containedin=pregPattern_D display contains=pregEscapePHP
+
+      syn match pregEscapeMainQuote /\\'/ contained containedin=pregPattern_S display
+      syn match pregEscapeMainQuote /\\"/ contained containedin=pregPattern_D display
+
+      " match the escaped strings which are known
+      syn match pregBackreference /\\[1-9][0-9]\=/ contained containedin=pregEscapeUnknown display
+      syn match pregEscapeSpecial /\C\\[rnt]/ contained containedin=pregEscapeUnknown display
+      syn match pregEscapeSpecial /\C\\x\x\{0,2}/ contained containedin=pregEscapeUnknown display
+      syn match pregEscapeSpecial /\\\%(0\o\{0,2}\|\o\o\o\)/ contained containedin=pregEscapeUnknown display
+      syn match pregEscapeRange   /\\[wsd]/ contained containedin=pregEscapeUnknown display
+      syn match pregEscapeAnchor  /\C\\[AbBGzZ]/ contained containedin=pregEscapeUnknown display
+
+      " unicode characters
+      syn match pregEscapeUnicode /\C\\X/ contained containedin=pregEscapeUnknown display
+      syn match pregEscapeUnicodeError /\c\\p{\^\=\w\+}/ contained display
+            \ containedin=pregEscapeUnknown,pregClassEscapeUnknown
+      syn match pregEscapeUnicode /\\p{^\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CC[cfnos]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CL[lmotu]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CM[cen]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CN[dlo]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CP[cdefios]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CS[ckmo]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /\CZ[lps]\=/ contained containedin=pregEscapeUnicodeError display
+      syn match pregEscapeUnicode /}/ contained containedin=pregEscapeUnicodeError display
+      " shorthand
+      syn match pregEscapeUnicode /\C\\[pP][CLMNPSZ]/ contained display
+            \ containedin=pregEscapeUnknown,pregClassEscapeUnknown
+
+      " match the PHP escaping in literal escapes
+      syn match pregEscapePHP /\\./he=s+1 contained display containedin=pregEscapeMainQuote
+      syn match pregEscapePHP /\\\\/he=s+1 contained display containedin=pregEscapeLiteral
+
+      " this captures confusing usage of escape characters:
+      " - need to make sure they don't capture the quote character because
+      "   that wouldn't right
+      syn match pregEscapeNotNeeded /\\\ze\\[^\\']/ contained display containedin=pregPattern_S,@pregClass_any_S
+      syn match pregEscapeNotNeeded /\\\ze\\[^\\"]/ contained display containedin=pregPattern_D,@pregClass_any_D
+
+      " a triple-backslash can be dangerous: it is not obvious that
+      " the meaning of the 3rd backslash is dependent on the following
+      " character; if the following character is changed to a
+      " single-quote or backslash, it will change the meaning of the 3
+      " backslashes
+      syn match pregEscapeLiteral /\\\{3}\ze[^\\']/ contained display containedin=pregPattern_S
+      syn match pregEscapeLiteral /\\\{3}\ze[^\\"]/ contained display containedin=pregPattern_D
+      syn match pregClassEscape /\\\{3}\ze[^\\']/ contained display contains=pregClassEscapePHP containedin=@pregClass_any_S
+      syn match pregClassEscape /\\\{3}\ze[^\\"]/ contained display contains=pregClassEscapePHP containedin=@pregClass_any_D
+      syn match pregClassEscapePHP /\\\\/he=s+1 contained
+      hi link pregClassEscapePHP  pregEscapePHP
+    " }}}
+
+    " 4) Look for quantifiers ?*+{1,2} {{{
+
+      syn match pregQuantifier /\*?\=/ contained containedin=@pregPattern_Q display
+      syn match pregQuantifier /+?\=/  contained containedin=@pregPattern_Q display
+      syn match pregQuantifier /??\=/  contained containedin=@pregPattern_Q display
+
+      syn match pregQuantifierComplex /{\d\+\(,\d*\)\=}/ contained containedin=@pregPattern_Q display
+      syn match pregQuantifierComplex /{,\d\+}/ contained containedin=@pregPattern_Q display
+      syn match pregQuantifier /\d\+/ contained containedin=pregQuantifierComplex display
+    " }}}
+
+    " 5) Look for sub-patterns {{{
+      syn match pregParens /(/ contained containedin=@pregPattern_Q display
+      syn match pregParens /(?<[=!]/ contained containedin=@pregPattern_Q display extend
+      syn match pregParens /(?[:>=!]/ contained containedin=@pregPattern_Q display extend
+      syn match pregParens /(?(?<\=[=!]/ contained containedin=@pregPattern_Q display extend
+
+      " recursion
+      syn match pregParens /(?R)/ contained containedin=@pregPattern_Q display extend
+      syn match pregParens /(?[1-9]\d\=)/ contained containedin=@pregPattern_Q display extend
+            \ contains=pregBackreferenceNumber
+
+      " conditional sub-patterns
+      syn match pregParens /(?(\d\+)/ contained containedin=@pregPattern_Q display
+            \ contains=pregBackreferenceNumber
+      syn match pregBackreferenceNumber /\d\+/ contained display
+      " TODO: move hi link out of here?
+      hi link pregBackreferenceNumber pregBackreference
+      syn match pregParens /(?\a\+\(-\a\+\)\=[):]/ contained containedin=@pregPattern_Q display
+        \ contains=pregOption
+      syn match pregParens /(?-\a\+[):]/ contained containedin=@pregPattern_Q display
+        \ contains=pregOption
+      syn match pregParens /)/ contained containedin=@pregPattern_Q display
+
+      " find a named backreference
+      syn match pregBackreference contained containedin=@pregPattern_Q /(?P>\w\+)/ display
+            \ contains=pregNamedBackreference
+      syn match pregParens contained containedin=@pregPattern_Q /(?P<\w\+>/ display
+            \ contains=pregNamedBackreference
+
+      syn match pregNamedBackreference /(?P>\zs\w\+\ze)/ contained display
+      syn match pregNamedBackreference /(?P<\zs\w\+\ze>/ contained display
+      hi link pregNamedBackreference pregEscapeRange
+    " }}}
+
+    " 6) Look for PCRE patterns {{{
+      syn cluster phpClFunctions add=phpPREGFunctions
+
+      " look for preg_* functions which take a single pattern
+      syn keyword phpPREGFunctions contained preg_match preg_match_all preg_split preg_grep
+            \ nextgroup=phpPREGOpenParent,phpPREGRegion
+
+      " special case for preg_replace functions which can take an array of
+      " patterns
+      syn keyword phpPREGFunctions contained preg_replace preg_replace_callback
+            \ nextgroup=phpPREGOpenParentMulti,phpPREGRegionMulti skipwhite skipempty
+
+      if s:strict_blocks
+        " regions for ( ) after name of preg_* function
+        syn region phpPREGRegion matchgroup=phpParent start=/(/ end=/)/ keepend extend
+              \ contained contains=@phpClExpressions,phpPREGStringStarter
+        syn region phpPREGRegionMulti matchgroup=phpParent start=/(/ end=/)/ keepend extend
+              \ contained contains=@phpClExpressions,phpPREGStringStarter,phpPREGArray
+
+        " match an array of preg patterns
+        if s:alt_arrays
+          syn region phpPREGArray matchgroup=phpArrayParens start=/\%((\_s*\)\@<=array\_s*(/ end=/)/
+                \ keepend extend
+                \ contained
+                \ contains=@phpClExpressions,phpPREGStringStarter,phpPREGArrayComma,phpPREGArrayComment
+        else
+          syn match phpPREGArray /\%((\_s*\)\@<=array/ contained
+                \ nextgroup=phpPREGArrayRegion skipwhite skipempty
+          
+          syn region phpPREGArrayRegion matchgroup=phpParent start=/(/ end=/)/
+                \ keepend extend
+                \ contained
+                \ contains=phpPREGStringStarter,phpPREGArrayComment,phpPREGArrayComma
+        endif
+        hi link phpPREGArray phpArray
+
+        " a special match to open a pattern string immediately after a '('
+        " TODO: will this work as a match instead?
+"        syn region phpPREGStringStarter start=/\%((\_s*\)\@<=\z(['"]\)/ end=/\z1/ extend 
+"              \ contained contains=@phpPREGString_any
+        syn match phpPREGStringStarter /\%((\_s*\)\@<=['"]/ extend 
+              \ contained contains=@phpPREGString_any
+
+        " TODO: move 'hi link' commands out of here
+        hi link phpPREGArrayComma phpArrayComma
+      else
+        " highlight the opening parenthesis
+        syn match phpPREGOpenParent /(/ contained nextgroup=@phpPREGString_any display
+        hi link phpPREGOpenParent phpParent
+        syn match phpPREGOpenParentMulti /(/ contained display
+              \ nextgroup=@phpPREGString_any,phpPREGArray skipwhite skipnl skipempty
+        hi link phpPREGOpenParentMulti phpPREGOpenParent
+
+        " TODO: move 'hi link' commands out of here
+        " match an array of preg patterns
+        syn keyword phpPREGArray array contained nextgroup=phpPREGArrayOpenParent
+        hi link phpPREGArray phpType
+        syn match phpPREGArrayOpenParent /(/ contained display
+          \ nextgroup=@phpPREGArrayString_any skipwhite skipnl skipempty
+        hi link phpPREGArrayOpenParent phpPREGOpenParent
+      endif
+
+      " match a phpString (single or double-quoted) which is able to contain a
+      " pregPattern
+      " NOTE: we can only error on comma-ending as long as the delimiter is
+      " not a comma!!!
+      syn cluster phpPREGString_any add=phpPREGStringSingle,phpPREGStringDouble
+      syn region phpPREGStringSingle matchgroup=phpQuoteSingle start=/'\ze\z(.\)/ end=/'/
+        \ keepend extend contained contains=pregPattern_S
+        \ matchgroup=Error end=/\z1\@!,/
+      syn region phpPREGStringDouble matchgroup=phpQuoteSingle start=/"\ze\z(.\)/ end=/"/
+        \ keepend extend contained contains=pregPattern_D
+        \ matchgroup=Error end=/\z1\@!,/
+
+      " match a single-quoted string inside an array, followed by a comma
+      " and another string
+      " TODO: remove hi link commands from here
+      syn cluster phpPREGArrayString_any add=phpPREGArrayStringSingle,phpPREGArrayStringDouble
+      syn region phpPREGArrayStringSingle matchgroup=phpQuoteSingle start=/'/ end=/'/
+        \ keepend extend contained contains=pregPattern_S
+        \ nextgroup=phpPREGArrayComma skipwhite skipnl skipempty
+      hi link phpPREGArrayStringSingle phpPREGStringSingle
+      syn region phpPREGArrayStringDouble matchgroup=phpQuoteDouble start=/"/ end=/"/
+        \ keepend extend contained contains=pregPattern_D
+        \ nextgroup=phpPREGArrayComma skipwhite skipnl skipempty
+      hi link phpPREGArrayStringDouble phpPREGStringDouble
+
+      " use the comma inside a pattern array to trigger off the next pattern
+      syn match phpPREGArrayComma /,/ contained
+            \ nextgroup=@phpPREGArrayString_any skipwhite skipnl skipempty
+
+      " use the comments inside a pattern array to trigger off the next pattern
+      syn region phpPREGArrayComment start=#//# end=#$# contained keepend extend contains=@Spell
+            \ nextgroup=@phpPREGArrayString_any skipwhite skipnl skipempty
+      syn region phpPREGArrayComment start=#/\*# end=#\*/# contained keepend extend contains=@Spell
+            \ nextgroup=@phpPREGArrayString_any skipwhite skipnl skipempty
+      hi link phpPREGArrayComment phpComment
+    " }}}
+
+    " 7) Look for pattern delimiters {{{
+      syn cluster pregPattern_Q add=pregPattern_S,pregPattern_D
+
+      " add a region which starts with any valid delimiter character
+      " and ends when the delimiter character is met again
+      syn region pregPattern_S matchgroup=pregDelimiter
+        \ start=/\z([ !"#$%&*+,-./:;=?@^_`|~]\)/ start=/\z(\\'\)/
+        \ end=/\z1/ skip=/\\\\\{2,3}\|\\\\\z1\=\|\\\z1/ keepend extend
+        \ contained nextgroup=pregOptionError_S
+        \ contains=pregCommentMultiline
+      " repeat above command, but this time instead of the multi-line comment,
+      " make it 'oneline'
+      syn region pregPattern_S matchgroup=pregDelimiter
+        \ start=/\z([ !"#$%&*+,-./:;=?@^_`|~]\)/ start=/\z(\\'\)/
+        \ end=/\z1/ skip=/\\\\\{2,3}\|\\\\\z1\=\|\\\z1/ keepend extend
+        \ contained nextgroup=pregOptionError_S
+        \ oneline
+
+      function! s:pregPattern_S(open, close)
+        execute 'syntax region pregPattern_S matchgroup=pregDelimiter'
+              \ 'start=/' . a:open . '/'
+              \ 'end=/' . a:close . '/'
+              \ 'skip=/\\\{4}\|\\\\\=./ keepend extend'
+              \ 'contained nextgroup=pregOptionError_S'
+      endfunction
+      function! s:pregPattern_D(open, close)
+        execute 'syntax region pregPattern_D matchgroup=pregDelimiter'
+              \ 'start=/' . a:open . '/'
+              \ 'end=/' . a:close . '/'
+              \ 'skip=/\\\{4}\|\\\\\=./ keepend extend'
+              \ 'contained nextgroup=pregOptionError_D'
+      endfunction
+      call s:pregPattern_S('(', ')')
+      call s:pregPattern_S('<', '>')
+      call s:pregPattern_S('\[', '\]')
+      call s:pregPattern_S('{', '}')
+      call s:pregPattern_D('(', ')')
+      call s:pregPattern_D('<', '>')
+      call s:pregPattern_D('\[', '\]')
+      call s:pregPattern_D('{', '}')
+
+      " TODO: make a cluster for the things which go inside double-quoted
+      " strings!
+      syn region pregPattern_D matchgroup=pregDelimiter
+        \ start=/\z([ !'#$%&*+,-./:;=?@^_`|~]\)/ start=/\z(\\"\)/
+        \ end=/\z1/ skip=/\\\\\{2,3}\|\\\\\z1\=\|\\\z1/
+        \ keepend extend
+        \ contained nextgroup=pregOptionError_D
+        \ contains=phpIdentifierInString,phpIdentifierInStringComplex,pregCommentMultiline
+      " repeat above command, but this time instead of the multi-line comment,
+      " make it 'oneline'
+      syn region pregPattern_D matchgroup=pregDelimiter
+        \ start=/\z([ !'#$%&*+,-./:;=?@^_`|~]\)/ start=/\z(\\"\)/
+        \ end=/\z1/ skip=/\\\\\{2,3}\|\\\\\z1\=\|\\\z1/
+        \ keepend extend
+        \ contained nextgroup=pregOptionError_D
+        \ contains=phpIdentifierInString,phpIdentifierInStringComplex
+        \ oneline
+
+      " TODO: work out how to have '$' as delimiter in a double-quoted string
+"      syn region pregPattern_D matchgroup=pregDelimiter
+"        \ start=/\\\$\|\$[a-z_]\@!\%({[a-z_$]\)\@!/
+"        \ end=/\\\$\|\$[a-z_]\@!\%({[a-z_$]\)\@!/ skip=/\\\{4}\|\\\{3}[^$]\|\\\\\$/
+"        \ keepend extend
+"        \ contained nextgroup=pregOptionError_D
+"        \ contains=phpIdentifierInString,phpIdentifierInStringComplex
+
+      " TODO move hi link out of here
+      hi link pregPattern_S pregPattern
+      hi link pregPattern_D pregPattern
+    " }}}
+
+    " 8) Look for character classes {{{
+      " Inc[lusive] and Exc[lusive] character classes:
+      "  if the first char is ']'
+      " that is tricky so is handled by another match below
+      syn cluster pregClassInc_Q add=pregClassInc_S,pregClassInc_D
+      syn cluster pregClassExc_Q add=pregClassExc_S,pregClassExc_D
+      syn cluster pregClass_any_S add=pregClassInc_S,pregClassExc_S
+      syn cluster pregClass_any_D add=pregClassInc_D,pregClassExc_D
+      syn cluster pregClass_any_Q add=@pregClassInc_Q,@pregClassExc_Q
+
+      " TODO: does that 'skip' need to be copied to the line below?
+      syn region pregClassInc_S matchgroup=pregClassParent start=/\[\ze[^\^\]]/ end=/\]/ skip=/\\\%(\\\\\]\)\@!\&\\./
+            \ keepend display contained containedin=pregPattern_S
+      syn region pregClassInc_D matchgroup=pregClassParent start=/\[\ze[^\^\]]/ end=/\]/ skip=/\\./
+            \ keepend display contained containedin=pregPattern_D
+      " TODO: move these out of here???
+      hi link pregClassInc_S pregClassInc
+      hi link pregClassInc_D pregClassInc
+      hi link pregClassExc_S pregClassExc
+      hi link pregClassExc_D pregClassExc
+
+      syn region pregClassExc_S matchgroup=pregClassParent start=/\[\^\]\@!/ end=/\]/ skip=/\\./
+        \ keepend display contained containedin=pregPattern_S
+      syn region pregClassExc_D matchgroup=pregClassParent start=/\[\^\]\@!/ end=/\]/ skip=/\\./
+        \ keepend display contained containedin=pregPattern_D
+
+      " TODO: move hi link commands out of here
+
+      " TODO: just use one match for all character classes???
+      " this is an alternate form of the character class region,
+      " it is not contained in @pregPattern_Q and can only be activated
+      " by a nextgroup=pregClassInc.
+      " 'EXECUTE'ed:
+      "syntax region pregClassInc_S start=/\ze./ matchgroup=pregClassParent end=/\]/ skip=/\\\\\|\\]/ contained display
+      "syntax region pregClassInc_D start=/\ze./ matchgroup=pregClassParent end=/\]/ skip=/\\\\\|\\]/ contained display
+      "syntax region pregClassExc_S start=/\ze./ matchgroup=pregClassParent end=/\]/ skip=/\\\\\|\\]/ contained display
+      "syntax region pregClassExc_D start=/\ze./ matchgroup=pregClassParent end=/\]/ skip=/\\\\\|\\]/ contained display
+      let s:command = 'syntax region pregClass<TYPE> start=/\ze./ matchgroup=pregClassParent end=/\]/'
+        \ . ' skip=/\\\\\|\\]/ contained display keepend'
+      execute substitute(s:command, '<TYPE>', 'Inc_S', 'g')
+      execute substitute(s:command, '<TYPE>', 'Inc_D', 'g')
+      execute substitute(s:command, '<TYPE>', 'Exc_S', 'g')
+      execute substitute(s:command, '<TYPE>', 'Exc_D', 'g')
+      unlet! s:command
+
+      " this is a special match to start off the character class
+      " region when the very first character inside it is ']',
+      " because otherwise the character class region would end
+      " immediately
+      syn cluster pregClassIncStart_Q add=pregClassIncStart_S,pregClassIncStart_D
+      syn cluster pregClassExcStart_Q add=pregClassExcStart_S,pregClassExcStart_D
+      let s:command = 'syntax match pregClassIncStart_<QUOTE> /\[\]/ contained display'
+        \ . ' containedin=pregPattern_<QUOTE> nextgroup=pregClassInc_<QUOTE>,pregClassIncEnd'
+      execute substitute(s:command, '<QUOTE>', 'S', 'g')
+      execute substitute(s:command, '<QUOTE>', 'D', 'g')
+      let s:command = 'syntax match pregClassExcStart_<QUOTE> /\[\^\]/ contained display'
+        \ . ' containedin=pregPattern_<QUOTE> nextgroup=pregClassExc_<QUOTE>,pregClassExcEnd'
+      execute substitute(s:command, '<QUOTE>', 'S', 'g')
+      execute substitute(s:command, '<QUOTE>', 'D', 'g')
+      unlet! s:command
+
+      " TODO: move hi link commands out of here
+      hi link pregClassIncStart_S pregClassParent
+      hi link pregClassIncStart_D pregClassParent
+      hi link pregClassExcStart_S pregClassParent
+      hi link pregClassExcStart_D pregClassParent
+
+      " this is a special match to end off the character class immediately
+      " should a ']' be followed immediately by another ']'
+      " TODO: move hi link commands out of here
+      syn match pregClassIncEnd /\]/ contained display
+      hi link pregClassIncEnd pregClassParent
+      syn match pregClassExcEnd /\]/ contained display
+      hi link pregClassExcEnd pregClassParent
+
+      " add the range-matching string here
+      syn cluster pregClassIncRange_Q add=pregClassIncRange_S,pregClassIncRange_D
+      syn cluster pregClassExcRange_Q add=pregClassExcRange_S,pregClassExcRange_D
+      syn match pregClassIncRange_S contained display
+        \ containedin=pregClassInc_S,pregClassIncStart_S
+        \ /\%([^\\]\|\\\%(\\\{2}[\\']\=\|x\x\{0,2}\|\o\{1,3}\|[^dsw]\)\)-\%(\\\{3,4}\|\\[^dsw]\|[^\\\]]\)/
+      syn match pregClassIncRange_D contained display
+        \ containedin=pregClassInc_D,pregClassIncStart_D
+        \ /\%([^\\]\|\\\%(\\\{2}[\\"]\=\|x\x\{0,2}\|\o\{1,3}\|[^dsw]\)\)-\%(\\\{3,4}\|\\[^dsw]\|[^\\\]]\)/
+      syn match pregClassExcRange_S contained display
+        \ containedin=pregClassExc_S,pregClassExcStart_S
+        \ /\%([^\\]\|\\\%(\\\{2}[\\']\=\|x\x\{0,2}\|\o\{1,3}\|[^dsw]\)\)-\%(\\\{3,4}\|\\[^dsw]\|[^\\\]]\)/
+      syn match pregClassExcRange_D contained display
+        \ containedin=pregClassExc_D,pregClassExcStart_D
+        \ /\%([^\\]\|\\\%(\\\{2}[\\']\=\|x\x\{0,2}\|\o\{1,3}\|[^dsw]\)\)-\%(\\\{3,4}\|\\[^dsw]\|[^\\\]]\)/
+      hi link pregClassIncRange_S pregClassIncRange
+      hi link pregClassIncRange_D pregClassIncRange
+      hi link pregClassExcRange_S pregClassExcRange
+      hi link pregClassExcRange_D pregClassExcRange
+
+      " what about the pre-defined sets using [:space:]?
+      syn region pregClassSetRegion matchgroup=pregClassSet start=/\[:/ end=/:\]/
+            \ extend keepend
+            \ contained containedin=@pregClass_any_Q contains=pregClassSet
+      hi link pregClassSetRegion Error
+      syn keyword pregClassSet contained
+            \ alnum digit punct
+            \ alpha graph space
+            \ blank lower upper
+            \ cntrl print xdigit
+      hi link pregClassSet pregEscapeRange
+
+      " highlighted a lone single/double quote as an error
+      syn match pregClassQuoteError contained display /'/ containedin=@pregClass_any_S
+      syn match pregClassQuoteError contained display /"/ containedin=@pregClass_any_D
+      hi link pregClassQuoteError Error
+
+    " }}}
+      
+    " 9) Look for escaping using \Q and \E {{{
+      syn region pregNonSpecial_S matchgroup=pregParens start=/\C\\Q/ end=/\C\\E/
+            \ contained containedin=pregPattern_S
+      syn region pregNonSpecial_D matchgroup=pregParens start=/\C\\Q/ end=/\C\\E/
+            \ contained containedin=pregPattern_D
+      hi link pregNonSpecial_S pregNonSpecial
+      hi link pregNonSpecial_D pregNonSpecial
+      hi link pregNonSpecial pregPattern
+
+         " I'm just going to rebuild escapes here to make it easier
+         syn match pregError /'/ contained containedin=pregNonSpecial_S display
+         syn match pregError /"/ contained containedin=pregNonSpecial_D display
+         syn match pregNonSpecialEscape /\\['\\]/ contained containedin=pregNonSpecial_S display
+         syn match pregNonSpecialEscape /\\["\\$]/ contained containedin=pregNonSpecial_D display
+         syn match pregNonSpecialEscapePHP /\\./he=s+1 contained containedin=pregNonSpecialEscape display
+         syn match pregNonSpecialEscapePHP /\\[rnt]/ contained containedin=pregNonSpecial_D display
+      hi link pregNonSpecialEscapePHP pregEscapePHP
+    " }}}
+
+    " 10) Match PCRE pattern options {{{
+      syn match pregOptionError_S /\%(\\[\\']\|[^']\)\+/ contained contains=pregOption display
+      syn match pregOptionError_D /\%(\\[\\"]\|[^"]\)\+/ contained display
+            \ contains=pregOption,phpIdentifierInString,phpIdentifierInStringComplex
+      syn match pregOption /\C[eimsuxADSUX]\+/ contained display
+      " TODO: move hi links out of here?
+      hi link pregOptionError_S pregOptionError
+      hi link pregOptionError_D pregOptionError
+    " }}}
+
+    " 11) PCRE pattern comments {{{
+      syn match pregComment /\v\(\?\#[^)]*\)/ contained containedin=@pregPattern_Q contains=@Spell
+
+      " TODO: multi-line comments must be turned on explicitly!?
+      " syntax match pregComment /\v\#(.*)@>/ contained containedin=@pregPattern_Q
+"      if exists('b:php_preg_multiline')
+        syntax match pregCommentMultiline /\#\(.*\)\@>/ contained contains=@Spell
+        hi! link pregCommentMultiline pregComment
+"      endif
+    " }}}
+
+    " 12) highlight links {{{
+      command -nargs=+ HiLink hi link <args>
+
+      HiLink phpPREGFunctions phpFunctions
+      HiLink phpPREGOpenParent phpParent
+      HiLink phpPREGStringSingle phpStringSingle
+      HiLink phpPREGStringDouble phpStringDouble
+
+      HiLink pregError Error
+      HiLink pregAmbiguous Todo
+
+      HiLink pregDelimiter Statement
+
+      HiLink pregOptionError Error
+      HiLink pregOption Type
+
+      HiLink pregComment phpComment
+
+      HiLink pregEscapeDelimiter pregDelimiter
+      HiLink pregEscapeUnknown pregAmbiguous
+      HiLink pregEscapeLiteral Comment
+      HiLink pregEscapeSpecial Number
+      HiLink pregEscapeAnchor  Typedef
+      HiLink pregEscapeRange   Identifier
+      HiLink pregEscapePHP        phpSpecialChar
+      HiLink pregEscapeUnicode pregEscapeRange
+      HiLink pregEscapeUnicodeError pregError
+
+      HiLink pregEscapeNotNeeded pregEscapePHP
+
+      HiLink pregPattern       Normal
+      HiLink pregSpecial       Typedef
+      HiLink pregDot        Typedef
+      HiLink pregParens        PreProc
+      HiLink pregBackreference pregParens
+
+      HiLink pregQuantifier        Typedef
+      HiLink pregQuantifierComplex Typedef
+
+      HiLink pregClassParent  pregParens
+      HiLink pregClassInc     pregClassParent
+      HiLink pregClassExc     pregClassParent
+      HiLink pregClassIncRange Identifier
+      HiLink pregClassExcRange Identifier
+      HiLink pregClassEscape   Comment
+      HiLink pregClassIncEscapeKnown pregEscapeSpecial
+      HiLink pregClassIncEscapeRange pregClassIncRange
+      HiLink pregClassExcEscapeKnown Type
+      HiLink pregClassExcEscapeRange pregClassExcRange
+      HiLink pregClassEscapeUnknown pregAmbiguous
+
+      delcommand HiLink
+    " }}}
+endif
+
+" ================================================================
+
+let b:current_syntax = "php"
+
+if main_syntax == 'php'
+  unlet main_syntax
+endif
+
+" vim: sw=2 sts=2 et fdm=marker fdc=1
diff --git a/vim/syntax/privoxy.vim b/vim/syntax/privoxy.vim
new file mode 100644 (file)
index 0000000..9e6ff1d
--- /dev/null
@@ -0,0 +1,71 @@
+" Vim syntax file
+" Language:    Privoxy actions file
+" Maintainer:  Doug Kearns <dougkearns@gmail.com>
+" URL:         http://gus.gscit.monash.edu.au/~djkea2/vim/syntax/privoxy.vim
+" Last Change: 2007 Mar 30
+
+" Privoxy 3.0.6
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+setlocal iskeyword=@,48-57,_,-
+
+syn keyword privoxyTodo                 contained TODO FIXME XXX NOTE
+syn match   privoxyComment "#.*" contains=privoxyTodo,@Spell
+
+syn region privoxyActionLine matchgroup=privoxyActionLineDelimiter start="^\s*\zs{" end="}\ze\s*$"
+       \ contains=privoxyEnabledPrefix,privoxyDisabledPrefix
+
+syn match privoxyEnabledPrefix "\%(^\|\s\|{\)\@<=+\l\@=" nextgroup=privoxyAction,privoxyFilterAction contained
+syn match privoxyDisabledPrefix "\%(^\|\s\|{\)\@<=-\l\@=" nextgroup=privoxyAction,privoxyFilterAction contained
+
+syn match privoxyAction "\%(add-header\|block\|content-type-overwrite\|crunch-client-header\|crunch-if-none-match\)\>" contained
+syn match privoxyAction "\%(crunch-incoming-cookies\|crunch-outgoing-cookies\|crunch-server-header\|deanimate-gifs\)\>" contained
+syn match privoxyAction "\%(downgrade-http-version\|fast-redirects\|filter-client-headers\|filter-server-headers\)\>" contained
+syn match privoxyAction "\%(filter\|force-text-mode\|handle-as-empty-document\|handle-as-image\)\>" contained
+syn match privoxyAction "\%(hide-accept-language\|hide-content-disposition\|hide-forwarded-for-headers\)\>" contained
+syn match privoxyAction "\%(hide-from-header\|hide-if-modified-since\|hide-referrer\|hide-user-agent\|inspect-jpegs\)\>" contained
+syn match privoxyAction "\%(kill-popups\|limit-connect\|overwrite-last-modified\|prevent-compression\|redirect\)\>" contained
+syn match privoxyAction "\%(send-vanilla-wafer\|send-wafer\|session-cookies-only\|set-image-blocker\)\>" contained
+syn match privoxyAction "\%(treat-forbidden-connects-like-blocks\)\>"
+
+syn match privoxyFilterAction "filter{[^}]*}" contained contains=privoxyFilterArg,privoxyActionBraces
+syn match privoxyActionBraces "[{}]" contained
+syn keyword privoxyFilterArg js-annoyances js-events html-annoyances content-cookies refresh-tags unsolicited-popups all-popups
+       \ img-reorder banners-by-size banners-by-link webbugs tiny-textforms jumping-windows frameset-borders demoronizer
+       \ shockwave-flash quicktime-kioskmode fun crude-parental ie-exploits site-specifics no-ping google yahoo msn blogspot
+       \ x-httpd-php-to-html html-to-xml xml-to-html hide-tor-exit-notation contained
+
+" Alternative spellings
+syn match privoxyAction "\%(kill-popup\|hide-referer\|prevent-keeping-cookies\)\>" contained
+
+" Pre-3.0 compatibility
+syn match privoxyAction "\%(no-cookie-read\|no-cookie-set\|prevent-reading-cookies\|prevent-setting-cookies\)\>" contained
+syn match privoxyAction "\%(downgrade\|hide-forwarded\|hide-from\|image\|image-blocker\|no-compression\)\>" contained
+syn match privoxyAction "\%(no-cookies-keep\|no-cookies-read\|no-cookies-set\|no-popups\|vanilla-wafer\|wafer\)\>" contained
+
+syn match privoxySetting "\<for-privoxy-version\>"
+
+syn match privoxyHeader "^\s*\zs{{\%(alias\|settings\)}}\ze\s*$"
+
+hi def link privoxyAction              Identifier
+hi def link privoxyFilterAction                Identifier
+hi def link privoxyActionLineDelimiter Delimiter
+hi def link privoxyDisabledPrefix      SpecialChar
+hi def link privoxyEnabledPrefix       SpecialChar
+hi def link privoxyHeader              PreProc
+hi def link privoxySetting             Identifier
+hi def link privoxyFilterArg           Constant
+
+hi def link privoxyComment             Comment
+hi def link privoxyTodo                        Todo
+
+let b:current_syntax = "privoxy"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/vim/syntax/python.vim b/vim/syntax/python.vim
new file mode 100644 (file)
index 0000000..3f739af
--- /dev/null
@@ -0,0 +1,352 @@
+" Vim syntax file
+" Language:    Python
+" Maintainer:  Dmitry Vasiliev <dima@hlabs.spb.ru>
+" URL:         http://www.hlabs.spb.ru/vim/python.vim
+" Last Change: 2008-09-29
+" Filenames:   *.py
+" Version:     2.6.3
+"
+" Based on python.vim (from Vim 6.1 distribution)
+" by Neil Schemenauer <nas@python.ca>
+"
+" Thanks:
+"
+"    Jeroen Ruigrok van der Werven
+"        for the idea to highlight erroneous operators
+"    Pedro Algarvio
+"        for the patch to enable spell checking only for the right spots
+"        (strings and comments)
+"    John Eikenberry
+"        for the patch fixing small typo
+
+"
+" Options:
+"
+"    For set option do: let OPTION_NAME = 1
+"    For clear option do: let OPTION_NAME = 0
+"
+" Option names:
+"
+"    For highlight builtin functions:
+"       python_highlight_builtins
+"
+"    For highlight standard exceptions:
+"       python_highlight_exceptions
+"
+"    For highlight string formatting:
+"       python_highlight_string_formatting
+"
+"    For highlight str.format syntax:
+"       python_highlight_string_format
+"
+"    For highlight string.Template syntax:
+"       python_highlight_string_templates
+"
+"    For highlight indentation errors:
+"       python_highlight_indent_errors
+"
+"    For highlight trailing spaces:
+"       python_highlight_space_errors
+"
+"    For highlight doc-tests:
+"       python_highlight_doctests
+"
+"    If you want all Python highlightings above:
+"       python_highlight_all
+"    (This option not override previously set options)
+"
+"    For fast machines:
+"       python_slow_sync
+"
+"    For "print" builtin as function:
+"       python_print_as_function
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+if exists("python_highlight_all") && python_highlight_all != 0
+  " Not override previously set options
+  if !exists("python_highlight_builtins")
+    let python_highlight_builtins = 1
+  endif
+  if !exists("python_highlight_exceptions")
+    let python_highlight_exceptions = 1
+  endif
+  if !exists("python_highlight_string_formatting")
+    let python_highlight_string_formatting = 1
+  endif
+  if !exists("python_highlight_string_format")
+    let python_highlight_string_format = 1
+  endif
+  if !exists("python_highlight_string_templates")
+    let python_highlight_string_templates = 1
+  endif
+  if !exists("python_highlight_indent_errors")
+    let python_highlight_indent_errors = 1
+  endif
+  if !exists("python_highlight_space_errors")
+    let python_highlight_space_errors = 1
+  endif
+  if !exists("python_highlight_doctests")
+    let python_highlight_doctests = 1
+  endif
+endif
+
+" Keywords
+syn keyword pythonStatement    break continue del
+syn keyword pythonStatement    exec return
+syn keyword pythonStatement    pass raise
+syn keyword pythonStatement    global assert
+syn keyword pythonStatement    lambda yield
+syn keyword pythonStatement    with
+syn keyword pythonStatement    def class nextgroup=pythonFunction skipwhite
+syn match   pythonFunction     "[a-zA-Z_][a-zA-Z0-9_]*" display contained
+syn keyword pythonRepeat       for while
+syn keyword pythonConditional  if elif else
+syn keyword pythonImport       import from as
+syn keyword pythonException    try except finally
+syn keyword pythonOperator     and in is not or
+
+if !exists("python_print_as_function") || python_print_as_function == 0
+  syn keyword pythonStatement print
+endif
+
+" Decorators (new in Python 2.4)
+syn match   pythonDecorator    "@" display nextgroup=pythonFunction skipwhite
+
+" Comments
+syn match   pythonComment      "#.*$" display contains=pythonTodo,@Spell
+syn match   pythonRun          "\%^#!.*$"
+syn match   pythonCoding       "\%^.*\(\n.*\)\?#.*coding[:=]\s*[0-9A-Za-z-_.]\+.*$"
+syn keyword pythonTodo         TODO FIXME XXX contained
+
+" Errors
+syn match pythonError          "\<\d\+\D\+\>" display
+syn match pythonError          "[$?]" display
+syn match pythonError          "[&|]\{2,}" display
+syn match pythonError          "[=]\{3,}" display
+
+" TODO: Mixing spaces and tabs also may be used for pretty formatting multiline
+" statements. For now I don't know how to work around this.
+if exists("python_highlight_indent_errors") && python_highlight_indent_errors != 0
+  syn match pythonIndentError  "^\s*\( \t\|\t \)\s*\S"me=e-1 display
+endif
+
+" Trailing space errors
+if exists("python_highlight_space_errors") && python_highlight_space_errors != 0
+  syn match pythonSpaceError   "\s\+$" display
+endif
+
+" Strings
+syn region pythonString                start=+[bB]\='+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonEscape,pythonEscapeError,@Spell
+syn region pythonString                start=+[bB]\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonEscape,pythonEscapeError,@Spell
+syn region pythonString                start=+[bB]\="""+ end=+"""+ keepend contains=pythonEscape,pythonEscapeError,pythonDocTest2,pythonSpaceError,@Spell
+syn region pythonString                start=+[bB]\='''+ end=+'''+ keepend contains=pythonEscape,pythonEscapeError,pythonDocTest,pythonSpaceError,@Spell
+
+syn match  pythonEscape                +\\[abfnrtv'"\\]+ display contained
+syn match  pythonEscape                "\\\o\o\=\o\=" display contained
+syn match  pythonEscapeError   "\\\o\{,2}[89]" display contained
+syn match  pythonEscape                "\\x\x\{2}" display contained
+syn match  pythonEscapeError   "\\x\x\=\X" display contained
+syn match  pythonEscape                "\\$"
+
+" Unicode strings
+syn region pythonUniString     start=+[uU]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,@Spell
+syn region pythonUniString     start=+[uU]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,@Spell
+syn region pythonUniString     start=+[uU]"""+ end=+"""+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,pythonDocTest2,pythonSpaceError,@Spell
+syn region pythonUniString     start=+[uU]'''+ end=+'''+ keepend contains=pythonEscape,pythonUniEscape,pythonEscapeError,pythonUniEscapeError,pythonDocTest,pythonSpaceError,@Spell
+
+syn match  pythonUniEscape     "\\u\x\{4}" display contained
+syn match  pythonUniEscapeError        "\\u\x\{,3}\X" display contained
+syn match  pythonUniEscape     "\\U\x\{8}" display contained
+syn match  pythonUniEscapeError        "\\U\x\{,7}\X" display contained
+syn match  pythonUniEscape     "\\N{[A-Z ]\+}" display contained
+syn match  pythonUniEscapeError        "\\N{[^A-Z ]\+}" display contained
+
+" Raw strings
+syn region pythonRawString     start=+[rR]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonRawEscape,@Spell
+syn region pythonRawString     start=+[rR]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonRawEscape,@Spell
+syn region pythonRawString     start=+[rR]"""+ end=+"""+ keepend contains=pythonDocTest2,pythonSpaceError,@Spell
+syn region pythonRawString     start=+[rR]'''+ end=+'''+ keepend contains=pythonDocTest,pythonSpaceError,@Spell
+
+syn match pythonRawEscape      +\\['"]+ display transparent contained
+
+" Unicode raw strings
+syn region pythonUniRawString  start=+[uU][rR]'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end=+$+ keepend contains=pythonRawEscape,pythonUniRawEscape,pythonUniRawEscapeError,@Spell
+syn region pythonUniRawString  start=+[uU][rR]"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end=+$+ keepend contains=pythonRawEscape,pythonUniRawEscape,pythonUniRawEscapeError,@Spell
+syn region pythonUniRawString  start=+[uU][rR]"""+ end=+"""+ keepend contains=pythonUniRawEscape,pythonUniRawEscapeError,pythonDocTest2,pythonSpaceError,@Spell
+syn region pythonUniRawString  start=+[uU][rR]'''+ end=+'''+ keepend contains=pythonUniRawEscape,pythonUniRawEscapeError,pythonDocTest,pythonSpaceError,@Spell
+
+syn match  pythonUniRawEscape          "\([^\\]\(\\\\\)*\)\@<=\\u\x\{4}" display contained
+syn match  pythonUniRawEscapeError     "\([^\\]\(\\\\\)*\)\@<=\\u\x\{,3}\X" display contained
+
+if exists("python_highlight_string_formatting") && python_highlight_string_formatting != 0
+  " String formatting
+  syn match pythonStrFormatting        "%\(([^)]\+)\)\=[-#0 +]*\d*\(\.\d\+\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+  syn match pythonStrFormatting        "%[-#0 +]*\(\*\|\d\+\)\=\(\.\(\*\|\d\+\)\)\=[hlL]\=[diouxXeEfFgGcrs%]" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+endif
+
+if exists("python_highlight_string_format") && python_highlight_string_format != 0
+  " str.format syntax
+  syn match pythonStrFormat "{{\|}}" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+  syn match pythonStrFormat    "{\([a-zA-Z_][a-zA-Z0-9_]*\|\d\+\)\(\.[a-zA-Z_][a-zA-Z0-9_]*\|\[\(\d\+\|[^!:\}]\+\)\]\)*\(![rs]\)\=\(:\({\([a-zA-Z_][a-zA-Z0-9_]*\|\d\+\)}\|\([^}]\=[<>=^]\)\=[ +-]\=#\=0\=\d*\(\.\d\+\)\=[bcdeEfFgGnoxX%]\=\)\=\)\=}" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+endif
+
+if exists("python_highlight_string_templates") && python_highlight_string_templates != 0
+  " String templates
+  syn match pythonStrTemplate  "\$\$" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+  syn match pythonStrTemplate  "\${[a-zA-Z_][a-zA-Z0-9_]*}" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+  syn match pythonStrTemplate  "\$[a-zA-Z_][a-zA-Z0-9_]*" contained containedin=pythonString,pythonUniString,pythonRawString,pythonUniRawString
+endif
+
+if exists("python_highlight_doctests") && python_highlight_doctests != 0
+  " DocTests
+  syn region pythonDocTest     start="^\s*>>>" end=+'''+he=s-1 end="^\s*$" contained
+  syn region pythonDocTest2    start="^\s*>>>" end=+"""+he=s-1 end="^\s*$" contained
+endif
+
+" Numbers (ints, longs, floats, complex)
+syn match   pythonHexError     "\<0[xX]\x*[g-zG-Z]\x*[lL]\=\>" display
+
+syn match   pythonHexNumber    "\<0[xX]\x\+[lL]\=\>" display
+syn match   pythonOctNumber "\<0[oO]\o\+[lL]\=\>" display
+syn match   pythonBinNumber "\<0[bB][01]\+[lL]\=\>" display
+
+syn match   pythonNumber       "\<\d\+[lLjJ]\=\>" display
+
+syn match   pythonFloat                "\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>" display
+syn match   pythonFloat                "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display
+syn match   pythonFloat                "\<\d\+\.\d*\([eE][+-]\=\d\+\)\=[jJ]\=" display
+
+syn match   pythonOctError     "\<0[oO]\=\o*[8-9]\d*[lL]\=\>" display
+syn match   pythonBinError     "\<0[bB][01]*[2-9]\d*[lL]\=\>" display
+
+if exists("python_highlight_builtins") && python_highlight_builtins != 0
+  " Builtin functions, types and objects
+  syn keyword pythonBuiltinObj True False Ellipsis None NotImplemented
+  syn keyword pythonBuiltinObj __debug__ __doc__ __file__ __name__ __package__
+
+  syn keyword pythonBuiltinFunc        __import__ abs all any apply
+  syn keyword pythonBuiltinFunc        basestring bin bool buffer bytearray bytes callable
+  syn keyword pythonBuiltinFunc        chr classmethod cmp coerce compile complex
+  syn keyword pythonBuiltinFunc        delattr dict dir divmod enumerate eval
+  syn keyword pythonBuiltinFunc        execfile file filter float format frozenset getattr
+  syn keyword pythonBuiltinFunc        globals hasattr hash help hex id 
+  syn keyword pythonBuiltinFunc        input int intern isinstance
+  syn keyword pythonBuiltinFunc        issubclass iter len list locals long map max
+  syn keyword pythonBuiltinFunc        min next object oct open ord
+  syn keyword pythonBuiltinFunc        pow property range
+  syn keyword pythonBuiltinFunc        raw_input reduce reload repr
+  syn keyword pythonBuiltinFunc        reversed round set setattr
+  syn keyword pythonBuiltinFunc        slice sorted staticmethod str sum super tuple
+  syn keyword pythonBuiltinFunc        type unichr unicode vars xrange zip
+
+  if exists("python_print_as_function") && python_print_as_function != 0
+      syn keyword pythonBuiltinFunc    print
+  endif
+endif
+
+if exists("python_highlight_exceptions") && python_highlight_exceptions != 0
+  " Builtin exceptions and warnings
+  syn keyword pythonExClass    BaseException
+  syn keyword pythonExClass    Exception StandardError ArithmeticError
+  syn keyword pythonExClass    LookupError EnvironmentError
+
+  syn keyword pythonExClass    AssertionError AttributeError BufferError EOFError
+  syn keyword pythonExClass    FloatingPointError GeneratorExit IOError
+  syn keyword pythonExClass    ImportError IndexError KeyError
+  syn keyword pythonExClass    KeyboardInterrupt MemoryError NameError
+  syn keyword pythonExClass    NotImplementedError OSError OverflowError
+  syn keyword pythonExClass    ReferenceError RuntimeError StopIteration
+  syn keyword pythonExClass    SyntaxError IndentationError TabError
+  syn keyword pythonExClass    SystemError SystemExit TypeError
+  syn keyword pythonExClass    UnboundLocalError UnicodeError
+  syn keyword pythonExClass    UnicodeEncodeError UnicodeDecodeError
+  syn keyword pythonExClass    UnicodeTranslateError ValueError VMSError
+  syn keyword pythonExClass    WindowsError ZeroDivisionError
+
+  syn keyword pythonExClass    Warning UserWarning BytesWarning DeprecationWarning
+  syn keyword pythonExClass    PendingDepricationWarning SyntaxWarning
+  syn keyword pythonExClass    RuntimeWarning FutureWarning
+  syn keyword pythonExClass    ImportWarning UnicodeWarning
+endif
+
+if exists("python_slow_sync") && python_slow_sync != 0
+  syn sync minlines=2000
+else
+  " This is fast but code inside triple quoted strings screws it up. It
+  " is impossible to fix because the only way to know if you are inside a
+  " triple quoted string is to start from the beginning of the file.
+  syn sync match pythonSync grouphere NONE "):$"
+  syn sync maxlines=200
+endif
+
+if version >= 508 || !exists("did_python_syn_inits")
+  if version <= 508
+    let did_python_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pythonStatement       Statement
+  HiLink pythonImport          Statement
+  HiLink pythonFunction                Function
+  HiLink pythonConditional     Conditional
+  HiLink pythonRepeat          Repeat
+  HiLink pythonException       Exception
+  HiLink pythonOperator                Operator
+
+  HiLink pythonDecorator       Define
+
+  HiLink pythonComment         Comment
+  HiLink pythonCoding          Special
+  HiLink pythonRun             Special
+  HiLink pythonTodo            Todo
+
+  HiLink pythonError           Error
+  HiLink pythonIndentError     Error
+  HiLink pythonSpaceError      Error
+
+  HiLink pythonString          String
+  HiLink pythonUniString       String
+  HiLink pythonRawString       String
+  HiLink pythonUniRawString    String
+
+  HiLink pythonEscape                  Special
+  HiLink pythonEscapeError             Error
+  HiLink pythonUniEscape               Special
+  HiLink pythonUniEscapeError          Error
+  HiLink pythonUniRawEscape            Special
+  HiLink pythonUniRawEscapeError       Error
+
+  HiLink pythonStrFormatting   Special
+  HiLink pythonStrFormat       Special
+  HiLink pythonStrTemplate         Special
+
+  HiLink pythonDocTest         Special
+  HiLink pythonDocTest2                Special
+
+  HiLink pythonNumber          Number
+  HiLink pythonHexNumber       Number
+  HiLink pythonOctNumber       Number
+  HiLink pythonBinNumber       Number
+  HiLink pythonFloat           Float
+  HiLink pythonOctError            Error
+  HiLink pythonHexError                Error
+  HiLink pythonBinError                Error
+
+  HiLink pythonBuiltinObj      Structure
+  HiLink pythonBuiltinFunc     Function
+
+  HiLink pythonExClass Structure
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "python"
diff --git a/vim/syntax/tcl.vim b/vim/syntax/tcl.vim
new file mode 100644 (file)
index 0000000..e79e2eb
--- /dev/null
@@ -0,0 +1,1100 @@
+" Vim syntax file for Tcl/tk language
+" Language:    Tcl
+" Maintained:  SM Smithfield <m_smithfield@yahoo.com>
+" Last Change: 05/01/2007 (20:03:29)
+" Filenames:    *.tcl
+" Version:      0.5
+" ------------------------------------------------------------------
+" GetLatestVimScripts: 1603 1 :AutoInstall: syntax/tcl.vim
+" ------------------------------------------------------------------
+
+" -------------------------
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+" Highlight Options: restart vim, after changing these options.
+" let s:tcl_highlight_namespace_bold = 1
+" let s:tcl_highlight_bookends = 1
+" let s:tcl_highlight_primary = 1
+" let s:tcl_highlight_expressions = 1
+" let s:tcl_highlight_variables = 1
+" let s:tcl_highlight_secondary = 1
+" let s:tcl_highlight_options = 1
+" let s:tcl_highlight_lcs_are_warnings = 1
+" let s:tcl_comments_ignore_nested_braces = 1
+let s:tcl_highlight_all = 1
+
+" Extended Syntax:
+" let s:tcl_snit_active = 1
+" let s:tcl_sqlite_active = 1
+" let s:tcl_critcl_active = 1
+" let s:tcl_togl_active = 1
+" let s:tcl_itcl_active = 1
+let s:tcl_ttk_active = 1
+
+" one more highlight than the law allows
+if exists("s:tcl_highlight_bookends")
+    if !hlexists("Bold")
+        hi Bold guifg=fg guibg=bg gui=bold
+        if version > 700
+            " on colorscheme, create Bold
+            augroup tclsyntax
+                au!
+                au ColorScheme * hi Bold guifg=fg guibg=bg gui=bold
+            augroup end
+        endif
+    endif
+endif
+
+" -------------------------
+" Basics:
+" -------------------------
+" see Note in :h /\@=
+syn match tclKeywordGroup contained "\([^\[{ ]\)\@<!\w\+" contains=@tclKeywords,@tkKeywords
+syn region tclWord1      contained start=+[^\[#{}"\]]\&\S+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclStuff
+syn region tclWord0      contained start=+[^#]\&\S+ end=+\s\|$+ contains=@tclWord0Cluster skipwhite nextgroup=@tclWord1Cluster
+syn region tclQuotes     contained extend keepend matchgroup=tclQuotes start=+\(\\\)\@<!"+ end=+"+ skip=+\(\\\)\@<!\\"\|\(\\\\\\\)\@<!\\"\|\\\\+ contains=@tclQuotesCluster
+syn region tclBrackets   contained extend keepend matchgroup=Bold start=+\(\\\)\@<!\[+ end=+]\|$+ skip=+\\\s*$\|\(\\\)\@<!\\]+ contains=@tclCommandCluster
+syn region tclBraces     contained extend keepend matchgroup=Bold start=+\(\\\)\@<!{+  end=+}+ skip=+$\|\(\\\)\@<!\\}+ contains=@tclCommandCluster,tclComment
+syn region tclFoldBraces contained extend keepend fold matchgroup=Bold start=+\(\\\)\@<!{+ end=+}+ skip=+$\|\(\\\)\@<!\\}+ contains=@tclCommandCluster
+syn match  tclSemiColon  contained ";\s*" skipwhite nextgroup=@tclCommandCluster
+if exists("s:tcl_comments_ignore_nested_braces")
+    syn region tclComment    contained extend keepend start=+^\s*\#+ms=e-1 start=+\([;{]\s*\)\@<=\#+ end="\\\s\+$\|$" skip=+\\$+ contains=tclTodo,@tclLContinue,@Spell
+else
+    syn region tclComment       contained extend keepend start=+^\s*\#+ms=e-1 start=+\([;{]\s*\)\@<=\#+ end="\\\s\+$\|$" skip=+\\$\|\(\\\)\@<!\\}+ end="}"me=e-1 contains=tclTodo,@tclLContinue,@Spell,tclCommentBraces
+    syn region tclCommentBraces contained extend keepend matchgroup=Comment start=+\(\\\)\@<!{+  end=+}+ skip=+$\|\(\\\)\@<!\\}+ 
+endif
+
+syn region tclCommand start=+[^;]\&.+ skip=+\\$+ end=+;\|$+ contains=@tclCommandCluster
+
+syn match tclStart "\%^\s*#!.*$"
+syn region tclStart start="\%^\s*#!/bin/sh"  end="^\s*exec.*$"
+
+
+" -------------------------
+" Clusters:
+" -------------------------
+syn cluster tcltkKeywords      contains=@tclKeywords,@tkKeywords
+syn cluster tclKeywords        contains=tclPrimary,tclKeyword,tclException,tclConditional,tclRepeat,tclLabel,tclMagicName,tclNamespace
+syn cluster tkKeywords         contains=tkKeyword,tkReserved,tkWidget,tkDialog
+" ------------------
+syn cluster tclBits            contains=tclBraces,tclBrackets,tclComment,tclExpand,@tclLContinue,tclNumber,tclQuotes,tclSpecial,tkColor,tkEvent,tclSemiColon
+syn cluster tclStuff           contains=@tclBits,tclVariable,tkBindSubstGroup,tkWidgetName,tclREClassGroup
+syn cluster tclWord0Cluster    contains=@tclStuff
+syn cluster tclWord1Cluster    contains=tclWord1,tclSecondary,tkWidgetCreate,tclConditional,@tclStuff
+syn cluster tclQuotesCluster   contains=tclSpecial,@tclLContinue,@Spell
+syn cluster tclLContinue       contains=tclLContinueOk,tclLContinueError
+syn cluster tclCommandCluster contains=@tcltkKeywords,tclWord0,tclComment
+
+
+
+" -------------------------
+" Tcl: Syntax
+" -------------------------
+syn keyword tclKeyword      contained append apply auto_execok auto_import auto_load auto_mkindex auto_qualify auto_reset cd close concat eof exit fblocked flush format gets global http incr join lappend lassign lindex linsert llength load lrange lrepeat lreplace lreverse lset namespace parray pid pkg_mkIndex proc pwd registry rename return scan set split tclLog tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tell time unknown upvar variable vwait skipwhite nextgroup=tclPred
+syn keyword tclMagicName    contained argc argv argv0 auto_index auto_oldpath auto_path env errorCode errorInfo tcl_interactive tcl_libpath tcl_library tlc_patchlevel tcl_pkgPath tcl_platform tcl_precision tcl_rcFileName tcl_rcRsrcName tcl_traceCompile tcl_traceExec tcl_version
+" ------------------
+syn keyword tkKeyword       contained bell bind clipboard console consoleinterp event focus grid pack place tkwait winfo wm
+syn keyword tkKeyword       contained bindtags destroy lower option raise send tkerror tkwait tk_bisque tk_focusNext tk_focusPrev tk_focusFollowsMouse tk_popup tk_setPalette tk_textCut tk_TextCopy tk_textPaste skipwhite nextgroup=tclPred
+syn keyword tkDialog        contained chooseColor tk_chooseColor tk_chooseDirectory tk_dialog tk_getOpenFile tkDialog tk_getSaveFile tk_messageBox
+syn keyword tkReserved      contained tk_library tk_strictMotif tk_version
+syn keyword tkWidget        contained button canvas checkbutton entry frame image label labelframe listbox menu menubutton message panedwindow radiobutton scale scrollbar spinbox toplevel skipwhite nextgroup=tkWidgetPredicate
+" TODO widgets that are NOT part of tk
+syn keyword tkWidget        contained table mclistbox skipwhite nextgroup=tkWidgetPredicate
+
+syn region tclPred contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclStuff
+
+" CONDITIONALS
+syn keyword tclPrimary      contained if skipwhite nextgroup=tclIfCommentStart,tclExpression,@tclStuff
+syn keyword tclConditional  contained elseif skipwhite nextgroup=tclExpression,@tclStuff
+syn keyword tclConditional  contained else then
+
+" REPEAT
+" syn keyword tclRepeat       contained for skipwhite nextgroup=tclForStart,@tclStuff
+syn keyword tclRepeat       contained for skipwhite nextgroup=tclForStart
+syn match tclForStart       contained extend "\s*{[^}]\{-}}" contains=@tclCommandCluster skipwhite nextgroup=tclExpression,@tclStuff
+syn keyword tclRepeat       contained while skipwhite nextgroup=tclExpression,@tclStuff
+syn keyword tclRepeat       contained foreach skipwhite nextgroup=tclPred
+syn keyword tclRepeat       contained break continue
+syn keyword tclLabel        contained default
+syn keyword tclException    contained catch error
+
+" EXPRESSION - that presumes to be an expression, occurs in expr, conditional, loops, etc...
+syn keyword tclPrimary      contained expr skipwhite nextgroup=tclExpression
+syn match  tclExpression    contained "\\" skipwhite skipnl nextgroup=tclExpression contains=tclLContinueOk
+syn match  tclExpression    contained extend "\\\s\+$" contains=tclLContinueError
+syn region tclExpression    contained extend start=+[^ {\\]+ skip=+\\$+ end=+}\|]\|;\|$+me=e-1 contains=tclMaths,@tclStuff
+" NOTE: must include '\s*' in start, for while etc don't work w/o it, I think
+" this is because matching the whitespace allows the expression to supercede
+" the other regions
+syn region tclExpression    contained keepend extend matchgroup=Bold start=+\s*{+ end=+}+ skip=+$\|\\}+ contains=tclMaths,@tclStuff
+syn keyword tclMaths        contained abs acos asin atan atan2 bool ceil cos cosh double entier exp floor fmod hypot int isqrt log log10 max min pow rand round sin sinh sqrt srand tan tanh wide
+syn keyword tclMaths        contained ne eq in ni
+syn match tclMaths          contained "[()^%~<>!=+*\-|&?:/]"
+
+" IF - permits use of if{0} {} commenting idiom
+syn region tclIfComment     contained extend keepend matchgroup=Comment start=+\(\\\)\@<!{+  skip=+$\|\\}+ end=+}+ contains=tclIfComment,tclTodo,@Spell
+syn match tclIfCommentStart contained extend  "\s*\(0\|{0}\)" skipwhite nextgroup=tclIfComment
+
+" PROC - proc name hilite AND folding
+syn keyword tclPrimary      contained proc skipwhite nextgroup=tclProcName
+" def-script pattern
+syn match tclProcDef        contained "\S\+" skipwhite nextgroup=tclFoldBraces
+" type-name-args-script pattern
+syn match tclProcType       contained "\S\+" skipwhite nextgroup=tclProcName
+syn match tclProcName       contained "\S\+" skipwhite nextgroup=tclProcArgs
+syn region tclProcArgs      contained extend keepend excludenl matchgroup=Bold start=+\(\\\)\@<!{+  skip=+$\|\\}+ end=+}+ contains=tclProcArgs skipwhite nextgroup=tclFoldBraces
+
+
+" -------------------------
+" Tcl: Syntax - Bits
+" -------------------------
+syn keyword tclTodo         contained TODO
+syn match tkEvent           contained "<\S\+>"
+syn match tkEvent           contained "<<.\+>>"
+syn match tkColor           contained "#[0-9A-Fa-f]\{6}\|#[0-9A-Fa-f]\{3}"
+syn match tclNumber         contained "\<\d\+\(u\=l\=\|lu\|f\|L\)\>"
+syn match tclNumber         contained "\<\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=\>"
+syn match tclNumber         contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
+syn match tclNumber         contained "\<\d\+e[-+]\=\d\+[fl]\=\>"
+syn match tclNumber         contained "0x[0-9a-f]\+\(u\=l\=\|lu\)\>"
+syn match tclVariable       contained "\$\(\(:\{2,}\)\?\([[:alnum:]_]*::\)*\)[[:alnum:]_]*"
+syn region tclVariable      contained start=+\$\(\(:\{2,}\)\?\([[:alnum:]_]*::\)*\)[[:alnum:]_]\+(+ skip=+\\)+ end=+)+ contains=@tclStuff
+syn match tclVariable       contained extend "${[^}]*}"
+syn match tclSpecial        contained "\\\d\d\d\=\|\\."
+syn match tkWidgetName      contained "\([[:alnum:]]\)\@<!\.[[:alpha:]][[:alnum:]]*\(\.[[:alpha:]][[:alnum:]]*\)*\>"
+if exists("s:tcl_highlight_lcs_are_warnings")
+    syn match tclLContinueOk    contained "\\$"
+else
+    syn match tclLContinueOk    contained "\\$" transparent
+endif
+syn match tclLContinueError contained "\\\s\+$" excludenl
+syn match tclExpand         contained extend "{expand}"
+syn match tclExpand         contained extend "{\*}"
+syn match tclREClassGroup   contained extend +\(\\\)\@<!\[^\?\[:\(\w\+\|[<>]\):]_\?]+  contains=tclREClass
+syn keyword tclREClass contained alpha upper lower digit xdigit alnum print blank space punct graph cntrl 
+
+
+
+" -------------------------
+" Tcl: Syntax - Keyword Predicates
+" -------------------------
+
+" SPECIAL CASE: predicate can contain a command 
+syn region tclListPred contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclCommandCluster
+syn keyword tclPrimary contained eval list skipwhite nextgroup=tclListPred
+
+
+" SPECIAL CASE: contains a command and a leve
+syn region tclUplevelPred contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclCommandCluster
+syn match tclUplevelLevel contained "\S\+" contains=@tclCommandCluster skipwhite nextgroup=tclUplevelPred
+syn keyword tclPrimary contained uplevel skipwhite nextgroup=tclUplevelLevel
+
+
+" SPECIAL CASE: FOLDING
+syn keyword tclPrimary                        contained namespace skipwhite nextgroup=tclNamespacePred
+syn keyword tclNamespaceCmds                  contained children code current delete eval exists forget inscope origin parent path qualifiers tail unknown upvar
+syn region tclNamespacePred                   contained keepend fold start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclNamespaceCmds,tclNamespaceEnsemble,@tclStuff
+syn match tclNamespaceExportOptsGroup         contained "-\a\+" contains=tclNamespaceExportOpts
+syn keyword tclNamespaceExportOpts            contained clear force command variable
+syn region tclNamespaceExportPred             contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclNamespaceExportOptsGroup,@tclStuff
+syn keyword tclNamespaceCmds                  contained export import which skipwhite nextgroup=tclNamespaceExportPred
+syn match tclNamespaceEnsembleExistsOptsGroup contained "-\a\+" contains=tclNamespaceEnsembleExistsOpts
+syn keyword tclNamespaceEnsembleExistsOpts    contained map prefixes subcommands unknown command namespace
+syn region tclNamespaceEnsembleExistsPred     contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclNamespaceEnsembleExistsOptsGroup,@tclStuff
+syn keyword tclNamespaceEnsembleCmds          contained exists create configure skipwhite nextgroup=tclNamespaceEnsembleExistsPred
+syn region tclNamespaceEnsemblePred           contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclNamespaceEnsembleCmds,@tclStuff
+syn keyword tclNamespaceEnsemble              contained ensemble skipwhite nextgroup=tclNamespaceEnsemblePred
+
+
+syn keyword tclPrimary contained puts read skipwhite nextgroup=tclPutsPred
+syn region tclPutsPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclPutsOptsGroup,@tclStuff
+syn match tclPutsOptsGroup contained "-\a\+" contains=tclPutsOpts
+syn keyword tclPutsOpts contained nonewline
+
+syn keyword tclPrimary contained return skipwhite nextgroup=tclReturnPred
+syn region tclReturnPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclReturnOptsGroup,@tclStuff
+syn match tclReturnOptsGroup contained "-\a\+" contains=tclReturnOpts
+syn keyword tclReturnOpts contained code errorcode errorinfo level options
+
+syn keyword tclPrimary contained source skipwhite nextgroup=tclSourcePred
+syn region tclSourcePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclSourceOptsGroup,@tclStuff
+syn match tclSourceOptsGroup contained "-\a\+" contains=tclSourceOpts
+syn keyword tclSourceOpts contained encoding
+
+syn keyword tclPrimary contained after skipwhite nextgroup=tclAfterPred
+syn region tclAfterPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclAfterCmds,@tclStuff
+syn keyword tclAfterCmds contained cancel idle info skipwhite nextgroup=tclAfterCmdsCancelPred
+syn region tclAfterCmdsCancelPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained array skipwhite nextgroup=tclArrayPred
+syn region tclArrayPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclArrayCmds,@tclStuff
+syn keyword tclArrayCmds contained anymore donesearch exists get nextelement set size startsearch statistics unset skipwhite nextgroup=tclArrayCmdsAnymorePred
+syn region tclArrayCmdsAnymorePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclArrayCmdsNamesOptsGroup contained "-\a\+" contains=tclArrayCmdsNamesOpts
+syn keyword tclArrayCmdsNamesOpts contained exact glob regexp
+syn keyword tclArrayCmds contained names skipwhite nextgroup=tclArrayCmdsNamesPred
+syn region tclArrayCmdsNamesPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclArrayCmdsNamesOptsGroup,@tclStuff skipwhite nextgroup=tclArrayCmds
+
+syn keyword tclPrimary contained binary skipwhite nextgroup=tclBinaryPred
+syn region tclBinaryPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclBinaryCmds,@tclStuff
+syn keyword tclBinaryCmds contained format scan skipwhite nextgroup=tclBinaryCmdsFormatPred
+syn region tclBinaryCmdsFormatPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained encoding skipwhite nextgroup=tclEncodingPred
+syn region tclEncodingPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclEncodingCmds,@tclStuff
+syn keyword tclEncodingCmds contained convertfrom convertto names system skipwhite nextgroup=tclEncodingCmdsConvertfromPred
+syn region tclEncodingCmdsConvertfromPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained info skipwhite nextgroup=tclInfoPred
+syn region tclInfoPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInfoCmds,@tclStuff
+syn keyword tclInfoCmds contained args body cmdcount commands complete default exists frame functions globals hostname level library loaded locals nameofexecutable patchlevel procs script sharedlibextension tclversion vars skipwhite nextgroup=tclInfoCmdsArgsPred
+syn region tclInfoCmdsArgsPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained memory skipwhite nextgroup=tclMemoryPred
+syn region tclMemoryPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclMemoryCmds,@tclStuff
+syn keyword tclMemoryCmds contained active break info init onexit tag trace validate skipwhite nextgroup=tclMemoryCmdsActivePred
+syn region tclMemoryCmdsActivePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained update skipwhite nextgroup=tclUpdatePred
+syn region tclUpdatePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclUpdateCmds,@tclStuff
+syn keyword tclUpdateCmds contained idletasks skipwhite nextgroup=tclUpdateCmdsIdletasksPred
+syn region tclUpdateCmdsIdletasksPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained exec skipwhite nextgroup=tclExecPred
+syn region tclExecPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclExecOptsGroup,@tclStuff
+syn match tclExecOptsGroup contained "-\a\+" contains=tclExecOpts
+syn keyword tclExecOpts contained keepnewline ignorestderr
+
+syn keyword tclPrimary contained glob skipwhite nextgroup=tclGlobPred
+syn region tclGlobPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclGlobOptsGroup,@tclStuff
+syn match tclGlobOptsGroup contained "-\a\+" contains=tclGlobOpts
+syn keyword tclGlobOpts contained directory join nocomplain path tails types
+
+syn keyword tclPrimary contained regexp skipwhite nextgroup=tclRegexpPred
+syn region tclRegexpPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclRegexpOptsGroup,@tclStuff
+syn match tclRegexpOptsGroup contained "-\a\+" contains=tclRegexpOpts
+syn keyword tclRegexpOpts contained about expanded indicies line linestop lineanchor nocase all inline start
+
+syn keyword tclPrimary contained regsub skipwhite nextgroup=tclRegsubPred
+syn region tclRegsubPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclRegsubOptsGroup,@tclStuff
+syn match tclRegsubOptsGroup contained "-\a\+" contains=tclRegsubOpts
+syn keyword tclRegsubOpts contained all expanded line linestop nocase start
+
+syn keyword tclPrimary contained switch skipwhite nextgroup=tclSwitchPred
+syn region tclSwitchPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclSwitchOptsGroup,@tclStuff
+syn match tclSwitchOptsGroup contained "-\a\+" contains=tclSwitchOpts
+syn keyword tclSwitchOpts contained exact glob regexp nocase matchvar indexvar
+
+syn keyword tclPrimary contained unload skipwhite nextgroup=tclUnloadPred
+syn region tclUnloadPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclUnloadOptsGroup,@tclStuff
+syn match tclUnloadOptsGroup contained "-\a\+" contains=tclUnloadOpts
+syn keyword tclUnloadOpts contained nocomplain keeplibrary
+
+syn keyword tclPrimary contained unset skipwhite nextgroup=tclUnsetPred
+syn region tclUnsetPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclUnsetOptsGroup,@tclStuff
+syn match tclUnsetOptsGroup contained "-\a\+" contains=tclUnsetOpts
+syn keyword tclUnsetOpts contained nocomplain
+
+syn keyword tclPrimary contained subst skipwhite nextgroup=tclSubstPred
+syn region tclSubstPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclSubstOptsGroup,@tclStuff
+syn match tclSubstOptsGroup contained "-\a\+" contains=tclSubstOpts
+syn keyword tclSubstOpts contained nocommands novariables nobackslashes
+
+syn keyword tclPrimary contained lsearch skipwhite nextgroup=tclLsearchPred
+syn region tclLsearchPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclLsearchOptsGroup,@tclStuff
+syn match tclLsearchOptsGroup contained "-\a\+" contains=tclLsearchOpts
+syn keyword tclLsearchOpts contained exact glob regexp sorted all inline not ascii dictionary integer nocase real decreasing increasing subindices
+syn match tclLsearchOptsGroup contained "-\a\+" contains=tclLsearchOpts
+syn keyword tclLsearchOpts contained start index
+
+syn keyword tclPrimary contained lsort skipwhite nextgroup=tclLsortPred
+syn region tclLsortPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclLsortOptsGroup,@tclStuff
+syn match tclLsortOptsGroup contained "-\a\+" contains=tclLsortOpts
+syn keyword tclLsortOpts contained ascii dictionary integer real increasing decreasing indicies nocase unique
+syn match tclLsortOptsGroup contained "-\a\+" contains=tclLsortOpts
+syn keyword tclLsortOpts contained command index
+
+syn keyword tclPrimary contained fconfigure skipwhite nextgroup=tclFconfigurePred
+syn region tclFconfigurePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclFconfigureOptsGroup,@tclStuff
+syn match tclFconfigureOptsGroup contained "-\a\+" contains=tclFconfigureOpts
+syn keyword tclFconfigureOpts contained blocking buffering buffersize encoding eofchar error
+syn match tclFconfigureOptsGroup contained "-\a\+" contains=tclFconfigureOpts
+syn keyword tclFconfigureOpts contained translation
+
+syn keyword tclPrimary contained fcopy skipwhite nextgroup=tclFcopyPred
+syn region tclFcopyPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclFcopyOptsGroup,@tclStuff
+syn match tclFcopyOptsGroup contained "-\a\+" contains=tclFcopyOpts
+syn keyword tclFcopyOpts contained size command
+
+syn keyword tclPrimary contained socket skipwhite nextgroup=tclSocketPred
+syn region tclSocketPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclSocketOptsGroup,@tclStuff
+syn match tclSocketOptsGroup contained "-\a\+" contains=tclSocketOpts
+syn keyword tclSocketOpts contained server myaddr myport async myaddr error sockname peername
+
+syn keyword tclPrimary contained fileevent skipwhite nextgroup=tclFileeventPred
+syn region tclFileeventPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclFileeventCmds,@tclStuff
+syn keyword tclFileeventCmds contained readable writable skipwhite nextgroup=tclFileeventCmdsReadablePred
+syn region tclFileeventCmdsReadablePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained open skipwhite nextgroup=tclOpenPred
+syn region tclOpenPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclOpenOptsGroup,@tclStuff
+syn match tclOpenOptsGroup contained "-\a\+" contains=tclOpenOpts
+syn keyword tclOpenOpts contained mode handshake queue timeout ttycontrol ttystatus xchar pollinterval sysbuffer lasterror
+
+syn keyword tclPrimary contained seek skipwhite nextgroup=tclSeekPred
+syn region tclSeekPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclSeekCmds,@tclStuff
+syn keyword tclSeekCmds contained start current end skipwhite nextgroup=tclSeekCmdsStartPred
+syn region tclSeekCmdsStartPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tclPrimary contained clock skipwhite nextgroup=tclClockPred
+syn region tclClockPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclClockCmds,@tclStuff
+syn keyword tclClockCmds contained microseconds milliseconds seconds skipwhite nextgroup=tclClockCmdsMicrosecondsPred
+syn region tclClockCmdsMicrosecondsPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclClockCmdsAddOptsGroup contained "-\a\+" contains=tclClockCmdsAddOpts
+syn keyword tclClockCmdsAddOpts contained base format gmt locale timezone
+syn keyword tclClockCmds contained add clicks format scan skipwhite nextgroup=tclClockCmdsAddPred
+syn region tclClockCmdsAddPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclClockCmdsAddOptsGroup,@tclStuff skipwhite nextgroup=tclClockCmds
+
+syn keyword tclPrimary contained dict skipwhite nextgroup=tclDictPred
+syn region tclDictPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclDictCmds,@tclStuff
+syn keyword tclDictCmds contained append create exists for get incr info keys lappend merge remove replace set size unset update values with skipwhite nextgroup=tclDictCmdsAppendPred
+syn region tclDictCmdsAppendPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclDictCmdsFilterOptsGroup contained "-\a\+" contains=tclDictCmdsFilterOpts
+syn keyword tclDictCmdsFilterOpts contained key script value
+syn keyword tclDictCmds contained filter skipwhite nextgroup=tclDictCmdsFilterPred
+syn region tclDictCmdsFilterPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclDictCmdsFilterOptsGroup,@tclStuff skipwhite nextgroup=tclDictCmds
+
+syn keyword tclPrimary contained chan skipwhite nextgroup=tclChanPred
+syn region tclChanPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclChanCmds,@tclStuff
+syn keyword tclChanCmds contained blocked close create eof event flush gets names pending postevent seek tell truncate skipwhite nextgroup=tclChanCmdsBlockedPred
+syn region tclChanCmdsBlockedPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclChanCmdsConfigureOptsGroup contained "-\a\+" contains=tclChanCmdsConfigureOpts
+syn keyword tclChanCmdsConfigureOpts contained blocking buffering buffersize encoding eofchar translation
+syn keyword tclChanCmds contained configure skipwhite nextgroup=tclChanCmdsConfigurePred
+syn region tclChanCmdsConfigurePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclChanCmdsConfigureOptsGroup,@tclStuff skipwhite nextgroup=tclChanCmds
+syn match tclChanCmdsCopyOptsGroup contained "-\a\+" contains=tclChanCmdsCopyOpts
+syn keyword tclChanCmdsCopyOpts contained size command
+syn keyword tclChanCmds contained copy skipwhite nextgroup=tclChanCmdsCopyPred
+syn region tclChanCmdsCopyPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclChanCmdsCopyOptsGroup,@tclStuff skipwhite nextgroup=tclChanCmds
+syn match tclChanCmdsPutsOptsGroup contained "-\a\+" contains=tclChanCmdsPutsOpts
+syn keyword tclChanCmdsPutsOpts contained nonewline
+syn keyword tclChanCmds contained puts read skipwhite nextgroup=tclChanCmdsPutsPred
+syn region tclChanCmdsPutsPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclChanCmdsPutsOptsGroup,@tclStuff skipwhite nextgroup=tclChanCmds
+syn keyword tclSecondary contained initialize finalize watch read write seek configure cget cgetall blocking skipwhite nextgroup=tclChanSUBInitializePred
+syn region tclChanSUBInitializePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclStuff
+
+syn keyword tclPrimary contained file skipwhite nextgroup=tclFilePred
+syn region tclFilePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclFileCmds,@tclStuff
+syn keyword tclFileCmds contained channels dirname executable exists extension isdirectory isfile join link lstat mkdir mtime nativename normalize owned pathtype readable readlink rootname separator size split stat system tail volumes writable skipwhite nextgroup=tclFileCmdsChannelsPred
+syn region tclFileCmdsChannelsPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclFileCmdsAtimeOptsGroup contained "-\a\+" contains=tclFileCmdsAtimeOpts
+syn keyword tclFileCmdsAtimeOpts contained time
+syn keyword tclFileCmds contained atime skipwhite nextgroup=tclFileCmdsAtimePred
+syn region tclFileCmdsAtimePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclFileCmdsAtimeOptsGroup,@tclStuff skipwhite nextgroup=tclFileCmds
+syn match tclFileCmdsCopyOptsGroup contained "-\a\+" contains=tclFileCmdsCopyOpts
+syn keyword tclFileCmdsCopyOpts contained force
+syn keyword tclFileCmds contained copy delete rename skipwhite nextgroup=tclFileCmdsCopyPred
+syn region tclFileCmdsCopyPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$\|--+ contains=tclFileCmdsCopyOptsGroup,@tclStuff skipwhite nextgroup=tclFileCmds
+syn match tclFileCmdsAttributesOptsGroup contained "-\a\+" contains=tclFileCmdsAttributesOpts
+syn keyword tclFileCmdsAttributesOpts contained group owner permissions readonly archive hidden longname shortname system creator rsrclength
+syn keyword tclFileCmds contained attributes skipwhite nextgroup=tclFileCmdsAttributesPred
+syn region tclFileCmdsAttributesPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclFileCmdsAttributesOptsGroup,@tclStuff skipwhite nextgroup=tclFileCmds
+
+syn keyword tclPrimary contained history skipwhite nextgroup=tclHistoryPred
+syn region tclHistoryPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclHistoryCmds,@tclStuff
+syn keyword tclHistoryCmds contained change clear event info keep nextid redo skipwhite nextgroup=tclHistoryCmdsChangePred
+syn region tclHistoryCmdsChangePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclHistoryCmdsAddCmds contained exec skipwhite nextgroup=tclHistoryCmdsAddCmdsExecPred
+syn region tclHistoryCmdsAddCmdsExecPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclHistoryCmds contained add skipwhite nextgroup=tclHistoryCmdsAddPred
+syn region tclHistoryCmdsAddPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclHistoryCmdsAddCmds,@tclStuff skipwhite nextgroup=tclHistoryCmds
+
+syn keyword tclPrimary contained package skipwhite nextgroup=tclPackagePred
+syn region tclPackagePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclPackageCmds,@tclStuff
+syn keyword tclPackageCmds contained forget ifneeded names provide unknown vcompare versions vsatisfies skipwhite nextgroup=tclPackageCmdsForgetPred
+syn region tclPackageCmdsForgetPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclPackageCmdsPresentOptsGroup contained "-\a\+" contains=tclPackageCmdsPresentOpts
+syn keyword tclPackageCmdsPresentOpts contained exact
+syn keyword tclPackageCmds contained present require skipwhite nextgroup=tclPackageCmdsPresentPred
+syn region tclPackageCmdsPresentPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclPackageCmdsPresentOptsGroup,@tclStuff skipwhite nextgroup=tclPackageCmds
+
+
+syn keyword tclPrimary contained string skipwhite nextgroup=tclStringPred
+syn region tclStringPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclStringCmds,@tclStuff
+syn keyword tclStringCmds contained bytelength first index last length range repeat replace reverse tolower totitle toupper trim trimleft trimright wordend wordstart skipwhite nextgroup=tclStringCmdsBytelengthPred
+syn region tclStringCmdsBytelengthPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tclStringCmdsCompareOptsGroup contained "-\a\+" contains=tclStringCmdsCompareOpts
+syn keyword tclStringCmdsCompareOpts contained nocase length
+syn keyword tclStringCmds contained compare equal skipwhite nextgroup=tclStringCmdsComparePred
+syn region tclStringCmdsComparePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclStringCmdsCompareOptsGroup,@tclStuff skipwhite nextgroup=tclStringCmds
+syn match tclStringCmdsMapOptsGroup contained "-\a\+" contains=tclStringCmdsMapOpts
+syn keyword tclStringCmdsMapOpts contained nocase
+syn keyword tclStringCmds contained map match skipwhite nextgroup=tclStringCmdsMapPred
+syn region tclStringCmdsMapPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclStringCmdsMapOptsGroup,@tclStuff skipwhite nextgroup=tclStringCmds
+syn match tclStringCmdsIsClassAlnumOptsGroup contained "-\a\+" contains=tclStringCmdsIsClassAlnumOpts
+syn keyword tclStringCmdsIsClassAlnumOpts contained strict failindex
+syn keyword tclStringCmdsIsClass contained alnum alpha ascii boolean control digit double false graph integer list lower print punct space true upper wideinteger wordchar xdigit skipwhite nextgroup=tclStringCmdsIsClassAlnumPred
+syn region tclStringCmdsIsClassAlnumPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclStringCmdsIsClassAlnumOptsGroup,@tclStuff skipwhite nextgroup=tclStringCmdsIsClass
+syn keyword tclStringCmds contained is skipwhite nextgroup=tclStringCmdsIsPred
+syn region tclStringCmdsIsPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclStringCmdsIsClass,@tclStuff skipwhite nextgroup=tclStringCmds
+
+syn keyword tclPrimary contained trace skipwhite nextgroup=tclTracePred
+syn region tclTracePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmds,@tclStuff
+syn keyword tclTraceCmds contained variable vdelete vinfo skipwhite nextgroup=tclTraceCmdsVariablePred
+syn region tclTraceCmdsVariablePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclTraceCmdsAddCmdsCommandCmds contained rename trace skipwhite nextgroup=tclTraceCmdsAddCmdsCommandCmdsRenamePred
+syn region tclTraceCmdsAddCmdsCommandCmdsRenamePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclTraceCmdsAddCmds contained command skipwhite nextgroup=tclTraceCmdsAddCmdsCommandPred
+syn region tclTraceCmdsAddCmdsCommandPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmdsAddCmdsCommandCmds,@tclStuff skipwhite nextgroup=tclTraceCmdsAddCmds
+syn keyword tclTraceCmds contained add remove info skipwhite nextgroup=tclTraceCmdsAddPred
+syn region tclTraceCmdsAddPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmdsAddCmds,@tclStuff skipwhite nextgroup=tclTraceCmds
+syn keyword tclTraceCmdsAddCmdsExecutionCmds contained enter leave enterstep leavestep skipwhite nextgroup=tclTraceCmdsAddCmdsExecutionCmdsEnterPred
+syn region tclTraceCmdsAddCmdsExecutionCmdsEnterPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclTraceCmdsAddCmds contained execution skipwhite nextgroup=tclTraceCmdsAddCmdsExecutionPred
+syn region tclTraceCmdsAddCmdsExecutionPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmdsAddCmdsExecutionCmds,@tclStuff skipwhite nextgroup=tclTraceCmdsAddCmds
+syn keyword tclTraceCmds contained add remove info skipwhite nextgroup=tclTraceCmdsAddPred
+syn region tclTraceCmdsAddPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmdsAddCmds,@tclStuff skipwhite nextgroup=tclTraceCmds
+syn keyword tclTraceCmdsAddCmdsVariableCmds contained array read write unset skipwhite nextgroup=tclTraceCmdsAddCmdsVariableCmdsArrayPred
+syn region tclTraceCmdsAddCmdsVariableCmdsArrayPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclTraceCmdsAddCmds contained variable skipwhite nextgroup=tclTraceCmdsAddCmdsVariablePred
+syn region tclTraceCmdsAddCmdsVariablePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmdsAddCmdsVariableCmds,@tclStuff skipwhite nextgroup=tclTraceCmdsAddCmds
+syn keyword tclTraceCmds contained add remove info skipwhite nextgroup=tclTraceCmdsAddPred
+syn region tclTraceCmdsAddPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclTraceCmdsAddCmds,@tclStuff skipwhite nextgroup=tclTraceCmds
+
+syn keyword tclPrimary contained interp skipwhite nextgroup=tclInterpPred
+syn region tclInterpPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInterpCmds,@tclStuff
+syn match tclInterpCmdsCreateOptsGroup contained "-\a\+" contains=tclInterpCmdsCreateOpts
+syn keyword tclInterpCmdsCreateOpts contained safe
+syn keyword tclInterpCmds contained create skipwhite nextgroup=tclInterpCmdsCreatePred
+syn region tclInterpCmdsCreatePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInterpCmdsCreateOptsGroup,@tclStuff skipwhite nextgroup=tclInterpCmds
+syn match tclInterpCmdsInvokehiddenOptsGroup contained "-\a\+" contains=tclInterpCmdsInvokehiddenOpts
+syn keyword tclInterpCmdsInvokehiddenOpts contained namespace global
+syn keyword tclInterpCmds contained invokehidden skipwhite nextgroup=tclInterpCmdsInvokehiddenPred
+syn region tclInterpCmdsInvokehiddenPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInterpCmdsInvokehiddenOptsGroup,@tclStuff skipwhite nextgroup=tclInterpCmds
+syn match tclInterpCmdsLimitOptsGroup contained "-\a\+" contains=tclInterpCmdsLimitOpts
+syn keyword tclInterpCmdsLimitOpts contained command granularity milliseconds seconds value
+syn keyword tclInterpCmds contained limit skipwhite nextgroup=tclInterpCmdsLimitPred
+syn region tclInterpCmdsLimitPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInterpCmdsLimitOptsGroup,@tclStuff skipwhite nextgroup=tclInterpCmds
+syn keyword tclInterpCmds contained alias aliases bgerror delete eval exists expose hide hidden issafe marktrusted recursionlimit share slaves target transfer skipwhite nextgroup=tclInterpCmdsAliasPred
+syn region tclInterpCmdsAliasPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn keyword tclSecondary contained aliases alias bgerror eval expose hide hidden issafe marktrusted recursionlimit skipwhite nextgroup=tclInterpSUBAliasesPred
+syn region tclInterpSUBAliasesPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclStuff
+syn keyword tclSecondary contained invokehidden skipwhite nextgroup=tclInterpSUBInvokehiddenPred
+syn region tclInterpSUBInvokehiddenPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInterpSUBInvokehiddenOptsGroup,@tclStuff
+syn match tclInterpSUBInvokehiddenOptsGroup contained "-\a\+" contains=tclInterpSUBInvokehiddenOpts
+syn keyword tclInterpSUBInvokehiddenOpts contained namespace global
+syn keyword tclSecondary contained limit skipwhite nextgroup=tclInterpSUBLimitPred
+syn region tclInterpSUBLimitPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tclInterpSUBLimitOptsGroup,@tclStuff
+syn match tclInterpSUBLimitOptsGroup contained "-\a\+" contains=tclInterpSUBLimitOpts
+syn keyword tclInterpSUBLimitOpts contained command granularity milliseconds seconds value
+
+syn keyword tkKeyword contained bell skipwhite nextgroup=tkBellPred
+syn region tkBellPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkBellOptsGroup,@tclStuff
+syn match tkBellOptsGroup contained "-\a\+" contains=tkBellOpts
+syn keyword tkBellOpts contained nice displayof
+
+syn keyword tkKeyword contained clipboard skipwhite nextgroup=tkClipboardPred
+syn region tkClipboardPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkClipboardCmds,@tclStuff
+syn match tkClipboardCmdsClearOptsGroup contained "-\a\+" contains=tkClipboardCmdsClearOpts
+syn keyword tkClipboardCmdsClearOpts contained displayof format type
+syn keyword tkClipboardCmds contained clear append get skipwhite nextgroup=tkClipboardCmdsClearPred
+syn region tkClipboardCmdsClearPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkClipboardCmdsClearOptsGroup,@tclStuff skipwhite nextgroup=tkClipboardCmds
+
+syn keyword tkKeyword contained console consoleinterp skipwhite nextgroup=tkConsolePred
+syn region tkConsolePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkConsoleCmds,@tclStuff
+syn keyword tkConsoleCmds contained eval hide show title record skipwhite nextgroup=tkConsoleCmdsEvalPred
+syn region tkConsoleCmdsEvalPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tkKeyword contained focus skipwhite nextgroup=tkFocusPred
+syn region tkFocusPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkFocusOptsGroup,@tclStuff
+syn match tkFocusOptsGroup contained "-\a\+" contains=tkFocusOpts
+syn keyword tkFocusOpts contained displayof force lastfor
+
+syn keyword tkKeyword contained tkwait skipwhite nextgroup=tkTkwaitPred
+syn region tkTkwaitPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTkwaitCmds,@tclStuff
+syn keyword tkTkwaitCmds contained variable visibility window skipwhite nextgroup=tkTkwaitCmdsVariablePred
+syn region tkTkwaitCmdsVariablePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tkKeyword contained winfo skipwhite nextgroup=tkWinfoPred
+syn region tkWinfoPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWinfoCmds,@tclStuff
+syn keyword tkWinfoCmds contained containing interps pathname visualscells children class colormapfull depth exists fpixels geom[etry] height id ismapped manager name parent pixels pointerx pointerxy pointery reqheight reqwidth rgb rootx rooty screen screencells screendepth screenheight screenmmheight screenmmwidth screenvisual screenwidth server toplevel viewable visual visualid vrootheight vrootwidth vrootx vrooty width x y skipwhite nextgroup=tkWinfoCmdsContainingPred
+syn region tkWinfoCmdsContainingPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkWinfoCmdsAtomOptsGroup contained "-\a\+" contains=tkWinfoCmdsAtomOpts
+syn keyword tkWinfoCmdsAtomOpts contained displayof includeids
+syn keyword tkWinfoCmds contained atom atomname containing interps pathname visualsavailable skipwhite nextgroup=tkWinfoCmdsAtomPred
+syn region tkWinfoCmdsAtomPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWinfoCmdsAtomOptsGroup,@tclStuff skipwhite nextgroup=tkWinfoCmds
+
+syn keyword tkKeyword contained wm skipwhite nextgroup=tkWmPred
+syn region tkWmPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWmCmds,@tclStuff
+syn keyword tkWmCmds contained aspect attributes attributes attributes client colormapwindows command deiconify focusmodel frame geom[etry] grid group iconbitmap iconify iconmask iconname iconphoto iconposition iconwindow maxsize minsize overrideredirect positionfrom protocol resizable sizefrom stackorder state title transient withdraw skipwhite nextgroup=tkWmCmdsAspectPred
+syn region tkWmCmdsAspectPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tkKeyword contained grab skipwhite nextgroup=tkGrabPred
+syn region tkGrabPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkGrabOptsGroup,tkGrabCmds,@tclStuff
+syn keyword tkGrabCmds contained current release set status skipwhite nextgroup=tkGrabOptsGroup skipwhite nextgroup=tkGrabCmdsCurrentPred
+syn region tkGrabCmdsCurrentPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkGrabOptsGroup contained "-\a\+" contains=tkGrabOpts
+syn keyword tkGrabOpts contained global
+
+syn keyword tkKeyword contained font skipwhite nextgroup=tkFontPred
+syn region tkFontPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkFontCmds,@tclStuff
+syn keyword tkFontCmds contained delete names skipwhite nextgroup=tkFontCmdsDeletePred
+syn region tkFontCmdsDeletePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkFontCmdsFamiliesOptsGroup contained "-\a\+" contains=tkFontCmdsFamiliesOpts
+syn keyword tkFontCmdsFamiliesOpts contained displayof
+syn keyword tkFontCmds contained families measure skipwhite nextgroup=tkFontCmdsFamiliesPred
+syn region tkFontCmdsFamiliesPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkFontCmdsFamiliesOptsGroup,@tclStuff skipwhite nextgroup=tkFontCmds
+syn match tkFontCmdsActualOptsGroup contained "-\a\+" contains=tkFontCmdsActualOpts
+syn keyword tkFontCmdsActualOpts contained displayof ascent descent linespace fixed family size weight slant underline overstrike
+syn keyword tkFontCmds contained actual configure create metrics skipwhite nextgroup=tkFontCmdsActualPred
+syn region tkFontCmdsActualPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkFontCmdsActualOptsGroup,@tclStuff skipwhite nextgroup=tkFontCmds
+
+syn keyword tkKeyword contained option skipwhite nextgroup=tkOptionPred
+syn region tkOptionPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkOptionCmds,@tclStuff
+syn keyword tkOptionCmds contained add clear get readfile skipwhite nextgroup=tkOptionCmdsAddPred
+syn region tkOptionCmdsAddPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+
+syn keyword tkKeyword contained grid skipwhite nextgroup=tkGridPred
+syn region tkGridPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkGridOptsGroup,tkGridCmds,@tclStuff
+syn keyword tkGridCmds contained anchor bbox forget info location propogate remove size slaves skipwhite nextgroup=tkGridCmdsAnchorPred
+syn region tkGridCmdsAnchorPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkGridCmdsColumnconfigureOptsGroup contained "-\a\+" contains=tkGridCmdsColumnconfigureOpts
+syn keyword tkGridCmdsColumnconfigureOpts contained column columnspan in ipadx ipady padx pady row rowspan sticky minsize weight uniform pad
+syn keyword tkGridCmds contained columnconfigure rowconfigure configure skipwhite nextgroup=tkGridCmdsColumnconfigurePred
+syn region tkGridCmdsColumnconfigurePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkGridCmdsColumnconfigureOptsGroup,@tclStuff skipwhite nextgroup=tkGridCmds
+syn match tkGridOptsGroup contained "-\a\+" contains=tkGridOpts
+syn keyword tkGridOpts contained column columnspan in ipadx ipady padx pady row rowspan sticky minsize weight uniform pad
+
+syn keyword tkKeyword contained pack skipwhite nextgroup=tkPackPred
+syn region tkPackPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkPackOptsGroup,tkPackCmds,@tclStuff
+syn keyword tkPackCmds contained forget info propogate slaves skipwhite nextgroup=tkPackCmdsForgetPred
+syn region tkPackCmdsForgetPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkPackCmdsConfigureOptsGroup contained "-\a\+" contains=tkPackCmdsConfigureOpts
+syn keyword tkPackCmdsConfigureOpts contained after anchor before expand fill in ipadx ipady padx pady side
+syn keyword tkPackCmds contained configure skipwhite nextgroup=tkPackCmdsConfigurePred
+syn region tkPackCmdsConfigurePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkPackCmdsConfigureOptsGroup,@tclStuff skipwhite nextgroup=tkPackCmds
+syn match tkPackOptsGroup contained "-\a\+" contains=tkPackOpts
+syn keyword tkPackOpts contained after anchor before expand fill in ipadx ipady padx pady side
+
+syn keyword tkKeyword contained place skipwhite nextgroup=tkPlacePred
+syn region tkPlacePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkPlaceOptsGroup,tkPlaceCmds,@tclStuff
+syn keyword tkPlaceCmds contained forget info slaves skipwhite nextgroup=tkPlaceCmdsForgetPred
+syn region tkPlaceCmdsForgetPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkPlaceCmdsConfigureOptsGroup contained "-\a\+" contains=tkPlaceCmdsConfigureOpts
+syn keyword tkPlaceCmdsConfigureOpts contained anchor bordermode height in relheight relwidth relx rely width x y
+syn keyword tkPlaceCmds contained configure skipwhite nextgroup=tkPlaceCmdsConfigurePred
+syn region tkPlaceCmdsConfigurePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkPlaceCmdsConfigureOptsGroup,@tclStuff skipwhite nextgroup=tkPlaceCmds
+syn match tkPlaceOptsGroup contained "-\a\+" contains=tkPlaceOpts
+syn keyword tkPlaceOpts contained anchor bordermode height in relheight relwidth relx rely width x y
+
+syn keyword tkKeyword contained tk_messageBox skipwhite nextgroup=tkTk_messageboxPred
+syn region tkTk_messageboxPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTk_messageboxOptsGroup,@tclStuff
+syn match tkTk_messageboxOptsGroup contained "-\a\+" contains=tkTk_messageboxOpts
+syn keyword tkTk_messageboxOpts contained default detail icon message parent title type
+
+syn keyword tkKeyword contained tk skipwhite nextgroup=tkTkPred
+syn region tkTkPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTkCmds,@tclStuff
+syn keyword tkTkCmds contained appname windowingsystem skipwhite nextgroup=tkTkCmdsAppnamePred
+syn region tkTkCmdsAppnamePred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=,@tclStuff
+syn match tkTkCmdsScalingOptsGroup contained "-\a\+" contains=tkTkCmdsScalingOpts
+syn keyword tkTkCmdsScalingOpts contained displayof
+syn keyword tkTkCmds contained scaling inactive useinputmethods skipwhite nextgroup=tkTkCmdsScalingPred
+syn region tkTkCmdsScalingPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTkCmdsScalingOptsGroup,@tclStuff skipwhite nextgroup=tkTkCmds
+syn match tkTkCmdsCaretCmdsWindowOptsGroup contained "-\a\+" contains=tkTkCmdsCaretCmdsWindowOpts
+syn keyword tkTkCmdsCaretCmdsWindowOpts contained x y height
+syn keyword tkTkCmdsCaretCmds contained window skipwhite nextgroup=tkTkCmdsCaretCmdsWindowPred
+syn region tkTkCmdsCaretCmdsWindowPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTkCmdsCaretCmdsWindowOptsGroup,@tclStuff skipwhite nextgroup=tkTkCmdsCaretCmds
+syn keyword tkTkCmds contained caret skipwhite nextgroup=tkTkCmdsCaretPred
+syn region tkTkCmdsCaretPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTkCmdsCaretCmds,@tclStuff skipwhite nextgroup=tkTkCmds
+
+syn keyword tkKeyword contained send skipwhite nextgroup=tkSendPred
+syn region tkSendPred contained excludenl keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkSendOptsGroup,@tclStuff
+syn match tkSendOptsGroup contained "-\a\+" contains=tkSendOpts
+syn keyword tkSendOpts contained async displayof
+
+
+" -------------------------
+" tk: Syntax - special case words
+" -------------------------
+syn keyword tkWidgetMenu              contained cascade separator command checkbutton radiobutton
+syn keyword tclSecondary              contained activate addtag bbox canvasx canvasy clone coords curselection dchars delete delta deselect dtag entrycget entryconfigure find flash focus fraction get gettags icursor identify index insert invoke lower move moveto nearest panecget paneconfigure panes post postcascade proxy raise replace sash scale see set toggle type unpost validate xposition yposition
+syn keyword tclSecondary              contained conf[igure] cget skipwhite nextgroup=tkWidgetPredicate
+syn keyword tclSecondary              contained add skipwhite nextgroup=tkWidgetAddPredicate
+syn region tkWidgetPredicate          contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetOptsGroup,@tclStuff
+syn region tkWidgetAddPredicate       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetMenu,tkWidgetOptsGroup,@tclStuff
+
+" these come from various widgets, their predicate spaces are a superset of everything required
+syn keyword tclSecondary              contained scan skipwhite nextgroup=tkWidgetScanPredicate
+syn region tkWidgetScanPredicate      contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkBindSubstGroup,tkScanCmds,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained select skipwhite nextgroup=tkWidgetSelectPredicate
+syn region tkWidgetSelectPredicate    contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkSelectCmds,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained scroll skipwhite nextgroup=tkWidgetScrollPredicate
+syn region tkWidgetScrollPredicate    contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkScrollCmds,tkScrollbarElems,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained xview yview skipwhite nextgroup=tkWidgetViewPredicate
+syn region tkWidgetViewPredicate      contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkViewCmds,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained edit skipwhite nextgroup=tkWidgetEditPredicate
+syn region tkWidgetEditPredicate      contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkEditCmds,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained mark skipwhite nextgroup=tkWidgetMarkPredicate
+syn region tkWidgetMarkPredicate      contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkMarkCmds,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained peer skipwhite nextgroup=tkWidgetPeerPredicate
+syn region tkWidgetPeerPredicate      contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkPeerCmds,tkWidgetOptsGroup,@tclStuff
+" terminated switches, needs keeepend
+syn keyword tclSecondary              contained search skipwhite nextgroup=tkWidgetSearchPredicate
+syn region tkWidgetSearchPredicate    contained excludenl keepend start=+.+ end=+}\|]\|;\|.$\|--+ contains=tkWidgetSearchOptsGroup,@tclStuff
+syn match tkWidgetSearchOptsGroup     contained "-\a\+" contains=tkWidgetSearchOpts skipwhite nextgroup=tkWidgetSearchOptsGroup,tkWidgetOptsGroup,@tclStuff
+syn keyword tkWidgetSearchOpts        contained forwards back[wards] exact regexp nolinestop nocase count all overlap elide
+syn keyword tclSecondary              contained selection skipwhite nextgroup=tkWidgetSelectionPredicate
+syn region tkWidgetSelectionPredicate contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkSelectionCmds,tkWidgetOptsGroup,@tclStuff
+syn keyword tclSecondary              contained tag skipwhite nextgroup=tkWidgetTagPredicate
+syn region tkWidgetTagPredicate       contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkTagCmds,tkTagOptsGroup,@tclStuff
+syn keyword tclSecondary              contained window skipwhite nextgroup=tkWidgetWindowPredicate
+syn region tkWidgetWindowPredicate    contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWindowCmds,tkWidgetOptsGroup,@tclStuff
+
+syn keyword tclSecondary contained compare skipwhite nextgroup=tkWidgetComparePredicate
+" syn region tkWidgetComparePredicate   contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tclStuff
+" TODO compare predicate is:
+" anything
+" operator -> an expression
+" anything
+
+syn keyword tclSecondary contained count skipwhite nextgroup=tkWidgetCountPredicate
+syn region tkWidgetCountPredicate   contained excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkCountOptsGroup,@tclStuff
+syn match tkCountOptsGroup  contained "-\a\+" contains=tkCountOpts skipwhite nextgroup=tkCountOpts,@tclStuff
+syn keyword tkCountOpts contained chars displaychars displayindicies displaylines indices lines xpixels ypixels update
+hi link tkCountOpts tclOption
+
+
+syn keyword tkEditCmds            contained modified redo reset separator undo
+syn keyword tkMarkCmds            contained gravity names next previous set unset 
+syn keyword tkPeerCmds            contained create names
+syn keyword tkScanCmds             contained mark dragto
+syn keyword tkSelectCmds           contained adjust anchor clear element from includes item present range set to
+syn keyword tkSelectionCmds        contained anchor clear includes set
+syn keyword tkScrollCmds           contained units pages
+syn keyword tkScrollbarElems       contained arrow1 arrow2 slider trough1 trough2
+syn keyword tkTagCmds             contained add bind cget config[ure] delete lower names nextrange prevrange raise ranges remove
+syn match tkTagOptsGroup contained "-\a\+" contains=tkTagOpts
+syn keyword tkTagOpts    contained background bgstipple borderwidth elide fgstipple font foreground justify lmargin1 lmargin2 offset overstrike relief spacing1 spacing2 spacing3 tabs tabstyle under[line] wrap
+syn keyword tkViewCmds             contained moveto scroll
+syn keyword tkWidgetOpts           contained accel[erator] activebackground activeborderwidth activeforeground anchor background bd bg bitmap borderwidth columnbreak command compound cursor disabledfore[ground] exportselection fg font foreground hidemargin highlightbackground highlightcolor highlightthick[ness] image indicatoron insertbackground insertborderwidth insertofftime insertontime insertwidth jump justify label menu offvalue onvalue ori[ent] padx pady relief repeatdelay repeatinterval selectbackground selectborderwidth selectcolor selectforeground selectimage setgrid state takefocus text textvar[iable] troughcolor underline value variable wraplength xscrollcommand yscrollcommand
+syn keyword tkWidgetOpts           contained activerelief activestyle aspect background bigincrement buttonbackground buttoncursor buttondownrelief buttonuprelief class closeenough colormap command confine container default digits direction disabledback[ground] disabledfore[ground] elementborderwidth format from handlepad handlesize height increment indicatoron invalidcommand invcmd justify label labelanchor labelwidget length listvariable menu offrelief offvalue onvalue opaqueresize overrelief postcommand readonlybackground resolution sashcursor sashpad sashrelief sashwidth screen scrollregion selectcolor selectimage selectmode show showhandle showvalue sliderlength sliderrelief state tearoff tearoffcommand tickinterval title to tristateimage tristatevalue type use validate validatecommand value values variable vcmd visual width wrap xscrollincrement yscrollincrement
+syn keyword tkWidgetOpts           contained autoseparators blockcursor endline inactiveselectionbackground maxundo spacing1 spacing2 spacing3 startline state tabs tabstyle undo wrap
+syn keyword tkWindowCmds          contained cget configure create names
+syn match tkWidgetOptsGroup        contained "-\a\+" contains=tkWidgetOpts
+
+" SPECIAL CASE: 
+syn keyword tkKeyword      contained bind skipwhite nextgroup=tkBindPredicate
+syn keyword tclSecondary   contained bind skipwhite nextgroup=tkBindPredicate
+syn region tkBindPredicate contained keepend extend excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkBindTag
+syn region tkBindTag       contained start="." end="\s\|]" skipwhite nextgroup=tkBindSeq contains=@tclStuff
+syn region tkBindSeq       contained start="." end="\s\|]" skipwhite nextgroup=tkBindScript contains=tkEvent
+syn region tkBindScript    contained keepend extend excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+                                     contains=@tclCommandCluster
+syn region tkBindScript    contained keepend extend excludenl matchgroup=Bold start=+\s*\(\\\)\@<!{+  end=+}+ skip=+$\|\\$\|\\}+ contains=@tclCommandCluster
+syn match tkBindSubstGroup contained "%%"
+syn match tkBindSubstGroup contained "%#"
+syn match tkBindSubstGroup contained "%\a\>" contains=tkBindSubst
+syn keyword tkBindSubst    contained a b c d f h i k m o p s t w x y A B D E K N P R S T W X Y
+
+" SPECIAL CASE: 
+syn keyword tkKeyword           contained event skipwhite nextgroup=tkEventPredicate,@tclStuff
+syn region tkEventPredicate     contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkEventCmds
+syn region tkEventCmdsPredicate contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tkEventCluster
+syn keyword tkEventCmds         contained add delete generate info skipwhite nextgroup=tkEventCmdsPredicate
+syn match tkEventFieldsGroup    contained "-\a\+" contains=tkEventFields
+syn keyword tkEventFields       contained above borderwidth button count data delta detail focus height keycode keysym mode override place root rootx rooty sendevent serial state subwindow time warp width when x y
+syn keyword tkEventWhen         contained now tail head mark
+syn cluster tkEventCluster contains=tkEventCmds,tkEventFieldsGroup,tkEventWhen,@tclStuff
+
+" SPECIAL CASE: 
+syn keyword tkWidget                    contained canvas skipwhite nextgroup=tkCanvasPredicate
+syn region tkCanvasPredicate            contained keepend excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tkCanvasCluster,@tclStuff
+syn keyword tkCanvasTagOpts             contained above all below closest enclosed overlapping withtag
+syn keyword tkCanvasPsOpts              contained colormap colormode file fontmap height pageanchor pageheight pagewidth pagex pagey rotate width x y
+syn keyword tkCanvasItemOpts            contained activebackground activebitmap activedash activefill activeforeground activeimage activeoutline activeoutlinestipple activestipple activewidth anchor arrow arrowshape background bitmap capstyle dash dashoffset disabledbackground disabledbitmap disableddash disabledfill disabledforeground disabledimage disabledoutline disabledoutlinestipple disabledstipple disabledwidth extent fill font foreground height image joinstyle justify offset outline outlinestipple smooth splinesteps start state stipple style tag[s] text width window
+syn cluster tkCanvasCluster            contains=tkCanvasItemOpts,tkCanvasTagOpts,tkWidgetOptsGroup
+" the create command
+syn keyword tkWidgetCreate              contained create skipwhite nextgroup=tkWidgetCreatePredicate
+syn region tkWidgetCreatePredicate      contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateCmds,@tclStuff
+syn match tkWidgetCreateCommonOptsGroup contained "-\a\+" contains=tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateCommonOpts    contained activedash activefill activeoutline activeoutlinestipple activestipple activewidth dash dashoffset disableddash disabledfill disabledoutline disabledoutlinestipple disabledstipple disabledwidth fill offset outline outlinestipple state stipple tag[s] width
+syn keyword tkWidgetCreateCmds          contained arc skipwhite nextgroup=tkWidgetCreateArcPred
+syn region tkWidgetCreateArcPred        contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateArcOptsGroup,@tclStuff
+syn match tkWidgetCreateArcOptsGroup    contained "-\a\+" contains=tkWidgetCreateArcOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateArcOpts       contained extent start style
+syn keyword tkWidgetCreateCmds          contained bitmap skipwhite nextgroup=tkWidgetCreateBitmapPred
+syn region tkWidgetCreateBitmapPred     contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateBitmapOptsGroup,@tclStuff
+syn match tkWidgetCreateBitmapOptsGroup contained "-\a\+" contains=tkWidgetCreateBitmapOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateBitmapOpts    contained activebackground activebitmap activeforeground anchor background bitmap disabledbackground disabledbitmap disabledforeground foreground
+syn keyword tkWidgetCreateCmds          contained image skipwhite nextgroup=tkWidgetCreateImagePred
+syn region tkWidgetCreateImagePred      contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateImageOptsGroup,@tclStuff
+syn match tkWidgetCreateImageOptsGroup  contained "-\a\+" contains=tkWidgetCreateImageOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateImageOpts     contained anchor image activeimage disabledimage
+syn keyword tkWidgetCreateCmds          contained line skipwhite nextgroup=tkWidgetCreateLinePred
+syn region tkWidgetCreateLinePred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateLineOptsGroup,@tclStuff
+syn match tkWidgetCreateLineOptsGroup   contained "-\a\+" contains=tkWidgetCreateLineOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateLineOpts      contained arrow arrowshape capstyle joinstyle smooth splinesteps
+syn keyword tkWidgetCreateCmds          contained oval skipwhite nextgroup=tkWidgetCreateOvalPred
+syn region tkWidgetCreateOvalPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateCommonOptsGroup,@tclStuff
+syn keyword tkWidgetCreateCmds          contained poly[gon] skipwhite nextgroup=tkWidgetCreatePolyPred
+syn region tkWidgetCreatePolyPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreatePolyOptsGroup,@tclStuff
+syn match tkWidgetCreatePolyOptsGroup   contained "-\a\+" contains=tkWidgetCreatePolyOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreatePolyOpts      contained joinstyle smooth splinesteps
+syn keyword tkWidgetCreateCmds          contained rect[angle] skipwhite nextgroup=tkWidgetCreateRectPred
+syn region tkWidgetCreateRectPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateCommonOptsGroup,@tclStuff
+syn keyword tkWidgetCreateCmds          contained text skipwhite nextgroup=tkWidgetCreateTextPred
+syn region tkWidgetCreateTextPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateTextOptsGroup,@tclStuff
+syn match tkWidgetCreateTextOptsGroup   contained "-\a\+" contains=tkWidgetCreateTextOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateTextOpts      contained anchor font justify text width
+syn keyword tkWidgetCreateCmds          contained window skipwhite nextgroup=tkWidgetCreateWinPred
+syn region tkWidgetCreateWinPred        contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateWinOptsGroup,@tclStuff
+syn match tkWidgetCreateWinOptsGroup    contained "-\a\+" contains=tkWidgetCreateWinOpts,tkWidgetCreateCommonOpts
+syn keyword tkWidgetCreateWinOpts       contained anchor height width window
+syn keyword tclSecondary                contained itemconfig[ure] itemcget skipwhite nextgroup=tkCanvasItemConfigurePred
+syn region tkCanvasItemConfigurePred    contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreateArcOpts,tkWidgetCreateBitmapOpts,tkWidgetCreateCommonOpts,tkWidgetCreateImageOpts,tkWidgetCreateLineOpts,tkWidgetCreateOvalOpts,tkWidgetCreatePolyOpts,tkWidgetCreateRectOpts,tkWidgetCreateTextOpts,tkWidgetCreateWinOpts,@tclStuff
+
+" postscript
+syn keyword tclSecondary contained postscript skipwhite nextgroup=tkCanvasPsPred
+syn region tkCanvasPsPred contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkCanvasPsOptsGroup,@tclStuff
+syn match tkCanvasPsOptsGroup contained "-\a\+" contains=tkCanvasPsOpts
+
+" SPECIAL CASE: 
+" , includes -  bitmap photo
+syn keyword tkWidget                   contained image skipwhite nextgroup=tkWidgetImagePred
+syn region tkWidgetImagePred           contained keepend excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkImageCmds,tkWidgetCreate,@tclStuff
+syn keyword tkImageCmds                contained delete inuse names type types 
+syn keyword tkImageCmds                contained anchor height width window
+
+" create bitmap starts in canvas, this appends
+syn keyword tkWidgetCreateBitmapOpts   contained background data file foreground maskdata maskfile
+syn keyword tkWidgetCreateCmds         contained photo skipwhite nextgroup=tkWidgetCreatePhotoPred
+syn region tkWidgetCreatePhotoPred     contained keepend excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetCreatePhotoOptsGroup,@tclStuff
+syn match tkWidgetCreatePhotoOptsGroup contained "-\a\+" contains=tkWidgetCreatePhotoOpts
+syn keyword tkWidgetCreatePhotoOpts    contained data format file gamma height palette width
+
+" Syntax: from photo
+syn keyword tclSecondary               contained blank
+syn keyword tclSecondary               contained copy skipwhite nextgroup=tkWidgetImageCopyPred
+syn region tkWidgetImageCopyPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetImageCopyOptsGroup,@tclStuff
+syn match tkWidgetImageCopyOptsGroup   contained "-\a\+" contains=tkWidgetImageCopyOpts
+syn keyword tkWidgetImageCopyOpts      contained from to shrink zoom subsample compositingrule
+syn keyword tclSecondary               contained data skipwhite nextgroup=tkWidgetImageDataPred
+syn region tkWidgetImageDataPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetImageDataOptsGroup,@tclStuff
+syn match tkWidgetImageDataOptsGroup   contained "-\a\+" contains=tkWidgetImageDataOpts
+syn keyword tkWidgetImageDataOpts      contained background format from grayscale
+syn keyword tclSecondary               contained put skipwhite nextgroup=tkWidgetImagePutPred
+syn region tkWidgetImagePutPred        contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetImagePutOptsGroup,@tclStuff
+syn match tkWidgetImagePutOptsGroup    contained "-\a\+" contains=tkWidgetImagePutOpts
+syn keyword tkWidgetImagePutOpts       contained format to
+syn keyword tclSecondary               contained read skipwhite nextgroup=tkWidgetImageReadPred
+syn region tkWidgetImageReadPred       contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetImageReadOptsGroup,@tclStuff
+syn match tkWidgetImageReadOptsGroup   contained "-\a\+" contains=tkWidgetImageReadOpts
+syn keyword tkWidgetImageReadOpts      contained format from shrink to
+syn keyword tclSecondary               contained redither
+syn keyword tclSecondary               contained transparency skipwhite nextgroup=tkWidgetImageTransPred
+syn region tkWidgetImageTransPred      contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetImageTransOptsGroup,@tclStuff
+syn match tkWidgetImageTransOptsGroup  contained "-\a\+" contains=tkWidgetImageTransOpts
+syn keyword tkWidgetImageTransOpts     contained get set
+syn keyword tclSecondary               contained write skipwhite nextgroup=tkWidgetImageWritePred
+syn region tkWidgetImageWritePred      contained keepend start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=tkWidgetImageWriteOptsGroup,@tclStuff
+syn match tkWidgetImageWriteOptsGroup  contained "-\a\+" contains=tkWidgetImageWriteOpts
+syn keyword tkWidgetImageWriteOpts     contained background format from grayscale
+
+" SPECIAL CASE: 
+syn keyword tkWidget           contained text skipwhite nextgroup=tkTextPredicate
+syn keyword tkKeyword          contained tk_textCopy tk_textCut tk_textPaste
+syn region tkTextPredicate     contained keepend excludenl start=+.+ skip=+\\$+ end=+}\|]\|;\|$+ contains=@tkTextCluster,@tclStuff
+" this is how you 'subclass' an OptsGroup
+syn match tkTextWidgetOptsGroup contained "-\a\+" contains=tkTextWidgetOpts,tkWidgetOpts
+syn keyword tkTextWidgetOpts    contained autoseparators blockcursor endline inactiveselectionbackground maxundo spacing1 spacing2 spacing3 startline state tabs tabstyle undo wrap
+syn cluster tkTextCluster      contains=tkTextWidgetOptsGroup
+
+
+" SPECIAL CASE: 
+syn keyword tkWidget           contained listbox skipwhite nextgroup=tkWidgetPredicate
+
+
+
+" -------------------------
+" Tcl: Packages
+" ------------------------- 
+
+if exists("s:tcl_snit_active")
+    runtime! syntax/tcl_snit.vim
+endif
+
+if exists("s:tcl_sqlite_active")
+    runtime! syntax/tcl_sqlite.vim
+endif
+
+if exists("s:tcl_critcl_active")
+    runtime! syntax/tcl_critcl.vim
+endif
+
+if exists("s:tcl_togl_active")
+    runtime! syntax/tcl_togl.vim
+endif
+
+if exists("s:tcl_itcl_active")
+    runtime! syntax/tcl_itcl.vim
+endif
+
+if exists("s:tcl_ttk_active")
+    runtime! syntax/tcl_ttk.vim
+endif
+
+" -------------------------
+
+if exists("s:tcl_highlight_all")
+    let s:tcl_highlight_bookends = 1
+    let s:tcl_highlight_primary = 1
+    let s:tcl_highlight_secondary = 1
+    let s:tcl_highlight_variables = 1
+    let s:tcl_highlight_options = 1
+    let s:tcl_highlight_expressions = 1
+endif
+
+if version >= 508 || !exists("s:did_tcl_syn_inits")
+    if version <= 508
+        let s:did_tcl_syn_inits = 1
+        command -nargs=+ HiLink hi link <args>
+    else
+        command -nargs=+ HiLink hi def link <args>
+    endif
+endif
+
+" -------------------------
+" Highlights: - Basic
+" -------------------------
+HiLink tclStart          Special
+HiLink tclLContinueOK    Special
+HiLink tclLContinueError Error
+HiLink tclQuotes         String
+HiLink tclNumber         Number
+HiLink tclComment        Comment
+HiLink tclComment2       Comment
+HiLink tclCommentBraces  Comment
+HiLink tclIfComment      Comment
+HiLink tclIfCommentStart Comment
+HiLink tclSpecial        Special
+HiLink tclTodo           Todo
+HiLink tclExpand         Underlined
+HiLink tclREClassGroup   Special
+HiLink tclREClass        Special
+" ------------------
+if exists("s:tcl_highlight_primary")
+    HiLink tclKeyword        Statement
+    HiLink tclNamespace      Statement
+    HiLink tclPrimary        Statement
+    HiLink tclConditional    Conditional
+    HiLink tclRepeat         Repeat
+    HiLink tclException      Exception
+    HiLink tclLabel          Label
+    HiLink tkWidget          Underlined
+endif
+" ------------------
+if exists("s:tcl_highlight_lcs_are_warnings")
+    hi! def link tclLContinueOk WarningMsg
+endif
+" ------------------
+if exists("s:tcl_highlight_namespace_bold")
+    hi! def link tclNamespace      Bold
+endif
+" ------------------
+if exists("s:tcl_highlight_options")
+    hi! def link tclOption         PreProc
+endif
+" ------------------
+if exists("s:tcl_highlight_secondary")
+    hi! def link tclSecondary      Type
+    hi! def link tclSubcommand     Type
+endif
+" ------------------
+if exists("s:tcl_highlight_variables")
+    hi! def link tclVariable       Identifier
+endif
+" ------------------
+if exists("s:tcl_highlight_expressions")
+    hi! def link tclEnsemble       Special
+    hi! def link tclMaths          Special
+endif
+" ------------------
+HiLink tclProcName       Bold
+HiLink tclProcDef        Bold
+HiLink tclProcType       Bold
+" ------------------
+HiLink tkColor           Bold
+HiLink tkWidgetCmds      tclSubcommand
+HiLink tkWidgetOpts      tclOption
+HiLink tclMagicName      tclKeyword
+HiLink tkKeyword         tclKeyword
+HiLink tkReserved        tclKeyword
+HiLink tkDialog          tclKeyword
+HiLink tkEvent           tclQuotes
+HiLink tkWidgetName      tclQuotes
+
+
+" -------------------------
+" Highlights: - Extended
+" -------------------------
+HiLink tclAfterCmds tclSubcommand
+HiLink tclArrayCmds tclSubcommand
+HiLink tclArrayCmdsNamesOpts tclOption
+HiLink tclBinaryCmds tclSubcommand
+HiLink tclChanCmds tclSubcommand
+HiLink tclChanCmdsConfigureOpts tclOption
+HiLink tclChanCmdsCopyOpts tclOption
+HiLink tclChanCmdsPutsOpts tclOption
+HiLink tclClockCmds tclSubcommand
+HiLink tclClockCmdsAddOpts tclOption
+HiLink tclDictCmds tclSubcommand
+HiLink tclDictCmdsFilterOpts tclOption
+HiLink tclEncodingCmds tclSubcommand
+HiLink tclExecOpts tclOption
+HiLink tclFconfigureOpts tclOption
+HiLink tclFcopyOpts tclOption
+HiLink tclFileCmds tclSubcommand
+HiLink tclFileCmdsAtimeOpts tclOption
+HiLink tclFileCmdsAttributesOpts tclOption
+HiLink tclFileCmdsCopyOpts tclOption
+HiLink tclFileeventCmds tclSubcommand
+HiLink tclGlobOpts tclOption
+HiLink tclHistoryCmds tclSubcommand
+HiLink tclHistoryCmdsAddCmds tclSubcommand
+HiLink tclInfoCmds tclSubcommand
+HiLink tclInterpCmds tclSubcommand
+HiLink tclInterpCmdsCreateOpts tclOption
+HiLink tclInterpCmdsInvokehiddenOpts tclOption
+HiLink tclInterpCmdsLimitOpts tclOption
+HiLink tclInterpSUBInvokehiddenOpts tclOption
+HiLink tclInterpSUBLimitOpts tclOption
+HiLink tclLsearchOpts tclOption
+HiLink tclLsortOpts tclOption
+HiLink tclMemoryCmds tclSubcommand
+HiLink tclOpenOpts tclOption
+HiLink tclPackageCmds tclSubcommand
+HiLink tclPackageCmdsPresentOpts tclOption
+HiLink tclPutsOpts tclOption
+HiLink tclRegexpOpts tclOption
+HiLink tclRegsubOpts tclOption
+HiLink tclReturnOpts tclOption
+HiLink tclSeekCmds tclSubcommand
+HiLink tclSocketOpts tclOption
+HiLink tclSourceOpts tclOption
+HiLink tclStringCmds tclSubcommand
+HiLink tclStringCmdsCompareOpts tclOption
+HiLink tclStringCmdsIsClass tclEnsemble
+HiLink tclStringCmdsIsClassAlnumOpts tclOption
+HiLink tclStringCmdsMapOpts tclOption
+HiLink tclSubstOpts tclOption
+HiLink tclSwitchOpts tclOption
+HiLink tclTraceCmds tclSubcommand
+HiLink tclTraceCmdsAddCmds tclSubcommand
+HiLink tclTraceCmdsAddCmdsCommandCmds tclSubcommand
+HiLink tclTraceCmdsAddCmdsExecutionCmds tclSubcommand
+HiLink tclTraceCmdsAddCmdsVariableCmds tclSubcommand
+HiLink tclUnloadOpts tclOption
+HiLink tclUnsetOpts tclOption
+HiLink tclUpdateCmds tclSubcommand
+HiLink tkBellOpts tclOption
+HiLink tkClipboardCmds tclSubcommand
+HiLink tkClipboardCmdsClearOpts tclOption
+HiLink tkConsoleCmds tclSubcommand
+HiLink tkFocusOpts tclOption
+HiLink tkFontCmds tclSubcommand
+HiLink tkFontCmdsActualOpts tclOption
+HiLink tkFontCmdsFamiliesOpts tclOption
+HiLink tkGrabCmds tclSubcommand
+HiLink tkGrabOpts tclOption
+HiLink tkGridCmds tclSubcommand
+HiLink tkGridCmdsColumnconfigureOpts tclOption
+HiLink tkGridOpts tclOption
+HiLink tkOptionCmds tclSubcommand
+HiLink tkPackCmds tclSubcommand
+HiLink tkPackCmdsConfigureOpts tclOption
+HiLink tkPackOpts tclOption
+HiLink tkPlaceCmds tclSubcommand
+HiLink tkPlaceCmdsConfigureOpts tclOption
+HiLink tkPlaceOpts tclOption
+HiLink tkSendOpts tclOption
+HiLink tkTkCmds tclSubcommand
+HiLink tkTkCmdsCaretCmds tclSubcommand
+HiLink tkTkCmdsCaretCmdsWindowOpts tclOption
+HiLink tkTkCmdsScalingOpts tclOption
+HiLink tkTk_messageboxOpts tclOption
+HiLink tkTkwaitCmds tclSubcommand
+HiLink tkWinfoCmds tclSubcommand
+HiLink tkWinfoCmdsAtomOpts tclOption
+HiLink tkWmCmds tclSubcommand
+
+" -------------------------
+" Highlights: - Special Case
+" -------------------------
+HiLink tclNamespaceCmds               tclSubcommand
+HiLink tclNamespaceEnsemble           tclEnsemble
+HiLink tclNamespaceEnsembleCmds       tclSubcommand
+HiLink tclNamespaceEnsembleExistsOpts tclOption
+HiLink tclNamespaceExportOpts         tclOption
+HiLink tkBindSubst                    tclQuotes
+HiLink tkBindSubstGroup               tclQuotes
+HiLink tkEventCmds                    tclSubcommand
+HiLink tkEventFields                  tclOption
+HiLink tkEventWhen                    tclString
+HiLink tkCanvasItemOpts               tclOption
+HiLink tkCanvasPsOpts                 tclOption
+HiLink tkCanvasTagOpts                tclOption
+HiLink tkWidgetCreate                 tclSubcommand
+HiLink tkWidgetCreateArcOpts          tclOption
+HiLink tkWidgetCreateBitmapOpts       tclOption
+HiLink tkWidgetCreateCmds             tclEnsemble
+HiLink tkWidgetCreateCommonOpts       tclOption
+HiLink tkWidgetCreateImageOpts        tclOption
+HiLink tkWidgetCreateLineOpts         tclOption
+HiLink tkWidgetCreateOvalOpts         tclOption
+HiLink tkWidgetCreatePhotoOpts        tclOption
+HiLink tkWidgetCreatePolyOpts         tclOption
+HiLink tkWidgetCreateRectOpts         tclOption
+HiLink tkWidgetCreateTextOpts         tclOption
+HiLink tkWidgetCreateWinOpts          tclOption
+HiLink tkImageCmds                    tclSubcommand
+HiLink tkWidgetImageCopyOpts          tclOption
+HiLink tkWidgetImageDataOpts          tclOption
+HiLink tkWidgetImagePutOpts           tclOption
+HiLink tkWidgetImageReadOpts          tclOption
+HiLink tkWidgetImageTransOpts         tclOption
+HiLink tkWidgetImageWriteOpts         tclOption
+
+HiLink tkTextWidgetOpts               tclOption
+HiLink tkMarkCmds                     tclEnsemble
+HiLink tkTagCmds                      tclEnsemble
+HiLink tkTagOpts                      tclOption
+HiLink tkWidgetSearchOpts             tclOption
+
+HiLink tkScanCmds                     tclEnsemble
+HiLink tkScrollCmds                   tclEnsemble
+HiLink tkSelectCmds                   tclEnsemble
+HiLink tkScrollbarElems               tclOption
+HiLink tkScrollbarElems               tclString
+HiLink tkWidgetMenu                   tclEnsemble
+HiLink tkViewCmds                     tclEnsemble
+
+
+delcommand HiLink
+
+" -------------------------
+" Hoodage:
+" -------------------------
+
+let b:current_syntax = "tcl"
+" override the sync commands from the other syntax files
+syn sync clear
+" syn sync minlines=300
+syn sync fromstart
+
+" -------------------------
+
+" vim:ft=vim
diff --git a/vim/syntax/vimperator.vim b/vim/syntax/vimperator.vim
new file mode 100644 (file)
index 0000000..ad73c87
--- /dev/null
@@ -0,0 +1,75 @@
+" Vim syntax file
+" Language:         VIMperator configuration file
+" Maintainer:       Doug Kearns <dougkearns@gmail.com>
+" Latest Revision:  2008 August 19
+
+if exists("b:current_syntax")
+  finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn include @javascriptTop syntax/javascript.vim
+unlet b:current_syntax
+
+syn keyword vimperatorTodo FIXME NOTE TODO XXX contained
+syn match   vimperatorComment     +".*$+     contains=vimperatorTodo,@Spell
+
+syn region  vimperatorString  start="\z(["']\)" end="\z1" skip="\\\\\|\\\z1" oneline
+
+syn match   vimperatorLineComment +^\s*".*$+ contains=vimperatorTodo,@Spell
+
+syn keyword vimperatorCommand ab[breviate] ab[clear] addo[ns] au[tocmd] b[uffer] ba[ck] bd[elete] beep bma[rk] bmarks buffers
+    \ bun[load] bw[ipeout] ca[bbrev] cabc[lear] cd cuna[bbrev] cm[ap] cmapc[lear] cno[remap] comc[lear] com[mand] cu[nmap]
+    \ delbm[arks] delc[ommand] delmac[ros] delm[arks] delqm[arks] dia[log] dl downl[oads] e[dit] ec[ho] echoe[rr] em[enu]
+    \ exe[cute] exu[sage] files fo[rward] fw h[elp] ha[rdcopy] hist[ory] hs ia[bbrev] iabc[lear] im[ap] imapc[lear] ino[remap]
+    \ iuna[bbrev] iu[nmap] javas[cript] ju[mps] js let ls macros ma[rk] map mapc[lear] marks mkv[imperatorrc] no[remap]
+    \ noh[lsearch] norm[al] o[pen] pa[geinfo] pagest[yle] pc[lose] pl[ay] pref[erences] prefs pwd q[uit] qa[ll] qma[rk] qmarks
+    \ quita[ll] re[draw] re[load] reloada[ll] res[tart] run sav[eas] sb[ar] sb[open] sbcl[ose] se[t] setg[lobal] setl[ocal]
+    \ sideb[ar] so[urce] st[op] tN[ext] t[open] tab tabd[uplicate] tabN[ext] tabc[lose] tabe[dit] tabfir[st] tabl[ast] tabm[ove]
+    \ tabn[ext] tabnew tabo[nly] tabopen tabp[revious] tabr[ewind] tabs time tn[ext] tp[revious] u[ndo] una[bbreviate] undoa[ll]
+    \ unl[et] unm[ap] ve[rsion] vie[wsource] viu[sage] w[rite] wc[lose] win[open] winc[lose] wine[dit] wo[pen] wqa[ll] wq xa[ll]
+    \ zo[om]
+       \ contained
+
+syn match vimperatorCommand "!" contained
+
+" FIXME
+syn match vimperatorCommandWrapper "\%(^\s*:\=\)\@<=\%(!\|\h\w*\>\)" contains=vimperatorCommand
+
+syn region vimperatorSet matchgroup=vimperatorCommand start="\%(^\s*:\=\)\@<=\<set\=\>" end="$" keepend oneline contains=vimperatorOption
+syn keyword vimperatorOption activate act activelinkfgcolor alfc activelinkbgcolor albc complete cpt defsearch ds editor
+    \ extendedhinttags eht focuscontent fc nofocuscontent nofc fullscreen fs nofullscreen nofs guioptions go hintmatching hm
+    \ hintstyle hs hinttags ht hinttimeout hto history hi hlsearch hls nohlsearch nohls hlsearchstyle hlss incsearch is
+    \ noincsearch nois ignorecase ic noignorecase noic insertmode im noinsertmode noim laststatus ls linkbgcolor lbc linkfgcolor
+    \ lfc linksearch lks nolinksearch nolks more newtab nextpattern nomore pageinfo pa popups pps preload nopreload previewheight
+    \ pvh previouspattern online noonline scroll scr shell sh shellcmdflag shcf showmode smd noshowmode nosmd showstatuslinks ssli
+    \ showtabline stal smartcase scs nosmartcase noscs suggestengines titlestring usermode um nousermode noum urlseparator verbose
+    \ vbs visualbell vb novisualbell novb visualbellstyle wildmode wim wildoptions wop wordseparators wsp
+    \ contained
+
+syn region vimperatorJavascript start="\%(^\s*\%(javascript\|js\)\s\+\)\@<=" end="$" contains=@javascriptTop keepend oneline
+syn region vimperatorJavascript matchgroup=vimperatorJavascriptDelimiter
+       \ start="\%(^\s*\%(javascript\|js\)\s\+\)\@<=<<\z(\h\w*\)"hs=s+2 end="^\z1$" contains=@javascriptTop fold
+
+syn region vimperatorMap matchgroup=vimperatorCommand start="\%(^\s*:\=\)\@<=\<map\>" end="$" keepend oneline contains=vimperatorKeySym
+
+syn match vimperatorKeySym "<[0-9A-Za-z-]\+>"
+
+" Note: match vim.vim highlighting groups
+hi def link vimperatorCommand                      Statement
+hi def link vimperatorComment                      Comment
+hi def link vimperatorJavascriptDelimiter      Delimiter
+hi def link vimperatorKeySym                       Special
+hi def link vimperatorLineComment                  Comment
+hi def link vimperatorOption                       PreProc
+hi def link vimperatorString                       String 
+hi def link vimperatorTodo                  Todo
+
+let b:current_syntax = "vimperator"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim: tw=130 et ts=4 sw=4:
diff --git a/vim/syntax/yaml.vim b/vim/syntax/yaml.vim
new file mode 100644 (file)
index 0000000..cbf7f13
--- /dev/null
@@ -0,0 +1,109 @@
+" Vim syntax file
+" Language:     YAML
+" Maintainer:   motemen <motemen@gmail.com>
+" Version:     20070822
+
+syntax clear
+
+if !exists('g:yaml_syntax_highlight_numbers')
+    let g:yaml_syntax_highlight_numbers = 0
+endif
+
+syn match  yamlValue contained +\s*\%(#.*\)\?+ contains=yamlComment nextgroup=yamlType,yamlLabel,yamlFlowMap,yamlFlowSeq,yamlBool,yamlNull,yamlTextBlock,yamlString,yamlTimestamp,yamlInt,yamlFloat,yamlPlainString
+
+" Plain string
+syn match  yamlPlainString       contained +.\++
+syn match  yamlPlainStringInFlow contained +[^}\],]\++
+
+" Number
+if g:yaml_syntax_highlight_numbers
+    syn match  yamlInt contained /[-+]\?\%(0\|[1-9][0-9_]*\)\+\%(\.\|[0-9]\)\@!/
+    syn match  yamlInt contained /[-+]\?0b[0-1_]\+/
+    syn match  yamlInt contained /[-+]\?0[0-7_]\+/
+    syn match  yamlInt contained /[-+]\?0x[0-9a-fA-F_]\+/
+    syn match  yamlInt contained /[-+]\?[1-9][0-9_]*\%(:[0-5]\?[0-9]\)\+/
+    syn match  yamlFloat contained /[-+]\?\%([0-9][0-9_]*\)\?\.[0-9_]\+\%([eE][-+][0-9]\+\)\?\%(\.\|[0-9]\)\@!/
+    syn match  yamlFloat contained /[-+]\?[0-9][0-9_]*\%(:[0-5]\?[0-9]\)\+\.[0-9_]*/
+endif
+syn match  yamlFloat contained /[-+]\?\.\%(inf\|Inf\|INF\)\s*\%(#.*\)\?$/
+syn match  yamlFloat contained /\.\%(nan\|NaN\|NAN\)\s*\%(#.*\)\?$/
+
+" Timestamp
+syn match  yamlTimestamp contained /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/
+syn match  yamlTimestamp contained /[0-9][0-9][0-9][0-9]-[0-9][0-9]\?-[0-9][0-9]\?\%([Tt]\|[ \t]\+\)[0-9][0-9]\?:[0-9][0-9]:[0-9][0-9]\%(\.[0-9]*\)\?\%([ \t]*Z\|[-+][0-9][0-9]\?\%(:[0-9][0-9]\)\?\)\?/
+
+" Flow sequence
+syn region yamlFlowSeq matchgroup=Delimiter start=+\[+ end=+\]+ contains=yamlKeyInFlow,yamlQuotedKeyInFlow,yamlComma
+
+" Flow mapping
+syn region yamlFlowMap matchgroup=Delimiter start=+{+ end=+}+ contains=yamlKeyInFlow,yamlQuotedKeyInFlow,yamlComma
+
+" Flow mapping/sequence
+syn match  yamlComma +,+
+
+syn match  yamlKeyColonInFlow  contained +:+ nextgroup=yamlValueInFlow
+syn match  yamlValueInFlow     contained +\s*+ nextgroup=yamlTypeInFlow,yamlFlowMap,yamlFlowSeq,yamlConstant,yamlTextBlock,yamlString,yamlPlainStringInFlow
+syn match  yamlKeyInFlow       contained +[^,#'" ][^}\]]\{-}\ze:+ nextgroup=yamlKeyColonInFlow
+syn region yamlQuotedKeyInFlow contained matchgroup=String start=+"+rs=e skip=+\\"+ end=+"\s*\ze:+ contains=yamlEscape nextgroup=yamlKeyColonInFlow
+syn region yamlQuotedKeyInFlow contained matchgroup=String start=+'+rs=e skip=+''+  end=+'\s*\ze:+ contains=yamlSingleEscape nextgroup=yamlKeyColonInFlow
+
+" Block mapping
+syn match  yamlKeyColon  +:+ nextgroup=yamlValue
+syn match  yamlKey       +[^#'"{\[ ]\%(.\)\{-}\ze:\%( \|$\)+ nextgroup=yamlKeyColon
+syn region yamlQuotedKey matchgroup=String start=+"+rs=e skip=+\\"+ end=+"\s*\ze:+ contains=yamlEscape       nextgroup=yamlKeyColon
+syn region yamlQuotedKey matchgroup=String start=+'+rs=e skip=+''+  end=+'\s*\ze:+ contains=yamlSingleEscape nextgroup=yamlKeyColon
+syn region yamlKey matchgroup=Delimiter start=+?+ end=+:+rs=e-1 contains=yamlValue nextgroup=yamlKeyColon
+
+" Block sequence
+syn match  yamlSeqMark   +-\s*+ nextgroup=yamlValue,yamlKey
+
+" Label
+syn match  yamlLabel contained +[*&]\S\++
+
+" Comment
+syn keyword yamlTodo    contained TODO FIXME XXX NOTE
+syn match   yamlComment +#.*+ contains=yamlTodo
+syn region  yamlComment start=+^\.\.\.+ end=+\%$+ contains=yamlTodo
+
+" String
+syn region yamlString       contained start=+"+ skip=+\\"+ end=+"+ contains=yamlEscape
+syn region yamlString       contained start=+'+ skip=+''+  end=+'+ contains=yamlSingleEscape
+syn match  yamlEscape       contained +\\[\\"abefnrtv^0_ NLP]+
+syn match  yamlEscape       contained '\\x\x\{2}'
+syn match  yamlEscape       contained '\\u\x\{4}'
+syn match  yamlEscape       contained '\\U\x\{8}'
+syn match  yamlEscape       contained '\\\%(\r\n\|[\r\n]\)'
+syn match  yamlSingleEscape contained +''+
+
+" Type
+syn match  yamlType +!\S*+ nextgroup=yamlValue
+
+" Block style
+syn region yamlTextBlock start=/[|>][+-]\?\%([1-9]\d*\)\?\n\z\( \+\)/ end=/^\%(\z1\|$\)\@!/
+
+" Constant
+syn match  yamlBool     +\%(y\|Y\|yes\|Yes\|YES\|n\|N\|no\|No\|NO\|true\|True\|TRUE\|false\|False\|FALSE\|on\|On\|ON\|off\|Off\|OFF\)\ze\s*\%(#.*\)\?$+ contained
+syn match  yamlNull     +\%(null\|\~\)\ze\s*\%(#.*\)\?$+ contained
+
+" Directive
+syn match  yamlDirective +^%[^#]*\%(#.*\)\?$+ contains=yamlComment
+syn match  yamlDocHeader +^---\s*+
+
+highlight link yamlTodo            TODO
+highlight link yamlComment         Comment
+highlight link yamlKeyColon        Delimiter
+highlight link yamlKeyColonInFlow  Delimiter
+highlight link yamlSeqMark         Delimiter
+highlight link yamlKey             Identifier
+highlight link yamlQuotedKey       Identifier
+highlight link yamlKeyInFlow       Identifier
+highlight link yamlQuotedKeyInFlow Identifier
+highlight link yamlBool            Constant
+highlight link yamlNull            Constant
+highlight link yamlTextBlock       String
+highlight link yamlType            Type
+highlight link yamlDocHeader       Statement
+highlight link yamlDirective       PreProc
+highlight link yamlLabel           Label
+highlight link yamlInt             Number
+highlight link yamlFloat           Number