vim-addon-manager
diff --git a/vim-addon-manager/.gitignore b/vim-addon-manager/.gitignore
new file mode 100644
index 0000000..926ccaa
--- /dev/null
+++ b/vim-addon-manager/.gitignore
@@ -0,0 +1 @@
+doc/tags
diff --git a/vim-addon-manager/README b/vim-addon-manager/README
new file mode 100644
index 0000000..9a86e65
--- /dev/null
+++ b/vim-addon-manager/README
@@ -0,0 +1,65 @@
+ATTENTION:
+There is another project which has the same name:
+http://packages.debian.org/sid/vim-addon-manager
+The author (Jamessan) is fine with this project sharing the same name.
+
+VIM ADDON MANAGER (VAM)
+=======================
+1) installation, configuration:
+ http://github.com/MarcWeber/vim-addon-manager/blob/master/doc/vim-addon-manager.txt)
+
+The following text is a common github README file so that github visitors
+immediately see what VAM is about:
+
+VAM installs and updates additional scripts augmenting the feature list of the
+text editor Vim.
+It also handles plugin dependencies and puts each script distribution into its
+own directory resulting in a painless installation management.
+
+Supported PLUGIN SOURCES: git, mercurial, svn, bzr, www.vim.org, ...
+
+Being 100% pure VimL (depending on some additional tools such as curl) it should
+run everywhere. [1]
+
+Feature list:
+
+- declarative script management (example lines that should go to your .vimrc):
+
+ set runtimepath+=/path/to/vam
+ call vam#ActivateAddons(["snipmate","vimdevplugin", .... ])
+
+
+- optional manual runtime activation of scripts:
+
+ :ActivateAddons plugin-name
+
+
+- update feature:
+
+ :UpdateAddons [optional name list]
+
+ This even tries to keep your local modification to archive based
+ installations ! [2]
+
+
+- a function which configures plugin sources:
+
+ 1) www.vim.org (the plugin list is updated once within 10 days by a cron job)
+
+ 2) some scripts have been added manually. Some of them are development
+ versions which are also contained in 1)
+
+ Contact me and I will add additional sources.
+
+
+- community driven: several maintainers & contributors providing feedback and
+ fixing bugs. Thanks to you all! (list provided in the documentation)
+
+
+Continue reading the documentation: doc/vim-addon-manager.txt (online:
+
+I could quote several people who told me how "awesome" this small tool is.
+But I prefer letting you explore it yourself.
+
+[1] most testing has been done on Unix environments
+[2] diff tools (diff and patch) required
diff --git a/vim-addon-manager/autoload/sample_vimrc_for_new_users.vim b/vim-addon-manager/autoload/sample_vimrc_for_new_users.vim
new file mode 100644
index 0000000..1d231c0
--- /dev/null
+++ b/vim-addon-manager/autoload/sample_vimrc_for_new_users.vim
@@ -0,0 +1,376 @@
+" minimal useful unbiased recommended .vimrc: http://vim.wikia.com/wiki/Example_vimrc
+
+
+" kept recoding the same things over and over again.
+" So I write what I think is useful to you here.
+"
+" How to use?
+" Either copy paste contents into your .vimrc (omitting the Load function)
+" or call the load function
+
+
+" these markers { { { enable folding. see modeline at the bottom
+" You don't have to close them if you append the folding level.
+
+" set nocompatible should be default. This should be the first line:
+set nocompatible
+
+
+" You should have this in your .vimrc:
+" (The {{ { starts a fold.
+" type zR to open all or za to open one fold only
+" zM folds everything again
+
+" enable filetype, plugin and syntax support {{{1
+" This means
+filetype indent plugin on | syn on
+
+" allow buffers to go in background without saving etc.
+set hidden
+
+" useful mappings: {{{1
+
+" open this file fast so that you can take notes below the line "finish" and
+" add more mappings:
+noremap \c :e ~/.vimrc<cr>
+
+" :w! is always bad to type. So create your own mapping for it. Example:
+noremap \w :w!<cr>
+
+" you may want to remove the <c-d> if you have many files opened
+" This switches buffers
+" Note: :b foo will also select some-foo-text.txt file if it was opened :)
+noremap \b :b<space><c-d>
+
+" being able to open the help fast is always fine.
+" note that you can use tab / shift -tab to select next / previous match
+" also glob patterns are allowed. Eg :h com*func<tab>
+noremap \h :h<space>
+
+" open one file, use tab and shift-tab again if there are multiple files
+" after using this mapping the command line should have started showing
+" :e **/* . Eg use :e **/*fil*txt to match file.txt in any subdir
+noremap \e :e<space>**/*
+
+" open multiple files at once. Eg add .txt to open all .txt files
+" Using :bn @: you can cycle them all
+" :bn = :bnext @: repeats last command
+noremap \n :n<space>**/*
+
+" open a filetype file. Those files are sourced by Vim to setup filetype
+" specific mappings. Eg use it for defining commands / mappings which apply
+" for python or perl files only
+" eg command -buffer DoStuff call DoStuff()
+" or map <buffer> \dostuff :call DoStuff()<cr>
+noremap \ft :exec 'e ~/.vim/after/ftplugin/'.&filetype.'_you.vim'<cr>
+
+" when pasting code you may want to enable paste option so that Vim doesn't
+" treat the pasted text like typed text. Typed text casues vim to to repeating
+" comments and change indentation - when pasting you don't want this.
+noremap \ip :set invpaste<bar>echo &paste ? 'pasting is on' : 'pasting is off'
+
+" for windows: make backspace work. Doesn't hurt on linux. This should be
+" default!
+set bs=2
+
+" foreign plugin vim-addon-manager {{{1
+
+" commenting this code because I assume you already have it in your ~/.vimrc:
+
+ " tell Vim where to find the autoload function:
+" set runtimepath+=~/vim-plugins/vim-addon-manager
+
+" Activate the addons called 'JSON', 'name1', 'name2'
+" This adds them to runtimepath and ensures that plugin/* and after/plugin/*
+" files are sourced. JSON is not that important. It highlights the
+" NAME-addon-info.txt files. Probably you want to substitude nameN by plugins
+" such as snipMate, tlib etc.
+
+" call vam#ActivateAddons(['JSON',"tmru","matchit.zip","vim-dev-plugin","name1","name2"])
+" JSON: syntax highlighting for the *info* files
+" tmru: list of most recentely used files
+" matchit.zip: make % (match to mathing items such as opening closing parenthesis) even smarter
+" vim-dev-plugin: smarter omni completion and goto autoload function for VimL scripts
+
+" foreign plugins tlib {{{1
+
+" this is from tlib. I highly recommend having a look at that library.
+" Eg its plugin tmru (most recently used files) provides the command
+" TRecentlyUsedFiles you can map to easily:
+noremap \r :TRecentlyUsedFiles<cr>
+
+" simple glob open based on tlib's List function (similar to TCommand or fuzzy
+" plugin etc)
+noremap \go :exec 'e '. fnameescape(tlib#input#List('s','select file', split(glob(input('glob pattern, curr dir:','**/*')),"\n") ))<cr>
+
+" sometimes when using tags the list is too long. filtering it by library or
+" such can easily be achived by such code: {{{'
+ fun! SelectTag(regex)
+ let tag = eval(tlib#input#List('s','select tag', map(taglist(a:regex), 'string([v:val.kind, v:val.filename, v:val.cmd])')))
+ exec 'e '.fnameescape(tag[1])
+ exec tag[2]
+ endf
+ command!-nargs=1 TJump call SelectTag(<f-args>)
+
+" }}}
+
+" dummy func to enabling you to load this file after adding the top level {{{1
+" dir to runtimepath using :set runtimpeth+=ROOT
+fun! sample_vimrc_for_new_users#Load()
+ " no code. If this function is called this file is sourced
+ " As alternative this can be used:
+ " runtime autoload/sample_vimrc_for_new_users.vim
+endf
+
+" create directory for files before Vim tries writing them:
+augroup CREATE_MISSING_DIR_ON_BUF_WRITE
+ autocmd BufWritePre * if !isdirectory(expand('%:h')) | call mkdir(expand('%:h'),'p') | endif
+augroup end
+
+finish
+Vim is ignoring this text after finish.
+
+DON'T MISS THESE {{{1
+
+Each vim boolean setting can be off or on. You can invert by invNAME. Example:
+enable setting: :set swap
+disable setting: :set noswap
+toggle setting: :set invswap
+Settings can be found easily by :h '*chars*'<c-d>
+
+== typing characters which are not on your keyboard ==
+digraphs: type chars which are untypable, for example:
+c-k =e : types € (see :h digraph)
+
+== completions ==
+c-x c-f : file completion
+c-x c-l : line completion
+c-n : kind of keyword completion - completes everything found in all opened buffers.
+ So maybe even consider openining many files uing :n **/*.ext
+ (if you're a nerd get vim-addon-completion and use the camel case buffer completion found in there)
+all: :h ins-completion
+
+== most important movement keys ==
+hjkl - as experienced user you'll notice that you don't use them that often.
+So you should at least know about the following and have a look at :h motion.txt
+and create your own by mappings
+
+how to reach insert mode:
+| is cursor location
+
+ O
+I i|a A
+ o
+
+important movements and their relation:
+
+ gg
+ <c-u> H (top line window)
+
+- k
+0 h | l $ M
+<cr> j
+ <c-v>
+ L
+ G
+
+
+movements:
+
+use search / ? to place cursor. Remember that typing a word is not always the
+ most efficient way. Eg try /ys t this. And you'll get excatly
+ one match in the whole document.
+
+c-o c-i : jump list history
+
+g; : where did I edit last (current buffer) - you can repeat it
+
+Learn about w vs W. Try it CURSOR_HERE.then.type.it (same for e,E)
+
+f,F,t,T : move to char or just before it forward / backward current line. (A
+ must)
+
+be faster: delete then goto insert mode:
+C: deletes till end of line
+c a-movement-action: deletes characters visited while moving
+
+more movements:
+(, ): move by sentence
+[[, ]], {, } : more blockwise movements which are often helpful
+...
+
+This script may also have its usage: Jump to charater location fast:
+http://www.vim.org/scripts/script.php?script_id=3437
+
+How to get O(1) access to your files you're editing at the moment {{{1
+
+Yes :b name is fine, cause it matches HeHiname.ext. Still too much to type.
+Usually you work with only a set of buffers. Open them in tabs. Add something
+like this to your .vimrc so that you can switch buffers using m-1 m-2 etc:
+
+ " m-X key jump to tab X
+ for i in range(1,8)
+ exec 'map <m-'.i.'> '.i.'gt'
+ endfor
+
+ " faster novigation in windows:
+ for i in ["i","j","k","l","q"]
+ exec 'noremap <m-s-'.i.'> <c-w>'.i
+ endfor
+
+The ways to optimize code navigation are endless. Watch yourself.
+If you think something takes too long - optimize it.
+
+Bindings in command line are shitty?
+yes - remap them - or use "emacscommandline" plugin which does this for you.
+or use q: (normal mode) or c-f in commandline
+
+
+
+== indentation, spaces, tabs ==
+Tab: default behavior of vim is: add &tabstop spaces unless expandtab is not
+set. You can always insert real tabs by <c-v><tab>. However tabstob should be
+treated as display setting. Use sw setting and c-t, c-d instead.
+
+c-t: increase indentation
+c-d: decrease indentation
+c-f: auto indent current line (requires indentation setup)
+:setlocal sw=4: use 4 spacse for indentation
+:setlocal expandtab: expand tab to spaces (default)
+>3j . . increase indentation of 3 lines and repeat two times
+:setlocal tabstop: a tab is viewed as how many spaces in a file?
+
+:set list : displays spaces and tabs
+
+project specific settings: see vim-addon-local-vimrc
+
+
+
+MY COMMENTS ABOUT VIM AND ITS USAGE {{{1
+========================================
+
+
+I like Vim cause its that fast and easy to extend.
+I also learned that VimL is a nice language. It was ahead of time when it
+was invented. However today it can be considered limiting in various ways.
+Eg you don't want to write parsers in it. Its too slow for those use cases.
+Yet its powerful enough to make everydays work easier - even competitive to
+bloated IDEs. Example plugins you should know about:
+
+- tlib library (and all of Tom's plugins
+
+- snipmate (or xptemplate): Insert text snippets. Its not only about speed.
+ Snippets are a nice way to organize your memos.
+
+- matchit: match everything, eg matching xml tags, fun -> return -> endfun
+ statements (same for for, while etc)
+
+- The_NERD_tree: directory tree in Vim. You can easily hit the limits of
+ Vim/VimL here whene opening large directories it takes a way too long :-(
+ Yet you may find it useful.
+
+- commenting plugins
+
+- vim-addon-local-vimrc (project specific settings)
+
+- ... (You want a plugin added here?)
+
+What you should know about:
+- :h motion.txt (skim it once)
+- Vim keeps history as tree. (g+ g- mappings)
+- :h quickfix (load compiler output into an error list)
+- how to use tags - because this (sometimes fuzzzy) thing
+ is still fast to setup and works very well for many use cases.
+- Vim can assist you in spelling
+
+
+most important mappings / commands:
+g; = jump back in list of last edited locations
+<c-o> <c-i> = jump back and forth in location list
+<c-^> = toggle buffers
+c-w then one of v s w q t h j k l (z) : move cursor, split windows, quit buffer
+
+q:, ?:, /: : Open mini buffer to browse or edit command or search history
+ You can open this from command line using <c-f>!
+... I could keep writing for 2 hours now at least.
+
+
+I'm also aware of Emacs emulating most important editing features of Vim.
+Eg there is the vimpulse plugin for Emacs. So I know that I should use the
+tool which is best for a given task. This can be Vim for coding. But for debugging
+you may prefer Emacs or a bloated IDE such as Eclipse, Netbeans, IDEA (which all have
+vim like keybindgs!).
+
+What are the limitations causing greatest impact to software developers using Vim?
+- no async communication support unless you depend on client-server feature
+ which requires X. This means Vim will hang until an operation has finished
+ when interfacing with external tools.
+ Impact: People tried writing debugger features. But all solutions are kind
+ of doomed unless Vim gets a nice async communication interface.
+
+ Possible known ways to work around it?
+
+ - vim-addon-async (depends on client-server but works very well)
+
+ - implement windows version of this patch
+ http://github.com/bartman/vim.git (which still can be improved a lot)
+ and make it it poll file handlers when not typing. Implement a shell
+ like interface. doc: http://github.com/bartman/vim/wiki/_pages
+
+ - There is a patch which let's you start a shell in Vim. I don't think
+ it got updated (which is linux only)
+ http://www.wana.at/vimshell/
+ (Maybe cygwin or such ?) - I never tried it.
+
+ - vimshell (www.vim.org). You have to get a dell or such. I think this
+ could satisfy you.
+ (vcs: http://github.com/Shougo/vimshell)
+
+ - screen (see other mail)
+ c-a S splits the window
+ c-a tab switches focus
+
+ if you run interpreter this way: tcl | tee log
+
+ you may have a chance getting errors into quickfix or such
+
+ (requires cygwin or such - I never tried it on Windows ?)
+
+ use Emacs and vimpulse (I hate to say it)
+
+
+- Many coding helpers should not have been written in VimL. They should have
+ been written in a proper language so that all open source editors can
+ benefit from their features. An Example is the broken PHP completion which
+ doesn't even complete static member functions like A::foo();
+
+ Examples how this can be done better:
+ * vim-addon-scion (Haskell development helper app is written in Haskell. Vim
+ is only a coding editor backend)
+ * codefellow (same for Scala).
+ * eclim (Eclipse features exposed to Vim And Vim backend implementation)
+
+Vim can be one of the fastest editors you'll start to love (and hate for some
+of the shortcomings)
+
+
+" additional resources - how to continue learning about Vim? {{{1
+The way to start learning Vim:
+vimtutor
+
+additional advanced info:
+http://github.com/dahu/LearnVim
+
+Vim Wiki:
+http://vim.wikia.com
+Checkout its sample .vimrc: http://vim.wikia.com/wiki/Example_vimrc
+
+join #vim (irc.freenode.net)
+
+join the mailinglist (www.vim.org -> community)
+
+Tell me to add additional resources here
+
+
+" this modeline tells vim to enable folding {{{1
+" vim: fdm=marker
diff --git a/vim-addon-manager/autoload/scriptmanager.vim b/vim-addon-manager/autoload/scriptmanager.vim
new file mode 100644
index 0000000..327f402
--- /dev/null
+++ b/vim-addon-manager/autoload/scriptmanager.vim
@@ -0,0 +1,34 @@
+fun! s:UpdateVimrc()
+ " This codes renames old name scriptmanager#Activate to vam#ActivateAddons
+ " for you. I'd like to ask the user. But not all are using shells so the
+ " question can get lost.
+ let cmd='%s@scriptmanager#Activate(@vam#ActivateAddons(@g | %s/\<vim_script_manager\>/vim_addon_manager/g'
+ let files = filter([expand("~/.vimrc"), expand('~/_vimrc')], 'filewritable(v:val)==1')
+ if len(files) == 1
+ call vam#Log( "scriptmanager#Activate and g:vim_script_manager were renamed to vam#ActivateAddons and g:vim_addon_manager.")
+ if confirm("Replace given names in ".files[0]."?", "&No\n&Yes")==2
+ exec 'e '.fnameescape(files[0])
+ exec cmd | w
+ endif
+ else
+ echo "open your the file calling scriptmanager#Activate and run: ".cmd." . Rename happened for consistency"
+ endif
+endfun
+fun! scriptmanager#Activate(...) abort
+ " historical. Call vam#ActivateAddons instead
+ augroup scriptmanagerRebrand
+ autocmd!
+ autocmd VimEnter * call s:UpdateVimrc()
+ augroup END
+ if exists('g:vim_script_manager')
+ let g:vim_addon_manager=g:vim_script_manager
+ endif
+ call call(function('vam#ActivateAddons'),a:000)
+endf
+
+fun! scriptmanager#DefineAndBind(...)
+ echoe "fix your code!, scriptmanager#DefineAndBind was renamed to vam#DefineAndBind(. Drop this function to find the usage location faster!"
+ return call(function('vam#DefineAndBind'),a:000)
+endf
+
+" vim: sts=2 et sw=2
diff --git a/vim-addon-manager/autoload/vam.vim b/vim-addon-manager/autoload/vam.vim
new file mode 100644
index 0000000..4cd2ba6
--- /dev/null
+++ b/vim-addon-manager/autoload/vam.vim
@@ -0,0 +1,377 @@
+" see README
+
+" this file contains code which is always used
+" code which is used for installing / updating etc should go into vam/install.vim
+
+
+" don't need a plugin. If you want to use this plugin you call Activate once
+" anyway
+augroup VIM_ADDON_MANAGER
+ autocmd!
+ autocmd BufRead,BufNewFile *-addon-info.txt,addon-info.json
+ \ setlocal ft=addon-info
+ \ | setlocal syntax=json
+ \ | syn match Error "^\s*'"
+ autocmd BufWritePost *-addon-info.txt,addon-info.json call vam#ReadAddonInfo(expand('%'))
+augroup end
+
+fun! vam#DefineAndBind(local,global,default)
+ return 'if !exists('.string(a:global).') | let '.a:global.' = '.a:default.' | endif | let '.a:local.' = '.a:global
+endf
+
+
+" assign g:os
+for os in split('amiga beos dos32 dos16 mac macunix os2 qnx unix vms win16 win32 win64 win32unix', ' ')
+ if has(os) | let g:os = os | break | endif
+endfor
+let g:is_win = g:os[:2] == 'win'
+
+exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}')
+let s:c['auto_install'] = get(s:c,'auto_install', 0)
+" repository locations:
+let s:c['plugin_sources'] = get(s:c,'plugin_sources', {})
+" if a plugin has an item here the dict value contents will be written as plugin info file
+let s:c['activated_plugins'] = get(s:c,'activated_plugins', {})
+
+" gentoo users may install VAM system wide. In that case s:d is not writeable.
+" In the future this may be put into a gentoo specific patch.
+let s:d = expand('<sfile>:h:h:h')
+let s:c['plugin_root_dir'] = get(s:c, 'plugin_root_dir', filewritable(s:d) ? s:d : '~/.vim/vim-addons' )
+unlet s:d
+
+" ensure we have absolute paths (windows doesn't like ~/.. ) :
+let s:c['plugin_root_dir'] = expand(s:c['plugin_root_dir'])
+let s:c['dont_source'] = get(s:c, 'dont_source', 0)
+let s:c['plugin_dir_by_name'] = get(s:c, 'plugin_dir_by_name', 'vam#DefaultPluginDirFromName')
+
+" More options that are used for plugins’ installation are listed in
+" autoload/vam/install.vim
+
+" for testing it is necessary to avoid the "Press enter to continue lines"
+" (cygwin?). Thus provide an option making all shell commands silent
+" However don't set this to 1 by default. If something goes wrong I want users
+" to see what went wrong. Not everybody knows how to debug VimL!
+let s:c['silent_shell_commands'] = get(s:c,'silent_shell_commands', 0)
+
+if g:is_win
+ " if binary-utils path exists then add it to PATH
+ let s:c['binary_utils'] = get(s:c,'binary_utils',s:c['plugin_root_dir'].'\binary-utils')
+ let s:c['binary_utils_bin'] = s:c['binary_utils'].'\dist\bin'
+ if isdirectory(s:c['binary_utils'])
+ let $PATH=$PATH.';'.s:c['binary_utils_bin']
+ endif
+endif
+
+" additional plugin sources should go into your .vimrc or into the repository
+" called "vim-addon-manager-known-repositories" referenced here:
+if executable('git')
+ let s:c['plugin_sources']["vim-addon-manager-known-repositories"] = { 'type' : 'git', 'url': 'git://github.com/MarcWeber/vim-addon-manager-known-repositories.git' }
+else
+ let s:c['plugin_sources']["vim-addon-manager-known-repositories"] = { 'type' : 'archive', 'url': 'http://github.com/MarcWeber/vim-addon-manager-known-repositories/tarball/master', 'archive_name': 'vim-addon-manager-known-repositories-tip.tar.gz' }
+endif
+
+fun! vam#VerifyIsJSON(s)
+ " You must allow single-quoted strings in order for writefile([string()]) that
+ " adds missing addon information to work
+ let scalarless_body = substitute(a:s, '\v\"%(\\.|[^"\\])*\"|\''%(\''{2}|[^''])*\''|true|false|null|[+-]?\d+%(\.\d+%([Ee][+-]?\d+)?)?', '', 'g')
+ return scalarless_body !~# "[^,:{}[\\] \t]"
+endf
+
+" use join so that you can break the dict into multiple lines. This makes
+" reading it much easier
+fun! vam#ReadAddonInfo(path)
+
+ " don't add "b" because it'll read dos files as "\r\n" which will fail the
+ " check and evaluate in eval. \r\n is checked out by some msys git
+ " versions with strange settings
+
+ " using eval is evil!
+ let body = join(readfile(a:path),"")
+
+ if vam#VerifyIsJSON(body)
+ let true=1
+ let false=0
+ let null=''
+ " using eval is now safe!
+ return eval(body)
+ else
+ call vam#Log( "Invalid JSON in ".a:path."!")
+ return {}
+ endif
+
+endf
+
+fun! vam#DefaultPluginDirFromName(name)
+ " this function maps addon names to their storage location. \/: are replaced
+ " by - (See name rewriting)
+ return s:c.plugin_root_dir.'/'.substitute(a:name, '[\\/:]\+', '-', 'g')
+endfun
+fun! vam#PluginDirFromName(...)
+ return call(s:c.plugin_dir_by_name, a:000, {})
+endf
+fun! vam#PluginRuntimePath(name)
+ let info = vam#AddonInfo(a:name)
+ return vam#PluginDirFromName(a:name).(has_key(info, 'runtimepath') ? '/'.info['runtimepath'] : '')
+endf
+
+" doesn't check dependencies!
+fun! vam#IsPluginInstalled(name)
+ let d = vam#PluginDirFromName(a:name)
+
+ " this will be dropped in about 12 months which is end of 2012
+ let old_path=s:c.plugin_root_dir.'/'.substitute(a:name, '[\\/:]\+', '', 'g')
+ if d != old_path && isdirectory(old_path)
+ if confirm("VAM has changed addon names policy for name rewriting. Rename ".old_path." to ".d."?", "&Ok") == 1
+ call rename(old_path, d)
+ endif
+ endif
+
+ " if dir exists and its not a failed download
+ " (empty archive directory)
+ return isdirectory(d)
+ \ && ( !isdirectory(d.'/archive')
+ \ || len(glob(d.'/archive/*')) > 0 )
+endf
+
+" {} if file doesn't exist
+fun! vam#AddonInfo(name)
+ let infoFile = vam#AddonInfoFile(a:name)
+ return filereadable(infoFile)
+ \ ? vam#ReadAddonInfo(infoFile)
+ \ : {}
+endf
+
+
+" opts: {
+" 'plugin_sources': additional sources (used when installing dependencies)
+" 'auto_install': when 1 overrides global setting, so you can autoinstall
+" trusted repositories only
+" }
+fun! vam#ActivateRecursively(list_of_names, ...)
+ let opts = a:0 == 0 ? {} : a:1
+
+ for name in a:list_of_names
+ if !has_key(s:c['activated_plugins'], name)
+ " break circular dependencies..
+ let s:c['activated_plugins'][name] = 0
+
+ let infoFile = vam#AddonInfoFile(name)
+ if !filereadable(infoFile) && !vam#IsPluginInstalled(name)
+ call vam#install#Install([name], opts)
+ endif
+ let info = vam#AddonInfo(name)
+ let dependencies = get(info,'dependencies', {})
+
+ " activate dependencies merging opts with given repository sources
+ " sources given in opts will win
+ call vam#ActivateAddons(keys(dependencies),
+ \ extend(copy(opts), {
+ \ 'plugin_sources' : extend(copy(dependencies), get(opts, 'plugin_sources',{})),
+ \ 'requested_by' : [name] + get(opts, 'requested_by', [])
+ \ }))
+
+ " source plugin/* files ?
+ let rtp = vam#PluginRuntimePath(name)
+ call add(opts['new_runtime_paths'], rtp)
+
+ let s:c['activated_plugins'][name] = 1
+ endif
+ endfor
+endf
+
+let s:top_level = 0
+" see also ActivateRecursively
+" Activate activates the plugins and their dependencies recursively.
+" I sources both: plugin/*.vim and after/plugin/*.vim files when called after
+" .vimrc has been sourced which happens when you activate plugins manually.
+fun! vam#ActivateAddons(...) abort
+ let args = copy(a:000)
+ if a:0 == 0 | return | endif
+
+ if type(args[0])==type("")
+ " way of usage 1: pass addon names as function arguments
+ " Example: ActivateAddons("name1","name2")
+
+ " This way of calling has two flaws:
+ " - doesn't scale due to amount of args limitation
+ " - you can't pass autoinstall=1
+ " Therefore we should get rid of this way..
+
+ " verify that all args are strings only because errors are hard to debug
+ if !empty(filter(copy(args),'type(v:val) != type("")'))
+ throw "Bad argument to vam#ActivateAddons: only Strings are permitted. Use ActivateAddons(['n1','n2',..], {..}) to pass options dictionary"
+ endif
+
+ let args=[args, {}]
+ else
+ " way of usage 2: pass addon names as list optionally passing options
+ " Example: ActivateAddons(["name1","name2"], { options })
+
+ let args=[args[0], get(args,1,{})]
+ endif
+
+ " now opts should be defined
+ " args[0] = plugin names
+ " args[1] = options
+
+ let opts = args[1]
+ let topLevel = !has_key(opts, 'new_runtime_paths')
+
+ " add new_runtime_paths state if not present in opts yet
+ let new_runtime_paths = get(opts, 'new_runtime_paths',[])
+ let opts['new_runtime_paths'] = new_runtime_paths
+
+ call call('vam#ActivateRecursively', args)
+
+ if topLevel
+ " deferred tasks:
+ " - add addons to runtimepath
+ " - add source plugin/**/*.vim files in case Activate was called long
+ " after .vimrc has been sourced
+
+ " add paths after ~/.vim but before $VIMRUNTIME
+ " don't miss the after directories if they exist and
+ " put them last! (Thanks to Oliver Teuliere)
+ let rtp = split(&runtimepath, '\v(\\@<!(\\.)*\\)@<!\,')
+ let escapeComma = 'escape(v:val, '','')'
+ let after = filter(map(copy(new_runtime_paths), 'v:val."/after"'), 'isdirectory(v:val)')
+ if !s:c.dont_source
+ let &runtimepath=join(rtp[:0] + map(copy(new_runtime_paths), escapeComma)
+ \ + rtp[1:]
+ \ + map(after, escapeComma),
+ \ ",")
+ endif
+ unlet rtp
+
+ if !has('vim_starting')
+ for rtp in new_runtime_paths
+ call vam#GlobThenSource(rtp.'/plugin/**/*.vim')
+ call vam#GlobThenSource(rtp.'/after/plugin/**/*.vim')
+ endfor
+ endif
+
+ for rtp in new_runtime_paths
+ " filetype off/on would do the same ?
+ call vam#GlobThenSource(rtp.'/ftdetect/*.vim')
+ endfor
+
+ endif
+endfun
+
+fun! vam#DisplayAddonInfo(name)
+ let plugin = get(g:vim_addon_manager['plugin_sources'], a:name, {})
+ let name = a:name
+ if empty(plugin) && a:name =~ '^\d\+$'
+ " try to find by script id
+ let dict = filter(copy(g:vim_addon_manager['plugin_sources']), 'get(v:val,"vim_script_nr","")."" == '.string(1*a:name))
+ if (empty(dict))
+ throw "unkown script ".a:name
+ else
+ let plugin = get(values(dict), 0, {})
+ let name = keys(dict)[0]
+ endif
+ end
+ if empty(plugin)
+ echo "Invalid plugin name: " . a:name
+ return
+ endif
+ echo '========================'
+ echo 'VAM name: '.name
+ for key in keys(plugin)
+ echo key . ': ' . plugin[key]
+ endfor
+endfun
+
+fun! vam#DisplayAddonsInfo(names)
+ call vam#install#LoadPool()
+ for name in a:names
+ call vam#DisplayAddonInfo(name)
+ endfor
+endfun
+
+fun! vam#GlobThenSource(glob)
+ if s:c.dont_source | return | endif
+ for file in split(glob(a:glob),"\n")
+ exec 'source '.fnameescape(file)
+ endfor
+endf
+
+augroup VIM_PLUGIN_MANAGER
+ autocmd VimEnter * call vam#Hack()
+augroup end
+
+" hack: Vim sources plugin files after sourcing .vimrc
+" Vim doesn't source the after/plugin/*.vim files in other runtime
+" paths. So do this *after* plugin/* files have been sourced
+fun! vam#Hack()
+ " now source after/plugin/**/*.vim files explicitly. Vim doesn't do it (hack!)
+ for p in keys(s:c['activated_plugins'])
+ call vam#GlobThenSource(vam#PluginDirFromName(p).'/after/plugin/**/*.vim')
+ endfor
+endf
+
+fun! vam#AddonInfoFile(name)
+ " history:
+ " 1) plugin-info.txt was the first name (deprecated)
+ " 2) a:name-addon-info.txt was the second recommended name (maybe deprecated - no hurry)
+ " 3) Now the recommended way is addon-info.json because:
+ " - you can rename a script without having to rename the file
+ " - json says all about its contents (Let's hope all browsers still render
+ " it in a readable way
+
+ let p = vam#PluginDirFromName(a:name)
+ let default = p.'/addon-info.json'
+ let choices = [ default , p.'/plugin-info.txt', p.'/'.a:name.'-addon-info.txt']
+ for f in choices
+ if filereadable(f)
+ return f
+ endif
+ endfor
+ return default
+endfun
+
+" looks like an error but is not. Catches users attention. Logs to :messages
+fun! vam#Log(s, ...)
+ let hi = a:0 > 0 ? a:1 : 'WarningMsg'
+ exec 'echohl '. hi
+ for l in split(a:s, "\n", 1)
+ if empty(l)
+ echom ' '
+ else
+ echom l
+ endif
+ endfor
+ echohl None
+endfun
+
+" If you want these commands witohut activating plugins call
+" vam#ActivateAddons([]) with empty list. Not moving them into plugin/vam.vim
+" to prevent additional IO seeks.
+
+" its likely that the command names change introducing nice naming sheme
+" Not sure which is best. Options:
+" 1) *VAM 2) Addon* 3) VAM*
+" 3 seems to be best but is more to type.
+" Using 1) you can still show all commands by :*VAM<c-d> but this scheme is
+" less common. So 2) is my favorite right now. I'm too lazy to break things at
+command! -nargs=* -complete=customlist,vam#install#NotInstalledAddonCompletion InstallAddons :call vam#install#Install([<f-args>])
+command! -nargs=* -complete=customlist,vam#install#AddonCompletion ActivateAddons :call vam#ActivateAddons([<f-args>])
+command! -nargs=* -complete=customlist,vam#install#AddonCompletion AddonsInfo :call vam#DisplayAddonsInfo([<f-args>])
+command! -nargs=* -complete=customlist,vam#install#InstalledAddonCompletion ActivateInstalledAddons :call vam#ActivateAddons([<f-args>])
+command! -nargs=* -complete=customlist,vam#install#UpdateCompletion UpdateAddons :call vam#install#Update([<f-args>])
+command! -nargs=0 UpdateActivatedAddons exec 'UpdateAddons '.join(keys(g:vim_addon_manager['activated_plugins']),' ')
+command! -nargs=* -complete=customlist,vam#install#UninstallCompletion UninstallNotLoadedAddons :call vam#install#UninstallAddons([<f-args>])
+
+
+" plugin name completion function:
+augroup VAM
+ " yes, this overwrites omnifunc set by vim-dev plugin for instance. I don't
+ " care. You install plugins, then you usually restart anyway.
+ autocmd BufRead,BufNewFile *.vim,*vimrc inoremap <buffer> <C-x><c-p> <c-o>:setlocal omnifunc=vam#install#CompleteAddonName<cr><c-x><c-o>
+augroup end
+
+" plugin completion:
+
+
+
+" vim: et ts=8 sts=2 sw=2
diff --git a/vim-addon-manager/autoload/vam/install.vim b/vim-addon-manager/autoload/vam/install.vim
new file mode 100644
index 0000000..e91908f
--- /dev/null
+++ b/vim-addon-manager/autoload/vam/install.vim
@@ -0,0 +1,815 @@
+" vam#install contains code which is used when install plugins only
+
+let s:curl = exists('g:netrw_http_cmd') ? g:netrw_http_cmd : 'curl -o'
+exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}')
+
+let s:c['change_to_unix_ff'] = get(s:c, 'change_to_unix_ff', (g:os=~#'unix'))
+let s:c['do_diff'] = get(s:c, 'do_diff', 1)
+let s:c['known'] = get(s:c,'known','vim-addon-manager-known-repositories')
+let s:c['MergeSources'] = get(s:c, 'MergeSources', 'vam_known_repositories#MergeSources')
+let s:c['pool_fun'] = get(s:c, 'pool_fun', 'vam#install#Pool')
+let s:c['name_rewriting'] = get(s:c, 'name_rewriting', {})
+
+call extend(s:c.name_rewriting, {'99git+github': 'vam#install#RewriteName'})
+
+fun! s:confirm(msg, ...)
+ if getchar(1)
+ let char = getchar()
+ if type(char) == type(0)
+ let char = nr2char(char)
+ endif
+ let char = tolower(char)
+ if a:0
+ if type(a:1)==type("")
+ let choices = tolower(substitute(a:1, '\v\&@<!.', '', 'g'))
+ let idx = stridx(choices, char)+1
+ return idx ? idx : get(a:000, 1, 1)
+ else
+ return char is# 's'
+ endif
+ else
+ return char isnot# 'n'
+ endif
+ elseif a:0 && type(a:1) == type("")
+ return call("confirm", [a:msg]+a:000)
+ else
+ " Don't allow [y] with additional argument intentionally: it is too easy to
+ " overlook the dialog. So force users typing [s] instead
+ return confirm(a:msg, a:0 ? "&No\nYe&s" : "&Yes\n&No") == 1+a:0
+ endif
+endfun
+
+fun! vam#install#RewriteName(name)
+ if a:name[:6]==#'github:'
+ " github:{Name} {"type": "git", "url": "git://github.com/{Name}/vim-addon-{Name}}
+ " github:{N}/{Repo} {"type": "git", "url": "git://github.com/{N}/{Repo}"}
+ let rest = a:name[len('github:'):]
+ return {'type' : 'git', 'url' : 'git://github.com/'.(rest =~ '/' ? rest : rest.'/vim-addon-'.rest)}
+ elseif a:name[:3]==#'git:'
+ " git:{URL} {"type": "git", "url": {URL}}
+ return {'type' : 'git', 'url' : a:name[len('git:'):]}
+ endif
+endfun
+
+fun! vam#install#GetRepo(name, opts)
+ if a:name isnot# s:c['known'] | call vam#install#LoadPool() |endif
+
+ let repository = get(s:c['plugin_sources'], a:name, get(a:opts, a:name, 0))
+ if repository is 0
+ unlet repository
+ for key in sort(keys(s:c.name_rewriting))
+ let repository=call(s:c.name_rewriting[key], [a:name], {})
+ if type(repository) == type({})
+ break
+ endif
+ unlet repository
+ endfor
+ if exists('repository')
+ echom 'Name '.a:name.' expanded to :'.string(repository)
+ else
+ " try to find typos and renamings. Tell user about failure
+ let maybe_fixes = []
+ let name_ = vam#utils#TypoFix(a:name)
+ for x in keys(s:c.plugin_sources)
+ if vam#utils#TypoFix(x) == name_
+ call add(maybe_fixes, a:name.' might be a typo, did you mean: '.x.' ?')
+ endif
+ endfor
+ " try finding new name (VAM-kr only)
+ try
+ " using try because pool implementations other then VAM-kr could be
+ " used
+ call extend(maybe_fixes, vamkr#SuggestNewName(a:name))
+ catch /Vim(call):E117:/
+ " If VAM-kr activation policy is never, then the above will yield
+ " unknown function error
+ endtry
+ call vam#Log(join(["No repository location info known for plugin ".a:name."."] + maybe_fixes,"\n"))
+ return 0
+ endif
+ endif
+ return repository
+endfun
+
+" Install let's you install plugins by passing the url of a addon-info file
+" This preprocessor replaces the urls by the plugin-names putting the
+" repository information into the global dict
+fun! vam#install#ReplaceAndFetchUrls(list)
+ let l = a:list
+ let idx = 0
+ for idx in range(0, len(l)-1)
+ if exists('t') | unlet t | endif
+ let n = l[idx]
+ " assume n is either an url or a path
+ if n =~ '^http://' && s:confirm('Fetch plugin info from URL '.n.'?')
+ let t = tempfile()
+ call vam#utils#RunShell(s:curl.' $ > $', n, t)
+ elseif n =~ '[/\\]' && filereadable(n)
+ let t = n
+ endif
+ if exists('t')
+ let dic = vam#ReadAddonInfo(t)
+ if !has_key(dic,'name') || !has_key(dic, 'repository')
+ call vam#Log( n." is no valid addon-info file. It must contain both keys: name and repository")
+ continue
+ endif
+ let s:c['plugin_sources'][dic['name']] = dic['repository']
+ let l[idx] = dic['name']
+ endif
+ endfor
+ return l
+endfun
+
+
+" opts: same as ActivateAddons
+fun! vam#install#Install(toBeInstalledList, ...)
+ let toBeInstalledList = vam#install#ReplaceAndFetchUrls(a:toBeInstalledList)
+ let opts = a:0 == 0 ? {} : a:1
+ let auto_install = s:c['auto_install'] || get(opts,'auto_install',0)
+ for name in filter(copy(toBeInstalledList), '!vam#IsPluginInstalled(v:val)')
+ let repository = vam#install#GetRepo(name, opts)
+ " make sure all sources are known
+ if repository is 0
+ continue
+ endif
+
+ let confirmed = 0
+ let origin = get(repository,'type','').' '.get(repository,'url','')
+ call vam#Log('Plugin Name: '.name.' ver. '.get(repository, 'version', ''), 'None')
+ call vam#Log('Script Nr: '.get(repository, 'vim_script_nr', 'none'), 'None')
+ if (has_key(opts, 'requested_by'))
+ call vam#Log('dependency chain: '.name.' < '.join(opts.requested_by,' < '))
+ endif
+
+ " tell user about target directory. Some users don't get it the first time..
+ let pluginDir = vam#PluginDirFromName(name)
+ echom "Target: ".pluginDir
+
+ let d = get(repository, 'deprecated', '')
+ if type(d) == type('') && d != ''
+ echom "!> Deprecation warning package ".name. ":"
+ echom d
+ " even for auto_install make user confirm the deprecation case
+ if !vam#Log('Origin: '.origin ,"None")
+ \ && s:confirm('Plugin '.name.' is deprecated, see warning above. Install it?', 1)
+ let confirmed = 1
+ else
+ continue
+ endif
+ endif
+
+ " ask user for to confirm installation unless he set auto_install
+
+ if auto_install
+ \ || confirmed
+ \ || (!vam#Log('Origin: '.origin ,"None")
+ \ && s:confirm("Install plugin `".name."'?"))
+
+ let infoFile = vam#AddonInfoFile(name)
+ call vam#install#Checkout(pluginDir, repository)
+
+ if !filereadable(infoFile) && has_key(repository, 'addon-info')
+ call writefile([string(repository['addon-info'])], infoFile)
+ endif
+
+ " install dependencies
+
+ let infoFile = vam#AddonInfoFile(name)
+ let info = vam#AddonInfo(name)
+
+ let dependencies = get(info,'dependencies', {})
+
+ " install dependencies merging opts with given repository sources
+ " sources given in opts will win
+ call vam#install#Install(keys(dependencies),
+ \ extend(copy(opts), {
+ \ 'plugin_sources' : extend(copy(dependencies), get(opts, 'plugin_sources',{})),
+ \ 'requested_by' : [name] + get(opts, 'requested_by', [])
+ \ }))
+ endif
+ call vam#install#HelpTags(name)
+ endfor
+endf
+
+" this function will be refactored slightly soon by either me or ZyX.
+fun! vam#install#UpdateAddon(name)
+ call vam#Log( "Considering ".a:name." for update" ,'type','unknown')
+ let pluginDir = vam#PluginDirFromName(a:name)
+ " First, try updating using VCS. Return 1 if everything is ok, 0 if exception
+ " is thrown
+ try
+ if vcs_checkouts#Update(pluginDir)
+ return 1
+ endif
+ catch /.*/
+ call vam#Log(v:exception)
+ return 0
+ endtry
+
+ "Next, try updating plugin by archive
+
+ " we have to find out whether there is a new version:
+ call vam#install#LoadPool()
+ let repository = get(s:c['plugin_sources'], a:name, {})
+ if empty(repository)
+ call vam#Log("Don't know how to update ".a:name." because it is not contained in plugin_sources")
+ return 0
+ endif
+ let newVersion = get(repository, 'version', '?')
+
+
+ if a:name is# 'vim-addon-manager'
+ " load utils before the file is moved below
+ runtime autoload/vam/util.vim
+ endif
+
+ if get(repository, 'type', '') != 'archive'
+ call vam#Log("Not updating ".a:name." because the repository description suggests using VCS ".get(repository, 'type', 'unknown').'.'
+ \ ."\nYour install seems to be of type archive/manual/www.vim.org/unknown."
+ \ ."\nIf you want to update ".a:name." remove ".pluginDir." and let VAM check it out again."
+ \ )
+ return 0
+ endif
+
+ let versionFile = pluginDir.'/version'
+ let oldVersion = filereadable(versionFile) ? readfile(versionFile, 1)[0] : "?"
+ if oldVersion !=# newVersion || newVersion == '?'
+ " update plugin
+ echom "Updating plugin ".a:name." because ".(newVersion == '?' ? 'version is unknown' : 'there is a different version')
+
+ " move plugin to backup destination:
+ let pluginDirBackup = pluginDir.'-'.oldVersion
+ if isdirectory(pluginDirBackup) || filereadable(pluginDirBackup)
+ if s:confirm("Remove old plugin backup directory (".pluginDirBackup.")?")
+ call vam#utils#RmFR(pluginDirBackup)
+ else
+ throw "User abort: remove ".pluginDirBackup." manually"
+ endif
+ endif
+ call rename(pluginDir, pluginDirBackup)
+ " can be romved. old version is encoded in tmp dir. Removing makes
+ " diffing easier
+ silent! call delete(pluginDirBackup.'/version')
+
+ " try creating diff by checking out old version again
+ if s:c['do_diff'] && executable('diff')
+ let diff_file = pluginDir.'-'.oldVersion.'.diff'
+ " try to create a diff
+ let archiveName = vam#install#ArchiveNameFromDict(repository)
+ let archiveFileBackup = pluginDirBackup.'/archive/'.archiveName
+ if !filereadable(archiveFileBackup)
+ call vam#Log( "Old archive file ".archiveFileBackup." is gone, can't try to create diff.")
+ else
+ let archiveFile = pluginDir.'/archive/'.archiveName
+ call mkdir(pluginDir.'/archive','p')
+
+ let rep_copy = deepcopy(repository)
+ let rep_copy['url'] = 'file://'.expand(archiveFileBackup)
+ call vam#install#Checkout(pluginDir, rep_copy)
+ silent! call delete(pluginDir.'/version')
+ try
+ call vam#utils#ExecInDir([{'d': fnamemodify(pluginDir, ':h'), 'c': vam#utils#ShellDSL('diff -U3 -r -a --binary $p $p', fnamemodify(pluginDir,':t'), fnamemodify(pluginDirBackup,':t')).' > '.diff_file}])
+ silent! call delete(diff_file)
+ catch /.*/
+ " :-( this is expected. diff returns non zero exit status. This is hacky
+ let diff=1
+ endtry
+ call vam#utils#RmFR(pluginDir)
+ echo 6
+ endif
+ endif
+
+ " checkout new version (checkout into empty location - same as installing):
+ call vam#install#Checkout(pluginDir, repository)
+
+ " try applying patch
+ let patch_failure = 0
+ if exists('diff')
+ if executable("patch")
+ try
+ call vam#utils#ExecInDir([{'d': pluginDir, 'c': vam#utils#ShellDSL('patch --binary -p1 --input=$p', diff_file)}])
+ echom "Patching suceeded"
+ let patch_failure = 0
+ call delete(diff_file)
+ let patch_failure = 0
+ catch /.*/
+ let patch_failure = 1
+ call vam#Log( "Failed applying patch ".diff_file." kept old dir in ".pluginDirBackup)
+ endtry
+ else
+ call vam#Log( "Failed trying to apply diff. patch exectubale not found")
+ let patch_failure = 1
+ endif
+ endif
+
+ " tidy up - if user didn't provide diff we remove old directory
+ if !patch_failure
+ call vam#utils#RmFR(pluginDirBackup)
+ endif
+ elseif oldVersion == newVersion
+ call vam#Log( "Not updating plugin ".a:name.", ".newVersion." is current")
+ return 1
+ else
+ call vam#Log( "Not updating plugin ".a:name." because there is no version according to version key")
+ endif
+ return 1
+endf
+
+fun! vam#install#Update(list)
+ let list = a:list
+
+ if s:c.known isnot 0
+ if vam#install#UpdateAddon(s:c.known)
+ call vam#install#HelpTags(s:c.known)
+ endif
+ endif
+ " refresh sources:
+ call vam#install#LoadPool(1)
+
+ if empty(list) && s:confirm('Update all loaded plugins?')
+ let list = keys(s:c['activated_plugins'])
+ endif
+ let failed = []
+ for p in list
+ if vam#install#UpdateAddon(p)
+ call vam#install#HelpTags(p)
+ else
+ call add(failed,p)
+ endif
+ endfor
+ if !empty(failed)
+ call vam#Log( "Failed updating plugins: ".string(failed).".")
+ endif
+endf
+
+" completion {{{
+
+fun! vam#install#KnownAddons(type)
+ call vam#install#LoadPool()
+ let k = {}
+ " from pool
+ call extend(k, s:c.plugin_sources)
+ " Disk completion using default plugin dir location.
+ " Don’t do this if plugin_root_dir contains newline: split(glob) does not work
+ " properly in this case. Also don’t do this if we require notinstalled
+ " plugins.
+ if a:type isnot# 'notinstalled' &&
+ \s:c.plugin_dir_by_name is# 'vam#DefaultPluginDirFromName' &&
+ \stridx(s:c.plugin_root_dir, "\n")==-1
+ for n in split(glob(s:c.plugin_root_dir.'/*', "\n"))
+ " We don’t care about values: so no need to make it complex
+ let k[fnamemodify(n, ':t')] = 1
+ endfor
+ endif
+ return keys(k)
+endf
+
+" Filters:
+" 1. Start of the name must be the same as completed name
+" 2. Part of the name must be the same as completed name
+" 3. Word may be a “glob” (supports only stars)
+" 4. There may be missing characters somewhere at the word boundary, but user
+" correctly entered start of the word
+" 5. There may be missing characters somewhere at the word boundary, but first
+" character is correct
+" 6. Name has completely wrong order of characters, but not the first character
+" 7. There may be missing characters somewhere at the word boundary
+" 8. There may be some missing charaters inside a word
+let s:smartfilters=[
+ \['1', '"v:val[:".(len(a:str)-1)."]==?".string(a:str)'],
+ \['stridx(a:str, "*")!=-1', '"v:val=~?".string("\\V".substitute(escape(a:str, "\\"), "\\*", ''\\.\\*'', "g"))'],
+ \['1', '"stridx(tolower(v:val), ".string(tolower(a:str)).")!=-1"'],
+ \['haspunct', '"v:val=~?".string("\\v^".regboundary)'],
+ \['lstr>1', '"v:val=~?".string("\\v^".reginside)'],
+ \['lstr>1', '"v:val=~?".string(regwrongorder)'],
+ \['haspunct', '"v:val=~?".string(regboundary)'],
+ \['lstr>1', '"v:val=~?".string(reginside)'],
+ \]
+fun! vam#install#GetFilters(str)
+ if empty(a:str)
+ return ['1']
+ endif
+ let lstr=len(a:str)
+ let haspunct=(match(a:str, "[[:punct:]]")!=-1)
+ let estrchars=map(split(a:str,'\v\_.@='), 'escape(v:val, "\\")')
+ let regwrongorder='\V\^'.estrchars[0].'\%(\.\*'.join(estrchars[1:], '\)\@=\%(\.\*').'\)\@='
+ let regboundary='\V'.join(map(split(a:str, '\v[[:punct:]]@<=|[[:punct:]]@='), 'escape(v:val, "\\")'), '\.\*')
+ let reginside='\V'.join(estrchars, '\.\*')
+ return map(filter(copy(s:smartfilters), 'eval(v:val[0])'), 'eval(v:val[1])')
+endfun
+
+let s:postfilters={
+ \'installed': 'isdirectory(vam#PluginDirFromName(v:val))',
+ \'notloaded': '(!has_key(s:c.activated_plugins, v:val)) && '.
+ \ 'isdirectory(vam#PluginDirFromName(v:val))',
+ \'notinstalled': '!isdirectory(vam#PluginDirFromName(v:val))',
+ \}
+fun! vam#install#DoCompletion(A, L, P, ...)
+ let list=sort(vam#install#KnownAddons(get(a:000, 0, 0)))
+ let str=matchstr(a:L[:a:P-1], '\S*$')
+ let r=[]
+ for filter in vam#install#GetFilters(str)
+ let newlist=[]
+ call map(list, '('.filter.')?(add(r, v:val)):(add(newlist, v:val))')
+ " We already have enough results to show, so stop thinking that user needs
+ " more variants
+ if len(r)>8
+ break
+ endif
+ let list=newlist
+ endfor
+ if a:0
+ call filter(r, s:postfilters[a:1])
+ endif
+ return r
+endfun
+
+fun! vam#install#AddonCompletion(...)
+ return call('vam#install#DoCompletion',a:000)
+endf
+
+fun! vam#install#NotInstalledAddonCompletion(...)
+ return call('vam#install#DoCompletion',a:000+["notinstalled"])
+endf
+
+fun! vam#install#InstalledAddonCompletion(...)
+ return call('vam#install#DoCompletion',a:000+["installed"])
+endf
+
+fun! vam#install#UninstallCompletion(...)
+ return call('vam#install#DoCompletion',a:000+["notloaded"])
+endf
+
+fun! vam#install#UpdateCompletion(...)
+ return call('vam#install#DoCompletion',a:000+["installed"])
+endf
+"}}}
+
+
+fun! vam#install#UninstallAddons(list)
+ let list = a:list
+ if list == []
+ echo "No plugins selected. If you ran UninstallNotLoadedAddons use <tab> or <c-d> to get a list of not loaded plugins."
+ return
+ endif
+ call map(list, 'vam#PluginDirFromName(v:val)')
+ if s:confirm('Will now remove '.join(list, ', ').'. Confirm?')
+ call map(list, 'vam#utils#RmFR(v:val)')
+ endif
+endf
+
+fun! vam#install#HelpTags(name)
+ let d=vam#PluginDirFromName(a:name).'/doc'
+ if isdirectory(d) | exec 'helptags '.d | endif
+endf
+
+" " if --strip-components fails finish this workaround:
+" " emulate it in VimL
+" fun! s:StripComponents(targetDir, num)
+" let dostrip = 1*a:num
+" while x in range(1, 1*a:num)
+" let dirs = split(glob(a:targetDir.'/*'),"\n")
+" if len(dirs) > 1
+" throw "can't strip, multiple dirs found!"
+" endif
+" for f in split(glob(dirs[0].'/*'),"\n")
+" call rename(file_or_dir, fnamemodify(f,':h:h').'/'.fnamemodify(f,':t'))
+" endfor
+" call remove_dir_or_file(fnamemodify(f,':h'))
+" endwhile
+" endfun
+
+" basename of url. if archive_name is given use that instead
+fun! vam#install#ArchiveNameFromDict(repository)
+ let archiveName = fnamemodify(substitute(get(a:repository,'archive_name',''), '\.\@<=VIM$', 'vim', ''),':t')
+ if empty(archiveName)
+ let archiveName = fnamemodify(a:repository['url'],':t')
+ endif
+ return archiveName
+endf
+
+
+" may throw EXCEPTION_UNPACK
+fun! vam#install#Checkout(targetDir, repository) abort
+ if get(a:repository, 'script-type') is 'patch'
+ call vam#Log(
+ \ "This plugin requires patching and recompiling vim.\n"
+ \ ."VAM could not do this, so you have to apply patch\n"
+ \ ."manually."
+ \ )
+ endif
+ if get(a:repository,'type','') =~ 'git\|hg\|svn\|bzr'
+ call vcs_checkouts#Checkout(a:targetDir, a:repository)
+ else
+ " archive based repositories - no VCS
+
+ if !isdirectory(a:targetDir) | call mkdir(a:targetDir.'/archive','p') | endif
+
+ " basename VIM -> vim
+ let archiveName = vam#install#ArchiveNameFromDict(a:repository)
+
+ " archive will be downloaded to this location
+ let archiveFile = a:targetDir.'/archive/'.archiveName
+
+ call vam#utils#Download(a:repository['url'], archiveFile)
+
+ call vam#utils#Unpack(archiveFile, a:targetDir,
+ \ {'strip-components': get(a:repository,'strip-components',-1),
+ \ 'script-type': tolower(get(a:repository, 'script-type', 'plugin')),
+ \ 'unix_ff': get(a:repository, 'unix_ff', get(s:c, 'change_to_unix_ff')) })
+
+ call writefile([get(a:repository,"version","?")], a:targetDir."/version")
+ endif
+endfun
+
+" is there a library providing an OS abstraction? This breaks Winndows
+" xcopy or copy should be used there..
+fun! vam#install#Copy(f,t)
+ if g:is_win
+ call vam#utils#RunShell('xcopy /e /i $ $', a:f, a:t)
+ else
+ call vam#utils#RunShell('cp -r $ $', a:f, a:t)
+ endif
+endfun
+
+fun! vam#install#MergeTarget()
+ return split(&runtimepath,",")[0].'/after/plugin/vim-addon-manager-merged.vim'
+endf
+
+" if you machine is under IO load starting up Vim can take some time
+" This function tries to optimize this by reading all the plugin/*.vim
+" files joining them to one vim file.
+"
+" 1) rename plugin to plugin-merged (so that they are no longer sourced by Vim)
+" 2) read plugin/*.vim_merged files
+" 3) replace clashing s:name vars by uniq names
+" 4) rewrite the guards (everything containing finish)
+" 5) write final merged file to ~/.vim/after/plugin/vim-addon-manager-merged.vim
+" so that its sourced automatically
+"
+" TODO: take after plugins int account?
+fun! vam#install#MergePluginFiles(plugins, skip_pattern)
+ if !filereadable('/bin/sh')
+ throw "you should be using Linux.. This code is likely to break on other operating systems!"
+ endif
+
+ let target = vam#install#MergeTarget()
+
+ for r in a:plugins
+ if !has_key(s:c['activated_plugins'], r)
+ throw "JoinPluginFiles: all plugins must be activated (which ensures that they have been installed). This plugin is not active: ".r
+ endif
+ endfor
+
+ let runtimepaths = map(copy(a:plugins), 'vam#PluginRuntimePath(v:val)')
+
+ " 1)
+ for r in runtimepaths
+ if (isdirectory(r.'/plugin'))
+ call vam#utils#RunShell('mv $ $', r.'/plugin', r.'/plugin-merged')
+ endif
+ endfor
+
+ " 2)
+ let file_local_vars = {}
+ let uniq = 1
+ let all_contents = ""
+ for r in runtimepaths
+ for file in split(glob(r.'/plugin-merged/*.vim'),"\n")
+
+ if file =~ a:skip_pattern
+ let all_contents .= "\" ignoring ".file."\n"
+ continue
+ endif
+
+ let names_this_file = {}
+ let contents =join(readfile(file, 'b'),"\n")
+ for l in split("s:abc s:foobar",'\ze\<s:')[1:]
+ let names_this_file[matchstr(l,'^s:\zs[^ [(=)\]]*')] = 1
+ endfor
+ " handle duplicate local vars: 3)
+ for k in keys(names_this_file)
+ if has_key(file_local_vars, k)
+ let new = 'uniq_'.uniq
+ let uniq += 1
+ let file_local_vars[new] = 1
+ let contents = "\" replaced: ".k." by ".new."\n".substitute(contents, 's:'.k,'s:'.new,'g')
+ else
+ let file_local_vars[k] = 1
+ endif
+ endfor
+
+ " find finish which start at the end of a line.
+ " They are often used to separated Vim code from additional info such as
+ " history (eg tlib is using it). Comment remaining lines
+ let lines = split(contents,"\n")
+ let comment = 0
+ for i in range(0,len(lines)-1)
+ if lines[i] =~ '^finish'
+ let comment = 1
+ endif
+ if comment
+ let lines[i] = "\" ".lines[i]
+ endif
+ endfor
+ let contents = join(lines,"\n")
+
+ " guards 4)
+ " find guards replace them by if .. endif blocks
+ let lines = split(contents,"\n")
+ for i in range(2,len(lines)-1)
+ if lines[i] =~ '^\s*finish' && lines[i-1] =~ '^\s*if\s'
+ " found a guard
+
+ " negate if, remove triple { if present (I don't care)
+ let lines[i-1] = 'if !('.matchstr(substitute(lines[i-1],'"[^"]*{\{3}.*','',''),'if\s*\zs.*').')'
+ let j = i+1
+ while j < len(lines) && lines[j] !~ '^\s*endif'
+ let lines[j] = ''
+ let j = j+1
+ endwhile
+ let lines[j] = ''
+ " guards are never longer than 10 lines
+ if j - i > 10
+ throw "something probably has gone wrong while removing guard for file".file." start at line: ".i
+ endif
+ call add(lines,'endif')
+ let contents = join(lines,"\n")
+ break
+ endif
+ endfor
+
+
+ " comment remaining finish lines. This does not catch if .. | finish | endif and such
+ " :-(
+ " adding additional \n because not all scripts have a final \n..
+ let contents = substitute(contents, '\<finish\>','" finish','g')
+ let all_contents .= "\n"
+ \ ."\"merged: ".file."\n"
+ \ .contents
+ \ ."\n"
+ \ ."\"merged: ".file." end\n"
+ endfor
+ endfor
+
+ let d =fnamemodify(target,':h')
+ if !isdirectory(d) | call mkdir(d,'p') | endif
+ call writefile(split(all_contents,"\n"), target)
+
+endf
+
+fun! vam#install#UnmergePluginFiles()
+ let path = fnamemodify(vam#PluginRuntimePath('vim-addon-manager'),':h')
+ for merged in split(glob(path.'/*/plugin-merged'),"\n")
+ \ +split(glob(path.'/*/*/plugin-merged'),"\n")
+ echo "unmerging ".merged
+ call rename(merged, substitute(merged,'-merged$','',''))
+ endfor
+ call delete(vam#install#MergeTarget())
+endfun
+
+"{{{1 Pool
+" VAM does call this function for you when using {Activate/Install}Addon() or
+" one of those commands. Read doc/vim-addon-manager.txt to learn about the
+" pool of plugin sources. Also see option "known_repos_activation_policy"
+fun! vam#install#LoadKnownRepos()
+ let known = s:c['known']
+ let reason = a:0 > 0 ? a:1 : 'get more plugin sources'
+ if 0 == get(s:c['activated_plugins'], known, 0)
+ let policy=get(s:c, 'known_repos_activation_policy', 'autoload')
+ if policy==?"ask"
+ let reply = s:confirm('Activate plugin '.known.' to '.reason."?", "&Yes\n&No\nN&ever (during session)")
+ elseif policy==?"never"
+ let reply=2
+ else
+ let reply=1
+ endif
+ if reply == 3 | let s:c.known_repos_activation_policy = "never" | endif
+ if reply == 1
+ " don't pass opts so that new_runtime_paths is not set which will
+ " trigger topLevel adding -known-repos to rtp immediately
+ call vam#ActivateAddons([known], {})
+ endif
+ endif
+endfun
+
+" The default pool of know plugins for VAM: vim-addon-manager-known-repositories
+fun! vam#install#Pool()
+ call vam#install#LoadKnownRepos()
+ return vam_known_repositories#Pool()
+endfun
+
+" (re)loads pool of known plugins
+fun! vam#install#LoadPool(...)
+ let force = a:0 > 0 ? a:1 : 0
+ if force || !has_key(s:c, 'pool_loaded')
+ " update plugin_sources
+ let s:c.plugin_sources = call(s:c.pool_fun, [], {})
+
+ let s:c.pool_loaded = 1
+ endif
+endf
+"}}}1
+
+
+if g:is_win
+ fun! vam#install#FetchAdditionalWindowsTools() abort
+ if !executable("curl") && s:curl == "curl -o"
+ throw "No curl found. Either set g:netrw_http_cmd='path/curl -o' or put it in PATH"
+ endif
+ if !isdirectory(s:c['binary_utils'].'\dist')
+ call mkdir(s:c['binary_utils'].'\dist','p')
+ endif
+ " we have curl, so we can fetch remaining deps using Download and Unpack
+ let tools = {
+ \ 'gzip': ['mirror://sourceforge/gnuwin32/gzip/1.3.12-1/', "gzip-1.3.12-1-bin.zip", ["gzip", "7z"]],
+ \ 'bzip2':['mirror://sourceforge/gnuwin32/bzip2/1.0.5/', "bzip2-1.0.5-bin.zip", ["bzip2", "7z"] ],
+ \ 'tar': ['mirror://sourceforge/gnuwin32/tar/1.13-1/',"tar-1.13-1-bin.zip", ["tar", "7z"] ],
+ \ 'zip': ['mirror://sourceforge/gnuwin32/unzip/5.51-1/', "unzip-5.51-1-bin.zip", ["unzip","7z"] ],
+ \ 'diffutils': ['mirror://sourceforge/gnuwin32/diffutils/2.8.7-1/',"diffutils-2.8.7-1-bin.zip", "diff"],
+ \ 'patch': [ 'mirror://sourceforge/gnuwin32/patch/2.5.9-7/',"patch-2.5.9-7-bin.zip", "patch"]
+ \ }
+ for v in values(tools)
+ echo "downloading ".v[1]
+ for ex in v[2]
+ if executable(ex) | continue | endif
+ endfor
+ if !filereadable(s:c['binary_utils'].'\'.v[1])
+ call vam#utils#DownloadFromMirrors(v[0].v[1], s:c['binary_utils'])
+ endif
+ endfor
+
+ if !executable('unzip')
+ " colorize this?
+ echo "__ its your turn: __"
+ echom "__ move all files of the zip directory into ".s:c['binary_utils'].'/dist . Close the Explorer window and the shell window to continue. Press any key'
+ call getchar()
+ exec "!".expand(s:c['binary_utils'].'/'. tools.zip[1])
+ let $PATH=$PATH.';'.s:c['binary_utils_bin']
+ if !executable('unzip')
+ throw "can't execute unzip. Something failed!"
+ endif
+ endif
+
+ " now we have unzip and can do rest
+ for k in ["gzip","bzip2","tar","diffutils","patch"]
+ if !executable(tools[k][2])
+ call vam#utils#Unpack(s:c['binary_utils'].'\'.tools[k][1], s:c['binary_utils'].'\dist')
+ endif
+ endfor
+
+ "if executable("7z")
+ "echo "you already have 7z in PATH. Nothing to be done"
+ "return
+ "endif
+ "let _7zurl = 'mirror://sourceforge/sevenzip/7-Zip/4.65/7z465.exe'
+ "call vam#utils#DownloadFromMirrors(_7zurl, s:c['binary_utils'].'/7z.exe')
+
+ endf
+endif
+
+" addon name completion {{{1
+" TODO tidy up, refactor so that common code (find plugin name fuzzily) is in
+" one function only
+
+function! vam#install#SplitAtCursor()
+ let pos = col('.') -1
+ let line = getline('.')
+ return [strpart(line,0,pos), strpart(line, pos, len(line)-pos)]
+endfunction
+
+
+fun! vam#install#CompleteAddonName(findstart, base)
+ if a:findstart
+ let [bc,ac] = vam#install#SplitAtCursor()
+ let s:match_text = matchstr(bc, "\\zs[^'\"()[\\]{}\\t ]*$")
+ return len(bc)-len(s:match_text)
+ else
+ " ! duplicate code !
+ " let lstr=len(a:base)
+ " let str = a:base
+ " let estr=escape(str, '\')
+ " let reg='\V'.join(split(estr, '\v[[:punct:]]@<=|[[:punct:]]@='), '\.\*')
+ " let reg2='\V'.join(map(split(str,'\v\_.@='),'escape(v:val,"\\")'), '\.\*')
+
+ let list = vam#install#KnownAddons()
+ call filter(list, 'v:val =~ '.string('\c'.a:base))
+ " let r=[]
+ " for filter in s:smartfilters
+ " let newlist=[]
+ " call map(list, '('.filter.')?(add(r, v:val)):(add(newlist, v:val))')
+ " let list=newlist
+ " endfor
+
+ for name in list
+ let d = s:c.plugin_sources[name]
+ let script_id = has_key(d, 'vim_script_nr') ? 'script-id: '.d.vim_script_nr : ''
+ call complete_add({'word': name, 'menu': script_id})
+ endfor
+ return []
+ endif
+endf
+
+" }}}
+
+" vim: et ts=8 sts=2 sw=2
diff --git a/vim-addon-manager/autoload/vam/test.vim b/vim-addon-manager/autoload/vam/test.vim
new file mode 100644
index 0000000..e4c08d1
--- /dev/null
+++ b/vim-addon-manager/autoload/vam/test.vim
@@ -0,0 +1,127 @@
+
+let s:plugin_root_dir = fnamemodify(expand('<sfile>'),':h:h:h')
+
+" called by vim-addon-manager-test.sh
+fun! vam#test#Test()
+ let test_dir = '/tmp/vim-addon-manager-test'
+
+ exec '!rm -fr ' test_dir
+ exec '!mkdir -p ' test_dir
+ exec '!cp -r' s:plugin_root_dir test_dir
+
+ " keep it simple:
+ let g:vim_addon_manager['activated_plugins']['vim-addon-manager-known-repositories'] = 1
+ let plugin_sources = g:vim_addon_manager['plugin_sources']
+
+ " test mercurial
+ call feedkeys("y")
+ let plugin_sources['vimstuff'] = { 'type': 'hg', 'url': 'http://vimstuff.hg.sourceforge.net:8000/hgroot/vimstuff/vimstuff' }
+ call vam#ActivateAddons(["vimstuff"])
+
+ " test git
+ call feedkeys("y")
+ let plugin_sources['vim-addon-views'] = { 'type' : 'git', 'url' : 'git://github.com/MarcWeber/vim-addon-views.git' }
+ call vam#ActivateAddons(["vim-addon-views"])
+
+ " test subversion
+ call feedkeys("y")
+ let plugin_sources['vim-latex'] = { 'type': 'svn', 'url': 'https://vim-latex.svn.sourceforge.net/svnroot/vim-latex/trunk/vimfiles'}
+ call vam#ActivateAddons(["vim-latex"])
+
+endf
+
+" vam#utils#Unpack tests
+
+" test: . = all tests
+" tar$ = onnly the tar test
+fun! vam#test#TestUnpack(test) abort
+ let tests = {
+ \ 'tar': ['autocorrect', ['README', 'archive', 'archive/autocorrect.tar', 'autocorrect.dat', 'autocorrect.vim', 'generator.rb', 'version'] ],
+ \ 'tar.gz': ['ack', ['archive', 'archive/ack.tar.gz', 'doc', 'doc/ack.txt', 'plugin', 'plugin/ack.vim', 'version']],
+ \ 'tgz': ['VIlisp', ['README', 'VIlisp-hyperspec.pl', 'VIlisp.vim', 'changelog', 'funnel.pl', 'lisp-thesaurus', 'make-lisp-thes.pl', 'archive', 'archive/VIlisp.2.3.tgz', 'version']],
+ \ 'tar.bz2': ['DetectIndent', ['archive', 'archive/detectindent-1.0.tar.bz2', 'doc', 'doc/detectindent.txt', 'plugin', 'plugin/detectindent.vim', 'version']],
+ \ 'tbz2': ['xterm16', ['ChangeLog', 'archive', 'archive/xterm16-2.43.tbz2', 'cpalette.pl', 'version', 'xterm16.ct', 'xterm16.schema', 'xterm16.txt', 'xterm16.vim']],
+ \ 'vim_ftplugin': ['srec1008', ['archive', 'archive/srec.vim', 'ftplugin', 'ftplugin/srec.vim', 'version']],
+ \ 'vba': ['Templates_for_Files_and_Function_Groups', ['archive', 'archive/file_templates.vba', 'plugin', 'plugin/file_templates.vim', 'templates', 'templates/example.c', 'version', 'templates/example.h']],
+ \ 'vba.gz': ['gitolite', ['archive', 'archive/gitolite.vba.gz', 'ftdetect', 'ftdetect/gitolite.vim', 'syntax', 'syntax/gitolite.vim', 'version']],
+ \ 'vba.bz2': ['winmanager1440',['archive', 'archive/winmanager.vba.bz2', 'doc', 'doc/tags', 'doc/winmanager.txt', 'plugin', 'plugin/start.gnome', 'plugin/start.kde', 'plugin/winfileexplorer.vim', 'plugin/winmanager.vim', 'plugin/wintagexplorer.vim', 'version']]
+ \ }
+
+ let tmpDir = vam#utils#TempDir("vim-addon-manager-test")
+
+ call vam#install#LoadPool()
+
+ for [k,v] in items(tests)
+ if k !~ a:test | continue | endif
+ call vam#utils#RmFR(tmpDir)
+ let dict = g:vim_addon_manager['plugin_sources'][v[0]]
+ call vam#install#Checkout(tmpDir, dict)
+ let files = split(glob(tmpDir.'/**'),"\n")
+ " replace \ by / on win and remove tmpDir prefix
+ call map(files, 'substitute(v:val,'.string('\').',"/","g")['.(len(tmpDir)+1).':]')
+ call sort(files)
+ call sort(v[1])
+ if v[1] != files
+ echoe "test failure :".k
+ echoe 'expected :'.string(v[1])
+ echoe 'got : '.string(files)
+ debug echoe 'continue'
+ endif
+ endfor
+endf
+
+" tests that creating and applying diffs when updating archive plugins (found
+" on www.vim.org) works as expected.
+fun! vam#test#TestUpdate(case) abort
+ call vam#install#LoadPool()
+ let tmpDir = vam#utils#TempDir("vim-addon-manager-test")
+ let plugin_name = "www_vim_org_update_test"
+ let plugin_source_file = tmpDir.'/'.plugin_name.'.vim'
+ let installDir = vam#PluginDirByName(plugin_name)
+ let installCompareDir = vam#PluginDirByName(plugin_name.'-1.0')
+ silent! unlet g:vim_addon_manager['activated_plugins'][plugin_name]
+ for dir in [tmpDir, installDir, installCompareDir]
+ if isdirectory(dir) | call vam#utils#RmFR(dir) | endif
+ endfor
+ call mkdir(tmpDir.'/plugin','p')
+
+ let file_v1 = ["version 1.0", "1", "2", "3", "4", "5" ]
+ let file_v1_patched = ["version 1.0", "1", "2", "3", "4", "patched" ]
+ let file_v2 = ["version 2.0", "1", "2", "3", "4", "5" ]
+ let file_v2_patched = ["version 2.0", "1", "2", "3", "4", "patched" ]
+
+
+ let file_v2_conflict = ["version 2.0", "1", "2", "3", "4", "conflicting line" ]
+
+ " install v1
+ call writefile( file_v1, plugin_source_file, 1)
+ let g:vim_addon_manager['plugin_sources'][plugin_name] = {'type': 'archive', 'url': 'file://'.plugin_source_file, 'version' : '1.0' , 'script-type': 'plugin' }
+ exec 'ActivateAddons '.plugin_name
+
+ " patch
+ call writefile( file_v1_patched, installDir.'/plugin/'.plugin_name.'.vim', 1)
+
+ if a:case == "normal"
+
+ " update to v2
+ call writefile( file_v2, plugin_source_file, 1)
+ let g:vim_addon_manager['plugin_sources'][plugin_name] = {'type': 'archive', 'url': 'file://'.plugin_source_file, 'version' : '2.0' , 'script-type': 'plugin' }
+ exec 'UpdateAddons '.plugin_name
+
+ " verify that the patch is still present
+ if file_v2_patched != readfile( installDir.'/plugin/'.plugin_name.'.vim', 1)
+ echoe "test failed"
+ endif
+
+ elseif a:case == "conflict"
+ " manual test: diff file should be kept
+ " update to v2 conflict
+ call writefile( file_v2_conflict, plugin_source_file, 1)
+ let g:vim_addon_manager['plugin_sources'][plugin_name] = {'type': 'archive', 'url': 'file://'.plugin_source_file, 'version' : '2.0' , 'script-type': 'plugin' }
+ exec 'UpdateAddons '.plugin_name
+ else
+ throw "unknown case"
+
+ endif
+endfun
+" vim: et ts=8 sts=2 sw=2
diff --git a/vim-addon-manager/autoload/vam/utils.vim b/vim-addon-manager/autoload/vam/utils.vim
new file mode 100644
index 0000000..df8dfa3
--- /dev/null
+++ b/vim-addon-manager/autoload/vam/utils.vim
@@ -0,0 +1,399 @@
+" vam#DefineAndBind('s:c','g:vim_addon_manager','{}')
+if !exists('g:vim_addon_manager') | let g:vim_addon_manager = {} | endif | let s:c = g:vim_addon_manager
+
+" let users override curl command. Reuse netrw setting
+let s:curl = exists('g:netrw_http_cmd') ? g:netrw_http_cmd : 'curl -o'
+
+" insert arguments at placeholders $ shell escaping the value
+" usage: s:shellescape("rm --arg $ -fr $p $p $p", [string, file1, file2, file3])
+"
+" the / \ annoyance of Windows is fixed by calling expand which replaces / by
+" \ on Windows. This only happens by the $p substitution
+" if $ is followed by a number its treated as index
+
+" EXamples:
+" vam#utils#ShellDSL('$', 'escape this/\') == '''escape this/\'''
+" vam#utils#ShellDSL('$1 $[2p] $1p', 'escape this/\',\'other\') =='''escape this/'' ''other'' ''escape this/'''
+" vam#utils#ShellDSL('$.url $[1p.url] $1p.url', {'url':'URL'} ) =='''URL'' ''URL'' ''URL'''
+fun! vam#utils#ShellDSL(cmd, ...) abort
+ let args = a:000
+ let r = ''
+ let l = split(a:cmd, '\V$', 1)
+ let r = l[0]
+ let i = 0
+ for x in l[1:]
+ let list = matchlist(x, '\[\?\(\d*\)\(p\)\?\(\.[^ \t\]]*\)\?\]\?')
+ if len(list) ==0
+ " should not happen
+ throw 'vam#utils#ShellDSL, bad : '.x
+ endif
+ if list[1] != ''
+ let p= args[list[1]-1]
+ else
+ let p = args[i]
+ let i += 1
+ endif
+ if list[3] != ''
+ for path in split(list[3],'\.')
+ let tmp = p[path] | unlet p | let p = tmp
+ endfor
+ endif
+ if list[2] == 'p'
+ let p = expand(fnameescape(p))
+ endif
+ let r .= shellescape(p,1).x[len(list[0]):]
+ unlet p
+ endfor
+ return r
+endf
+
+fun! s:Cmd(expect_code_0, cmd) abort
+ call vam#Log(a:cmd, "None")
+ exe (s:c.silent_shell_commands ? "silent " : "").'!'. a:cmd
+ if a:expect_code_0 && v:shell_error != 0
+ let s:c.last_shell_command = a:cmd
+ throw "error executing ". a:cmd
+ endif
+ return v:shell_error
+endf
+
+" TODO improve this and move somewhere else?
+fun! vam#utils#RunShell(...) abort
+ let cmd = call('vam#utils#ShellDSL', a:000)
+ return s:Cmd(0,cmd)
+endf
+
+" cmds = list of {'d': dir to run command in, 'c': the command line to be run }
+fun! vam#utils#ExecInDir(cmds) abort
+ if g:is_win
+ " set different lcd in extra buffer:
+ new
+ try
+ let lcd=""
+ for c in a:cmds
+ if has_key(c, "d")
+ exec "lcd ".fnameescape(c.d)
+ endif
+ if has_key(c, "c")
+ call s:Cmd(c.c)
+ endif
+ endfor
+ finally
+ bw!
+ endtry
+ else
+ " execute command sequences on linux
+ let cmds_str = []
+ for c in a:cmds
+ if has_key(c, "d")
+ call add(cmds_str, "cd ".shellescape(c.d, 1))
+ endif
+ if has_key(c, "c")
+ call add(cmds_str, c.c)
+ endif
+ endfor
+ call s:Cmd(1, join(cmds_str," && "))
+ endif
+endf
+let s:exec_in_dir=function('vam#utils#ExecInDir')
+
+"Usages: EndsWith('name.tar', '.tar', '.txt') returns 1 even if .tar was .txt
+fun! s:EndsWith(name, ...)
+ return a:name =~? '\%('.substitute(join(a:000,'\|'),'\.','\\.','g').'\)$'
+endf
+
+" may throw EXCEPTION_UNPACK.*
+" most packages are shipped in a directory. Eg ADDON/plugin/*
+" strip-components=1 strips of this ADDON directory (implemented for tar.* " archives only)
+"
+" assumes the dir containing archive is writable to place tmp files in. eg
+" .tar when unpacking .tar.gz. because gunzip and bunzip2 remove the original
+" file a backup is made if del-source is not set. However file permissions may
+" no tbe preserved. I don't think its worth fixing. If you think different
+" contact me.
+
+" !! If you change this run the test, please: call vim_addon_manager_tests#Tests('.')
+fun! vam#utils#Unpack(archive, targetDir, ...)
+ let opts = a:0 > 0 ? a:1 : {}
+ let strip_components = get(opts, 'strip-components', -1)
+ let delSource = get(opts, 'del-source', 0)
+
+ let esc_archive = vam#utils#ShellDSL('$', a:archive)
+ let tgt = [{'d': a:targetDir}]
+
+ if strip_components > 0 || strip_components == -1
+ " when stripping don' strip which was there before unpacking
+ let keep = vam#utils#Glob(a:targetDir.'/*')
+ let strip = 'call vam#utils#StripComponents(a:targetDir, strip_components, keep)'
+ else
+ let strip = ''
+ endif
+
+ " [ ending, chars to strip, chars to add, command to do the unpacking ]
+ let gzbzip2 = {
+ \ '.gz': [-4, '','gzip -d'],
+ \ '.tgz': [-3,'ar','gzip -d'],
+ \ '.bz2': [-5, '', 'bzip2 -d'],
+ \ '.tbz2': [-4,'ar','bzip2 -d'],
+ \ }
+
+ " .vim file and type syntax?
+ if a:archive =~? '\.vim$'
+ " hook for plugin / syntax files: Move into the correct direcotry:
+ let dir = a:targetDir.'/plugin'
+ let type = opts['script-type']
+ if type =~# '\v^%(%(after\/)?syntax|indent|ftplugin)$'
+ let dir = a:targetDir.'/'.type
+ elseif type is 'color scheme'
+ let dir = a:targetDir.'/colors'
+ endif
+ if (!isdirectory(dir))
+ call mkdir(dir, 'p')
+ endif
+ call writefile(readfile(a:archive,'b'), dir.'/'.fnamemodify(a:archive, ':t'), 'b')
+
+ " .gz .bzip2 (or .vba.* or .tar.*)
+ elseif call(function('s:EndsWith'), [a:archive] + keys(gzbzip2) )
+ " I was told tar on Windows is buggy and can't handle xj or xz correctly
+ " so unpack in two phases:
+
+ for [k,z] in items(gzbzip2)
+ if s:EndsWith(a:archive, k)
+ " without ext
+ let unpacked = a:archive[:z[0]]
+ " correct ext
+ let renameTo = unpacked.z[1]
+
+ " PHASE (1): gunzip or bunzip using gzip,bzip2 or 7z:
+ if executable('7z') && !exists('g:prefer_tar')
+ " defaulting to 7z why or why not?
+ call vam#utils#RunShell('7z x -o$ $', fnamemodify(a:archive, ':h'), a:archive)
+ " 7z renames tgz to tar
+ else
+ " make a backup. gunzip etc rm the original file
+ if !delSource
+ let b = a:archive.'.bak'
+ call vam#utils#CopyFile(a:archive, b)
+ endif
+
+ " unpack
+ call vam#utils#RunShell(z[2].' $', a:archive)
+
+ " copy backup back:
+ if !delSource | call rename(b, a:archive) | endif
+ endif
+
+ if !filereadable(renameTo)
+ " windows tar does not rename .tgz to .tar ?
+ call rename(unpacked, renameTo)
+ endif
+
+ " PHASE (2): now unpack .tar or .vba file and tidy up temp file:
+ call vam#utils#Unpack(renameTo, a:targetDir, { 'strip-components': strip_components, 'del-source': 1 })
+ call delete(renameTo)
+ break
+ endif
+ unlet k z
+ endfor
+
+ " execute in target dir:
+
+ " .tar
+ elseif s:EndsWith(a:archive, '.tar')
+ if executable('7z')
+ call vam#utils#RunShell('7z x -o$ $', a:targetDir, a:archive)
+ else
+ call s:exec_in_dir(tgt + [{'c': 'tar -xf '.esc_archive }])
+ endif
+ exec strip
+
+ " .zip
+ elseif s:EndsWith(a:archive, '.zip')
+ if executable('7z')
+ call vam#utils#RunShell('7z x -o$ $', a:targetDir, a:archive)
+ else
+ call s:exec_in_dir(tgt + [{'c': 'unzip '.esc_archive }])
+ endif
+ exec strip
+
+ " .7z, .cab, .rar, .arj, .jar
+ " (I have actually seen only .7z and .rar, but 7z supports other formats
+ " too)
+ elseif s:EndsWith(a:archive, '.7z','.cab','.arj','.rar','.jar')
+ call vam#utils#RunShell('7z x -o$ $', a:targetDir, a:archive)
+ exec strip
+
+ elseif s:EndsWith(a:archive, '.vba','.vmb')
+ " .vba reuse vimball#Vimball() function
+ exec 'sp '.fnameescape(a:archive)
+ call vimball#Vimball(1,a:targetDir)
+ " wipe out buffer
+ bw!
+ else
+ throw "EXCEPTION_UNPACK: don't know how to unpack ". a:archive
+ endif
+
+ if delSource && !filereadable(a:archive)
+ call delete(a:archive)
+ endif
+
+ " Do not use `has("unix")' here: it may be useful on `win32unix' (cygwin) and
+ " `macunix' (someone should ask users of these vims about that)
+ if get(opts, 'unix_ff', 0)
+ for f in filter(vam#utils#Glob(a:targetDir.'/**/*.vim'), 'filewritable(v:val)==1')
+ call writefile(map(readfile(f, 'b'),
+ \'((v:val[-1:]==#"\r")?(v:val[:-2]):(v:val))'), f, 'b')
+ endfor
+ endif
+ " Using :sp will fire unneeded autocommands
+
+endf
+
+" Usage: Glob($HOME.'/*')
+" FIXME won't list hidden files as well
+fun! vam#utils#Glob(path)
+ return split(glob(a:path),"\n")
+ " The following does not filter . and .. components at all and spoils **
+ " patterns (but it lacks `\' at the start of the line, so it is not even
+ " executed). Commenting this line just clarifies this issue
+ " + filter(split(glob(substitute(a:path,'\*','.*','g')),"\n"),'v:val != "." && v:val != ".."')
+endf
+
+" move */* one level up, then remove first * matches
+" if you don't want all dirs to be removed add them to keepdirs
+" Example:
+"
+" A/activte/file.tar
+" A/the-plugin/ftplugin/...
+" A/the-plugin/autoload/...
+" StripComponents(A, 1, "^activate")
+" will yield strip the-plugin directory off.
+"
+" This emulatios tar --strip-components option (which is not present in 7z or
+" unzip)
+"
+" If num==-1, then StripComponents will strip only if it finds that there is
+" only one directory that needs stripping
+fun! vam#utils#StripComponents(dir, num, keepdirs)
+ let num = a:num
+ let strip_single_dir = 0
+ if num == -1
+ let num = 1
+ let strip_single_dir = 1
+ endif
+ for i in range(0, num-1)
+ let tomove = []
+ let toremove = []
+ " for each a:dir/*
+ for gdir in filter(vam#utils#Glob(a:dir.'/*'),'isdirectory(v:val)')
+ if index(a:keepdirs, gdir)!=-1 | continue | endif
+ call add(toremove, gdir)
+ if strip_single_dir && len(toremove)>=2
+ return
+ endif
+ " for each gdir/*
+ for path in vam#utils#Glob(gdir.'/*')
+ " move out of dir
+ call add(tomove, [path, a:dir.'/'.fnamemodify(path, ':t')])
+ endfor
+ endfor
+ if strip_single_dir && !empty(toremove) && toremove[0]=~#'\v/%(autoload|colors|compiler|ftplugin|indent|keymap|lang|plugin|print|spell|syntax)$'
+ return
+ endif
+ call map(tomove, 'rename(v:val[0], v:val[1])')
+ call map(toremove, 'vam#utils#RmFR(v:val)')
+ endfor
+endf
+
+" also copies 0. May throw an exception on failure
+fun! vam#utils#CopyFile(a,b)
+ let fc = readfile(a:a, 'b')
+ if writefile(fc, a:b, 'b') != 0
+ throw "copying file ".a:a." to ".a:b." failed"
+ endif
+endf
+
+fun! vam#utils#Download(url, targetFile)
+ " allow redirection because of sourceforge mirrors:
+
+ let s:curl = exists('g:netrw_http_cmd') ? g:netrw_http_cmd : 'curl -o'
+ " Let's hope that nobody is using a dir called "curl " .. because
+ " substitution will be wrong then
+ let c = substitute(s:curl, '\ccurl\(\.exe\)\?\%( \|$\)','curl\1 --location --max-redirs 40 ','')
+ call vam#utils#RunShell(c.' $p $', a:targetFile, a:url)
+endf
+
+fun! vam#utils#RmFR(dir_or_file)
+ let cmd = ""
+ if has('win32') || has('win64')
+ if getftype(a:dir_or_file) == 'dir'
+ let cmd = 'rmdir /S /Q'
+ else
+ let cmd = 'erase /F'
+ endif
+ elseif has('win16') || has('win95')
+ " Dos-style COMMAND.COM. These are _UNTESTED_
+ if getftype(a:dir_or_file) == 'dir'
+ let cmd = 'deltree /Y'
+ else
+ let cmd = 'erase /F'
+ endif
+ else
+ let cmd = "rm -fr"
+ endif
+ if cmd == ""
+ throw "don't know how to RmFR on this system: ".g:os
+ else
+ call vam#utils#RunShell(cmd.' $', a:dir_or_file)
+ endif
+endf
+
+
+" a "direct link" (found on the download page)
+" such as "http://downloads.sourceforge.net/project/gnuwin32/gzip/1.3.12-1/gzip-1.3.12-1-bin.zip"
+" can be downloaded this way:
+" call vam#utils#DownloadFromMirrors("mirror://sourceforge/gnuwin32/gzip/1.3.12-1/gzip-1.3.12-1-bin.zip","/tmp")
+fun! vam#utils#DownloadFromMirrors(url, targetDir)
+ let mirrors_sourceforge = [
+ \ 'http://heanet.dl.sourceforge.net/sourceforge/',
+ \ 'http://surfnet.dl.sourceforge.net/sourceforge/',
+ \ ]
+
+ let m = matchlist(a:url, '^mirror:\/\/\([^/\\]\+\)\/\(.*\)')
+
+ if len(m) > 3
+ let url = mirrors_{m[1]}[0].m[2]
+ endif
+ " if target is a directory append basename of url
+ let t = a:targetDir
+ if isdirectory(t)
+ let t = t .'/'.fnamemodify(url,':t')
+ endif
+ call vam#utils#Download(url, t)
+endf
+
+
+let s:tmpDir = ""
+" this is not cleaned up on shutdown yet !
+" tmpname():
+" on windows C:\Users\NAME\AppData\Local\Temp\VIG3DB6.tmp
+" on linux /tmp/v106312/111
+"
+" on linux this returns /tmp/a:name
+" on windows it returns C:\Users\NAME\AppData\Local\Temp/a:name
+fun! vam#utils#TempDir(name)
+ if s:tmpDir == ""
+ let s:tmpDir = fnamemodify(tempname(), ":h".(g:is_win ? '': ':h'))
+ endif
+ " expand make \ out of / on Windows
+ return expand(s:tmpDir.'/'.a:name)
+endf
+
+" tries finding a new name if a plugin was renamed.
+" Also tries to provide suggestions if you made trivial typos (case,
+" forgetting _ special characters and such)
+fun! vam#utils#TypoFix(name)
+ return substitute(tolower(a:name), '[_/\-]*', '', 'g')
+endf
+
+" vim: et ts=8 sts=2 sw=2
diff --git a/vim-addon-manager/autoload/vcs_checkouts.vim b/vim-addon-manager/autoload/vcs_checkouts.vim
new file mode 100644
index 0000000..c6090fb
--- /dev/null
+++ b/vim-addon-manager/autoload/vcs_checkouts.vim
@@ -0,0 +1,85 @@
+" eventually this code will be moved into its own plugin in the future. Cause
+" its very short probably VAM will keep a copy
+
+exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}')
+let s:c.shallow_clones = get(s:c,'shallow_clones', executable('git') && system('git clone --help') =~ '--depth')
+let s:c.scm_extra_args = get(s:c,'scm_extra_args',{})
+
+let s:se = s:c.scm_extra_args
+" this is not proberly quoted yet thus its will change:
+" using list so that we can encode ['$ $',[1,2]] (quoting values if needed)
+let s:se.git = get(s:c,'git', [s:c.shallow_clones ? '--depth 1' : ''])
+
+" What's important about these configurations ?
+"
+" s:*_checkout are called with (repository, targetDir)
+" s:*_update are called with (repository, vcs_directory)
+"
+" Thus you can overwrite them and implement whatever behaviour you like.
+" The default implemenation should be close to what users expect from the VCS
+" being used. However if you prefer mercurial overriding git_checkout is the
+" way to make mercurial checkout git repos instead (like ZyX ? :)
+"
+" Later we can even add additional implementations telling user that upstream
+" has changed etc .. (TODO)
+let s:c.git_checkout = get(s:c, 'git_checkout', { 'f': 'vam#utils#RunShell', 'a': ['git clone '.s:se.git[0].' $.url $p'] })
+let s:c.hg_checkout = get(s:c, 'hg_checkout', { 'f': 'vam#utils#RunShell', 'a': ['hg clone $.url $p']})
+let s:c.bzr_checkout = get(s:c, 'bzr_checkout', { 'f': 'vam#utils#RunShell', 'a': ['bzr branch $.url $p']})
+let s:c.svn_checkout = get(s:c, 'svn_checkout', { 'f': 'vcs_checkouts#SVNCheckout', 'a': []})
+
+" luckily "cd && cmd" works on both: win and linux ..
+let s:c.git_update = get(s:c, 'git_update', { 'f': 'vam#utils#RunShell', 'a': ['cd $p && git pull'] })
+let s:c.hg_update = get(s:c, 'hg_update', { 'f': 'vam#utils#RunShell', 'a': ['hg pull -u -R $p']})
+let s:c.bzr_update = get(s:c, 'bzr_update', { 'f': 'vam#utils#RunShell', 'a': ['bzr pull -d $p']})
+let s:c.svn_update = get(s:c, 'svn_update', { 'f': 'vam#utils#RunShell', 'a': ['cd $p && svn update']})
+
+fun! vcs_checkouts#SVNCheckout(repository, targetDir)
+ let args=['svn checkout $.url $3p', a:repository, a:repository.url, a:targetDir]
+ for key in filter(['username', 'password'], 'has_key(a:repository, v:val)')
+ let args[0].=' --'.key.' $'
+ let args+=[a:repository[key]]
+ endfor
+ call call('vam#utils#RunShell', args)
+endfun
+
+" this may be useful for other projects.
+" Thus move checking .hg .svn etc into a different file
+
+fun! vcs_checkouts#Update(dir)
+ let directory = a:dir
+ let types = {'.git' : 'git', '.hg' : 'hg', '.svn': 'svn' }
+ for [k, t] in items(types)
+ if isdirectory(directory.'/'.k) | let type = t | break | endif
+ endfor
+
+ if !exists('type')
+ " not knowing how to update a repo is not a failure
+ return 0
+ endif
+
+ let c = s:c[type . '_update']
+ call call(c.f, c.a + [directory])
+
+ if v:shell_error
+ throw "Updating ".a:dir." falied. Got exit code: ".v:shell_error
+ endif
+ return 1
+endf
+
+" repository = {'type': git|hg|svn|bzr, 'url': .. }
+fun! vcs_checkouts#Checkout(targetDir, repository)
+ if a:repository.type =~ '^\%(git\|hg\|bzr\|svn\)$'
+ let c = s:c[(a:repository.type) . '_checkout']
+ call call(c.f, c.a + [a:repository, a:targetDir])
+ else
+ " Keep old behavior: no throw for unknown repository type
+ return
+ endif
+ if !isdirectory(a:targetDir)
+ throw "Failure. Plugin directory ".a:targetDir." should have been created but does not exist !"
+ endif
+endf
+
+let s:exec_in_dir=function('vam#utils#ExecInDir')
+
+" vim: et ts=8 sts=2 sw=2
diff --git a/vim-addon-manager/doc/vim-addon-manager.txt b/vim-addon-manager/doc/vim-addon-manager.txt
new file mode 100644
index 0000000..036697d
--- /dev/null
+++ b/vim-addon-manager/doc/vim-addon-manager.txt
@@ -0,0 +1,1171 @@
+*vim-addon-manager.txt* Declarative package manager for Vim
+==============================================================================
+CONTENTS *VAM-contents*
+
+ 0. GETTING STARTED & LOOKING FOR HELP <<
+
+ 1. Intro |VAM-intro|
+ 2 Installation & installing plugins |VAM-installation|
+ 2.2 names of addons and addon soucres |VAM-addon-names|
+ 2.3 Example: personal |VAM-complex-setup-sample|
+ configurable setup
+ 2.4 unattended installation
+ 3. Functionality provided |VAM-functionality|
+ 3.1. Commands |VAM-commands|
+ 3.2. Functions |VAM-functions|
+ 4. Options |VAM-options|
+ 6. Uninstalling plugins |VAM-uninstall-plugins|
+ 7. Addon-info file |VAM-addon-info|
+ 8. Author, credits, some notes |VAM-related|
+ 9. Testing this plugin |VAM-testing|
+ 10. Some notes for windows users |VAM-windows|
+ 11. Some notes for Gentoo users |VAM-gentoo|
+ 12. Troubleshooting and known bug |VAM-trouble-shooting|
+ and TODOs as well as "I want .."
+ 13. VAM vs ...
+
+ 20. making plugins work with VAM
+ (rtp different from ~/.vim)
+
+==============================================================================
+
+0. GETTING STARTED & LOOKING FOR HELP - something doesn't work
+
+Getting started fast: ~
+Read: |VAM-installation| and |VAM-addon-names|
+
+
+NEED HELP: ~
+Join irc.freenode.net, /join #vim. Ask there. VAM has many users
+MarcWeber is hanging around often so ping him or create a github ticket [1] and
+people will try to help you. You should skim the docs before asking for
+help though. Also see |VAM-author|
+[1] https://github.com/MarcWeber/vim-addon-manager/issues
+
+==============================================================================
+1. Intro *VAM-intro*
+
+VAM is a shortcut for vim-addon-manager.
+Difference addon/plugin: None.
+>
+ :h plugin
+tells you about the old manual manual way of installing plugins. VAM helps
+keeping ~/.vim clean by separating plugins from each other.
+
+Features:
+
+ - Separate directories for each plugins
+ - Dependency resolution
+ - Popular VCS support: plugin supports fetching from Git, Mercurial,
+ Subversion and Bazaar repositories
+
+Dependencies:
+ - Curl, wget or other program that can output URL contents to stdout (in
+ order to get http protocol support)
+ - Git, Mercurial, Subversion and Bazaar (if you want to install plugins
+ from appropriate repositories)
+ - Either tar, gzip and zip or 7-zip (required for unpacking some addons)
+
+What does "Declarative package manager" mean? The final behaviour of Vim
+should be declared once. Your ~/.vimrc and |:UpdateAddons| should be enough
+to cause same Vim behaviour everywhere.
+
+
+==============================================================================
+2. Installation *VAM-installation*
+
+Windows users: see |VAM-windows|.
+Gentoo users: see |VAM-gentoo|.
+linux/cygwin/OSX (anything support /bin/sh like shells) users:
+
+The recommended setup is shown below. It installs VAM if it is not on your disk
+using a short shell script.
+
+Then it adds its PATH to Vim's |runtimepath|. If you don't like vam_install_path
+default setting change it.
+
+You make VAM install plugins by adding their names to the list in
+ |vam#ActivateAddons()|. Try understanding the comments. They'll help you get
+started fast.
+
+Add the following to your .vimrc >
+
+ fun SetupVAM()
+ " YES, you can customize this vam_install_path path and everything still works!
+ let vam_install_path = expand('$HOME') . '/.vim/vim-addons'
+ exec 'set runtimepath+='.vam_install_path.'/vim-addon-manager'
+
+ " * unix based os users may want to use this code checking out VAM
+ " * windows users want to use http://mawercer.de/~marc/vam/index.php
+ " to fetch VAM, VAM-known-repositories and the listed plugins
+ " without having to install curl, unzip, git tool chain first
+ " -> BUG [4] (git-less installation)
+ if !filereadable(vam_install_path.'/vim-addon-manager/.git/config') && 1 == confirm("git clone VAM into ".vam_install_path."?","&Y\n&N")
+ " I'm sorry having to add this reminder. Eventually it'll pay off.
+ call confirm("Remind yourself that most plugins ship with documentation (README*, doc/*.txt). Its your first source of knowledge. If you can't find the info you're looking for in reasonable time ask maintainers to improve documentation")
+ exec '!p='.shellescape(vam_install_path).'; mkdir -p "$p" && cd "$p" && git clone --depth 1 git://github.com/MarcWeber/vim-addon-manager.git'
+ " VAM run helptags automatically if you install or update plugins
+ exec 'helptags '.fnameescape(vam_install_path.'/vim-addon-manager/doc')
+ endif
+
+ " Example drop git sources unless git is in PATH. Same plugins can
+ " be installed form www.vim.org. Lookup MergeSources to get more control
+ " let g:vim_addon_manager['drop_git_sources'] = !executable('git')
+
+ call vam#ActivateAddons([], {'auto_install' : 0})
+ " sample: call vam#ActivateAddons(['pluginA','pluginB', ...], {'auto_install' : 0})
+ " - look up source from pool (<c-x><c-p> complete plugin names):
+ " ActivateAddons(["foo", ..
+ " - name rewritings:
+ " ..ActivateAddons(["github:foo", .. => github://foo/vim-addon-foo
+ " ..ActivateAddons(["github:user/repo", .. => github://user/repo
+ " Also see section "2.2. names of addons and addon sources" in VAM's documentation
+ endfun
+ call SetupVAM()
+ " experimental: run after gui has been started (gvim) [3]
+ " option1: au VimEnter * call SetupVAM()
+ " option2: au GUIEnter * call SetupVAM()
+ " See BUGS sections below [*]
+ " Vim 7.0 users see BUGS section [3]
+
+
+minimal setup ~
+>
+ set rtp+=PATH-TO-VAM
+ call vam#ActivateAddons([], {'auto_install' : 0})
+
+
+NOTES: ~
+
+ Depending on the option you choose to run ActivateAddons Vim may not be
+ able to show the questions correctly asking you to install a plugin.
+ If that's the case (for whatever reason) I recommend installing the plugin
+ using |:InstallAddon| or |:ActivateAddon| before adding it to the list in .vimrc
+
+ If you're annoyed by the message: >
+ "Press enter to continue"
+< There are at least two solutions you can try:
+
+ - press q once and Vim should stop asking
+ - set auto_install = 1 (to make Vim stop asking you any questions. However you
+ won't know if knew dependencies are fetched in that case etc)
+
+------------------------------------------------------------------------------
+2.2 names of addons and addon sources *VAM-addon-names*
+
+Because we are human VAM uses readable names as unique identifier for plugins.
+Those identifieres (= plugin names) are passed to |vam#ActivateAddons()|, |:InstallAddons|,
+|:ActivateAddons| . THe name is automatically derived from plugin titles at
+www.vim.org.
+
+types of names:
+ 1) plugin name (which is looked up in pool. Try :AddonInfo NAME) >
+ "NAME"
+<
+ determining addon names ~
+ - by id: |:AddonsInfo| SCRIPT_ID, pick the "VAM name" value.
+ - use |:InstallAddons|'s name completion by typing some chars then pressing
+ <c-d> then <tab>.
+ - use <c-x> <c-p> completion (yes, this overwrites 'omnifunc' setting)
+
+ 2) name which gets rewritten internally >
+ github:{Name} => {"type": "git", "url": "git://github.com/{Name}/vim-addon-{Name}}
+ github:{N}/{Repo} => {"type": "git", "url": "git://github.com/{N}/{Repo}"}
+< Don't use if you expect others to create plugins depending on yours. Add
+ your plugin to |VAM-kr| instead.
+
+ See |vam#install#RewriteName()|
+
+Instead of telling us to add your plugin to |VAM-kr| you can also patch the
+pool easily: |VAM-kr-patching| - however if you contribute to |VAM-kr| the
+community will benefit much more.
+
+ long descritpion (how to modify the pool - how does the pool look like - !little bit outdated! ~
+
+Read code in |VAM-kr|. The text below gives you an idea:
+
+Open the vim-addon-manager-known-repositories/plugin/vim-addon-manager-known-repositories.vim (-> |VAM-kr|
+There you'll find the two types of dictionaries which are used to find and
+install plugins. You'll find lines like this:
+>
+ let s:plugin_sources['Align294'] = {'title': 'Align', 'version': '35/41', 'url': 'http://www.vim.org/scripts/download_script.php?src_id=10110', 'vim_version': '7.0', 'date': '2009-03-04', 'vim_script_nr': 294, 'type': 'archive', 'script-type': 'utility', 'archive_name': 'Align.vba.gz', 'author': 'Charles Campbell'}
+ let s:plugin_sources['Align1497'] = {'title': 'Align.vim', 'version': '0.15', 'url': 'http://www.vim.org/scripts/download_script.php?src_id=5451', 'vim_version': '6.0', 'date': '2006-03-17', 'vim_script_nr': 1497, 'type': 'archive', 'script-type': 'utility', 'archive_name': 'Align.vim', 'author': 'Michael Gnezdov'}
+<
+In this example both titles are stripped to "Align" which would result in a
+name collision. Thus the gather script appends the script ids.
+The script id can be found in the plugin web url.
+
+There is a second type of dict containing bleeding edge versions:
+>
+ let s:scm_plugin_sources['tmru'] = {'type': 'git', 'url': 'git://github.com/tomtom/tmru_vim.git' }
+<
+The keys (eg tmru, Align294, Align1497) must be used instead of {name}.
+>
+ :ActivateAddons Align<c-d>[<tab>]
+< showes a list of all names containing "Align" which is often enough to
+identify the plugin you're looking for.
+
+
+*VAM-kr* : The default pool. Its checkout out by |vim-addon-manager| by
+default. its long name is *vim-addon-manager-known-repositories* .
+
+*VAM-kr-patching*
+Both dicts are merged. The default is to prefer the scm version but you can
+choose. (-> MergeSources). You can either overwrite the merge function or just
+predefine the dictionary and add your own sources for testing before
+submitting to |VAM-kr|:
+
+You can add your own sources to the pool easily (BUG/TODO [5]): >
+ let g:vim_addon_manager = {}
+ let g:vim_addon_manager.plugin_sources = {}
+ let g:vim_addon_manager.plugin_sources['your_plugin_name'] = { plugin dictionary }
+<
+
+Or overwrite the MergeSources function: >
+
+ fun! vam_known_repositories#MergeSources(plugin_sources, www_vim_org, scm_plugin_sources, patch_function, snr_to_name)
+
+ " run default:
+ call vam_known_repositories#MergeSources(a:plugin_sources, a:www_vim_org, a:scm_plugin_sources, a:patch_function, a:snr_to_name)
+
+ " patch sources the way you like. This example adds username and password
+ " for SVN repositories. As alternative you could overwrite git urls etc ..
+ for your_plugin in ['svn-driven-key1', ...]
+ let a:plugin_sources[your_plugin]['username'] = 'svn user'
+ let a:plugin_sources[your_plugin]['password'] = 'svn user'
+ endfor
+
+ let a:plugin_sources['your_plugin_name'] = { plugin dictionary }
+ endf
+ " tell VAM to use your MergeSources function:
+ let g:vim_addon_manager = {}
+ let g:vim_addon_manager['MergeSources'] = function('MyMergeSources')
+<
+
+
+------------------------------------------------------------------------------
+2.3 Example: personal configurable setup *VAM-complex-setup-sample*
+>
+ call vam#ActivateAddons(["github:YOURNAME"],{'auto_install' : 0})
+ " this initializes Vim the way *you* want also loading more plugins:
+ call vim_addon_YOURNAME#Activate(['c-dev','ruby-dev'])
+<
+ My implementation looks like this:
+ https://github.com/MarcWeber/vim-addon-MarcWeber/blob/master/autoload/vim_addon_MarcWeber.vim
+
+ You can then load plugins depending on env vars:
+ Example: >
+ call vim_addon_YOURNAME#Activate(['always']+split($V,','))
+< Then you can run vim like this from shell >
+ V=c-dev,ruby-dev vim
+<
+ This section was written to inspire you only.
+
+------------------------------------------------------------------------------
+2.4 unattended installation
+
+Note: You should always review foreign code before running it. That said this
+is how you can update or install unattended (without confirmations ..):
+
+ redir! > /tmp/log-vim.txt
+ silent! ACTION
+ messages
+
+where ACTION is either UpdateActivatedAddons or vam#InstallAddons()
+
+This works for http://mawercer.de/~marc/vam/index.php.
+
+There is also the undocumented g:vim_addon_manager['dont_source'] option
+adding additionally json syntax checks on addon-info.json files which are
+evaled by Vim which should be used if you want to checkout eventually
+untrusted code! If you're going to use the plugins anyway its of no use.
+You also want to set auto_install.
+
+==============================================================================
+3. Functionality provided *VAM-functionality*
+
+------------------------------------------------------------------------------
+3.1. Commands *VAM-commands*
+
+InstallAddons {name} ... *:InstallAddons*
+ Install addons with given names. See |vam#install#InstallAddons()| for
+ more details.
+ You use InstallAddons instead of ActivateAddons if you want to review
+ plugin source before running it.
+
+ActivateAddons {name} ... *:ActivateAddons*
+ Activate addons with given names. See |vam#ActivateAddons()| for
+ more details.
+
+ActivateInstalledAddons {name} ... *:ActivateInstalledAddons*
+ See |:ActivateAddons|, this command is just the same, but completion
+ function completes only installed addon names.
+
+UpdateAddons [{name} ...] *:UpdateAddons*
+ Update addons with given names. Without arguments updates all addons.
+ See |vam#install#Update()| for more details.
+
+UpdateActivatedAddons *:UpdateActivatedAddons*
+ Like |:UpdateAdons| with a list of all activated plugins in place of
+ its arguments.
+
+UninstallNotLoadedAddons {name} ... *:UninstallNotLoadedAddons*
+ Unistall addons with given names. See
+ |vam#install#UninstallAddons()| for more details.
+
+AddonsInfo {id/name} ... *:AddonsInfo*
+ Shows addon information. Accepts both VAM script names and www.vim.org
+ script numbers.
+
+------------------------------------------------------------------------------
+3.2. Functions *VAM-functions*
+
+vam#ActivateAddons({addons}[, {opts}]) *vam#ActivateAddons()*
+ Installs and activates plugins listed in {addons} (see description of
+ |vam#install#Install()|) list alongside with their dependencies. This
+ is meant to be called from your .vimrc. Installation takes place only
+ if plugin directory does not exist. Activation means adding plugin
+ directory to 'runtimepath'. If vim has already started VAM will also
+ source plugin/**/*.vim (in other case sourcing is done by vim).
+
+ Optional {opts} argument should be a dictionary with key
+ "auto_install". It will be used to override global option
+ |VAM-auto_install|. Other possible keys are for internal use only. In
+ order to manually activate plugins try using |:ActivateAddons| which
+ also provides completion.
+
+ In order to manually activate plugins try using |:ActivateAddons|
+ which also provides completion.
+
+ Implementation details: ~
+ Vim's startup behaviour is:
+ 1. source ~/.vimrc
+ 2. find all plugin/*.vim files in &rtp
+ 3. source them
+ 4. emit the VimEnter au command
+
+
+ Now it does not do its job 2. properly: some after/* files are not
+ sources. If you add paths rtp at runtime plugin/* files aren't sourced
+ either. VAM takes care of this for you - but changing source order may
+ fail in rare cases.
+
+vam#install#Install({addons}[, {opts}]) *vam#install#Install()*
+ Installs plugins listed in {addons} list. Each list item must be one
+ of the following:
+ - Name of the plugin
+ - Path to |addon-info.txt| file (it must contain at least one
+ forward or back slash, so use `./plugname-addon-info.txt' for
+ files located in the current directory)i
+ - |addon-info.txt| URL. In this case {arg} must start with
+ `http://'.
+ After installing the plugin help tags are updated, see |:helptags|.
+
+ {addons}: See |VAM-addon-names|
+
+ {opts} argument is described in |vam#ActivateAddons()|.
+
+vam#install#Update({addons}) *vam#install#Update()*
+ Updates plugins which names are listed in {addons}. If an empty list
+ is given, then updates all plugins. vam#install#Update also updates
+ the help tags. Note that if plugin is not under control of some VCS,
+ it tries to retain user changes unless |VAM-do_diff| is disabled.
+
+vam#AddonInfo({name}) *vam#AddonInfo()*
+ Returns dictionary that contains information given in |addon-info.txt|
+ file that comes with requested addon. If no |addon-info.txt| file is
+ present, it is not readable or addon with given name is not installed,
+ then it returns an empty dictionary.
+
+ *vam#install#MergePluginFiles()*
+vam#install#MergePluginFiles([{name}] [, blacklist-regex ])
+ Highly experimental function that may speed up vim start on heavy IO
+ load. This function renames all `plugin' directories to
+ contents into `~/.vim/after/plugin/vim-addon-manager-merged.vim' which
+ should cause less IO stress to your system, thus Vim will startup
+ faster. This can scripts because:
+ - s:... script global variables are renamed automatically to
+ prevent name clashes
+ - Guards are replaced by if ... endif which might be inefficient
+ - `finish' statement that start line and every line after them are
+ just commented out
+
+ Using the blacklist-regex you can filter plugin/*.vim files and
+ prevent them from being included. For example this excludes many tlib
+ plugins.: >
+
+ let s:merge = [ "tlib" ]
+ call vam#ActivateAddons(s:merge)
+ command MergePluginFiles call vam#install#MergePluginFiles(s:merge+["tlib"], '\%(cmdlinehelp\|concordance\|evalselection\|glark\|hookcursormoved\|linglang\|livetimestamp\|localvariables\|loremipsum\|my_tinymode\|pim\|quickfixsigns\|scalefont\|setsyntax\|shymenu\|spec\|tassert\|tbak\|tbibtools\|tcalc\|tcomment\|techopair\|tgpg\|tmarks\|tmboxbrowser\|tortoisesvn\|tregisters\|tselectbuffer\|tselectfile\|tsession\|tskeleton\|tstatus\|viki\|vikitasks\)\.vim_merged')
+ command UnmergePluginFiles call vam#install#UnmergePluginFiles()
+<
+
+ Yes, the info files should be cached as well (TODO)
+
+vam#install#RewriteName({name}) *vam#install#RewriteName()*
+ Returns a dictionary if {name} matches one of the following patterns:
+ Pattern Dictionary ~
+ github:{Name} {"type": "git",
+ "url": "git://github.com/{Name}/vim-addon-{Name}}
+ github:{N}/{Repo} {"type": "git",
+ "url": "git://github.com/{N}/{Repo}"}
+ git:{URL} {"type": "git", "url": {URL}} (experimental)
+
+==============================================================================
+4. Options *VAM-options*
+ *g:vim_addon_manager*
+
+All options are located in the global dictionary g:vim_addon_manager. It also
+contains some stuff that user should never modify if he wants to see this
+plugin working. Possible keys:
+
+auto_install *VAM-auto_install*
+ This options disables plugin installation confirmation. It will not
+ disable deprecation warnings and other prompts.
+plugin_sources *VAM-plugin_sources*
+ This option contains a dictionary where keys are plugin names and
+ values are described by |addon-info-repository|. Values defined in
+ this dictionary override corresponding values in |addon-info.txt|
+ files, so be careful when you extend it.
+plugin_root_dir *VAM-plugin_root_dir*
+ Defines a directory where plugins will be installed to. If directory
+ where this plugin is installed to (three levels up relative to
+ autoload/vam.vim: autoload/../..) is writeable by user, then
+ it defaults to directory in question (so, if user has installed
+ vim-addon-manager to ~/.vim/bundle/vim-addon-manager, this will be
+ equal to ~/.vim/bundle). If autoload/vam.vim is not
+ writeable by the user, then it defaults to ~/.vim/vim-addons.
+ Note that you must set this variable before calling any vam function
+ Note 2: it may be ignored in custom |VAM-plugin_dir_by_name|.
+ *VAM-known_repos_activation_policy*
+known_repos_activation_policy
+ String, valid values: `ask', `never' and `autoload' (default). Defines
+ when |VAM-known| plugin should be loaded. `Ask' means that user will
+ be prompted when this option is required. `Never' means that
+ |VAM-known| will not be loaded and the user will not get any prompts.
+ `Autoload' means that it will be loaded when it is required, user also
+ won't get asked.
+known *VAM-known*
+ String, specifies the name of plugin which provides list of
+ repositories. Default is vim-addon-manager-known-repositories.
+change_to_unix_ff *VAM-change_to_unix_ff*
+ Remove CR symbols before LF symbols in any vim files (changes dos and
+ mixed dos/unix line endings to unix line endings). Is on by default if
+ you are on unix (unix, win32unix, macunix), off otherwise.
+do_diff *VAM-do_diff*
+ If this option is true (default), then try to retain user changes to
+ installed plugins (unless they are under SCM control). Requires diff
+ and patch programs installed.
+name_rewriting *VAM-name_rewriting*
+ Set this to a dictionary with functions each taking a plugin name and
+ returning either a dictionary with repository location (see
+ |addon-info-repository|) for given name or zero. Location will be set
+ to the first non-zero value, functions are executed in order
+ determined by |sort()|ing |keys()| of the dictionary. These functions
+ will be called when repository location for requested plugin is not
+ found.
+ Value will be extended with >
+ {"99git+github": "vam#install#RewriteName"}
+< after it is read (see |vam#install#RewriteName()|).
+plugin_dir_by_name *VAM-plugin_dir_by_name*
+ Function name or function reference that transforms plugin names into
+ absolute paths plugins are to be installed into. Function must return
+ path without trailing path separators or |VAM-do_diff| will break.
+ Default is "vam#DefaultPluginDirFromName".
+ Note: If not all plugins are contained in the same direcotry
+ completion for |:UninstallAddons| breaks because simple globbing
+ is used.
+pool_fun *VAM-pool_fun*
+ Name or reference of a function that must return dictionary contains
+ {{plugin-name}: {repository}} ({repository} is described under
+ |addon-info-repository|) map.
+ Default is "vam#install#Pool".
+
+The following options are used by vim-addon-manager-known-repositories, not by
+VAM itself. So if you set |vim-addon-manager-known| to another value they may
+have no effect.
+ *VAM-drop_SCM_sources*
+drop_git_sources *VAM-drop_git_sources*
+drop_hg_sources *VAM-drop_hg_sources*
+drop_svn_sources *VAM-drop_svn_sources*
+drop_bzr_sources *VAM-drop_bzr_sources*
+ Determines whether given SCM sources should be dropped before merging
+ scm sources by |scm_merge_strategy|. This way you can force using
+ www.vim.org sources. But you may get different plugin versions
+scm_merge_strategy *VAM-scm_merge_strategy*
+ String, valid values: `force' (default), `keep' and `never'. Defines,
+ whether SCM sources should be used instead of www.vim.org sources:
+ `forces' stands for prefering SCM over www.vim.org, `keep' means that
+ SCM sources will be used only if the plugin is not available from
+ www.vim.org, `never' means that SCM sources will be never used.
+MergeSources *VAM-MergeSources*
+ Function reference, defines a function that will be used to merge
+ user, |VAM-kr| and SCM sources.
+ Overrides |VAM-scm_merge_strategy| and |VAM-drop_SCM_sources|. Will be
+ called with five arguments: user sources (most of time it is an empty
+ dictionary), non-SCM sources defined in |VAM-kr|, SCM sources also
+ defined there, patch function name and snr_to_name dictionary. Patch
+ function is a function that being given sources dictionary (like one
+ of first three arguments) and snr_to_name dictionary patches first
+ adding missing information (like missing dependencies). Last
+ dictionary is a map of vim.org script numbers to VAM-kr names.
+
+ If MergeSources function is a dictionary function, it will be provided
+ an empty dictionary as |self| dictionary.
+
+ An Example can be found in this file.
+
+==============================================================================
+6. Uninstalling Plugins *VAM-uninstall-plugins*
+
+Follow these steps:
+
+- Remove the plugin name from the call to |vam#ActivateAddons()| in your
+ vimrc.
+
+- Restart Vim and remove plugin directory using >
+ :UninstallNotLoadedAddons {pluginname}
+< or rm -fr those directories manually.
+
+==============================================================================
+7. Addon-info file *VAM-addon-info*
+ *addon-info.json* *addon-info.txt*
+
+Each plugin that intends to use vim-addon-manager for distributing itself
+needs to have addon-info.json [1] file in its root,
+that contains the JSON dictionary with the following keys (none of the keys
+are required):
+
+[1]: older alternative name: {plugname}-addon-info.txt
+
+name *addon-info-name*
+ Name of the plugin. Must not contain any characters that cannot be
+ used in a directory name (including directory names separator).
+ Note that if the value of this key, {plugname} part in addon-info.txt
+ file name and directory under which plugin is installed are not equal,
+ then user that tries to use your plugin may catch strange bugs.
+
+repository *addon-info-repository*
+ Describes where the plugin should be fetched from. Ignored unless the
+ plugin is installed using either the second or third form of
+ |vam#install#Install()| call (see its description). This is
+ a dictionary with the following keys:
+
+ !! Note: As very common in extreme programming documentation may be
+ !! outdated. So may be this section. So refer to the code:
+ !! |vam#install#Checkout()| to find out about all supported keys
+ !! Its easy to read and extend. Contact me if you're unsure. I'll help
+ !! you.
+ !! I'd even consider moving this section into the code only refering
+ |! to it - so that its kept in sync.
+
+ Key Description ~
+ addon-info
+ optional, contains dict which will be written to
+ addon-info.json for this plugin if the plugin does not ship
+ its own addon-info.json file. This way dependencies, that a
+ subdirectory contains vim data and similar "fixes" can be
+ applied easily. See samples in VAM-kr.
+
+ type Required, must be either one of `hg', `git', `svn', `bzr' or
+ an empty string.
+ url If `type' key contains a VCS name (`hg', `git', `bzr' or `svn'),
+ then this key describes a url that will be passed to this
+ VCS. If `type' key contains an empty string, then it should
+ contain location of the archive.
+ script-type
+ One of `plugin', `syntax', `color scheme', or `indent'. The
+ .vim file will be moved into the specific subdirectory.
+ Also accepts `after/syntax' which is a hack that makes VAM
+ move source into after/syntax directory.
+ archive_name
+ If `type' key contains an empty string, then archive which
+ location is described by the `url' key will be saved in file
+ with name {archive_name} and processed according to its
+ extension. Supported extensions (note that if you have 7-zip
+ installed no other archive tools are required):
+ Extension How it is handled ~
+ .vim This extension designates that plugin is
+ a single file. So, if exists key `script-type'
+ and it is equal to `syntax' or `indent', then
+ this file is put under {plugname}/syntax or
+ under {plugname}/indent, otherwise it is put
+ under directory described by
+ {plugname}/{target_dir} (where {target_dir} is
+ a value of `target_dir' key if it is present
+ and `plugin' otherwise).
+ .tar.gz, .tgz This extension designates that plugin is
+ contained inside tar archive compressed by
+ gzip. In this case, archive is uncompressed by
+ `gzip' and unpacked to its directory by `tar'
+ (both utilities may be replaced with `7z x').
+ .tar.bz2, .tbz2
+ Like .tar.gz, but with bzip2 compression.
+ .tar This extension designates that plugin is
+ contained inside uncompressed tar archive. In
+ this case, archive is unpacked to its directory
+ by `tar'.
+ .zip This extension designates that plugin is
+ contained inside a zip archive. In this case
+ archive is unpacked to its directory by
+ `unzip' (may be replaced by `7z x').
+ .7z, .rar, .cab, .arj, .jar
+ This extension designates that plugin is
+ contained inside an archive that is supported
+ by p7zip archiver. In this case archive is
+ unpacked to its directory by `7z x'.
+ .vba This extension designates that plugin is
+ contained in a vimball archive. In this case
+ vimball#Vimball() function is used, see
+ |:UseVimball| for more details.
+ .vba.gz This extension designates that plugin is
+ contained in a vimball archive compressed by
+ gzip. In this case archive is uncompressed and
+ vimball#Vimball() function is used, see
+ |:UseVimball| for more details.
+ .vba.bz2 Like .vba.bz2, but with bzip2 compression.
+ deprecated
+ If this key is present and contains non-empty string, then
+ every time when user tries to install this plugin he will see
+ this message and will have to confirm installation.
+ strip-components
+ Strip first {strip-components} directories after unpacking an
+ archive. If it is equal to special value `-1' (default), then
+ it will strip either one directory (if archive contains the
+ only directory that is not special) or will not strip anything
+ at all. Recognized special directories: [ft]plugin, autoload,
+ colors, compiler, indent, keymap, lang, print, spell, syntax.
+ addon-info
+ Contains addon information in case plugin does not supply its
+ own addon-info file.
+
+dependencies *addon-info-dependencies*
+ Describes plugins that are required for the plugin, must contain
+ a dictionary where keys are plugin names and values describe where
+ appropriate plugins should be fetched from (overriden by
+ |VAM-plugin_sources|). The format of the values is the same as
+ |addon-info-repository|.
+
+
+version *addon-info-version*
+author *addon-info-author*
+maintainer *addon-info-maintainer*
+description *addon-info-description*
+homepage *addon-info-homepage*
+ Version, author, maintainer, description and plugin homepage. Ignored,
+ but setting them to the real values will not do any harm.
+
+==============================================================================
+8. Author, credits, some notes *VAM-related*
+
+Related work: ~
+
+PATHOGEN:
+ Until now I thought it was only about manipulating runtimepath.
+ But the most recent announcement about mirroring all vim scripts
+ shows that it may become a competitive VAM alternative?
+ http://www.vim.org/scripts/script.php?script_id=2332
+ http://vim-scripts.org/index.html
+
+There are also some other package managers for vim:
+ http://github.com/c9s/Vimana
+ http://snk.tuxfamily.org/log/vim-script-management-system.html
+ http://github.com/gmarik/vundle (git support only, VimL)
+You can try and see which is the best.
+
+another list: http://vim-scripts.org/tools.html
+
+Emacs install scripts manager:
+ el-get http://github.com/dimitri/el-get/blob/master/el-get.el
+
+There is another project which has the same name:
+http://packages.debian.org/sid/vim-addon-manager
+The author (Jamessan) is fine with this project sharing the same name.
+
+------------------------------------------------------------------------------
+7.1. Author contacts *VAM-author*
+
+Github account: MarcWeber
+Email: marco-oweber@gmx.de
+
+------------------------------------------------------------------------------
+7.2. Contributors *VAM-contributors*
+
+(Incomplete list):
+Tim Pope (+) (tpope on github)
+ - Json validation
+ZyX (+) (Nikolay Pavlov, ZyX-I on github)
+ - enhancing this vim documentation
+ - various fixes
+ - discussing implementation details
+ - initial implementation for updating plugins which were installed by
+ archive
+ - pushing 7z and providing a reference implementation
+ - smart strip components implementation
+Tux Tom (+) (http://github.com/TuxTom)
+ - helping fixing a cd bug on Windows
+creidiki (Leonardo Valeri Manera)
+ - greatly improving Windows support
+ - working around the tar issues on Windows
+..
+Mike Smullin:
+ - for asking to find a way to source addons when gui is running.
+ There is a hint now. This is important if you don't start vim from console
+
+Israel Chauca Fuentes:
+ - reporting and fixing some bugs
+
+(+) means they are collaborators on github and could take action in case of serious
+ trouble.
+
+------------------------------------------------------------------------------
+ROADMAP:
+
+What features are missing?
+
+- When updating archive based plugins create diffs so that you can patch
+ those files without changes being lost. I expect users to customize mappings
+ and such
+
+- add a command like AddonManagerFetchUtils which does all the work listed in
+ 9. for you putting the tar etc into a directory and adding it to PATH
+
+- suggestions?
+
+
+==============================================================================
+9. Testing this plugin *VAM-testing*
+
+Run >
+ # Replace ~/.vim/vim-addons/vim-addon-manager with the path you installed this
+ # plugin to
+ cd ~/.vim/vim-addons/vim-addon-manager
+ sh vim-addon-manager-test.sh
+.
+You should see >
+ 1
+ 1
+ 1
+at the end. Written for Linux only. Code coverage is bad. Its a starting
+point.
+
+==============================================================================
+10. Some notes for windows users *VAM-windows*
+
+Finally the nightmare came to an end:
+http://mawercer.de/~marc/vam/index.php
+Enter plugins names, download final .zip. Be happy and enjoy VAM.
+We could create a vim-addon-curl-unzip-for-windowns plugin providing those
+executables. Then VAM would be able to install many plugins after
+bootstrapping without help of the vam/index.php url. Tell me to work on it.
+Also see BUG [4]
+
+OLD docs:
+
+Win32 tools for vim-addon-manager
+
+Fast: put curl into ~/.vim/vim-addons/binary-utils/dist then call this function
+to setup the remaining tools (tar, bzip, gzip, unzip)
+>
+ call vam#install#FetchAdditionalWindowsTools()
+<
+If 7z is in PATH bzip, unzip, gzip are not pulled. So consider installing that
+and add it to PATH by
+>
+ let $PATH=$PATH.';'.PATH_TO_7z
+<
+( TODO: test it, provide a way to install 7z instead? )
+
+After the tools are setup, sometimes installing an addon still fail.
+Usually this is triggered by a weird value of |shellslash| or |shellquote|.
+Here is that was found to be working:
+>
+ set shellslash=0
+ set shellquote=\"
+<
+
+See http://stackoverflow.com/questions/355988/how-do-i-deal-with-quote-characters-when-using-cmd-exe
+for more informations.
+
+Ashwin Nanjappa provided an alternative installation instruction here which
+worked for him. You may still want to read this section first. There are
+multiple ways to make VIM run on Windows and install all missing dependencies.
+http://choorucode.wordpress.com/2010/12/09/using-vim-addon-manager-on-windows/
+
+Does it make sense to support svn and git this way as well?
+Is it even possible?
+At least we can fetch and execute the installers..
+
+Section provided by creidiki:
+
+Curl:
+ Get Curl here: http://curl.haxx.se/download.html
+
+ 1. Scroll down to the end of the "Packages" list. You want (ideally) the
+ latest version, of type `binary' (not libcurl or devel). SSL is not
+ necessary but won't hurt. If your OS is 64-bit, you can get the Win64
+ version if you want, but it won't be any faster.
+ 2. Install it. Then point vim-addon-manager (and, incidentally, netrw) to
+ it by putting something like this in your _vimrc: >
+ let g:netrw_http_cmd='{path_to_curl}\curl.exe -o'
+< (replace {path-to-curl} with the installation directory, including the
+ brackets).
+
+ Don't forget the -o argument at the end. :)
+
+Archives:
+ Get Tar, Gzip and Unzip from the GnuWin32 project
+ Gzip: http://gnuwin32.sourceforge.net/packages/gzip.htm
+ Tar: http://gnuwin32.sourceforge.net/packages/gtar.htm
+ Unzip: http://gnuwin32.sourceforge.net/packages/unzip.htm
+
+ Either get the complete package setups, or the binary installers. All you
+ need is the binaries.
+ Install or unpack them somewhere.
+
+ Get xzdec here: http://nullprogram.com/blog/2010/04/16/
+ or here: http://www.stats.ox.ac.uk/pub/Rtools/goodies/xzutils.zip
+ You only need xzdec.exe. Put in the same place you put those other archive
+ tools.
+
+ Get p7zip here: http://7-zip.org/download.html. You need the full version
+ with gui because package with command-line version contains only 7za
+ executable, while you need 7z in order to support more archives.
+
+ Either add them to your system or user path (google it!) or add them just
+ to vim's path by putting something like this in _vimrc: >
+ let $PATH='{path-to-gnu-utils};'.$PATH
+< Again, replace the whole of {path-to-gnu-utils} including brackets with
+ the directory you have installed/unpacked them to.
+
+VCS:
+ MSysGit (and TortoiseGit/GitExtensions) by default add the `git'
+ executable to your PATH. If you chose not to for whatever reason, you can
+ use the trick above to let vim see them. TortoiseHG does the same with the
+ mercurial `hg' executable. TortoiseSVN does not include the commandline
+ `svn' executable, so if you need it install SilkSVN
+
+ SilkSVN: http://www.sliksvn.com/en/download/
+ MsysGit: http://code.google.com/p/msysgit/
+ Mercurial: http://mercurial.selenic.com/
+
+
+We tried thinking about making using vim-addon-manager easier for Windows
+users. One idea was introducing a proxy which asks a linux server to package
+git/svn/mercurial/bazaar as zip file on the fly. This would mean you don't
+have to install svn,hg,.. to use plugins only.
+
+If you want something like this to happen contact me.
+
+==============================================================================
+11. Some notes for Gentoo users *VAM-gentoo*
+
+Gentoo users may consider installing this plugin from pluginloader overlay
+which is accessible via mercurial, url:
+http://vimpluginloader.hg.sourceforge.net:8000/hgroot/vimpluginloader/pluginloader-overlay
+
+In order to use this overlay paludis users can add the pluginloader.conf file
+to /etc/paludis/repositories/ with the following contents: >
+ location = /var/paludis/repositories/pluginloader
+ format = e
+ sync = hg+http://vimpluginloader.hg.sourceforge.net:8000/hgroot/vimpluginloader/pluginloader-overlay
+
+ master_repository = gentoo
+ names_cache = ${location}/.cache/names
+ write_cache = /var/cache/paludis/metadata
+
+Then you should unmask app-vim/vim-addon-manager and run >
+ paludis --sync && paludis --install vim-addon-manager
+or >
+ cave sync && cave resolve -x vim-addon-manager
+and everything will probably be fine.
+
+For portage+layman users:
+1. Create a file /var/lib/layman/pluginloader-overlay.xml with the following
+ contents: >
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE repositories SYSTEM "/dtd/repositories.dtd">
+ <repositories xmlns="" version="1.0">
+ <repo quality="experimental" status="unofficial">
+ <name>pluginloader-overlay</name>
+ <description>Overlay that contains some additional vim plugins</description>
+ <source type="mercurial">http://vimpluginloader.hg.sourceforge.net:8000/hgroot/vimpluginloader/pluginloader-overlay</source>
+ </repo>
+ </repositories>
+2. Add the following line to /etc/layman/layman.cfg just after the line that
+ starts with `overlays' (do not forget to indent it, see comment above the
+ target line): >
+ file:///var/lib/layman/pluginloader-overlay.xml
+3. Run >
+ layman -ka pluginloader-overlay
+4. Unmask vim-addon-manager and run >
+ emerge vim-addon-manager
+
+
+==============================================================================
+*marc-weber-VAM-design-notes*
+
+Until now I tried following the "New Jersey", KISS, MIT principles:
+- Try to achieve 80% of value by spending 20% of effort
+- I consider this piece of code being perfect if there is nothing you can
+ remove.
+- If it behaves ok in 95% of all use cases its good enough (for me)
+ because I prefer a minimal code base.
+
+ZyX created a branch which tries to be accurate summarrized by quoting him:
+"I am trying to get rid of as much future errors as possible".
+See related work to get it instead of this. Lets watch it and be curious about
+what's going to happen.
+
+==============================================================================
+12. Troubleshooting and known bugs *VAM-trouble-shooting*
+
+ Think about how to integrate ideas found in ipi http://www.vim.org/scripts/script.php?script_id=3809
+
+ Runtimepath manipulation should be separated from installation / update
+ logic. This way you can have different implementation for updating plugins
+ eg one being written in python which you can run from commandline.
+ However to keep it portable this means we had to support
+ - a VimL solution (eg for Windows users ?)
+ - a python/ruby/perl/whatsoever commandline version
+ (See thread "which plugin management system to use?" on vim_use)
+
+ ERROR: Vim(call):E117: Unknown function: vam#Activate
+
+ SOLUTION: set runtimepath (rtp) correctly. It must match the directory you
+ installed VAM into.
+
+ ANY OTHER ERROR:
+ Try commenting all your code in .vimrc and other plugins - does it work
+ then? Settings which are known to cause trouble:
+
+ :echo &shell
+ :echo &shellslash (some windows users seem to set this differently?)
+
+ older vim's eg 7.0...
+ jolan78 has fixed one issue with older vims. There are likely to be more:
+ https://github.com/MarcWeber/vim-addon-manager/issues/51#issuecomment-2112747
+
+[*]: Comment about calling ActivateAddons() using autocommands:
+
+ Obviously GUIEnter is only an option if you use gvim only.
+
+ Some plugins may fail to assign their changes to existing buffers
+ this way. That's one of the reasons why calling ActivateAddons()
+ using an autocommand is marked as experimental.
+ Probably those are I "won't fix" bugs. Eventually consider patching
+ those plugins instead.
+
+ Workaround: Try adding this to to ActivateAddons() function which should
+ catch almost all issues by reassigning the filetype to each buffer: >
+ bufdo exec 'set ft='.&ft
+< (or use the tlib#buffer#BufDo() function from tlib which will try to
+ preserve the current buffer ... or ... - This may have undesired
+ side effects: Try "vim small-file 2gb-file.txt" and vim will startup fast
+ because the 2gb file will be loaded only if you switch to the buffer.
+ Eg try :bn and you'll wait several minutes. Using bufdo will force loading
+ the (all) buffers on command line immediately ..).
+ You get the idea why I'm not going to maintain this. Putting it into your
+ .vimrc should be easy enough.
+
+[3]: VAM does not work nicely with older versions of Vim (won't fix)
+ For vim-7.0 you can make it work easily by adding loading all .vim files
+ always:
+
+ 1) replace shellescape( [...] ,1) by shellescape([...])
+
+ 2) add to SetupVAM (because function(..) does not behave correctly load
+ all files always): >
+
+ " slow performance. This could be optimized some more - I do no longer
+ " care about such old Vim versions. Think about upgrading.
+ for f in split(glob(vam_install_path.'/vim-addon-manager*/**/*.vim'),"\n")
+ if f =~ 'plugin/vim-addon-manager-known-repositories.vim' | continue | endif
+ exec 'source '.fnameescape(f)
+ endfor
+<
+
+[4]: VAM depends on git. Why does it?
+ VAM-kr is checked out by git which contains the default merge function.
+ As advanced user you can define your own sources and define your own merge
+ function trivially - that somehow defeats the idea of having one working
+ maitained pool of sources though.
+ It can be fixed: Eg github allows downloading zip files. However then you
+ still have to
+ (1) download sources (curl, wget, python support + urllib, ...)
+ which is not the default for windows.
+ (2) implement a way to determine when updates should take place eg when a
+ repo is outdated. Again probably there are ways to query github even
+ though I know about web scraping only .. But isn't installing git or
+ using the web interface for Windows users much nicer?
+
+ Tell the VAM team if you want git-less installations to be easier and
+ supported, please. Right now we're lazy.
+
+ For windows users there is: http://mawercer.de/~marc/vam/index.php
+ which will also work on sytems not having git but an unzip implementation.
+
+TODOs:
+- support vim-scripts.org. This will let you get all www.vim.org scripts using
+ git repositories only. I think the general idea is great. However we have to
+ take care to keep patches which were written for git/hg in sync.
+
+ If you want this feature tell me. I'll add the sources to |VAM-kr| then.
+
+[5]
+- full update must be done by
+ :UpdateAddons -known<tab>
+ restart
+ :UpdateAddons
+
+ Running :UpdateAddons once should be enough
+
+ The fix is to force users to use MergeFunction when patching
+ and moving the sources into autoload functions you can reload.
+ Then you can rerun the MergeFunc to get up to date pool in Vim memory.
+
+Sometimes it happens that some small bugs appear. Most of the time they are
+easy to identify and trivial fix. Usually fixes happen very fast (within less
+than 2 days)
+If you don't want to wait try running >
+ git checkout HEAD^
+< in the vim-addon-manager directory up to 10 times to checkout older
+revisions and retry.
+
+tianyicui : Actually I think the name [vim-addon-manager] is too long
+(github) and totally uncool.
+Marc Weber: Your suggestion VAM as abbreviation is fine. Let's use that.
+ Switching the name means a lot of work and many dead links.
+ I'm not going to switch the name for 'uncoolness' reasons soon.
+
+Don't have those commands? See |VAM-installation|.
+Windows installation is more tedious than on Linux - yes.
+
+Still trouble? Get in touch, see |VAM-author|
+
+The help file should be using VAM. (Yes - but its too much work to get it
+right for now)
+
+You have to trust script authors:
+Because everybody can upload everything to the repositories (in particular
+www.vim.org) you must trust authors. I can't review all code - so expect code
+to steal your passwords, run sudo rm -fr / ... etc. (This never happened to
+me. But it could)
+Briefly: I'm not responsible for the code you get using vim-addon-manager.
+You can use |InstallAddons| to preview source.
+
+If something goes wrong - and if I don't reply within 24h:
+The following github users are collaborators. This means they have write
+access to the official repository:
+tpope, dertuxmalwieder, TuxTom.
+
+If a plugin behaves strangely then try
+http://github.com/dahu/VimLint/blob/master/plugin/vimlint.vim.
+Maybe you have an uncommon Vim setting causing some plugins to fail.
+
+There is currently no way forcing loading a plugin at .vimrc time.
+Vim delays executing plugin/*.vim files until .vimrc finished processing.
+This leads to some hacks such as defining g:in_load_known_repositories.
+Forcing loading a plugin earlier (including dependencies !) would allow us to
+get rid of this hack.
+
+Its a bug that VAM supports ',' in path items of runtimepath.
+Most other plugins do not. IMHO the true fix would be fixing Vim:
+call add(g:runtimepath, "newpath") and all the trouble would be gone.
+But vim does not use g:runtimpath, it uses an option with strange quoting.
+Same applies to errorformat.
+So don't use ',' in paths and everyone is happy.
+
+I only act uppon feedback. So if you want changes you have to contact me.
+Don't expect me to know what you dream about.
+
+"I want feature X" such as browsable lists of plugins. ActivateAddons FOO
+make launching the plugin permanent, ...
+Me too - pay me.
+Seriously: I don't want to add all features to VAM. It is designed as minimal
+as possible. This excludes any gui features. If you want to add such browser
+or the like create a new plugin "vim-addon-manager-gui" people can install and
+use. I'm happy to put a link into this manual or assist you. However
+I personally don't have time to write it.
+
+VAM only checks out 2 revisions using git.
+Its not a bug. You can get remaining versions by git fetch --depth=9999999
+or such. This speeds up installation very much and should be still be
+sufficient to prepare patches.
+
+
+==============================================================================
+13. VAM vs ...
+
+
+- ftdetect files are loaded if you set "filetype on".
+ Thus if you do it after calling pathogen/vundle/.. everything should be
+ fine. (Thanks to graywh for telling me)
+
+
+vs Pathogen
+-------------
+
+ 1) helptags is run automatically always when updating or installing plugins
+ only
+
+ 2) Because there is a maintained pool of plugins you can patch or
+ deprecate them:
+ This happened to Sanders snipmate.
+ Most patches just add "root" key telling VAM to add a subdir to rtp.
+
+ 3) simple dependency management
+
+ 4) supports all common VCS (svn, bazaar, git, mercurial)
+
+ 5) Automatic downloading of scripts from vim.org.
+
+ 7) You can easily load plugins at runtime.
+
+vs vundle
+---------
+
+ Vundle seems to source after/* files for you (since March 2011)
+
+ BUT: It doesn't take care about ordering when adding to rtp.
+ Thus ~/.vim/after/ftplugin/* is sourced before
+ ~/.vim/bundle/PLUGIN/ftplugin but should be the other way round.
+
+ However its unlikely that you run into this issue (I know about one case).
+
+
+vs X
+---------
+ TODO: Most people are using VAM or Pathogen now AFAIK - so if you feel need
+ for this list submit patches
+
+I personally don't have anything against the other solutions. I like to point
+out the importance of the "dependency" feature. It allows reusing code easily.
+Thus code will be reused easily. Thus code review will take place yielding
+more collaboration thus better code. That was the main reason why I started
+VAM. And that's good for community.
+
+==============================================================================
+20. making plugins work with VAM (rtp different from ~/.vim)
+
+Most plugins should work out of the box.
+
+Some older plugins expect to be installed into ~/.vim. Probably they can be
+patched easily by replacing ~/.vim by a path relative to the file running the
+code: >
+
+ " this is ~/.vim/vim-addons/foo/autoload/x.vim
+ " does not work inside a function!
+ let s:plugin_base_dir = expand('<sfile>:p:h:h')
+ " now s:plugin_base_dir contains ~/.vim/vim-addons/foo
+<
+Then plugins can find additional resources (templates, python files, ..)
+relative to s:parent_dir_of_this_file
+
+==============================================================================
+The linux script is gone. Search for "unix based os" to learn about its
+replacment.
+
+See :h 'modeline' to learn about the following line setting up defaults.
+Usually you'd prefer ftplugin files (do it once).
+vim: tw=78:ts=8:ft=help:norl
diff --git a/vim-addon-manager/test/activate-hg.ok b/vim-addon-manager/test/activate-hg.ok
new file mode 100644
index 0000000..3337d5a
--- /dev/null
+++ b/vim-addon-manager/test/activate-hg.ok
@@ -0,0 +1,2 @@
+::: In plugin {svn}/plugin/msgWrite.vim
+::: In {hg}/runtimepath/plugin/writeMsg.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/activate-mhg.ok b/vim-addon-manager/test/activate-mhg.ok
new file mode 100644
index 0000000..73f6949
--- /dev/null
+++ b/vim-addon-manager/test/activate-mhg.ok
@@ -0,0 +1 @@
+::: In plugin {rtp}/plugin/rtp.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/activate-mis.ok b/vim-addon-manager/test/activate-mis.ok
new file mode 100644
index 0000000..73f6949
--- /dev/null
+++ b/vim-addon-manager/test/activate-mis.ok
@@ -0,0 +1 @@
+::: In plugin {rtp}/plugin/rtp.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/activate-svn.ok b/vim-addon-manager/test/activate-svn.ok
new file mode 100644
index 0000000..2032208
--- /dev/null
+++ b/vim-addon-manager/test/activate-svn.ok
@@ -0,0 +1 @@
+::: In plugin {svn}/plugin/msgWrite.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/addmessages.vim b/vim-addon-manager/test/addmessages.vim
new file mode 100644
index 0000000..86d5a81
--- /dev/null
+++ b/vim-addon-manager/test/addmessages.vim
@@ -0,0 +1,9 @@
+redir => s:messages
+messages
+redir END
+let s:meslines=filter(split(s:messages, "\n")[1:], 'v:val=~#"\\v^E\\d"')
+if !empty(s:meslines)
+ call WriteFile(['>>> Messages:']+
+ \ s:meslines+
+ \ ['<<< Messages^'])
+endif
diff --git a/vim-addon-manager/test/addoninfo.in b/vim-addon-manager/test/addoninfo.in
new file mode 100644
index 0000000..b7b63db
--- /dev/null
+++ b/vim-addon-manager/test/addoninfo.in
@@ -0,0 +1,2 @@
+:call vam#install#Install(["vam_test_hg"])
+:call WriteFile(sort(map(items(vam#AddonInfo('vam_test_hg')), 'string(v:val)')))
diff --git a/vim-addon-manager/test/addoninfo.ok b/vim-addon-manager/test/addoninfo.ok
new file mode 100644
index 0000000..9159167
--- /dev/null
+++ b/vim-addon-manager/test/addoninfo.ok
@@ -0,0 +1,2 @@
+['dependencies', {'vam_test_svn': {}}]
+['runtimepath', 'runtimepath']
\ No newline at end of file
diff --git a/vim-addon-manager/test/comments-tgz2-dodiff.lst b/vim-addon-manager/test/comments-tgz2-dodiff.lst
new file mode 100644
index 0000000..765300b
--- /dev/null
+++ b/vim-addon-manager/test/comments-tgz2-dodiff.lst
@@ -0,0 +1 @@
+" Expands @... sequences at the start of plugin ID
\ No newline at end of file
diff --git a/vim-addon-manager/test/comments-tgz2-nodiff.lst b/vim-addon-manager/test/comments-tgz2-nodiff.lst
new file mode 100644
index 0000000..4c6f686
--- /dev/null
+++ b/vim-addon-manager/test/comments-tgz2-nodiff.lst
@@ -0,0 +1,43 @@
+"▶1 Header
+"▶1 Variable initialization
+"▶2 s:
+"▶2 Messages
+"▶1 s:Eval
+"▶1 expandplid :: String → plid
+" Expands @... sequences at the start of plugin ID
+"▶1 compareversions :: version, version → -1|0|1
+"▶1 normpath :: path + FS → path
+"▶1 parseplugpath :: filename + FS → (plugtype, plid, runtimepath)
+"▶1 recdictmap :: dict, expr[, path, processed] → dict + ?
+"▶1 createconsfunc :: efid, fname, consargs, suf → function
+"▶1 createcons :: plugdict, shadowdict, feature → dict
+"▶1 addcons :: plugdict + s:f.cons → + p:_f
+"▶1 featcomp :: feature, feature + s:selfdeps → -1|0|1
+" " Can't add s:FeatComp to _functions because it is required for unloadplugin
+" " to work and thus should not be removed by unloadpre event
+" let function('s:FeatComp')=function('s:FeatComp')
+"▶1 getfeatures :: plugdict, {: feature} → [feature]
+"▶1 runfeatures :: plugdict, fkey + shadowdict, +s:f → plugdict + shadowdict
+"▶1 initfeatures :: plugdict + shadowdict → + shadowdict
+"▶1 newplugin :: version, sid, file, dependencies, oneload, g → +s:pls,
+"▶1 addfeature :: plugdict, feature(ircl)[, load] → + shadowdict
+"▶1 getordereddeps :: plugdict + s:dependents → [plugdict]
+"▶1 loadplugin :: Either plugdict plid → 0|1|2 + plugdict, …
+"▶1 getdeps :: plugdict, hasdep::{plid: _} + s:dependents,… → [plugdict]
+"▶1 depcomp :: plugdict, plugdict + s:dependents → -1|0|1
+" Makes plugins which are being less depended on first in a list when passed as
+" a second argument to sort()
+"▶1 unloadplugin :: Either plugdict plid + … → [filename]
+" Returns a list of files that should be sourced to load plugin back
+"▶1 _unload
+"▶1 FraworRegister
+"▶1 FraworLoad
+"▶1 FraworUnload
+"▶1 isfunc :: funcref, key, fname, plid → + throw
+"▶1 features.newfeature.cons :: {f}, fid, fopts → + s:features, shadowdict, …
+"▶1 features.newfeature.unload :: {f} → + s:features, shadowdict, s:f
+"▶1 Plugin registration
+"▶1 warn feature :: {f}, msgid, … + p:_messages → message + echomsg
+"▶1 throw feature :: {f}, msgid, … → + throw
+"▶1
+" vim: fmr=▶,▲ sw=4 ts=4 sts=4 et tw=80
\ No newline at end of file
diff --git a/vim-addon-manager/test/dependencies-hg.lst b/vim-addon-manager/test/dependencies-hg.lst
new file mode 100644
index 0000000..c064af4
--- /dev/null
+++ b/vim-addon-manager/test/dependencies-hg.lst
@@ -0,0 +1 @@
+svn
diff --git a/vim-addon-manager/test/files-archive_name.lst b/vim-addon-manager/test/files-archive_name.lst
new file mode 100644
index 0000000..fdf8c04
--- /dev/null
+++ b/vim-addon-manager/test/files-archive_name.lst
@@ -0,0 +1,43 @@
+./vam_test_archive_name
+./vam_test_archive_name/README.markdown
+./vam_test_archive_name/addons
+./vam_test_archive_name/archive
+./vam_test_archive_name/archive/vam_test_archive_name.tar.gz
+./vam_test_archive_name/autoload
+./vam_test_archive_name/autoload/frawor.vim
+./vam_test_archive_name/doc
+./vam_test_archive_name/doc/FWC.txt
+./vam_test_archive_name/doc/frawor.txt
+./vam_test_archive_name/doc/tags
+./vam_test_archive_name/plugin
+./vam_test_archive_name/plugin/frawor
+./vam_test_archive_name/plugin/frawor/autocommands.vim
+./vam_test_archive_name/plugin/frawor/base64.vim
+./vam_test_archive_name/plugin/frawor/checks.vim
+./vam_test_archive_name/plugin/frawor/commands.vim
+./vam_test_archive_name/plugin/frawor/decorators
+./vam_test_archive_name/plugin/frawor/decorators/altervars.vim
+./vam_test_archive_name/plugin/frawor/decorators.vim
+./vam_test_archive_name/plugin/frawor/functions.vim
+./vam_test_archive_name/plugin/frawor/fwc
+./vam_test_archive_name/plugin/frawor/fwc/compiler.vim
+./vam_test_archive_name/plugin/frawor/fwc/constructor.vim
+./vam_test_archive_name/plugin/frawor/fwc/intfuncs.vim
+./vam_test_archive_name/plugin/frawor/fwc/parser.vim
+./vam_test_archive_name/plugin/frawor/fwc/topconstructs.vim
+./vam_test_archive_name/plugin/frawor/fwc.vim
+./vam_test_archive_name/plugin/frawor/lua.vim
+./vam_test_archive_name/plugin/frawor/mappings.vim
+./vam_test_archive_name/plugin/frawor/options.vim
+./vam_test_archive_name/plugin/frawor/os.vim
+./vam_test_archive_name/plugin/frawor/perl.vim
+./vam_test_archive_name/plugin/frawor/python.vim
+./vam_test_archive_name/plugin/frawor/resources.vim
+./vam_test_archive_name/plugin/frawor/ruby.vim
+./vam_test_archive_name/plugin/frawor/signs.vim
+./vam_test_archive_name/plugin/frawor/table.vim
+./vam_test_archive_name/plugin/frawor/tcl.vim
+./vam_test_archive_name/plugin/frawor.vim
+./vam_test_archive_name/templates
+./vam_test_archive_name/templates/oneload-frawor-plugin.vim
+./vam_test_archive_name/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-bzr.lst b/vim-addon-manager/test/files-bzr.lst
new file mode 100644
index 0000000..4d112ce
--- /dev/null
+++ b/vim-addon-manager/test/files-bzr.lst
@@ -0,0 +1,3 @@
+./vam_test_bzr
+./vam_test_bzr/macros
+./vam_test_bzr/macros/matchit.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-git.lst b/vim-addon-manager/test/files-git.lst
new file mode 100644
index 0000000..3df44ae
--- /dev/null
+++ b/vim-addon-manager/test/files-git.lst
@@ -0,0 +1,3 @@
+./vam_test_git
+./vam_test_git/autoload
+./vam_test_git/autoload/vam_known_repositories.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-hg.lst b/vim-addon-manager/test/files-hg.lst
new file mode 100644
index 0000000..c05d6d7
--- /dev/null
+++ b/vim-addon-manager/test/files-hg.lst
@@ -0,0 +1,8 @@
+./vam_test_hg
+./vam_test_hg/addon-info.json
+./vam_test_hg/runtimepath
+./vam_test_hg/runtimepath/plugin
+./vam_test_hg/runtimepath/plugin/writeMsg.vim
+./vam_test_svn
+./vam_test_svn/plugin
+./vam_test_svn/plugin/msgWrite.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-mhg.lst b/vim-addon-manager/test/files-mhg.lst
new file mode 100644
index 0000000..9225823
--- /dev/null
+++ b/vim-addon-manager/test/files-mhg.lst
@@ -0,0 +1,7 @@
+./vam_test_mhg
+./vam_test_mhg/addon-info.json
+./vam_test_mhg/plugin
+./vam_test_mhg/plugin/rtp.vim
+./vam_test_mhg/rtp
+./vam_test_mhg/rtp/plugin
+./vam_test_mhg/rtp/plugin/rtp.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-mis.lst b/vim-addon-manager/test/files-mis.lst
new file mode 100644
index 0000000..0f626a7
--- /dev/null
+++ b/vim-addon-manager/test/files-mis.lst
@@ -0,0 +1,10 @@
+./vam_test_mis
+./vam_test_mis/addon-info.json
+./vam_test_mis/archive
+./vam_test_mis/archive/vam_test_mis.tar.bz2
+./vam_test_mis/plugin
+./vam_test_mis/plugin/rtp.vim
+./vam_test_mis/rtp
+./vam_test_mis/rtp/plugin
+./vam_test_mis/rtp/plugin/rtp.vim
+./vam_test_mis/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-svn.lst b/vim-addon-manager/test/files-svn.lst
new file mode 100644
index 0000000..6ed012b
--- /dev/null
+++ b/vim-addon-manager/test/files-svn.lst
@@ -0,0 +1,3 @@
+./vam_test_svn
+./vam_test_svn/plugin
+./vam_test_svn/plugin/msgWrite.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-tar.lst b/vim-addon-manager/test/files-tar.lst
new file mode 100644
index 0000000..f90386b
--- /dev/null
+++ b/vim-addon-manager/test/files-tar.lst
@@ -0,0 +1,38 @@
+./vam_test_tar
+./vam_test_tar/archive
+./vam_test_tar/archive/vam_test_tar.tar
+./vam_test_tar/autoload
+./vam_test_tar/autoload/frawor.vim
+./vam_test_tar/doc
+./vam_test_tar/doc/oop.txt
+./vam_test_tar/doc/tags
+./vam_test_tar/plugin
+./vam_test_tar/plugin/frawor
+./vam_test_tar/plugin/frawor/autocommands.vim
+./vam_test_tar/plugin/frawor/checks.vim
+./vam_test_tar/plugin/frawor/decorators
+./vam_test_tar/plugin/frawor/decorators/altervars.vim
+./vam_test_tar/plugin/frawor/decorators.vim
+./vam_test_tar/plugin/frawor/functions.vim
+./vam_test_tar/plugin/frawor/fwc
+./vam_test_tar/plugin/frawor/fwc/compiler.vim
+./vam_test_tar/plugin/frawor/fwc/constructor.vim
+./vam_test_tar/plugin/frawor/fwc/intfuncs.vim
+./vam_test_tar/plugin/frawor/fwc/parser.vim
+./vam_test_tar/plugin/frawor/fwc/topconstructs.vim
+./vam_test_tar/plugin/frawor/fwc.vim
+./vam_test_tar/plugin/frawor/os.vim
+./vam_test_tar/plugin/frawor/resources.vim
+./vam_test_tar/plugin/frawor/signs.vim
+./vam_test_tar/plugin/frawor.vim
+./vam_test_tar/plugin/oop.vim
+./vam_test_tar/test
+./vam_test_tar/test/rtp
+./vam_test_tar/test/rtp/plugin
+./vam_test_tar/test/rtp/plugin/test1.vim
+./vam_test_tar/test/test.vim
+./vam_test_tar/test/test1.in
+./vam_test_tar/test/test1.ok
+./vam_test_tar/test/vimrc
+./vam_test_tar/version
+./vam_test_tar/vimoop-addon-info.txt
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-tbz.lst b/vim-addon-manager/test/files-tbz.lst
new file mode 100644
index 0000000..68e8063
--- /dev/null
+++ b/vim-addon-manager/test/files-tbz.lst
@@ -0,0 +1,48 @@
+./vam_test_tbz
+./vam_test_tbz/README.markdown
+./vam_test_tbz/addons
+./vam_test_tbz/archive
+./vam_test_tbz/archive/vam_test_tbz.tar.bz2
+./vam_test_tbz/autoload
+./vam_test_tbz/autoload/frawor.vim
+./vam_test_tbz/doc
+./vam_test_tbz/doc/FWC.txt
+./vam_test_tbz/doc/frawor.txt
+./vam_test_tbz/doc/oop.txt
+./vam_test_tbz/doc/tags
+./vam_test_tbz/doc/yaml.txt
+./vam_test_tbz/plugin
+./vam_test_tbz/plugin/frawor
+./vam_test_tbz/plugin/frawor/autocommands.vim
+./vam_test_tbz/plugin/frawor/base64.vim
+./vam_test_tbz/plugin/frawor/checks.vim
+./vam_test_tbz/plugin/frawor/commands.vim
+./vam_test_tbz/plugin/frawor/decorators
+./vam_test_tbz/plugin/frawor/decorators/altervars.vim
+./vam_test_tbz/plugin/frawor/decorators.vim
+./vam_test_tbz/plugin/frawor/functions.vim
+./vam_test_tbz/plugin/frawor/fwc
+./vam_test_tbz/plugin/frawor/fwc/compiler.vim
+./vam_test_tbz/plugin/frawor/fwc/constructor.vim
+./vam_test_tbz/plugin/frawor/fwc/intfuncs.vim
+./vam_test_tbz/plugin/frawor/fwc/parser.vim
+./vam_test_tbz/plugin/frawor/fwc/topconstructs.vim
+./vam_test_tbz/plugin/frawor/fwc.vim
+./vam_test_tbz/plugin/frawor/history.vim
+./vam_test_tbz/plugin/frawor/lua.vim
+./vam_test_tbz/plugin/frawor/mappings.vim
+./vam_test_tbz/plugin/frawor/options.vim
+./vam_test_tbz/plugin/frawor/os.vim
+./vam_test_tbz/plugin/frawor/perl.vim
+./vam_test_tbz/plugin/frawor/python.vim
+./vam_test_tbz/plugin/frawor/resources.vim
+./vam_test_tbz/plugin/frawor/ruby.vim
+./vam_test_tbz/plugin/frawor/signs.vim
+./vam_test_tbz/plugin/frawor/table.vim
+./vam_test_tbz/plugin/frawor/tcl.vim
+./vam_test_tbz/plugin/frawor.vim
+./vam_test_tbz/plugin/oop.vim
+./vam_test_tbz/plugin/yaml.vim
+./vam_test_tbz/templates
+./vam_test_tbz/templates/oneload-frawor-plugin.vim
+./vam_test_tbz/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-tbz2.lst b/vim-addon-manager/test/files-tbz2.lst
new file mode 100644
index 0000000..6414045
--- /dev/null
+++ b/vim-addon-manager/test/files-tbz2.lst
@@ -0,0 +1,46 @@
+./vam_test_tbz2
+./vam_test_tbz2/README.markdown
+./vam_test_tbz2/addons
+./vam_test_tbz2/archive
+./vam_test_tbz2/archive/vam_test_tbz_2.tbz2
+./vam_test_tbz2/autoload
+./vam_test_tbz2/autoload/frawor.vim
+./vam_test_tbz2/doc
+./vam_test_tbz2/doc/FWC.txt
+./vam_test_tbz2/doc/frawor.txt
+./vam_test_tbz2/doc/oop.txt
+./vam_test_tbz2/doc/tags
+./vam_test_tbz2/plugin
+./vam_test_tbz2/plugin/frawor
+./vam_test_tbz2/plugin/frawor/autocommands.vim
+./vam_test_tbz2/plugin/frawor/base64.vim
+./vam_test_tbz2/plugin/frawor/checks.vim
+./vam_test_tbz2/plugin/frawor/commands.vim
+./vam_test_tbz2/plugin/frawor/decorators
+./vam_test_tbz2/plugin/frawor/decorators/altervars.vim
+./vam_test_tbz2/plugin/frawor/decorators.vim
+./vam_test_tbz2/plugin/frawor/functions.vim
+./vam_test_tbz2/plugin/frawor/fwc
+./vam_test_tbz2/plugin/frawor/fwc/compiler.vim
+./vam_test_tbz2/plugin/frawor/fwc/constructor.vim
+./vam_test_tbz2/plugin/frawor/fwc/intfuncs.vim
+./vam_test_tbz2/plugin/frawor/fwc/parser.vim
+./vam_test_tbz2/plugin/frawor/fwc/topconstructs.vim
+./vam_test_tbz2/plugin/frawor/fwc.vim
+./vam_test_tbz2/plugin/frawor/history.vim
+./vam_test_tbz2/plugin/frawor/lua.vim
+./vam_test_tbz2/plugin/frawor/mappings.vim
+./vam_test_tbz2/plugin/frawor/options.vim
+./vam_test_tbz2/plugin/frawor/os.vim
+./vam_test_tbz2/plugin/frawor/perl.vim
+./vam_test_tbz2/plugin/frawor/python.vim
+./vam_test_tbz2/plugin/frawor/resources.vim
+./vam_test_tbz2/plugin/frawor/ruby.vim
+./vam_test_tbz2/plugin/frawor/signs.vim
+./vam_test_tbz2/plugin/frawor/table.vim
+./vam_test_tbz2/plugin/frawor/tcl.vim
+./vam_test_tbz2/plugin/frawor.vim
+./vam_test_tbz2/plugin/oop.vim
+./vam_test_tbz2/templates
+./vam_test_tbz2/templates/oneload-frawor-plugin.vim
+./vam_test_tbz2/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-tgz.lst b/vim-addon-manager/test/files-tgz.lst
new file mode 100644
index 0000000..5e62c32
--- /dev/null
+++ b/vim-addon-manager/test/files-tgz.lst
@@ -0,0 +1,44 @@
+./vam_test_tgz
+./vam_test_tgz/README.markdown
+./vam_test_tgz/addons
+./vam_test_tgz/archive
+./vam_test_tgz/archive/vam_test_tgz.tar.gz
+./vam_test_tgz/autoload
+./vam_test_tgz/autoload/frawor.vim
+./vam_test_tgz/doc
+./vam_test_tgz/doc/FWC.txt
+./vam_test_tgz/doc/frawor.txt
+./vam_test_tgz/doc/tags
+./vam_test_tgz/plugin
+./vam_test_tgz/plugin/frawor
+./vam_test_tgz/plugin/frawor/autocommands.vim
+./vam_test_tgz/plugin/frawor/base64.vim
+./vam_test_tgz/plugin/frawor/checks.vim
+./vam_test_tgz/plugin/frawor/commands.vim
+./vam_test_tgz/plugin/frawor/decorators
+./vam_test_tgz/plugin/frawor/decorators/altervars.vim
+./vam_test_tgz/plugin/frawor/decorators.vim
+./vam_test_tgz/plugin/frawor/functions.vim
+./vam_test_tgz/plugin/frawor/fwc
+./vam_test_tgz/plugin/frawor/fwc/compiler.vim
+./vam_test_tgz/plugin/frawor/fwc/constructor.vim
+./vam_test_tgz/plugin/frawor/fwc/intfuncs.vim
+./vam_test_tgz/plugin/frawor/fwc/parser.vim
+./vam_test_tgz/plugin/frawor/fwc/topconstructs.vim
+./vam_test_tgz/plugin/frawor/fwc.vim
+./vam_test_tgz/plugin/frawor/history.vim
+./vam_test_tgz/plugin/frawor/lua.vim
+./vam_test_tgz/plugin/frawor/mappings.vim
+./vam_test_tgz/plugin/frawor/options.vim
+./vam_test_tgz/plugin/frawor/os.vim
+./vam_test_tgz/plugin/frawor/perl.vim
+./vam_test_tgz/plugin/frawor/python.vim
+./vam_test_tgz/plugin/frawor/resources.vim
+./vam_test_tgz/plugin/frawor/ruby.vim
+./vam_test_tgz/plugin/frawor/signs.vim
+./vam_test_tgz/plugin/frawor/table.vim
+./vam_test_tgz/plugin/frawor/tcl.vim
+./vam_test_tgz/plugin/frawor.vim
+./vam_test_tgz/templates
+./vam_test_tgz/templates/oneload-frawor-plugin.vim
+./vam_test_tgz/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-tgz2-updated.lst b/vim-addon-manager/test/files-tgz2-updated.lst
new file mode 100644
index 0000000..b0f8704
--- /dev/null
+++ b/vim-addon-manager/test/files-tgz2-updated.lst
@@ -0,0 +1,39 @@
+./vam_test_tgz2
+./vam_test_tgz2/README.markdown
+./vam_test_tgz2/addons
+./vam_test_tgz2/archive
+./vam_test_tgz2/archive/vam_test_tgz_2-nodoc.tar.bz2
+./vam_test_tgz2/autoload
+./vam_test_tgz2/autoload/frawor.vim
+./vam_test_tgz2/plugin
+./vam_test_tgz2/plugin/frawor
+./vam_test_tgz2/plugin/frawor/autocommands.vim
+./vam_test_tgz2/plugin/frawor/base64.vim
+./vam_test_tgz2/plugin/frawor/checks.vim
+./vam_test_tgz2/plugin/frawor/commands.vim
+./vam_test_tgz2/plugin/frawor/decorators
+./vam_test_tgz2/plugin/frawor/decorators/altervars.vim
+./vam_test_tgz2/plugin/frawor/decorators.vim
+./vam_test_tgz2/plugin/frawor/functions.vim
+./vam_test_tgz2/plugin/frawor/fwc
+./vam_test_tgz2/plugin/frawor/fwc/compiler.vim
+./vam_test_tgz2/plugin/frawor/fwc/constructor.vim
+./vam_test_tgz2/plugin/frawor/fwc/intfuncs.vim
+./vam_test_tgz2/plugin/frawor/fwc/parser.vim
+./vam_test_tgz2/plugin/frawor/fwc/topconstructs.vim
+./vam_test_tgz2/plugin/frawor/fwc.vim
+./vam_test_tgz2/plugin/frawor/lua.vim
+./vam_test_tgz2/plugin/frawor/mappings.vim
+./vam_test_tgz2/plugin/frawor/options.vim
+./vam_test_tgz2/plugin/frawor/os.vim
+./vam_test_tgz2/plugin/frawor/perl.vim
+./vam_test_tgz2/plugin/frawor/python.vim
+./vam_test_tgz2/plugin/frawor/resources.vim
+./vam_test_tgz2/plugin/frawor/ruby.vim
+./vam_test_tgz2/plugin/frawor/signs.vim
+./vam_test_tgz2/plugin/frawor/table.vim
+./vam_test_tgz2/plugin/frawor/tcl.vim
+./vam_test_tgz2/plugin/frawor.vim
+./vam_test_tgz2/templates
+./vam_test_tgz2/templates/oneload-frawor-plugin.vim
+./vam_test_tgz2/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-tgz2.lst b/vim-addon-manager/test/files-tgz2.lst
new file mode 100644
index 0000000..59dd448
--- /dev/null
+++ b/vim-addon-manager/test/files-tgz2.lst
@@ -0,0 +1,43 @@
+./vam_test_tgz2
+./vam_test_tgz2/README.markdown
+./vam_test_tgz2/addons
+./vam_test_tgz2/archive
+./vam_test_tgz2/archive/vam_test_tgz_2.tgz
+./vam_test_tgz2/autoload
+./vam_test_tgz2/autoload/frawor.vim
+./vam_test_tgz2/doc
+./vam_test_tgz2/doc/FWC.txt
+./vam_test_tgz2/doc/frawor.txt
+./vam_test_tgz2/doc/tags
+./vam_test_tgz2/plugin
+./vam_test_tgz2/plugin/frawor
+./vam_test_tgz2/plugin/frawor/autocommands.vim
+./vam_test_tgz2/plugin/frawor/base64.vim
+./vam_test_tgz2/plugin/frawor/checks.vim
+./vam_test_tgz2/plugin/frawor/commands.vim
+./vam_test_tgz2/plugin/frawor/decorators
+./vam_test_tgz2/plugin/frawor/decorators/altervars.vim
+./vam_test_tgz2/plugin/frawor/decorators.vim
+./vam_test_tgz2/plugin/frawor/functions.vim
+./vam_test_tgz2/plugin/frawor/fwc
+./vam_test_tgz2/plugin/frawor/fwc/compiler.vim
+./vam_test_tgz2/plugin/frawor/fwc/constructor.vim
+./vam_test_tgz2/plugin/frawor/fwc/intfuncs.vim
+./vam_test_tgz2/plugin/frawor/fwc/parser.vim
+./vam_test_tgz2/plugin/frawor/fwc/topconstructs.vim
+./vam_test_tgz2/plugin/frawor/fwc.vim
+./vam_test_tgz2/plugin/frawor/lua.vim
+./vam_test_tgz2/plugin/frawor/mappings.vim
+./vam_test_tgz2/plugin/frawor/options.vim
+./vam_test_tgz2/plugin/frawor/os.vim
+./vam_test_tgz2/plugin/frawor/perl.vim
+./vam_test_tgz2/plugin/frawor/python.vim
+./vam_test_tgz2/plugin/frawor/resources.vim
+./vam_test_tgz2/plugin/frawor/ruby.vim
+./vam_test_tgz2/plugin/frawor/signs.vim
+./vam_test_tgz2/plugin/frawor/table.vim
+./vam_test_tgz2/plugin/frawor/tcl.vim
+./vam_test_tgz2/plugin/frawor.vim
+./vam_test_tgz2/templates
+./vam_test_tgz2/templates/oneload-frawor-plugin.vim
+./vam_test_tgz2/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-vba.lst b/vim-addon-manager/test/files-vba.lst
new file mode 100644
index 0000000..5311165
--- /dev/null
+++ b/vim-addon-manager/test/files-vba.lst
@@ -0,0 +1,13 @@
+./vam_test_vba
+./vam_test_vba/archive
+./vam_test_vba/archive/vam_test_vba.vba
+./vam_test_vba/autoload
+./vam_test_vba/autoload/frawor.vim
+./vam_test_vba/doc
+./vam_test_vba/doc/json.rux
+./vam_test_vba/doc/json.txt
+./vam_test_vba/doc/tags
+./vam_test_vba/doc/tags-ru
+./vam_test_vba/plugin
+./vam_test_vba/plugin/json.vim
+./vam_test_vba/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-vbz.lst b/vim-addon-manager/test/files-vbz.lst
new file mode 100644
index 0000000..146c0c4
--- /dev/null
+++ b/vim-addon-manager/test/files-vbz.lst
@@ -0,0 +1,13 @@
+./vam_test_vbz
+./vam_test_vbz/archive
+./vam_test_vbz/archive/vam_test_vbz.vba.bz2
+./vam_test_vbz/autoload
+./vam_test_vbz/autoload/frawor.vim
+./vam_test_vbz/doc
+./vam_test_vbz/doc/json.rux
+./vam_test_vbz/doc/json.txt
+./vam_test_vbz/doc/tags
+./vam_test_vbz/doc/tags-ru
+./vam_test_vbz/plugin
+./vam_test_vbz/plugin/json.vim
+./vam_test_vbz/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-vgz.lst b/vim-addon-manager/test/files-vgz.lst
new file mode 100644
index 0000000..ed6607d
--- /dev/null
+++ b/vim-addon-manager/test/files-vgz.lst
@@ -0,0 +1,13 @@
+./vam_test_vgz
+./vam_test_vgz/archive
+./vam_test_vgz/archive/vam_test_vgz.vba.gz
+./vam_test_vgz/autoload
+./vam_test_vgz/autoload/frawor.vim
+./vam_test_vgz/doc
+./vam_test_vgz/doc/json.rux
+./vam_test_vgz/doc/json.txt
+./vam_test_vgz/doc/tags
+./vam_test_vgz/doc/tags-ru
+./vam_test_vgz/plugin
+./vam_test_vgz/plugin/json.vim
+./vam_test_vgz/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-vmb.lst b/vim-addon-manager/test/files-vmb.lst
new file mode 100644
index 0000000..9d6fff7
--- /dev/null
+++ b/vim-addon-manager/test/files-vmb.lst
@@ -0,0 +1,13 @@
+./vam_test_vmb
+./vam_test_vmb/archive
+./vam_test_vmb/archive/vam_test_vmb.vmb
+./vam_test_vmb/autoload
+./vam_test_vmb/autoload/frawor.vim
+./vam_test_vmb/doc
+./vam_test_vmb/doc/json.rux
+./vam_test_vmb/doc/json.txt
+./vam_test_vmb/doc/tags
+./vam_test_vmb/doc/tags-ru
+./vam_test_vmb/plugin
+./vam_test_vmb/plugin/json.vim
+./vam_test_vmb/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/files-zip.lst b/vim-addon-manager/test/files-zip.lst
new file mode 100644
index 0000000..d89827e
--- /dev/null
+++ b/vim-addon-manager/test/files-zip.lst
@@ -0,0 +1,39 @@
+./vam_test_zip
+./vam_test_zip/archive
+./vam_test_zip/archive/vam_test_zip.zip
+./vam_test_zip/autoload
+./vam_test_zip/autoload/frawor.vim
+./vam_test_zip/doc
+./vam_test_zip/doc/json.rux
+./vam_test_zip/doc/json.txt
+./vam_test_zip/doc/tags
+./vam_test_zip/doc/tags-ru
+./vam_test_zip/jsonvim-addon-info.txt
+./vam_test_zip/plugin
+./vam_test_zip/plugin/json.vim
+./vam_test_zip/test
+./vam_test_zip/test/constants-nopython.ok
+./vam_test_zip/test/constants.in
+./vam_test_zip/test/constants.ok
+./vam_test_zip/test/dump-nopython.ok
+./vam_test_zip/test/dump.in
+./vam_test_zip/test/dump.ok
+./vam_test_zip/test/file-nopython.ok
+./vam_test_zip/test/file.in
+./vam_test_zip/test/file.ok
+./vam_test_zip/test/gentests-nopython.zsh
+./vam_test_zip/test/list-nopython.ok
+./vam_test_zip/test/list.in
+./vam_test_zip/test/list.json
+./vam_test_zip/test/list.ok
+./vam_test_zip/test/number-nopython.ok
+./vam_test_zip/test/number.in
+./vam_test_zip/test/number.ok
+./vam_test_zip/test/object-nopython.ok
+./vam_test_zip/test/object.in
+./vam_test_zip/test/object.ok
+./vam_test_zip/test/string-nopython.ok
+./vam_test_zip/test/string.in
+./vam_test_zip/test/string.ok
+./vam_test_zip/test/vimrc
+./vam_test_zip/version
\ No newline at end of file
diff --git a/vim-addon-manager/test/gentests-setuprtp.zsh b/vim-addon-manager/test/gentests-setuprtp.zsh
new file mode 100755
index 0000000..3a90708
--- /dev/null
+++ b/vim-addon-manager/test/gentests-setuprtp.zsh
@@ -0,0 +1,5 @@
+#!/bin/zsh
+emulate -L zsh
+cd ../rtp
+tar -xJf ../test/runtime.tar.xz
+rm ../test/runtime.tar.xz
diff --git a/vim-addon-manager/test/gentests-test-repos.zsh b/vim-addon-manager/test/gentests-test-repos.zsh
new file mode 100755
index 0000000..6d9767d
--- /dev/null
+++ b/vim-addon-manager/test/gentests-test-repos.zsh
@@ -0,0 +1,156 @@
+#!/bin/zsh
+emulate -L zsh
+#▶1 Clone vam-test-known
+FOREGROUND=1 \
+mkdir vam-init
+vimcmd -u $VIMRC \
+ --cmd 'let g:curtest="init"' \
+ -c 'call vam#ActivateAddons("vam-test-known")' \
+ -c 'qa!'
+function addtofile()
+{
+ target=$1
+ shift
+ (( $# )) || return
+ if ! test -e $1 ; then
+ shift
+ addtofile $target $@
+ return
+ fi
+ if test -e $target ; then
+ echo >> $target
+ cat $1 >> $target
+ else
+ cp $1 $target
+ fi
+ shift
+ for file in $@ ; do
+ test -e $file || continue
+ echo >> $target
+ cat $file >> $target
+ done
+}
+#▶1 Simple unpack tests
+typeset -a TESTS
+(( ISWINE )) || TESTS+=( git bzr )
+(( ISWINE )) && sed -r -i -e 's:/:\\:g' files-*.lst
+TESTS+=( hg svn tar tgz tgz2 tbz tbz2 zip vba vmb vgz vbz archive_name )
+TESTS+=( mis mhg )
+for t in $TESTS ; do
+local ANAME=vam_test_$t
+#▶2 activate
+cat > activate-$t.in <<EOF
+:call vam#ActivateAddons("$ANAME")
+:call WriteGlob()
+EOF
+addtofile activate-$t.ok init.ok files-$t.lst
+#▶2 activate-vimrc
+cat > activate-vimrc-$t.vim << EOF
+call vam#ActivateAddons("$ANAME")
+EOF
+cat > activate-vimrc-$t.in << EOF
+:call WriteGlob()
+EOF
+cp activate-$t.ok activate-vimrc-$t.ok
+#▶2 install
+cat > install-$t.in <<EOF
+:runtime! autoload/vam.vim
+:InstallAddons $ANAME
+:call WriteGlob()
+EOF
+addtofile install-$t.ok init.ok files-$t.lst
+#▶2 uninstall
+cp install-$t.in uninstall-$t.in
+cat >> uninstall-$t.in << EOF
+:UninstallNotLoadedAddons $ANAME
+y
+:call WriteGlob()
+EOF
+addtofile uninstall-$t.ok install-$t.ok init.ok
+if test -e dependencies-$t.lst ; then
+ for dep in $(< dependencies-$t.lst) ; do
+ addtofile uninstall-$t.ok files-$dep.lst
+ done
+fi
+#▲2
+done
+#▶1 Update
+UPDATETGZ2HEADER="\
+:let desc=copy(g:vim_addon_manager.plugin_sources.vam_test_tgz2)
+:let desc.version='0.1.8'
+:let desc.url=desc.url[:-5].'-nodoc.tar.bz2'
+:let patch={'vam_test_tgz2': desc}"
+#▶2 Update activate plugin
+T=update-tgz2
+cp activate-tgz2.in $T.in
+cat >> $T.in << EOF
+$UPDATETGZ2HEADER
+:UpdateAddons
+y
+:call WriteGlob()
+EOF
+addtofile $T.ok install-tgz2.ok init.ok files-tgz2-updated.lst
+#▶2 Update not activated plugin
+T=update-tgz2-not_active
+cp install-tgz2.in $T.in
+cat >> $T.in << EOF
+$UPDATETGZ2HEADER
+:UpdateAddons vam_test_tgz2
+:call WriteGlob()
+EOF
+addtofile $T.ok install-tgz2.ok init.ok files-tgz2-updated.lst
+#▶2 Be sure that not active plugin is not updated
+T=noupdate-tgz2-not_active
+cp install-tgz2.in $T.in
+cat >> $T.in << EOF
+$UPDATETGZ2HEADER
+:UpdateAddons
+y
+:call WriteGlob()
+EOF
+addtofile $T.ok install-tgz2.ok install-tgz2.ok
+#▶2 Check do_diff: 1
+T=update-tgz2-dodiff
+cp activate-tgz2.in $T.in
+cat >> $T.in << EOF
+:let desc=copy(g:vim_addon_manager.plugin_sources.vam_test_tgz2)
+:let desc.version='0.1.8'
+:let desc.archive_name=matchstr(desc.url, '\v[^/]+$')
+:let desc.url=desc.url[:-5].'-2.tgz'
+:let patch={'vam_test_tgz2': desc}
+:let file=g:vim_addon_manager.plugin_root_dir."/vam_test_tgz2/plugin/frawor.vim"
+:let g:vim_addon_manager.do_diff=1
+:execute "edit ".fnameescape(file)
+:%s/^"/#!
+:write!
+:set autoread
+:UpdateAddons
+y
+:call WriteGlob()
+:edit!
+qaq
+:g/^"/yank A
+:call WriteFile(split(@a, "\n"))
+EOF
+addtofile $T.ok install-tgz2.ok <(cat install-tgz2.ok | \
+ perl -pe '$_.="$1.orig\n"if/^(.*plugin.frawor\.vim)$/') \
+ comments-tgz2-dodiff.lst
+# addtofile $T.ok install-tgz2.ok install-tgz2.ok comments-tgz2-dodiff.lst
+#▶2 Check do_diff: 0
+T=update-tgz2-nodiff
+cat update-tgz2-dodiff.in | grep -v 'do_diff' > $T.in
+addtofile $T.ok install-tgz2.ok install-tgz2.ok comments-tgz2-nodiff.lst
+#▶1 Use cloned vam-test-known
+for test in *.in ; do
+ cp -r vam-init vam-$test:r
+done
+#▲1
+cat > init.in << EOF
+:call WriteGlob()
+EOF
+#▶1 Add `:source addmessages.vim'
+for f in *.in ; do
+ cat >> $f <<< $':source addmessages.vim\n'
+done
+#▲1
+# vim: fmr=▶,▲ fenc=utf-8 et ts=4 sts=4 sw=4 ft=zsh cms=#%s
diff --git a/vim-addon-manager/test/gwine b/vim-addon-manager/test/gwine
new file mode 120000
index 0000000..bd42d64
--- /dev/null
+++ b/vim-addon-manager/test/gwine
@@ -0,0 +1 @@
+wine
\ No newline at end of file
diff --git a/vim-addon-manager/test/init.ok b/vim-addon-manager/test/init.ok
new file mode 100644
index 0000000..5807b32
--- /dev/null
+++ b/vim-addon-manager/test/init.ok
@@ -0,0 +1,3 @@
+./vam-test-known
+./vam-test-known/autoload
+./vam-test-known/autoload/vam_known_repositories.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/lineendings.in b/vim-addon-manager/test/lineendings.in
new file mode 100644
index 0000000..ca55a79
--- /dev/null
+++ b/vim-addon-manager/test/lineendings.in
@@ -0,0 +1,2 @@
+:call Try('call vam#ActivateAddons(["vam_test_dos"])')
+:source addmessages.vim
diff --git a/vim-addon-manager/test/lineendings.ok b/vim-addon-manager/test/lineendings.ok
new file mode 100644
index 0000000..01a2143
--- /dev/null
+++ b/vim-addon-manager/test/lineendings.ok
@@ -0,0 +1 @@
+::: In {unix_ff}/plugin/writeMsg.vim
\ No newline at end of file
diff --git a/vim-addon-manager/test/runtime.tar.xz b/vim-addon-manager/test/runtime.tar.xz
new file mode 100644
index 0000000..81b9c68
--- /dev/null
+++ b/vim-addon-manager/test/runtime.tar.xz
Binary files differ
diff --git a/vim-addon-manager/test/vimrc b/vim-addon-manager/test/vimrc
new file mode 100644
index 0000000..2c03bd4
--- /dev/null
+++ b/vim-addon-manager/test/vimrc
@@ -0,0 +1,56 @@
+let g:vim_addon_manager={}
+let g:vim_addon_manager.known='vam-test-known'
+if executable('git')
+ let g:vim_addon_manager.plugin_sources={
+ \'vam-test-known': {'type': 'git',
+ \ 'url': 'git://vimpluginloader.git.sourceforge.net/gitroot/vimpluginloader/vam-test-repository/',},
+ \}
+else
+ let g:vim_addon_manager.plugin_sources={
+ \'vam-test-known': {'type': 'archive',
+ \ 'url': 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam-test-repository.tar.gz',
+ \ 'version': '9999',
+ \ 'archive_name': 'vam-test-known.tar.gz'},
+ \}
+endif
+let g:vim_addon_manager.auto_install=1
+let g:vim_addon_manager.do_diff=0
+let g:vim_addon_manager.plugin_root_dir=fnamemodify('./vam-'.g:curtest, ':p')[:-2]
+let g:vim_addon_manager.silent_shell_commands=1
+let s:outfile=fnamemodify(g:outfile, ':p')
+let s:errfile=fnamemodify(g:outfile, ':p:r').'.fail'
+function WriteFile(...)
+ let r=[]
+ if filereadable(s:outfile)
+ let r+=readfile(s:outfile, 'b')
+ endif
+ if type(a:1)==type([])
+ let r+=a:1
+ else
+ let r+=a:000
+ endif
+ call writefile(r, s:outfile, 'b')
+ return ''
+endfunction
+command -bar -nargs=1 W :call WriteFile(<q-args>)
+function WriteGlob()
+ cd `="vam-".g:curtest`
+ call WriteFile(split(glob('./**'), "\n"))
+ cd ..
+endfunction
+function Try(cmd)
+ let failed=1
+ try
+ execute a:cmd
+ let failed=0
+ finally
+ " Unlike :catch this won't loose trace
+ if failed
+ call writefile([], s:errfile, 'b')
+ endif
+ endtry
+endfunction
+command -nargs=1 Try :call Try(<q-args>)
+if filereadable(g:curtest.'.vim')
+ source `=g:curtest.".vim"`
+endif
diff --git a/vim-addon-manager/test/wine/init.ok b/vim-addon-manager/test/wine/init.ok
new file mode 100644
index 0000000..7a08fd7
--- /dev/null
+++ b/vim-addon-manager/test/wine/init.ok
@@ -0,0 +1,7 @@
+.\vam-test-known
+.\vam-test-known\archive
+.\vam-test-known\archive\vam-test-known.tar.gz
+.\vam-test-known\pax_global_header
+.\vam-test-known\plugin
+.\vam-test-known\plugin\vim-addon-manager-known-repositories.vim
+.\vam-test-known\version
\ No newline at end of file
diff --git a/vim-addon-manager/vim-addon-manager-addon-info.txt b/vim-addon-manager/vim-addon-manager-addon-info.txt
new file mode 100644
index 0000000..e5eab6f
--- /dev/null
+++ b/vim-addon-manager/vim-addon-manager-addon-info.txt
@@ -0,0 +1,9 @@
+{
+ "name" : "vim-addon-manager",
+ "version" : "0.0",
+ "author" : "Marc Weber <marco-oweber@gmx.de>",
+ "maintainer" : "Marc Weber <marco-oweber@gmx.de>",
+ "repository" : {"type": "git", "url": "git://github.com/MarcWeber/vim-addon-manager.git"},
+ "dependencies" : {},
+ "description" : "Manage vim plugins"
+}
diff --git a/vim-addon-manager/vim-addon-manager-test.sh b/vim-addon-manager/vim-addon-manager-test.sh
new file mode 100644
index 0000000..cc71c21
--- /dev/null
+++ b/vim-addon-manager/vim-addon-manager-test.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+case "$1" in
+ test)
+ ;;
+ *)
+ echo "this tests installation of various plugins"
+ echo "usage: vim-addon-manager-test.sh test"
+ exit 1
+ ;;
+esac
+
+set -e -x
+
+root=$(dirname $0)
+test_dir='/tmp/vim-addon-manager-test'
+
+[ -e $test_dir ] && rm -fr $test_dir || true
+mkdir -p $test_dir
+
+cp -r $root $test_dir/vim-addon-manager
+
+cat >> $test_dir/.vimrc << EOF
+set nocompatible
+set runtimepath+=${test_dir}/vim-addon-manager
+call sample_vimrc_for_new_users#Load()
+
+let opts = {'auto_install' : 1 }
+
+" test mercurial
+" test git
+" test subversion
+call vam#ActivateAddons(["Translit3","vim-addon-views","vim-latex"], opts)
+
+function CheckAll()
+ let res = [
+ \ exists(':Tr3Command') > 0,
+ \ exists('g:vim_views_config'),
+ \ exists('*AddSyntaxFoldItem')
+ \ ]
+ echoe string(res)
+ call writefile(res, '${test_dir}/result.txt')
+endfun
+
+EOF
+
+# yes necessary for enabling known repositories and
+# continuing after nasty "press enter to continue lines .."
+test_dir='/tmp/vim-addon-manager-test'
+yes | vim -u $test_dir/.vimrc -U /dev/null -c ':call CheckAll()|qa!'
+
+echo "should be an aray cotaining 1 values only. 0 means failure"
+cat ${test_dir}/result.txt