├── .gitignore ├── LICENSE.txt ├── README.md ├── addon-info.json ├── autoload ├── sample_vimrc_for_new_users.vim ├── scriptmanager.vim ├── vam.vim ├── vam │ ├── bisect.vim │ ├── install.vim │ ├── test.vim │ ├── utils.vim │ └── vcs.vim ├── vcs_checkouts.vim └── vundle.vim ├── doc ├── vim-addon-manager-additional-documentation.txt └── vim-addon-manager-getting-started.txt ├── downloader └── index.php ├── test ├── README.txt ├── activate-hg.ok ├── activate-mhg.ok ├── activate-mis.ok ├── activate-svn.ok ├── addmessages.vim ├── addoninfo.in ├── addoninfo.ok ├── bisect.in ├── bisect.ok ├── bisect.vim ├── comments-tgz2-dodiff.lst ├── comments-tgz2-nodiff.lst ├── dependencies-hg.lst ├── files-archive_name.lst ├── files-bzr.lst ├── files-git.lst ├── files-hg.lst ├── files-mhg.lst ├── files-mis.lst ├── files-svn.lst ├── files-tar.lst ├── files-tbz.lst ├── files-tbz2.lst ├── files-tgz.lst ├── files-tgz2-updated.lst ├── files-tgz2.lst ├── files-vba.lst ├── files-vbz.lst ├── files-vgz.lst ├── files-vmb.lst ├── files-zip.lst ├── gentests-setuprtp.zsh ├── gentests-test-repos.zsh ├── gwine ├── hooks.in ├── hooks.ok ├── hooks.vim ├── init.ok ├── lineendings.in ├── lineendings.ok ├── runtime.tar.xz ├── vimrc └── wine │ └── init.ok └── vim-addon-manager-test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Same as Vim. 2 | 3 | If any of the contributors till Tue Jul 30 2013 thinks differently talk to me. 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VAM — maximizing overall Vim experience 2 | “VAM” is short name for vim-addon-manager. 3 | You declare a set of plugins. VAM will fetch & activate them at startup or 4 | runtime depending on your needs. Activating means handling runtimepath and 5 | making sure all .vim file get sourced. The FEATURES to learn more. 6 | 7 | ![VAM](http://vam.mawercer.de/screenshot.png) 8 | 9 | This screenshot shows: 10 | - The log buffer 11 | - The plugin name completion 12 | - That vim-pi knows about plugins which are neither known by vim-scripts.org 13 | nor by vim.sf.net (marked by NA) 14 | 15 | ## If you believe in VAM's collaborative properties 16 | then you may also want to have a look at [vim-git-wiki](http://vim-wiki.mawercer.de). 17 | 18 | ## SUPPORT / HELP 19 | VAM is well supported by at least 2 maintainers. Try github tickets or Vim irc 20 | channel on freenode. 21 | 22 | ## NEOVIM SUPPORT 23 | VAMActivate after startup does load plugin/\*\*/\*.lua files. 24 | lazy.nvim plugin manager might be worth looking at, too 25 | 26 | ## PLUGIN_NAME - What is a plugin ? 27 | A plugin is set of files having Vim's rtp directory layout (plugin/, ftplugin/, ...). 28 | It is identified by name which will be looked up by vim-pi or a url such as 29 | git:url, github:user/repo, ... 30 | 31 | Plugin names can be found by using completion in .vim files. 32 | VAMActivate & VAMPluginInfo commands also offer name completion by or . 33 | 34 | In most cases you activate plugins by using its name. Wrapping the name 35 | in a dictionary {'name': 'name'} allows attaching additional information 36 | which could be used by checkout functions ... 37 | 38 | ## MINIMAL setup (3 lines) 39 | 40 | ```vim 41 | set nocompatible | filetype indent plugin on | syn on 42 | set runtimepath+=/path/to/vam 43 | call vam#ActivateAddons([PLUGIN_NAME]) 44 | ``` 45 | 46 | ## Recommended setup 47 | This setup will checkout VAM and all plugins on its own unless they exist: 48 | 49 | ```vim 50 | " put this line first in ~/.vimrc 51 | set nocompatible | filetype indent plugin on | syn on 52 | 53 | fun! SetupVAM() 54 | let c = get(g:, 'vim_addon_manager', {}) 55 | let g:vim_addon_manager = c 56 | let c.plugin_root_dir = expand('$HOME', 1) . '/.vim/vim-addons' 57 | 58 | " Force your ~/.vim/after directory to be last in &rtp always: 59 | " let g:vim_addon_manager.rtp_list_hook = 'vam#ForceUsersAfterDirectoriesToBeLast' 60 | 61 | " most used options you may want to use: 62 | " let c.log_to_buf = 1 63 | " let c.auto_install = 0 64 | let &rtp.=(empty(&rtp)?'':',').c.plugin_root_dir.'/vim-addon-manager' 65 | if !isdirectory(c.plugin_root_dir.'/vim-addon-manager/autoload') 66 | execute '!git clone --depth=1' 67 | \ 'https://github.com/MarcWeber/vim-addon-manager' 68 | \ shellescape(c.plugin_root_dir.'/vim-addon-manager', 1) 69 | endif 70 | 71 | " This provides the VAMActivate command, you could be passing plugin names, too 72 | call vam#ActivateAddons([], {}) 73 | endfun 74 | call SetupVAM() 75 | 76 | " ACTIVATING PLUGINS 77 | 78 | " OPTION 1, use VAMActivate 79 | VAMActivate PLUGIN_NAME PLUGIN_NAME .. 80 | 81 | " OPTION 2: use call vam#ActivateAddons 82 | call vam#ActivateAddons([PLUGIN_NAME], {}) 83 | " use to complete plugin names 84 | 85 | " OPTION 3: Create a file ~/.vim-scripts putting a PLUGIN_NAME into each line (# for comments) 86 | " See lazy loading plugins section in README.md for details 87 | call vam#Scripts('~/.vim-scripts', {'tag_regex': '.*'}) 88 | 89 | ``` 90 | 91 | ## easy setup windows users: 92 | Give the [downloader](http://vam.mawercer.de/) a try if you're too lazy to install supporting tools. In 93 | the doc/ directory you'll find additional information. https (self signed certificate) can be used, too. 94 | 95 | ## all commands 96 | 97 | ```vim 98 | " Note: All commands support completion ( or ) 99 | 100 | " install [UE] without activating for reviewing 101 | VAMInstall PLUGIN_NAME PLUGIN_NAME 102 | 103 | " install [UE], then activate 104 | VAMActivate P1 P2 ... 105 | VAMActivateInstalled (same, but completion is limited to installed plugins) 106 | 107 | " find plugins by name github url or script id and display all information 108 | VAMPluginInfo script_id or characters to match any description against 109 | 110 | " update plugins (by name or all you're using right now) - you should restart Vim afterwards: 111 | VAMUpdate vim-pi P1 P2 112 | VAMUpdateActivated 113 | 114 | VAMListActivated 115 | VAMUninstallNotLoadedPlugins P1 P2 116 | 117 | " [UE]: unless the directory exists 118 | " P1 P2 represents arbitrary plugin names, use to complete in .vim files 119 | 120 | " If you need a plugin to be activated immediately. Example: You require a command in your .vimrc: 121 | call vam#ActivateAddons(['P1', P2'], {'force_loading_plugins_now': 1}) 122 | " (should we create a special command for this?) 123 | ``` 124 | Also: Of course VAM allows using subdirectories of repositories as runtimepath. 125 | Eg See vim-pi-patching. 126 | 127 | ## lazily loading plugins / tag plugins by topic / pass dictionaries for adding arbitrary options 128 | You can tag plugins and load them lazily. If a plugin provides a 'au 129 | BufRead,BufNewFile set ft..' like code fource buftype by adding a key such as 130 | {'exec':'set ft=tss'} for instance 131 | 132 | ```vim 133 | let scripts = [] 134 | call add(scripts, {'names': ['plugin_for_c_1', 'plugin_for_c_2'], 'tag': 'c-dev'}) 135 | call add(scripts, {'name': 'plugin_ruby', 'tag': 'ruby-dev'}) 136 | " must activate by filename because .pov filetype is known after the script 137 | " script-povray got activated 138 | call add(scripts, {'name': 'script-povray', 'filename_regex':'\.pov$'}) 139 | " for others ft_regex can be used: 140 | call add(scripts, {'name': 'script-php', 'ft_regex':'^\.php$'}) 141 | 142 | " always activate this color scheme, and set runtimepath 143 | call add(scripts, {'name': 'github:daylerees/colour-schemes', 'addon-info': {'runtimepath': 'vim'} }) 144 | 145 | " just activate a rtp (also works at runtime with all hooks such as sourcing ftdetect/*.vim files) 146 | call add(scripts, {'activate_this_rtp': 'absolute-rtp-path'}) 147 | 148 | 149 | " tell VAM about all scripts, and immediately activate plugins having the c-dev tag: 150 | call vam#Scripts(scripts, {'tag_regex': 'c-dev'}) 151 | 152 | " activate all tagged scripts immediately 153 | call vam#Scripts([], {'tag_regex': '.*'}) 154 | ``` 155 | Instead of adding dictionaries to a local list you can make VAM read them from a file 156 | as show at [vim-wiki's plugin management article](http://vim-wiki.mawercer.de/wiki/topic/vim%20plugin%20managment.html) 157 | 158 | Having a declarative list of plugins you might be using allows 159 | * implementing a garbage collector 160 | * implementing third party update/checkout scripts which run checkout in parallel 161 | * reusing such interface by other plugin managers 162 | 163 | ## How does VAM know about dependencies? 164 | Plugins ship with addon-info.json files listing the dependencies as names 165 | (eventually with source location). Those who don't get patched by vim-pi. 166 | 167 | Only mandatory dependencies should be forced this way. Optional dependencies 168 | should still be installed/activated by you. 169 | 170 | 171 | ## emulating vundle 172 | NOTE: VAM is declarative. Thus Bundle behavel like VAMActivate: 173 | 1) checkout plugin unless directory exists 174 | 2) activate it 175 | Thus there is no reason to run BundleInstall or such (what for anyway?) 176 | 177 | ```vim 178 | set rtp+=~/.vim/bundle/vim-addon-manager/ 179 | call vundle#rc() 180 | Bundle fugitive 181 | VAMActivate by-name-and-pull-depenedencies 182 | ``` 183 | 184 | Emulation is not complete yet. If you want us to complete it (eg implement the 185 | second {rtp: ..} create a github issue. Its obsolete, because vim-pi is very 186 | likely to know about it if you install by name. 187 | 188 | ## learn more 189 | - by skimming this README.md file 190 | - by looking at headlines at [doc/\*getting-started.txt](https://raw.github.com/MarcWeber/vim-addon-manager/master/doc/vim-addon-manager-getting-started.txt). 191 | (Note: this is best read in Vim with :set ft=help) 192 | 193 | ## FEATURES 194 | - Declarative: The behaviour of Vim is determined by your .vimrc only. [1] 195 | - Automatic runtimepath handling: install/ update/ use manually installed addons 196 | on startup or load them lazily as needed when you feel that way. [3] 197 | - Builtin dependency management. [2] 198 | - Based on a [pool](http://vam.mawercer.de) of addons which is 199 | maintained by the community. This allows warning you if you’re going to 200 | install outdated packages. Of course you can opt-out and use your own pool 201 | easily. 202 | - Sources from www.vim.org, git, mercurial, subversion, bazaar, darcs, [...] 203 | - Addon name completion in .vim files and :(Update|Activate)Addons commands. 204 | - Short syntax for github repos: `github:name/repo`. 205 | - Optionally writes update logs. 206 | - Cares about [windows users](http://mawercer.de/~marc/vam/index.php). 207 | - Addon info by name or script id (:AddonInfo). 208 | - Tries to preserve user modifications by using diff/patch tools on unix like 209 | environments (for non-version-controlled sources). 210 | - 100 % VimL (is this really that good?..) 211 | - The VimL code which gets started each time is contained in one file: vam.vim 212 | (700 loc). Everything else has carefully been put into additional supporting 213 | files. 214 | 215 | [1]: assuming you always use latest versions 216 | 217 | [2]: this serves the community by making it easy to reuse other’s code. 218 | Implemented by a addon-info.json file and patchinfo database for addons 219 | without VAM support. 220 | 221 | [3]: Yes — there are some special cases where it does not work correctly because 222 | some autocommands don’t get triggered 223 | 224 | [4]: Plugin authors should use addon-info file instead. patchinfo.vim is for 225 | addons not supporting VAM. 226 | 227 | ## Let me see all docs! 228 | Here you go: 229 | 230 | - [GETTING STARTED](https://raw.github.com/MarcWeber/vim-addon-manager/master/doc/vim-addon-manager-getting-started.txt) 231 | - [additional docs](https://raw.github.com/MarcWeber/vim-addon-manager/master/doc/vim-addon-manager-additional-documentation.txt) 232 | 233 | ## BUGS 234 | It’ll never have nice install progress bars — because the “progress” is not very 235 | well known because addons can be installed at any time — and additional 236 | dependencies may be encountered. 237 | 238 | If you want to be able to rollback you have to use git submodules yourself or 239 | find a different solution — because VAM also supports other VCS and installing 240 | from archives. We have implemented experiemntal setup, but because VAM may add 241 | additional files such as addon-info.json in some cases repositories look dirty 242 | usually. 243 | 244 | VAM does not support parallel installation yet (Like NeoBundle) - we think 245 | dependencies are more important. If you feel strongly about this create a issue. 246 | This would require rewriting quite a lot of code. 247 | 248 | Each call of VAMActivate takes about 1ms - if that's too much pass many plugin 249 | names at once. 250 | 251 | ## FUTURE 252 | VAM suffers from installing one plugin after the other which is slowing down. 253 | It should install in parallel/in the background. 254 | Some plugins like YouCompleteMe might even depend on the Python interpreter to 255 | be used (conda env) 256 | 257 | Not all people use VAM. 258 | VAMActivate can be used on demand. 259 | So how should this all move into the future? 260 | using neovim's async/await? or sync'd install 261 | allowing users to 'plug' or whatever install a plugin? 262 | 263 | install_activate_plugin_wait('github:foo/bar') 264 | install_activate_plugin('github:foo/bar', clb) 265 | user could choose whether he wants to be asked before getting new code and 266 | activate it - there could be security issues. 267 | 268 | Then people could use the plugin manager they want and locations they want 269 | and they could rewrtite foo/bar by baz/bar if there is need ? 270 | 271 | [... TODO ... ] 272 | 273 | A totally different approach would be a cross language/cross platform package 274 | manager with a declarative dependency file {"requires": [...]} like. 275 | Then an external tool could be taking care of. 276 | Then updating all would be like conda .. 277 | 278 | This would also allow linux systems to package everything automatically. 279 | So I somewhat like this idea 280 | 281 | ## Related work 282 | 283 | [vim-wiki's list of alternatives](http://vim-wiki.mawercer.de/wiki/topic/vim%20plugin%20managment.html) 284 | 285 | [debian’s vim plugin manager](http://packages.debian.org/sid/vim-addon-manager) 286 | The author (Jamessan) is fine with this project sharing the same name. 287 | 288 | [vundle](http://github.com/gmarik/Vundle.vim) Referencing it here because 289 | gmarik taught us how important it is to have both: A simple nice user interface 290 | and a short descriptive, complete README.md - Other managers see link above. 291 | -------------------------------------------------------------------------------- /addon-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "vim-addon-manager", 3 | "version" : "0.0", 4 | "author" : "Marc Weber ", 5 | "maintainer" : "Marc Weber ", 6 | "repository" : {"type": "git", "url": "https://github.com/MarcWeber/vim-addon-manager.git"}, 7 | "dependencies" : {}, 8 | "description" : "Manage vim plugins" 9 | } 10 | -------------------------------------------------------------------------------- /autoload/sample_vimrc_for_new_users.vim: -------------------------------------------------------------------------------- 1 | " minimal useful unbiased recommended .vimrc: 2 | " http://vim.wikia.com/wiki/Example_vimrc 3 | " or 4 | " :h vimrc_example.vim 5 | " 6 | " more useful info for new users: 7 | " http://vim.wikia.com/wiki/Category:Getting_started 8 | 9 | 10 | " kept recoding the same things over and over again. 11 | " So I write what I think is useful to you here. 12 | " 13 | " How to use? 14 | " Skim it - then copy paste the lines you like into your personal .vimrc file. 15 | " Its a rough guide giving you hints about what can be done rather than 16 | " what should be done 17 | 18 | 19 | " these markers { { { enable folding. see modeline at the bottom 20 | " You don't have to close them if you append the folding level. 21 | 22 | " set nocompatible should be default. This is done automatically if a .vimrc 23 | " or .gvimrc exists. Explicitly listing it here for completness. 24 | set nocompatible 25 | 26 | " for YouCompleteMe etc 27 | set encoding=utf-8 28 | 29 | " You should have this in your .vimrc: 30 | " (The {{ { starts a fold. 31 | " type zR to open all or za to open one fold only 32 | " zM folds everything again 33 | 34 | " enable filetype, plugin and syntax support {{{1 35 | " This means 36 | filetype indent plugin on | syn on 37 | 38 | " allow buffers to go in background without saving etc. 39 | set hidden 40 | 41 | " useful mappings: {{{1 42 | 43 | " open this file fast so that you can take notes below the line "finish" and 44 | " add more mappings: 45 | noremap \c :e ~/.vimrc 46 | 47 | " :w! is always bad to type. So create your own mapping for it. Example: 48 | noremap \w :w! 49 | 50 | " you may want to remove the if you have many files opened 51 | " This switches buffers 52 | " Note: :b foo will also select some-foo-text.txt file if it was opened :) 53 | noremap \b :b 54 | 55 | " being able to open the help fast is always fine. 56 | " note that you can use tab / shift -tab to select next / previous match 57 | " also glob patterns are allowed. Eg :h com*func 58 | " will show all matches at once. 59 | noremap \h :h 60 | 61 | " open one file, use tab and shift-tab again if there are multiple files 62 | " after using this mapping the command line should have started showing 63 | " :e **/* . Eg use :e **/*fil*txt to match file.txt in any subdir 64 | noremap \e :e**/* 65 | 66 | " open multiple files at once. Eg add .txt to open all .txt files 67 | " Using :bn @: you can cycle them all 68 | " :bn = :bnext @: repeats last command 69 | noremap \n :n**/* 70 | 71 | " open a filetype file. Those files are sourced by Vim to setup filetype 72 | " specific mappings. Eg use it for defining commands / mappings which apply 73 | " for python or perl files only 74 | " eg command -buffer DoStuff call DoStuff() 75 | " or map \dostuff :call DoStuff() 76 | noremap \ft :exec 'e ~/.vim/after/ftplugin/'.&filetype.'_you.vim' 77 | 78 | " when pasting code you may want to enable paste option so that Vim doesn't 79 | " treat the pasted text like typed text. Typed text casues vim to to repeating 80 | " comments and change indentation - when pasting you don't want this. 81 | noremap \ip :set invpasteecho &paste ? 'pasting is on' : 'pasting is off' 82 | 83 | " for windows: make backspace work. Doesn't hurt on linux. This should be 84 | " default! 85 | set bs=indent,eol,start 86 | " (deprecated:) set bs=2 87 | 88 | " foreign plugin vim-addon-manager {{{1 89 | 90 | " commenting this code because I assume you already have it in your ~/.vimrc: 91 | 92 | " tell Vim where to find the autoload function: 93 | " set runtimepath+=~/vim-plugins/vim-addon-manager 94 | 95 | " Activate the addons called 'JSON', 'name1', 'name2' 96 | " This adds them to runtimepath and ensures that plugin/* and after/plugin/* 97 | " files are sourced. JSON is not that important. It highlights the 98 | " NAME-addon-info.txt files. Probably you want to substitude nameN by plugins 99 | " such as snipMate, tlib etc. 100 | 101 | " call vam#ActivateAddons(['JSON',"tmru","matchit.zip","vim-dev-plugin","name1","name2"]) 102 | " JSON: syntax highlighting for the *info* files 103 | " tmru: list of most recentely used files 104 | " matchit.zip: make % (match to mathing items such as opening closing parenthesis) even smarter 105 | " vim-dev-plugin: smarter omni completion and goto autoload function for VimL scripts 106 | 107 | " foreign plugins tlib {{{1 108 | 109 | " this is from tlib. I highly recommend having a look at that library. 110 | " Eg its plugin tmru (most recently used files) provides the command 111 | " TRecentlyUsedFiles you can map to easily: 112 | noremap \r :TRecentlyUsedFiles 113 | " the most simple alternative built into vim is the :oldfiles command 114 | " however it may not work that wel if you use many vim instances at the same 115 | " time 116 | 117 | " simple glob open based on tlib's List function (similar to TCommand or fuzzy 118 | " plugin etc) 119 | 120 | " don't ask me why glob() from Vim is that slow .. :( 121 | " one reason is that it doesn't follow symlinks (unless you pass -L to find) 122 | fun! FastGlob(glob) 123 | let g = '^'.a:glob.'$' 124 | let replace = {'**': '.*','*': '[^/\\]*','.': '\.'} 125 | let g = substitute(g, '\(\*\*\|\*\|\.\)', '\='.string(replace).'[submatch(1)]','g') 126 | let cmd = 'find | grep -e '.shellescape(g) 127 | " let exclude = a:exclude_pattern == ''? '' : ' | grep -v -e '.shellescape(a:exclude_pattern) 128 | " let cmd .= exclude 129 | return system(cmd) 130 | endfun 131 | noremap \go :exec 'e '. fnameescape(tlib#input#List('s','select file', split(FastGlob(input('glob pattern, curr dir:','**/*')),"\n") )) 132 | 133 | " sometimes when using tags the list is too long. filtering it by library or 134 | " such can easily be achived by such code: {{{' 135 | fun! SelectTag(regex) 136 | let tag = eval(tlib#input#List('s','select tag', map(taglist(a:regex), 'string([v:val.kind, v:val.filename, v:val.cmd])'))) 137 | exec 'e '.fnameescape(tag[1]) 138 | exec tag[2] 139 | endfun 140 | command!-nargs=1 TJump call SelectTag() 141 | 142 | " }}} 143 | " select a buffer from list 144 | command! SelectBuf exec 'b '.matchstr( tlib#input#List('s', 'select buffer', tlib#cmd#OutputAsList('ls')), '^\s*\zs\d\+\ze') 145 | noremap! \sb :SelectBuf 146 | 147 | " dummy func to enabling you to load this file after adding the top level {{{1 148 | " dir to runtimepath using :set runtimpeth+=ROOT 149 | fun! sample_vimrc_for_new_users#Load() 150 | " no code. If this function is called this file is sourced 151 | " As alternative this can be used: 152 | " runtime autoload/sample_vimrc_for_new_users.vim 153 | endfun 154 | 155 | " create directory for files before Vim tries writing them: 156 | augroup CREATE_MISSING_DIR_ON_BUF_WRITE 157 | au! 158 | autocmd BufWritePre * if !isdirectory(expand('%:h', 1)) | call mkdir(expand('%:h', 1),'p') | endif 159 | augroup end 160 | 161 | finish 162 | Vim is ignoring this text after finish. 163 | 164 | DON'T MISS THESE {{{1 165 | 166 | Each vim boolean setting can be off or on. You can invert by invNAME. Example: 167 | enable setting: :set swap 168 | disable setting: :set noswap 169 | toggle setting: :set invswap 170 | Settings can be found easily by :h '*chars*' 171 | 172 | == typing characters which are not on your keyboard == 173 | digraphs: type chars which are untypable, for example: 174 | c-k =e : types € (see :h digraph) 175 | 176 | == completions == 177 | c-x c-f : file completion 178 | c-x c-l : line completion 179 | c-n : kind of keyword completion - completes everything found in all opened buffers. 180 | So maybe even consider openining many files uing :n **/*.ext 181 | (if you're a nerd get vim-addon-completion and use the camel case buffer completion found in there) 182 | all: :h ins-completion 183 | 184 | == most important movement keys == 185 | hjkl - as experienced user you'll notice that you don't use them that often. 186 | So you should at least know about the following and have a look at :h motion.txt 187 | and create your own by mappings 188 | 189 | how to reach insert mode: 190 | | is cursor location 191 | 192 | O 193 | I i|a A 194 | o 195 | 196 | important movements and their relation: 197 | 198 | gg 199 | H (top line window) 200 | 201 | - k 202 | 0 h | l $ M 203 | j 204 | 205 | L 206 | G 207 | 208 | 209 | movements: 210 | 211 | use search / ? to place cursor. Remember that typing a word is not always the 212 | most efficient way. Eg try /ys t this. And you'll get excatly 213 | one match in the whole document. 214 | 215 | c-o c-i : jump list history 216 | 217 | g; : where did I edit last (current buffer) - you can repeat it 218 | 219 | Learn about w vs W. Try it CURSOR_HERE.then.type.it (same for e,E) 220 | 221 | f,F,t,T : move to char or just before it forward / backward current line. (A 222 | must) 223 | 224 | be faster: delete then goto insert mode: 225 | C: deletes till end of line 226 | c a-movement-action: deletes characters visited while moving 227 | 228 | more movements: 229 | (, ): move by sentence 230 | [[, ]], {, } : more blockwise movements which are often helpful 231 | ... 232 | 233 | This script may also have its usage: Jump to charater location fast: 234 | http://www.vim.org/scripts/script.php?script_id=3437 235 | 236 | How to get O(1) access to your files you're editing at the moment {{{1 237 | 238 | Yes :b name is fine, cause it matches HeHiname.ext. Still too much to type. 239 | Usually you work with only a set of buffers. Open them in tabs. Add something 240 | like this to your .vimrc so that you can switch buffers using m-1 m-2 etc: 241 | 242 | " m-X key jump to tab X 243 | for i in range(1,8) 244 | exec 'map '.i.'gt' 245 | endfor 246 | 247 | " faster novigation in windows: 248 | for i in ["i","j","k","l","q"] 249 | exec 'noremap '.i 250 | endfor 251 | 252 | The ways to optimize code navigation are endless. Watch yourself. 253 | If you think something takes too long - optimize it. 254 | 255 | Bindings in command line are shitty? 256 | yes - remap them - or use "emacscommandline" plugin which does this for you. 257 | or use q: (normal mode) or c-f in commandline 258 | 259 | 260 | 261 | == indentation, spaces, tabs == 262 | Tab: default behavior of vim is: add &tabstop spaces unless expandtab is not 263 | set. You can always insert real tabs by . However tabstob should be 264 | treated as display setting. Use sw setting and c-t, c-d instead. 265 | 266 | c-t: increase indentation 267 | c-d: decrease indentation 268 | c-f: auto indent current line (requires indentation setup) 269 | :setlocal sw=4: use 4 spacse for indentation 270 | :setlocal expandtab: expand tab to spaces (default) 271 | >3j . . increase indentation of 3 lines and repeat two times 272 | :setlocal tabstop: a tab is viewed as how many spaces in a file? 273 | 274 | :set list : displays spaces and tabs 275 | 276 | project specific settings: see vim-addon-local-vimrc 277 | 278 | 279 | 280 | MY COMMENTS ABOUT VIM AND ITS USAGE {{{1 281 | ======================================== 282 | 283 | 284 | I like Vim cause its that fast and easy to extend. 285 | I also learned that VimL is a nice language. It was ahead of time when it 286 | was invented. However today it can be considered limiting in various ways. 287 | Eg you don't want to write parsers in it. Its too slow for those use cases. 288 | Yet its powerful enough to make everydays work easier - even competitive to 289 | bloated IDEs. Example plugins you should know about: 290 | 291 | - tlib library (and all of Tom's plugins 292 | 293 | - snipmate (or xptemplate): Insert text snippets. Its not only about speed. 294 | Snippets are a nice way to organize your memos. 295 | 296 | - matchit: match everything, eg matching xml tags, fun -> return -> endfun 297 | statements (same for for, while etc) 298 | 299 | - The_NERD_tree: directory tree in Vim. You can easily hit the limits of 300 | Vim/VimL here whene opening large directories it takes a way too long :-( 301 | Yet you may find it useful. 302 | 303 | - commenting plugins 304 | 305 | - vim-addon-local-vimrc (project specific settings) 306 | 307 | - ... (You want a plugin added here?) 308 | 309 | What you should know about: 310 | - :h motion.txt (skim it once) 311 | - Vim keeps history as tree. (g+ g- mappings) 312 | - :h quickfix (load compiler output into an error list) 313 | - how to use tags - because this (sometimes fuzzzy) thing 314 | is still fast to setup and works very well for many use cases. 315 | - Vim can assist you in spelling 316 | 317 | 318 | most important mappings / commands: 319 | g; = jump back in list of last edited locations 320 | = jump back and forth in location list 321 | = toggle buffers 322 | c-w then one of v s w q t h j k l (z) : move cursor, split windows, quit buffer 323 | 324 | q:, ?:, /: : Open mini buffer to browse or edit command or search history 325 | You can open this from command line using ! 326 | ... I could keep writing for 2 hours now at least. 327 | 328 | 329 | I'm also aware of Emacs emulating most important editing features of Vim. 330 | Eg there is the vimpulse plugin for Emacs. So I know that I should use the 331 | tool which is best for a given task. This can be Vim for coding. But for debugging 332 | you may prefer Emacs or a bloated IDE such as Eclipse, Netbeans, IDEA (which all have 333 | vim like keybindgs!). 334 | 335 | What are the limitations causing greatest impact to software developers using Vim? 336 | - no async communication support unless you depend on client-server feature 337 | which requires X. This means Vim will hang until an operation has finished 338 | when interfacing with external tools. 339 | Impact: People tried writing debugger features. But all solutions are kind 340 | of doomed unless Vim gets a nice async communication interface. 341 | 342 | Possible known ways to work around it? 343 | 344 | - vim-addon-async (depends on client-server but works very well) 345 | 346 | - implement windows version of this patch 347 | http://github.com/bartman/vim.git (which still can be improved a lot) 348 | and make it it poll file handlers when not typing. Implement a shell 349 | like interface. doc: http://github.com/bartman/vim/wiki/_pages 350 | 351 | - There is a patch which let's you start a shell in Vim. I don't think 352 | it got updated (which is linux only) 353 | http://www.wana.at/vimshell/ 354 | (Maybe cygwin or such ?) - I never tried it. 355 | 356 | - vimshell (www.vim.org). You have to get a dell or such. I think this 357 | could satisfy you. 358 | (vcs: http://github.com/Shougo/vimshell) 359 | 360 | - screen (see other mail) 361 | c-a S splits the window 362 | c-a tab switches focus 363 | 364 | if you run interpreter this way: tcl | tee log 365 | 366 | you may have a chance getting errors into quickfix or such 367 | 368 | (requires cygwin or such - I never tried it on Windows ?) 369 | 370 | use Emacs and vimpulse (I hate to say it) 371 | 372 | 373 | - Many coding helpers should not have been written in VimL. They should have 374 | been written in a proper language so that all open source editors can 375 | benefit from their features. An Example is the broken PHP completion which 376 | doesn't even complete static member functions like A::foo(); 377 | 378 | Examples how this can be done better: 379 | * vim-addon-scion (Haskell development helper app is written in Haskell. Vim 380 | is only a coding editor backend) 381 | * codefellow (same for Scala). 382 | * eclim (Eclipse features exposed to Vim And Vim backend implementation) 383 | 384 | Vim can be one of the fastest editors you'll start to love (and hate for some 385 | of the shortcomings) 386 | 387 | 388 | " additional resources - how to continue learning about Vim? {{{1 389 | The way to start learning Vim: 390 | vimtutor 391 | 392 | additional advanced info: 393 | http://github.com/dahu/LearnVim 394 | 395 | Vim Wiki: 396 | http://vim.wikia.com 397 | Checkout its sample .vimrc: http://vim.wikia.com/wiki/Example_vimrc 398 | 399 | join #vim (irc.freenode.net) 400 | 401 | join the mailinglist (www.vim.org -> community) 402 | 403 | Tell me to add additional resources here 404 | 405 | 406 | " this modeline tells vim to enable folding {{{1 407 | -------------------------------------------------------------------------------- /autoload/scriptmanager.vim: -------------------------------------------------------------------------------- 1 | fun! s:UpdateVimrc() 2 | " This codes renames old name scriptmanager#Activate to vam#ActivateAddons 3 | " for you. I'd like to ask the user. But not all are using shells so the 4 | " question can get lost. 5 | let cmd='%s@scriptmanager#Activate(@vam#ActivateAddons(@g | %s/\/vim_addon_manager/g' 6 | let files = filter([expand("~/.vimrc", 1), expand('~/_vimrc', 1)], 'filewritable(v:val)==1') 7 | if len(files) == 1 8 | call vam#Log( "scriptmanager#Activate and g:vim_script_manager were renamed to vam#ActivateAddons and g:vim_addon_manager.") 9 | if confirm("Replace given names in ".files[0]."?", "&No\n&Yes")==2 10 | exec 'e '.fnameescape(files[0]) 11 | exec cmd | w 12 | endif 13 | else 14 | echo "open your the file calling scriptmanager#Activate and run: ".cmd." . Rename happened for consistency" 15 | endif 16 | endfun 17 | fun! scriptmanager#Activate(...) abort 18 | " historical. Call vam#ActivateAddons instead 19 | augroup scriptmanagerRebrand 20 | autocmd! 21 | autocmd VimEnter * call s:UpdateVimrc() 22 | augroup END 23 | if exists('g:vim_script_manager') 24 | let g:vim_addon_manager=g:vim_script_manager 25 | endif 26 | call call(function('vam#ActivateAddons'),a:000) 27 | endfun 28 | 29 | fun! scriptmanager#DefineAndBind(...) 30 | echoe "fix your code!, scriptmanager#DefineAndBind was renamed to vam#DefineAndBind(. Drop this function to find the usage location faster!" 31 | return call(function('vam#DefineAndBind'),a:000) 32 | endfun 33 | 34 | " vim: sts=2 et sw=2 35 | -------------------------------------------------------------------------------- /autoload/vam.vim: -------------------------------------------------------------------------------- 1 | " see README 2 | 3 | " this file contains code which is always used 4 | " code which is used for installing / updating etc should go into vam/install.vim 5 | 6 | " if people use VAM they also want nocompatible 7 | if &compatible | set nocompatible | endif 8 | 9 | 10 | " don't need a plugin. If you want to use this plugin you call Activate once 11 | " anyway 12 | fun! vam#DefineAndBind(local,global,default) 13 | return 'if !exists('.string(a:global).') | let '.a:global.' = '.a:default.' | endif | let '.a:local.' = '.a:global 14 | endfun 15 | 16 | 17 | " assign g:os 18 | for os in split('amiga beos dos32 dos16 mac macunix os2 qnx unix vms win16 win32 win64 win32unix', ' ') 19 | if has(os) | let g:os = os | break | endif 20 | endfor 21 | let g:is_win = g:os[:2] == 'win' 22 | 23 | exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}') 24 | let s:c.auto_install = get(s:c,'auto_install', 1) 25 | " repository locations: 26 | let s:c.plugin_sources = get(s:c,'plugin_sources', {}) 27 | " if a plugin has an item here the dict value contents will be written as plugin info file 28 | " Note: VAM itself may be added after definition of vam#PluginDirFromName 29 | " function 30 | let s:c.activated_plugins = get(s:c,'activated_plugins', {}) 31 | 32 | let s:c.create_addon_info_handlers = get(s:c, 'create_addon_info_handlers', 1) 33 | 34 | " Users may install VAM system wide. In that case s:d is not writeable. 35 | let s:d = expand(':h:h:h', 1) 36 | let s:c.plugin_root_dir = get(s:c, 'plugin_root_dir', filewritable(s:d) ? s:d : '~/.vim/vim-addons') 37 | unlet s:d 38 | 39 | if s:c.plugin_root_dir is# expand('~', 1) 40 | echohl Error 41 | echomsg "VAM: Don't install VAM into ~/.vim the normal way. See docs -> SetupVAM function. Put it int ~/.vim/vim-addons/vim-addon-manager for example." 42 | echohl None 43 | finish 44 | endif 45 | 46 | " ensure we have absolute paths (windows doesn't like ~/.. ) : 47 | let s:c.plugin_root_dir = expand(fnameescape(s:c.plugin_root_dir), 1) 48 | 49 | let s:c.additional_addon_dirs = get(s:c, 'additional_addon_dirs', []) 50 | call map(s:c.additional_addon_dirs, 'expand(fnameescape(v:val), 1)') 51 | 52 | let s:c.dont_source = get(s:c, 'dont_source', 0) 53 | let s:c.plugin_dir_by_name = get(s:c, 'plugin_dir_by_name', 'vam#DefaultPluginDirFromName') 54 | let s:c.addon_completion_lhs = get(s:c, 'addon_completion_lhs', '') 55 | let s:c.debug_activation = get(s:c, 'debug_activation', 0) 56 | let s:c.pool_item_check_fun = get(s:c, 'pool_item_check_fun', 'none') 57 | let s:c.source_missing_files = get(s:c, 'source_missing_files', &loadplugins) 58 | let s:c.activate_on = get(s:c, 'activate_on', {'tag': [], 'ft_regex': [], 'filename_regex': []}) 59 | let s:c.lazy_loading_au_commands = get(s:c, 'lazy_loading_au_commands', 1) 60 | 61 | " example: vam#ForceUsersAfterDirectoriesToBeLast 62 | let s:c.rtp_list_hook = get(s:c, 'rtp_list_hook', '') 63 | 64 | 65 | " experimental: will be documented when its tested 66 | " don't echo lines, add them to a buffer to prevent those nasty "Press Enter" 67 | " to show more requests by Vim 68 | " TODO: move log code into other file (such as utils.vim) because its not used on each startup 69 | " TODO: think about autowriting it 70 | let s:c.log_to_buf = get(s:c, 'log_to_buf', 0) 71 | let s:c.log_buffer_name = get(s:c, 'log_buffer_name', s:c.plugin_root_dir.'/VAM_LOG.txt') 72 | 73 | " More options that are used for plugins’ installation are listed in 74 | " autoload/vam/install.vim 75 | 76 | if g:is_win && has_key(s:c, 'binary_utils') 77 | " if binary-utils path exists then add it to PATH 78 | let s:c.binary_utils = get(s:c,'binary_utils', tr(s:c.plugin_root_dir, '/', '\').'\binary-utils') 79 | let s:c.binary_utils_bin = s:c.binary_utils.'\dist\bin' 80 | if isdirectory(s:c.binary_utils) 81 | let $PATH=$PATH.';'.s:c.binary_utils_bin 82 | endif 83 | endif 84 | 85 | " additional plugin sources should go into your .vimrc or into the repository 86 | " called "vim-pi" referenced here: 87 | if executable('git') 88 | let s:c.plugin_sources['vim-pi'] = {'type' : 'git', 'url': 'https://bitbucket.org/vimcommunity/vim-pi'} 89 | else 90 | let s:c.plugin_sources['vim-pi'] = {'type' : 'archive', 'url': 'https://bitbucket.org/vimcommunity/vim-pi/get/master.tar.bz2', 'archive_name': 'vim-pi.tar.gz'} 91 | endif 92 | 93 | if s:c.create_addon_info_handlers 94 | augroup VAM_addon_info_handlers 95 | autocmd! 96 | autocmd BufRead,BufNewFile *-addon-info.txt,addon-info.json 97 | \ setlocal ft=addon-info 98 | \ | setlocal syntax=json 99 | \ | syn match Error "^\s*'" 100 | autocmd BufWritePost *-addon-info.txt,addon-info.json call vam#ReadAddonInfo(expand('%', 1)) 101 | augroup END 102 | endif 103 | 104 | fun! vam#VerifyIsJSON(s) 105 | " You must allow single-quoted strings in order for writefile([string()]) that 106 | " adds missing addon information to work 107 | let scalarless_body = substitute(a:s, '\v\"%(\\.|[^"\\])*\"|\''%(\''{2}|[^''])*\''|true|false|null|[+-]?\d+%(\.\d+%([Ee][+-]?\d+)?)?', '', 'g') 108 | return scalarless_body !~# "[^,:{}[\\] \t]" 109 | endfun 110 | 111 | fun! vam#ForceUsersAfterDirectoriesToBeLast(list) 112 | let regex_last = '^'.escape($HOME, '/').'/[._]vim\/after$' 113 | return filter(copy(a:list), 'v:val !~ '.string(regex_last)) 114 | \ + filter(copy(a:list), 'v:val =~ '.string(regex_last)) 115 | endfun 116 | 117 | " use join so that you can break the dict into multiple lines. This makes 118 | " reading it much easier 119 | fun! vam#ReadAddonInfo(path) 120 | if !filereadable(a:path) 121 | return {} 122 | endif 123 | 124 | " don't add "b" because it'll read dos files as "\r\n" which will fail the 125 | " check and evaluate in eval. \r\n is checked out by some msys git 126 | " versions with strange settings 127 | 128 | " using eval is evil! 129 | let body = join(readfile(a:path),"") 130 | 131 | if vam#VerifyIsJSON(body) 132 | let true=1 133 | let false=0 134 | let null='' 135 | " using eval is now safe! 136 | return eval(body) 137 | else 138 | call vam#Log( "Invalid JSON in ".a:path."!") 139 | return {} 140 | endif 141 | 142 | endfun 143 | 144 | fun! vam#DefaultPluginDirFromName(name) abort 145 | " this function maps addon names to their storage location. \/: are replaced 146 | " by - (See name rewriting) 147 | let dirs = [s:c.plugin_root_dir] + s:c.additional_addon_dirs 148 | let name = substitute(a:name, '[\\/:]\+', '-', 'g') 149 | let existing = filter(copy(dirs), "isdirectory(v:val.'/'.".string(name).')') 150 | return (empty(existing) ? dirs[0] : existing[0]).'/'.name 151 | endfun 152 | fun! vam#PluginDirFromName(...) 153 | return call(s:c.plugin_dir_by_name, a:000, {}) 154 | endfun 155 | fun! vam#PluginRuntimePath(pluginDir, info) 156 | return a:pluginDir.(has_key(a:info, 'runtimepath') ? '/'. a:info.runtimepath : '') 157 | endfun 158 | 159 | " adding VAM, so that its contained in list passed to :UpdateActivatedAddons 160 | if filewritable(vam#PluginDirFromName('vim-addon-manager'))==2 161 | let s:c.activated_plugins['vim-addon-manager']=1 162 | endif 163 | 164 | " doesn't check dependencies! 165 | fun! vam#IsPluginInstalled(name) 166 | let d = vam#PluginDirFromName(a:name) 167 | 168 | " if dir exists and its not a failed download 169 | " (empty archive directory) 170 | return isdirectory(d) 171 | \ && (!isdirectory(d.'/archive') 172 | \ || !empty(glob(fnameescape(d).'/archive/*', 1))) 173 | endfun 174 | 175 | " TODO: remove this 176 | fun! vam#AddonInfo(name) 177 | throw "deprecated" 178 | " use this code instead: 179 | " vam#ReadAddonInfo(vam#AddonInfoFile(vam#PluginDirFromName(name), name)) 180 | endfun 181 | 182 | 183 | fun! vam#ActivateDependencies(opts, dependencies, name) 184 | 185 | " activate dependencies merging opts with given repository sources 186 | " sources given in opts will win 187 | call vam#ActivateAddons(keys(a:dependencies), 188 | \ extend(copy(a:opts), { 189 | \ 'plugin_sources' : extend(copy(a:dependencies), get(a:opts, 'plugin_sources',{})), 190 | \ 'requested_by' : [a:name] + get(a:opts, 'requested_by', []) 191 | \ })) 192 | endfun 193 | 194 | 195 | " opts: { 196 | " 'plugin_sources': additional sources (used when installing dependencies) 197 | " 'auto_install': when 1 overrides global setting, so you can autoinstall 198 | " trusted repositories only 199 | " } 200 | fun! vam#ActivateRecursively(list_of_scripts, ...) 201 | let opts = extend({'run_install_hooks': 1}, a:0 == 0 ? {} : a:1) 202 | 203 | for script_ in a:list_of_scripts 204 | " try to find plugin root / rtp 205 | 206 | if has_key(script_, 'activate_this_rtp') 207 | " hack: allow passing {'activate_this_rtp': 'path'} to get all the 208 | " workarounds when activating rtps after Vim has started up 209 | let name = get(script_, 'name', 'unkown, rtp: '. script_.activate_this_rtp) 210 | let rtp = script_.activate_this_rtp 211 | if index(split(&runtimepath, '\v(\\@ 0 212 | " don't readd rtp 213 | continue 214 | endif 215 | let info = vam#ReadAddonInfo(vam#AddonInfoFile(rtp, "")) 216 | call vam#ActivateDependencies(opts, get(info, 'dependencies', {}), name) 217 | 218 | let s:c.activated_plugins['rtp:'.rtp] = 1 219 | else 220 | let name = script_.name 221 | let pluginRoot = vam#PluginDirFromName(name) 222 | if has_key(s:c.activated_plugins, name) 223 | continue 224 | endif 225 | " break circular dependencies.. 226 | let s:c.activated_plugins[name] = 0 227 | 228 | let infoFile = vam#AddonInfoFile(pluginRoot, name) 229 | if !filereadable(infoFile) && !vam#IsPluginInstalled(name) 230 | if empty(vam#install#Install([script_], opts)) 231 | unlet s:c.activated_plugins[name] 232 | continue 233 | endif 234 | endif 235 | let info = vam#ReadAddonInfo(infoFile) 236 | call vam#ActivateDependencies(opts, get(info, 'dependencies', {}), name) 237 | 238 | let s:c.activated_plugins[name] = 1 239 | " source plugin/* files ? 240 | let rtp = vam#PluginRuntimePath(pluginRoot, info) 241 | endif 242 | 243 | call add(opts.new_runtime_paths, rtp) 244 | if (has_key(script_, 'exec')) 245 | call add(opts.execs, script_.exec) 246 | endif 247 | 248 | if s:c.debug_activation 249 | " activation takes place later (-> new_runtime_paths), but messages will be in order 250 | " XXX Lengths of “as it was requested by” and “which was requested by” 251 | " match 252 | call vam#Log('Will activate '.name.(empty(get(opts, 'requested_by'))? 253 | \ (' as it was specified by user.'): 254 | \ ("\n as it was requested by ". 255 | \ join(opts.requested_by, "\n which was requested by ").'.'))) 256 | endif 257 | endfor 258 | endfun 259 | 260 | fun! s:GetAuGroups() 261 | redir => aus 262 | silent autocmd VimEnter,BufEnter,TabEnter,BufWinEnter,WinEnter,GUIEnter 263 | redir END 264 | let augs = {} 265 | for [group, event] in map(filter(split(aus, "\n"), 266 | \ 'v:val=~#''\v^\w+\s+\w+$'''), 267 | \ 'split(v:val)') 268 | if has_key(augs, group) 269 | call add(augs[group], event) 270 | else 271 | let augs[group] = [event] 272 | endif 273 | endfor 274 | return augs 275 | endfun 276 | 277 | fun! s:ResetVars(buf) 278 | let filetype = getbufvar(a:buf, '&filetype') 279 | let syntax = getbufvar(a:buf, '&syntax') 280 | call setbufvar(a:buf, '&filetype', filetype) 281 | if filetype isnot# syntax 282 | call setbufvar(a:buf, '&syntax', syntax) 283 | endif 284 | endfun 285 | 286 | " turn name into {'name': ...} 287 | " turn {'names': ...} into {'name': name1}, {'name': name2} 288 | fun! vam#PreprocessScriptIdentifier(list, opts) 289 | let r = [] 290 | " turn name into dictionary 291 | for x in a:list 292 | " 1 is string 293 | if type(x) == 1 294 | call add(r, {'name': x}) 295 | elseif has_key(x, 'names') && a:opts.rewrite_names 296 | for n in x.names 297 | let y = extend({}, x) 298 | let y.name = n 299 | call remove(y, 'names') 300 | call add(r, y) 301 | endfor 302 | else 303 | call add(r, x) 304 | endif 305 | unlet x 306 | endfor 307 | 308 | return r 309 | 310 | " Merging with the pool will be done in install.vim because that's only 311 | " sourced when installations take place 312 | " only be loaded when installations take place 313 | endf 314 | 315 | fun! vam#AddRuntimePath(paths) abort 316 | let rtp = split(&runtimepath, '\v(\\@:h').'/.vim-scripts', " {'tag_regex':'.*'}) 497 | " 498 | " call vam#ActivateFromFile([dict1, dict2]) 499 | " 500 | " Sample contents of a file: 501 | " {'name': 'syntastic', 'on_ft': '\.c$"} 502 | " {'name': 'povray', 'on_name': '.pov$'} 503 | " {'name': 'snippets', 'tag': 'java ruby'} 504 | fun! vam#Scripts(scripts, opts) abort 505 | let activate = [] 506 | let keys_ = keys(s:c.activate_on) 507 | let scripts = (type(a:scripts) == type([])) ? a:scripts : ( get(a:opts, "optional_file", 0) && !file_readable(a:scripts) ? [] : map(filter(readfile(a:scripts), 'v:val !~ "#"'), 'eval(v:val)')) 508 | " filter expr - is eval evil ? You trust code anyway 509 | call filter(scripts, 'type(v:val) != 4 || !has_key(v:val, "expr") || eval(v:val["expr"])') 510 | let scripts = vam#PreprocessScriptIdentifier(scripts, {'rewrite_names': 0}) 511 | for x in scripts 512 | for k in keys_ 513 | if has_key(x, k) 514 | call add(s:c.activate_on[k], x) 515 | let added = 1 516 | endif 517 | endfor 518 | if exists('added') 519 | unlet added 520 | else 521 | call add(activate, x) 522 | endif 523 | endfor 524 | 525 | if has_key(a:opts, 'tag_regex') 526 | call extend(activate, filter(copy(s:c.activate_on.tag), 'v:val.tag =~ '.string(a:opts.tag_regex))) 527 | endif 528 | call vam#ActivateAddons(activate, a:opts) 529 | endfun 530 | 531 | fun! vam#DisplayAddonInfoLines(name, repository) 532 | let name = a:name 533 | let repository = a:repository 534 | let lines = [] 535 | call add(lines, 'Plugin: '.name.((has_key(repository, 'version'))?(' version '.repository.version):(''))) 536 | if has_key(repository, 'vim_script_nr') 537 | call add(lines, 'Script number: '.repository.vim_script_nr) 538 | call add(lines, 'Vim.org page: http://www.vim.org/scripts/script.php?script_id='.repository.vim_script_nr) 539 | endif 540 | if has_key(repository, 'homepage') 541 | call add(lines, 'Home page: '.repository.homepage) 542 | elseif repository.url =~? '^\w\+://github\.com/' 543 | call add(lines, 'Home page: https://github.com/'.substitute(repository.url, '^\V\w\+://github.com/\v([^/]+\/[^/]{-}%(\.git)?)%(\/|$)@=.*', '\1', '')) 544 | elseif repository.url =~? '^\w\+://bitbucket\.org/' 545 | call add(lines, 'Home page: https://bitbucket.org/'.substitute(repository.url, '^\V\w\+://bitbucket.org/\v([^/]+\/[^/]+).*', '\1', '')) 546 | endif 547 | call add(lines, 'Source URL: '.repository.url.' (type '.get(repository, 'type', 'archive').')',) 548 | for key in filter(keys(repository), 'v:val!~#''\vurl|vim_script_nr|version|type|homepage''') 549 | call add(lines, key.': '.string(repository[key])) 550 | endfor 551 | return lines 552 | endfun 553 | 554 | fun! vam#ShowRepositoryInfo(label, name, repository) 555 | call vam#Log('===== '.a:label.' '.repeat('=', &columns-10-len(a:label)), 'Comment') 556 | call vam#Log(join(vam#DisplayAddonInfoLines(a:name, a:repository),"\n"), 'None') 557 | endf 558 | 559 | fun! vam#DisplayAddonInfo(name, fuzzy) 560 | let name = a:name 561 | let found = 0 562 | 563 | let repository = get(g:vim_addon_manager.plugin_sources, name, {}) 564 | if !empty(repository) 565 | call vam#ShowRepositoryInfo("by-name", name, repository) 566 | let found += 1 567 | endif 568 | 569 | " try to find by script-id 570 | if empty(repository) && a:name =~ '^\d\+$' 571 | " try to find by script id 572 | let dict = filter(copy(g:vim_addon_manager.plugin_sources), '+get(v:val,"vim_script_nr",-1) == '.(+a:name)) 573 | if (empty(dict)) 574 | throw "Unknown script ".a:name 575 | else 576 | let name = keys(dict)[0] 577 | call vam#ShowRepositoryInfo("by-id", keys(dict)[0], values(dict)[0]) 578 | let found += 1 579 | endif 580 | endif 581 | 582 | if found == 0 && a:fuzzy 583 | 584 | " try to find by comparing name against anything found in the dictionary. 585 | " Thus you can also search for git://github/... 586 | 587 | " normalize .git in git(hub) names: 588 | let name = substitute(name, '\.git$','','g') 589 | 590 | for [r,k] in items(g:vim_addon_manager.plugin_sources) 591 | if string(k) =~ name 592 | call vam#ShowRepositoryInfo("by-fuzzy-search", r, k) 593 | let found += 1 594 | endif 595 | unlet r k 596 | endfor 597 | endif 598 | 599 | if found == 0 600 | echo "Invalid plugin name: " . a:name 601 | return 602 | endif 603 | 604 | endfun 605 | 606 | fun! vam#DisplayAddonsInfo(names) 607 | call vam#install#LoadPool() 608 | for name in a:names 609 | call vam#DisplayAddonInfo(name, 1) 610 | endfor 611 | endfun 612 | 613 | fun! vam#SourceFiles(fs) 614 | for file in a:fs 615 | exec 'source '.fnameescape(file) 616 | endfor 617 | endfun 618 | 619 | " FIXME won't list hidden files as well 620 | if v:version>703 || (v:version==703 && has('patch465')) 621 | fun! vam#GlobInDir(dir, glob) 622 | return glob(fnameescape(a:dir).'/'.a:glob, 1, 1) 623 | endfun 624 | else 625 | fun! vam#GlobInDir(dir, glob) 626 | return split(glob(fnameescape(a:dir).'/'.a:glob, 1), "\n") 627 | endfun 628 | endif 629 | 630 | fun! vam#GlobThenSource(dir, glob) 631 | if s:c.dont_source | return | endif 632 | call vam#SourceFiles(vam#GlobInDir(a:dir, a:glob)) 633 | endfun 634 | 635 | if s:c.source_missing_files 636 | augroup VIM_PLUGIN_MANAGER 637 | autocmd! VimEnter * nested call vam#SourceMissingPlugins() 638 | augroup END 639 | endif 640 | 641 | " taken from tlib 642 | fun! vam#OutputAsList(command) "{{{3 643 | " let lines = '' 644 | redir => lines 645 | silent! exec a:command 646 | redir END 647 | return split(lines, '\n') 648 | endfun 649 | 650 | let s:sep=fnamemodify(expand(':h', 1), ':p')[-1:] 651 | let s:sesep=escape(s:sep, '\&~') 652 | let s:resep='\V'.escape(s:sep, '\').'\+' 653 | fun! s:normpath(path) 654 | return substitute(expand(fnameescape(resolve(a:path)), 1), s:resep, s:sesep, 'g') 655 | endfun 656 | 657 | " hack: Vim sources plugin files after sourcing .vimrc 658 | " Vim doesn't source the after/plugin/*.vim files in other runtime 659 | " paths. So do this *after* plugin/* files have been sourced 660 | " 661 | " If you activate addons in plugin/*.vim files Vim will miss 662 | " plugin/*.vim files of those files - so make sure they are alle sourced 663 | " 664 | " This function takes about 1ms to execute my system 665 | fun! vam#SourceMissingPlugins() 666 | " files which should have been sourced: 667 | let fs = [] 668 | let rtp = split(&runtimepath, '\v(\\@>>>>>>>>>>> '.strftime('%c')) 703 | 704 | autocmd! BufDelete w 705 | " on quit BufDelete is not run!! 706 | autocmd! VimLeave w 707 | 708 | else 709 | exec 'b '.nr 710 | endif 711 | cal append('$', split(a:s, "\n", 1)) 712 | " if the buffer appears to be modified vim asks questions when quitting, 713 | " I want it to be silent, it gets written bi au command see above 714 | " yes - if vim crashes logs are lost. I hope it doesn't happen to often. 715 | " Writing on each messages seems overkill to me - The log may get long 716 | " over time 717 | setlocal nomodified 718 | else 719 | let hi = a:0 > 0 ? a:1 : 'WarningMsg' 720 | exec 'echohl '. hi 721 | for l in split(a:s, "\n", 1) 722 | if empty(l) 723 | echom ' ' 724 | else 725 | echom l 726 | endif 727 | endfor 728 | echohl None 729 | endif 730 | endfun 731 | 732 | " If you want these commands witohut activating plugins call 733 | " vam#ActivateAddons([]) with empty list. Not moving them into plugin/vam.vim 734 | " to prevent additional IO seeks. 735 | 736 | " old names: 737 | command! -nargs=* -bar -complete=customlist,vam#install#NotInstalledAddonCompletion InstallAddons :call vam#install#Install([]) 738 | command! -nargs=* -bar -complete=customlist,vam#install#AddonCompletion ActivateAddons :call vam#ActivateAddons([]) 739 | command! -nargs=* -bar -complete=customlist,vam#install#AddonCompletion AddonsInfo :call vam#DisplayAddonsInfo([]) 740 | command! -nargs=* -bar -complete=customlist,vam#install#InstalledAddonCompletion ActivateInstalledAddons :call vam#ActivateAddons([]) 741 | command! -nargs=* -bar -complete=customlist,vam#install#UpdateCompletion UpdateAddons :call vam#install#Update([]) 742 | command! -nargs=0 -bar UpdateActivatedAddons exec 'UpdateAddons '.join(keys(g:vim_addon_manager.activated_plugins),' ') 743 | command! -nargs=0 -bar ListActivatedAddons :echo join(keys(g:vim_addon_manager.activated_plugins)) 744 | command! -nargs=* -bar -complete=customlist,vam#install#UninstallCompletion UninstallNotLoadedAddons :call vam#install#UninstallAddons([]) 745 | command! -nargs=* -complete=customlist,vam#bisect#BisectCompletion AddonsBisect :call vam#bisect#Bisect() 746 | 747 | 748 | " new names (not documented, ZyX may change some of these in the near future) 749 | command! -nargs=* -bar -complete=customlist,vam#install#NotInstalledAddonCompletion VAMInstall :call vam#install#Install([]) 750 | command! -nargs=* -bar -complete=customlist,vam#install#AddonCompletion VAMActivate :call vam#ActivateAddons([]) 751 | command! -nargs=* -bar -complete=customlist,vam#install#AddonCompletion VAMPluginInfo :call vam#DisplayAddonsInfo([]) 752 | command! -nargs=* -bar -complete=customlist,vam#install#InstalledAddonCompletion VAMActivateInstalled :call vam#ActivateAddons([]) 753 | command! -nargs=* -bar -complete=customlist,vam#install#UpdateCompletion VAMUpdate :call vam#install#Update([]) 754 | command! -nargs=0 -bar VAMUpdateActivated exec 'UpdateAddons '.join(keys(g:vim_addon_manager.activated_plugins),' ') 755 | command! -nargs=0 -bar VAMListActivated :echo join(keys(g:vim_addon_manager.activated_plugins)) 756 | command! -nargs=* -bar -complete=customlist,vam#install#UninstallCompletion VAMUninstallNotLoadedPlugins :call vam#install#UninstallAddons([]) 757 | command! -nargs=* -complete=customlist,vam#bisect#BisectCompletion VAMBisect :call vam#bisect#Bisect() 758 | 759 | fun! s:RunInstallHooks(plugins) 760 | for name in a:plugins 761 | call vam#install#RunHook('post-install', vam#ReadAddonInfo(vam#AddonInfoFile(vam#PluginDirFromName(name), name)), vam#install#GetRepo(name, {}), vam#PluginDirFromName(name), {}) 762 | endfor 763 | endfun 764 | command! -nargs=+ -complete=customlist,vam#install#InstalledAddonCompletion RunInstallHooks :call s:RunInstallHooks([]) 765 | 766 | 767 | " plugin name completion function: 768 | if !empty(s:c.addon_completion_lhs) 769 | augroup VAM_addon_name_completion 770 | autocmd! 771 | execute 'autocmd FileType vim inoremap '.s:c.addon_completion_lhs.' vam#utils#CompleteWith("vam#install#CompleteAddonName")' 772 | augroup END 773 | endif 774 | 775 | if s:c.lazy_loading_au_commands 776 | au FileType * call vam#ActivateAddons(filter(copy(s:c.activate_on.ft_regex ), string(expand('')).' =~ v:val.ft_regex' ), {'force_loading_plugins_now':1}) 777 | au BufNewFile,BufRead * call vam#ActivateAddons(filter(copy(s:c.activate_on.filename_regex), string(expand('')).' =~ v:val.filename_regex'), {'force_loading_plugins_now':1}) 778 | endif 779 | 780 | let s:file_cache = {} 781 | fun! vam#FileContains(file, regex) 782 | if !has_key(a:file, s:file_cache) 783 | let s:file_cache[a:file] = file_readable(a:file) ? join(readfile(a:file), "\n") : "" 784 | endif 785 | return s:file_cache[a:file] =~ a:regex 786 | endf 787 | 788 | " vim: et ts=8 sts=2 sw=2 789 | -------------------------------------------------------------------------------- /autoload/vam/bisect.vim: -------------------------------------------------------------------------------- 1 | 2 | exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}') 3 | 4 | fun! vam#bisect#StepBad(vim, plain, addons, vimrc_tmp) abort 5 | let cmd_items = copy(a:vim) 6 | if a:plain 7 | call extend(cmd_items, ["-u", "NONE", "-U", "NONE", "-N"]) 8 | else 9 | let vimrc_contents = readfile($MYVIMRC) 10 | call writefile(['let g:vam_plugin_whitelist = '.string(a:addons)]+ vimrc_contents, a:vimrc_tmp) 11 | call extend(cmd_items, ["-u", a:vimrc_tmp]) 12 | endif 13 | 14 | call extend(cmd_items, ["--cmd", "command -bar -nargs=0 OKVAMBisect call writefile(['ok'], ".string(a:vimrc_tmp).")|qa!"]) 15 | call extend(cmd_items, ["--cmd", "command -bar -nargs=0 BADVAMBisect call writefile(['bad'], ".string(a:vimrc_tmp).")|qa!"]) 16 | call extend(cmd_items, ["-c", "echom 'VAM bisect running. Run your test and either of OKVAMBisect, BADVAMBisect to quit'"]) 17 | 18 | " call system(join(map(cmd_items,'shellescape(v:val)')," ")) 19 | " take care about %, use VAMs functions? 20 | 21 | if !vam#install#confirm('running vim with addons '.string(a:addons).' plain: '.a:plain) 22 | throw "user abort" 23 | endif 24 | exec '!'.join(map(cmd_items,'shellescape(v:val, 1)'), ' ') 25 | let r = readfile(a:vimrc_tmp) 26 | if r[0] == "ok" 27 | return 0 28 | elseif r[0] == "bad" 29 | return 1 30 | else 31 | throw "You used neither OKVAMBisect nor BADVAMBisect to exit vim!" 32 | endif 33 | endfun 34 | 35 | " ... must be cache 36 | fun! vam#bisect#List(vim_executable, skip_initial, addons, force_addons, ...) abort 37 | let cache = a:0 > 0 ? a:1 : {} 38 | 39 | if !exists('s:vimrc_tmp') 40 | let s:vimrc_tmp = tempname() 41 | endif 42 | 43 | " do we have a problem at all? 44 | let test = 'let bad = vam#bisect#StepBad(a:vim_executable, 0, addons + a:force_addons, s:vimrc_tmp)' 45 | let testPlain = 'let bad = vam#bisect#StepBad(a:vim_executable, 1, addons + a:force_addons, s:vimrc_tmp)' 46 | 47 | let addons = a:addons 48 | 49 | if !a:skip_initial 50 | let addons = a:addons 51 | exec test 52 | if !bad 53 | throw "Bisect failed: test passed with all initial plugins activated. Are you user you have a problem?" 54 | endif 55 | endif 56 | 57 | " from now on we can assume that the addons which are passed fail in some way 58 | 59 | if len(addons) == 0 60 | " try .vimrc and plain 61 | " test plain only once: 62 | if has_key(cache, 'bisect_plain_result') | return s:bisect_plain_result | endif 63 | " test .vimrc 64 | exec testPlain 65 | if bad 66 | return {'problem_found': 1, 'message': 'The problem even occurs without your .gvimrc, .vimrc or ~/.vim. Probably its your vim installation?'} 67 | else 68 | let cache.bisect_plain_result = {'problem_found': 0, 'message': 'Problem was not found - nothing left to test. Are you sure you have a problem?'} 69 | return cache.bisect_plain_result 70 | endif 71 | endif 72 | 73 | if len(addons) == 1 74 | let addons = a:addons 75 | " one plugin left, make sure its not the user's .vimrc causing the problem: 76 | let r = vam#bisect#List(a:vim_executable, 1, [], a:force_addons, cache) 77 | if r.problem_found 78 | return r 79 | else 80 | return {'problem_found': 1, 'message': 'The plugin '.addons[0].' or one of its dependencies is likely to cause the problem'} 81 | endif 82 | endif 83 | 84 | " try left half of plugins: 85 | let addons = a:addons[0:len(a:addons)/2-1] 86 | exec test 87 | if bad 88 | " left half causes problem, recurse 89 | return vam#bisect#List(a:vim_executable, 1, addons, a:force_addons, cache) 90 | else 91 | " right side should contain issue, verify it 92 | let addons = a:addons[len(a:addons)/2:-1] 93 | exec test 94 | if bad 95 | let r = vam#bisect#List(a:vim_executable, 1, addons, a:force_addons, cache) 96 | if r.problem_found 97 | return r 98 | else 99 | throw "unexpected" 100 | endif 101 | else 102 | " neither left nor right side cause problem. Thus a combination of 103 | " the plugins on both sides is causing the issue! 104 | " neither right nor left side contains problem, a combination of 105 | " plugins found in left/right must be causing the problem 106 | return {'problem_found': 1, 'message': 'a combination of plugins is causing your issue. Addon list :' .string(a:addons).". If you find this message you may ask VAM devs to continue this implementation. Right now you're on you own - you have to continue manually. The argument force_addons may be of help"} 107 | " TODO continue this way: 108 | " TODO: cache system and user's .vimrc result 109 | " 110 | " let left_half = a:addons[0:len(a:addons)/2-1] 111 | " let right_half = a:addons[len(a:addons)/2:-1] 112 | " " fix left_half 113 | " let r = vam#bisect#Bisect(a:vim_executable, right_half, left_half) 114 | 115 | " " fix right_half 116 | " let r = vam#bisect#Bisect(a:vim_executable, left_half, right_half) 117 | endif 118 | endif 119 | endfun 120 | 121 | " argument1: ['vim'] or ['gvim','--nofork'] 122 | " rerun vim bisecting the plugin list to find out which plugin might be 123 | " causing trouble you're experiencing 124 | fun! vam#bisect#Bisect(...) 125 | if a:0 126 | let vim_executable = copy(a:000) 127 | else 128 | let vim_executable = [v:progname, has('gui_running')? '-g' : '-v'] 129 | endif 130 | " It does not harm running non-gui vim with --nofork 131 | let vim_executable += ['--nofork'] 132 | let addons = keys(s:c.activated_plugins) 133 | try 134 | let r = vam#bisect#List(vim_executable, 0, addons, []) 135 | endtry 136 | let g:vim_addon_bisect_result = r 137 | call vam#Log(r.message) 138 | endfun 139 | 140 | fun! vam#bisect#BisectCompletion(A, L, P, ...) 141 | let list = ['vim','gvim'] 142 | return list 143 | endfun 144 | 145 | " vim: et ts=8 sts=2 sw=2 146 | -------------------------------------------------------------------------------- /autoload/vam/install.vim: -------------------------------------------------------------------------------- 1 | " vam#install contains code which is used when install plugins only 2 | 3 | exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}') 4 | 5 | let s:c.change_to_unix_ff = get(s:c, 'change_to_unix_ff', (g:os=~#'unix')) 6 | let s:c.do_diff = get(s:c, 'do_diff', 1) 7 | let s:c.known = get(s:c, 'known', 'vim-pi') 8 | let s:c.MergeSources = get(s:c, 'MergeSources', 'vam_known_repositories#MergeSources') 9 | let s:c.pool_fun = get(s:c, 'pool_fun', 'vam#install#Pool') 10 | let s:c.name_rewriting = get(s:c, 'name_rewriting', {}) 11 | let s:c.pre_update_hook_functions = get(s:c, 'pre_update_hook_functions', ['vam#install#CreatePatch']) 12 | let s:c.post_update_hook_functions = get(s:c, 'post_update_hook_functions', ['vam#install#ApplyPatch']) 13 | let s:c.post_scms_update_hook_functions = get(s:c, 'post_scms_update_hook_functions', ['vam#install#ShowShortLog']) 14 | let s:c.pool_item_check_funs = get(s:c, 'pool_item_check_funs', ['vam#install#CheckPoolItem']) 15 | 16 | call extend(s:c.name_rewriting, {'99git+github': 'vam#install#RewriteName'}) 17 | 18 | fun! s:confirm(msg, ...) 19 | if getchar(1) 20 | let char = getchar() 21 | if type(char) == type(0) 22 | let char = nr2char(char) 23 | endif 24 | let char = tolower(char) 25 | if a:0 26 | if type(a:1)==type("") 27 | let choices = tolower(substitute(a:1, '\v\&@ {"type" : "hg/svn/darcs", url : URL} 72 | return {'type' : match[1], 'url' : match[2]} 73 | endif 74 | endfun 75 | 76 | fun! vam#install#CompleteRepoData(repository, opts) 77 | if has_key(a:repository, 'type') 78 | " looks like repository is already complete .. 79 | return a:repository 80 | endif 81 | 82 | " add missing information by 83 | " 1) lookup in pool 84 | " 2) try turning name into source by s:c.name_rewriting 85 | let name = a:repository.name 86 | if name isnot# s:c.known | call vam#install#LoadPool() |endif 87 | 88 | let repository = get(s:c.plugin_sources, name, get(get(a:opts, 'plugin_sources', {}), name, 0)) 89 | if repository is 0 90 | unlet repository 91 | for key in sort(keys(s:c.name_rewriting)) 92 | let repository=call(s:c.name_rewriting[key], [name], {}) 93 | if type(repository) == type({}) 94 | break 95 | endif 96 | unlet repository 97 | endfor 98 | if exists('repository') 99 | echom 'Name '.name.' expanded to :'.string(repository) 100 | else 101 | " try to find typos and renamings. Tell user about failure 102 | let maybe_fixes = [] 103 | let name_ = vam#utils#TypoFix(name) 104 | for x in keys(s:c.plugin_sources) 105 | if vam#utils#TypoFix(x) == name_ 106 | call add(maybe_fixes, name.' might be a typo, did you mean: '.x.' ?') 107 | endif 108 | endfor 109 | " try finding new name (vim-pi only) 110 | try 111 | " using try because pool implementations other then vim-pi could be 112 | " used 113 | call extend(maybe_fixes, vimpi#SuggestNewName(name)) 114 | catch /Vim(call):E117:/ 115 | " If vim-pi activation policy is never, then the above will yield 116 | " unknown function error 117 | endtry 118 | call vam#Log(join(["No repository location info known for plugin ".name."."] + maybe_fixes,"\n")) 119 | return 0 120 | endif 121 | endif 122 | 123 | if has_key(repository, 'url') && repository.url =~# 'git://github.com' 124 | let repository.url = substitute(repository.url, '^git:\/\/', 'https://', '') 125 | end 126 | 127 | call extend(repository, a:repository) 128 | return repository 129 | endfun 130 | 131 | " Install let's you install plugins by passing the url of a addon-info file 132 | " This preprocessor replaces the urls by the plugin-names putting the 133 | " repository information into the global dict 134 | " 135 | " TODO: Does anybody use this? Is it worth keeping? 136 | fun! vam#install#ReplaceAndFetchUrls(list) 137 | let l = a:list 138 | let idx = 0 139 | for idx in range(0, len(l)-1) 140 | let n = l[idx] 141 | " assume n is either an url or a path 142 | if n =~ '\m^https\?://' && s:confirm('Fetch plugin info from URL '.n.'?') 143 | let t = tempname() 144 | call vam#utils#Download(n, t) 145 | elseif n =~ '[/\\]' && filereadable(n) 146 | let t = n 147 | endif 148 | if exists('t') 149 | let info = vam#ReadAddonInfo(t) 150 | unlet t 151 | if !has_key(info, 'name') || !has_key(info, 'repository') 152 | call vam#Log( n." is no valid addon-info file. It must contain both keys: name and repository") 153 | continue 154 | endif 155 | let s:c.plugin_sources[info.name] = info.repository 156 | let l[idx] = info.name 157 | endif 158 | endfor 159 | endfun 160 | 161 | fun! vam#install#RunHook(hook, info, repository, pluginDir, opts) 162 | let hkey=tr(a:hook, '-', '_').'_hook_functions' 163 | if has_key(s:c, hkey) 164 | let d={} 165 | for d.hook in s:c[hkey] 166 | call call(d.hook, [a:info, a:repository, a:pluginDir, a:opts], {}) 167 | endfor 168 | endif 169 | let hkey=a:hook.'-hook' 170 | if has_key(a:info, hkey) 171 | execute substitute(substitute(substitute(substitute(a:info[hkey], 172 | \'%d', 'a:pluginDir', 'g'), 173 | \'%r', 'a:repository', 'g'), 174 | \'%i', 'a:info', 'g'), 175 | \'%o', 'a:opts', 'g') 176 | endif 177 | endfun 178 | 179 | " opts: same as ActivateAddons 180 | fun! vam#install#Install(toBeInstalledList, ...) 181 | let toBeInstalledList = vam#PreprocessScriptIdentifier(a:toBeInstalledList, {'rewrite_names': 1}) 182 | call vam#install#ReplaceAndFetchUrls(map(copy(toBeInstalledList),'v:val.name')) 183 | let opts = a:0 == 0 ? {} : a:1 184 | let auto_install = get(opts, 'auto_install', s:c.auto_install) 185 | let installed = [] 186 | for to_install in filter(copy(toBeInstalledList), '!vam#IsPluginInstalled(v:val.name)') 187 | let repository = vam#install#CompleteRepoData(to_install, opts) 188 | let name = repository['name'] 189 | " make sure all sources are known 190 | if repository is 0 191 | continue 192 | endif 193 | 194 | let confirmed = 0 195 | let origin = get(repository,'type','').' '.get(repository,'url','') 196 | 197 | " tell user about target directory. Some users don't get it the first time.. 198 | let pluginDir = vam#PluginDirFromName(name) 199 | 200 | " call vam#DisplayAddonInfo(name), can't use due to plugin_sources 201 | call vam#Log(join(vam#DisplayAddonInfoLines(name, repository),"\n"), 'None') 202 | 203 | call vam#Log('Target: '.pluginDir, 'None') 204 | if (has_key(opts, 'requested_by')) 205 | call vam#Log('Dependency chain: '.join([name]+opts.requested_by,' < ')) 206 | endif 207 | 208 | let d = get(repository, 'deprecated', '') 209 | if type(d) == type('') && d != '' 210 | echom "!> Deprecation warning package ".name. ":" 211 | echom d 212 | " even for auto_install make user confirm the deprecation case 213 | if !vam#Log('Origin: '.origin ,"None") 214 | \ && s:confirm('Plugin '.name.' is deprecated, see warning above. Install it?', 1) 215 | let confirmed = 1 216 | else 217 | continue 218 | endif 219 | endif 220 | 221 | " ask user for to confirm installation unless he set auto_install 222 | 223 | if auto_install 224 | \ || confirmed 225 | \ || (!vam#Log('Origin: '.origin ,"None") 226 | \ && s:confirm("Install plugin `".name."'?")) 227 | 228 | call vam#install#Checkout(pluginDir, repository) 229 | 230 | let infoFile = vam#AddonInfoFile(pluginDir, name) 231 | if has_key(repository, 'addon-info') && !filereadable(infoFile) 232 | call writefile([string(repository['addon-info'])], infoFile) 233 | endif 234 | 235 | " install dependencies 236 | let info = vam#ReadAddonInfo(infoFile) 237 | 238 | let dependencies = get(info, 'dependencies', {}) 239 | 240 | " install dependencies merging opts with given repository sources 241 | " sources given in opts will win 242 | call vam#install#Install(keys(dependencies), 243 | \ extend(copy(opts), { 244 | \ 'plugin_sources' : extend(copy(dependencies), get(opts, 'plugin_sources',{})), 245 | \ 'requested_by' : [name] + get(opts, 'requested_by', []) 246 | \ })) 247 | 248 | call vam#install#HelpTags(name) 249 | if get(opts, 'run_install_hooks', 0) 250 | call vam#install#RunHook('post-install', info, repository, pluginDir, {}) 251 | endif 252 | endif 253 | 254 | let installed += [name] 255 | endfor 256 | return installed 257 | endfun 258 | 259 | fun! vam#install#CreatePatch(info, repository, pluginDir, hook_opts) 260 | let a:hook_opts.diff_do_diff=(s:c.do_diff && executable('diff')) 261 | " try creating diff by checking out old version again 262 | if a:hook_opts.diff_do_diff 263 | " move plugin to backup destination: 264 | let pluginDirBackup = a:pluginDir.'-'.a:hook_opts.oldVersion 265 | if isdirectory(pluginDirBackup) || filereadable(pluginDirBackup) 266 | if s:confirm('Remove old plugin backup directory ('.pluginDirBackup.')?') 267 | call vam#utils#RmFR(pluginDirBackup) 268 | else 269 | throw 'User abort: remove '.pluginDirBackup.' manually' 270 | endif 271 | endif 272 | call rename(a:pluginDir, pluginDirBackup) 273 | " can be romved. old version is encoded in tmp dir. Removing makes 274 | " diffing easier 275 | silent! call delete(pluginDirBackup.'/version') 276 | let a:hook_opts.diff_backup_dir=pluginDirBackup 277 | 278 | let diff_file = a:pluginDir.'-'.a:hook_opts.oldVersion.'.diff' 279 | let a:hook_opts.diff_file=diff_file 280 | " try to create a diff 281 | let archiveName = vam#install#ArchiveNameFromDict(a:repository) 282 | let archiveFileBackup = pluginDirBackup.'/archive/'.archiveName 283 | if !filereadable(archiveFileBackup) 284 | call vam#Log("Old archive file ".archiveFileBackup." is gone, can't try to create diff.") 285 | else 286 | let archiveFile = a:pluginDir.'/archive/'.archiveName 287 | call mkdir(a:pluginDir.'/archive', 'p') 288 | 289 | let rep_copy = deepcopy(a:repository) 290 | let rep_copy.url = 'file://'.expand(archiveFileBackup, 1) 291 | call vam#install#Checkout(a:pluginDir, rep_copy) 292 | silent! call delete(a:pluginDir.'/version') 293 | try 294 | call vam#utils#ExecInDir(fnamemodify(a:pluginDir, ':h'), 'diff -U3 -r -a --binary $p $p > $p', fnamemodify(a:pluginDir,':t'), fnamemodify(pluginDirBackup,':t'), diff_file) 295 | silent! call delete(diff_file) 296 | let a:hook_opts.diff_do_diff=0 297 | catch /.*/ 298 | " :-( this is expected. diff returns non zero exit status. This is hacky 299 | let a:hook_opts.diff_do_diff=1 300 | endtry 301 | call vam#utils#RmFR(a:pluginDir) 302 | endif 303 | endif 304 | endfun 305 | fun! vam#install#ApplyPatch(info, repository, pluginDir, hook_opts) 306 | " try applying patch 307 | if a:hook_opts.diff_do_diff 308 | if executable('patch') 309 | let diff_file=a:hook_opts.diff_file 310 | let pluginDirBackup=a:hook_opts.diff_backup_dir 311 | try 312 | call vam#utils#ExecInDir(a:pluginDir, 'patch --binary -p1 --input=$p', diff_file) 313 | call vam#Log('Patching suceeded', 'None') 314 | call delete(diff_file) 315 | call vam#utils#RmFR(pluginDirBackup) 316 | catch /.*/ 317 | call vam#Log('Failed to apply patch '.diff_file.' ('.v:exception.'), original files may be found in '.pluginDirBackup) 318 | endtry 319 | else 320 | call vam#Log('Failed trying to apply diff: “patch” executable not found') 321 | endif 322 | endif 323 | endfun 324 | 325 | " this function will be refactored slightly soon by either me or ZyX. 326 | " returns 327 | " "up-to-date" if addon is up to date 328 | " "updated" if addon was updated succesfully 329 | " "failed" if addon could not be updated. Error is logged in this case 330 | fun! vam#install#UpdateAddon(name) 331 | call vam#Log( "Considering ".a:name." for update" ,'type','unknown') 332 | let pluginDir = vam#PluginDirFromName(a:name) 333 | if !isdirectory(pluginDir) 334 | return 'missing' 335 | endif 336 | " First, try updating using VCS. Return 1 if everything is ok, 0 if exception 337 | " is thrown 338 | try 339 | let [r, oldVersion, newVersion, sdescr] = vam#vcs#Update(pluginDir) 340 | let hook_opts={'oldVersion': oldVersion, 'newVersion': newVersion, 'sdescr': sdescr} 341 | if r isnot# 'unknown' 342 | if r is# 'updated' 343 | call vam#install#RunHook('post-scms-update', vam#ReadAddonInfo(vam#AddonInfoFile(pluginDir, a:name)), {}, pluginDir, hook_opts) 344 | endif 345 | return r 346 | endif 347 | catch /.*/ 348 | call vam#Log(v:exception) 349 | return 'failed' 350 | endtry 351 | 352 | "Next, try updating plugin by archive 353 | 354 | " we have to find out whether there is a new version: 355 | call vam#install#LoadPool() 356 | let repository = get(s:c.plugin_sources, a:name, {}) 357 | if empty(repository) 358 | call vam#Log("Don't know how to update ".a:name." because it is not contained in plugin_sources") 359 | return 'failed' 360 | endif 361 | let newVersion = get(repository, 'version', '?') 362 | 363 | 364 | if a:name is# 'vim-addon-manager' 365 | " load utils before the file is moved below 366 | runtime autoload/vam/util.vim 367 | endif 368 | 369 | if get(repository, 'type', 0) isnot# 'archive' 370 | call vam#Log("Not updating ".a:name." because the repository description suggests using VCS ".get(repository, 'type', 'unknown').'.' 371 | \ ."\nYour install seems to be of type archive/manual/www.vim.org/unknown." 372 | \ ."\nIf you want to update ".a:name." remove ".pluginDir." and let VAM check it out again." 373 | \ ) 374 | return 'failed' 375 | endif 376 | 377 | let versionFile = pluginDir.'/version' 378 | let oldVersion = filereadable(versionFile) ? readfile(versionFile, 'b')[0] : "?" 379 | if oldVersion !=# newVersion || newVersion == '?' 380 | " update plugin 381 | echom "Updating plugin ".a:name." because ".(newVersion == '?' ? 'version is unknown' : 'there is a different version') 382 | 383 | let hook_opts={'oldVersion': oldVersion, 'newVersion': newVersion} 384 | call vam#install#RunHook('pre-update', vam#ReadAddonInfo(vam#AddonInfoFile(pluginDir, a:name)), repository, pluginDir, hook_opts) 385 | 386 | " checkout new version (checkout into empty location - same as installing): 387 | if isdirectory(pluginDir) 388 | call vam#utils#RmFR(pluginDir) 389 | endif 390 | call vam#install#Checkout(pluginDir, repository) 391 | 392 | " addon info file name could have changed here .. 393 | call vam#install#RunHook('post-update', vam#ReadAddonInfo(vam#AddonInfoFile(pluginDir, a:name)), repository, pluginDir, hook_opts) 394 | 395 | return 'updated' 396 | elseif oldVersion == newVersion 397 | call vam#Log( "Not updating plugin ".a:name.", ".newVersion." is current") 398 | return 'up-to-date' 399 | else 400 | call vam#Log( "Not updating plugin ".a:name." because there is no version according to version key") 401 | endif 402 | return 'up-to-date' 403 | endfun 404 | 405 | fun! vam#install#Update(list) 406 | let list = a:list 407 | 408 | if s:c.known isnot 0 409 | if vam#install#UpdateAddon(s:c.known) 410 | call vam#install#HelpTags(s:c.known) 411 | endif 412 | endif 413 | " refresh sources: 414 | call vam#install#LoadPool(1) 415 | 416 | if empty(list) && s:confirm('Update all loaded plugins?') 417 | let list = keys(s:c.activated_plugins) 418 | endif 419 | let by_reply = {} 420 | for p in list 421 | let r = vam#install#UpdateAddon(p) 422 | if r is# 'updated' 423 | call vam#install#HelpTags(p) 424 | endif 425 | if (!has_key(by_reply,r)) 426 | let by_reply[r] = [] 427 | endif 428 | call add(by_reply[r], p) 429 | endfor 430 | let labels = {'updated': 'Updated:', 'failed': 'Failed to update:', 431 | \ 'up-to-date': 'Already up to date:', 432 | \ 'possibly updated': 'Don’t know how to determine update state (possibly updated):', 433 | \ 'missing': 'Plugin not installed:',} 434 | for [k,v] in items(by_reply) 435 | call vam#Log(get(labels,k,k).' '.string(by_reply[k]).".", k is# 'failed' ? 'WarningMsg' : 'Type') 436 | endfor 437 | endfun 438 | 439 | " completion {{{ 440 | 441 | fun! vam#install#KnownAddons(type) 442 | call vam#install#LoadPool() 443 | let k = {} 444 | " from pool 445 | call extend(k, s:c.plugin_sources) 446 | " Disk completion using default plugin dir location. 447 | " Don’t do this if plugin_root_dir contains newline on outdated vim: 448 | " split(glob) does not work properly in this case. Also don’t do this if we 449 | " require notinstalled plugins. 450 | if a:type isnot# 'notinstalled' && 451 | \s:c.plugin_dir_by_name is# 'vam#DefaultPluginDirFromName' 452 | for dir in [s:c.plugin_root_dir]+s:c.additional_addon_dirs 453 | for key in map(vam#GlobInDir(dir, '*/'), 'fnamemodify(v:val[:-2], ":t")') 454 | " We don’t care about values: so no need to make it complex 455 | let k[key] = 1 456 | endfor 457 | endfor 458 | endif 459 | return sort(keys(k)) 460 | endfun 461 | 462 | " Filters: 463 | " 1. Start of the name must be the same as completed name 464 | " 2. Part of the name must be the same as completed name 465 | " 3. User correctly entered start of the string, but punctuation characters 466 | " inside were mistaken. Also takes globs as '*'=~'[[:punct:]]'. 467 | " 4. There may be missing characters somewhere at the word boundary, but user 468 | " correctly entered start of the word 469 | " 5. There may be missing characters somewhere at the word boundary, but first 470 | " character is correct 471 | " 6. Name has completely wrong order of characters, but not the first character 472 | " 7. Punctuation characters inside string were mistaken. 473 | " Also takes globs as '*'=~'[[:punct:]]'. 474 | " 8. There may be missing characters somewhere at the word boundary 475 | " 9. There may be some missing charaters inside a word 476 | let s:smartfilters=[ 477 | \['1', '"v:val[:".(len(a:str)-1)."]==?".string(a:str)'], 478 | \['1', '"stridx(tolower(v:val), ".string(tolower(a:str)).")!=-1"'], 479 | \['haspunct', '"v:val=~?".string("\\v^".regnopunct)'], 480 | \['haspunct', '"v:val=~?".string("\\v^".regboundary)'], 481 | \['lstr>1', '"v:val=~?".string("\\v^".reginside)'], 482 | \['lstr>1', '"v:val=~?".string(regwrongorder)'], 483 | \['haspunct', '"v:val=~?".string(regnopunct)'], 484 | \['haspunct', '"v:val=~?".string(regboundary)'], 485 | \['lstr>1', '"v:val=~?".string(reginside)'], 486 | \] 487 | fun! vam#install#GetFilters(str) 488 | if empty(a:str) 489 | return ['1'] 490 | endif 491 | let lstr=len(a:str) 492 | let haspunct=(match(a:str, "[[:punct:]]")!=-1) 493 | let regnopunct='\V'.substitute(a:str, '\v[[:punct:]]+', '\\.\\*', 'g') 494 | let estrchars=map(split(a:str,'\v\_.@='), 'escape(v:val, "\\")') 495 | let regwrongorder='\V\^'.estrchars[0].'\%(\.\*'.join(estrchars[1:], '\)\@=\%(\.\*').'\)\@=' 496 | let regboundary='\V'.join(map(split(a:str, '\v[[:punct:]]@<=|[[:punct:]]@='), 'escape(v:val, "\\")'), '\.\*') 497 | let reginside='\V'.join(estrchars, '\.\*') 498 | return map(filter(copy(s:smartfilters), 'eval(v:val[0])'), 'eval(v:val[1])') 499 | endfun 500 | 501 | fun! vam#install#FilterVariants(str, variants) 502 | let list=copy(a:variants) 503 | let r=[] 504 | for filter in vam#install#GetFilters(a:str) 505 | let newlist=[] 506 | call map(list, '('.filter.')?(add(r, v:val)):(add(newlist, v:val))') 507 | " We already have enough results to show, so stop thinking that user needs 508 | " more variants 509 | if len(r)>8 510 | break 511 | endif 512 | let list=newlist 513 | endfor 514 | return r 515 | endfun 516 | 517 | fun! vam#install#CompleteAddonName(findstart, base) 518 | if a:findstart 519 | let match_text=matchstr(getline('.')[:col('.')-2], "[^'\"()[\\]{}\t ]*$") 520 | return col('.')-len(match_text)-1 521 | else 522 | call map(vam#install#FilterVariants(a:base, vam#install#KnownAddons(0)), 523 | \ 'complete_add({"word": v:val, '. 524 | \ '"menu": "Script id: ".'. 525 | \ 'get(get(s:c.plugin_sources, v:val, {}), '. 526 | \ '"vim_script_nr", "NA")})') 527 | return [] 528 | endif 529 | endfun 530 | 531 | let s:postfilters={ 532 | \'installed': 'isdirectory(vam#PluginDirFromName(v:val))', 533 | \'notloaded': '(!has_key(s:c.activated_plugins, v:val)) && '. 534 | \ 'isdirectory(vam#PluginDirFromName(v:val))', 535 | \'notinstalled': '!isdirectory(vam#PluginDirFromName(v:val))', 536 | \} 537 | fun! vam#install#DoCompletion(A, L, P, ...) 538 | let list=vam#install#KnownAddons(get(a:000, 0, 0)) 539 | let str=matchstr(a:L[:a:P-1], '\S*$') 540 | let r=vam#install#FilterVariants(str, list) 541 | if a:0 542 | call filter(r, s:postfilters[a:1]) 543 | endif 544 | return r 545 | endfun 546 | 547 | fun! vam#install#AddonCompletion(...) 548 | return call('vam#install#DoCompletion',a:000) 549 | endfun 550 | 551 | fun! vam#install#NotInstalledAddonCompletion(...) 552 | return call('vam#install#DoCompletion',a:000+["notinstalled"]) 553 | endfun 554 | 555 | fun! vam#install#InstalledAddonCompletion(...) 556 | return call('vam#install#DoCompletion',a:000+["installed"]) 557 | endfun 558 | 559 | fun! vam#install#UninstallCompletion(...) 560 | return call('vam#install#DoCompletion',a:000+["notloaded"]) 561 | endfun 562 | 563 | fun! vam#install#UpdateCompletion(...) 564 | return call('vam#install#DoCompletion',a:000+["installed"]) 565 | endfun 566 | "}}} 567 | 568 | fun! vam#install#UninstallAddons(list) 569 | let list = a:list 570 | if list == [] 571 | echo "No plugins selected. If you ran UninstallNotLoadedAddons use or to get a list of not loaded plugins." 572 | return 573 | endif 574 | call map(list, 'vam#PluginDirFromName(v:val)') 575 | if s:confirm('Will now remove '.join(list, ', ').'. Confirm?') 576 | call map(list, 'vam#utils#RmFR(v:val)') 577 | endif 578 | endfun 579 | 580 | fun! vam#install#HelpTags(name) 581 | let pluginDir = vam#PluginDirFromName(a:name) 582 | let info = vam#ReadAddonInfo(vam#AddonInfoFile(pluginDir, a:name)) 583 | let d=vam#PluginRuntimePath(pluginDir, info).'/doc' 584 | if isdirectory(d) | exec 'helptags '.fnameescape(d) | endif 585 | endfun 586 | 587 | " basename of url. if archive_name is given use that instead 588 | fun! vam#install#ArchiveNameFromDict(repository) 589 | let archiveName = fnamemodify(substitute(get(a:repository,'archive_name',''), '\.\@<=VIM$', 'vim', ''),':t') 590 | if empty(archiveName) 591 | let archiveName = fnamemodify(a:repository.url,':t') 592 | endif 593 | return archiveName 594 | endfun 595 | 596 | 597 | " may throw EXCEPTION_UNPACK 598 | fun! vam#install#Checkout(targetDir, repository) abort 599 | if get(a:repository, 'script-type') is 'patch' 600 | call vam#Log( 601 | \ "This plugin requires patching and recompiling vim.\n" 602 | \ ."VAM could not do this, so you have to apply patch\n" 603 | \ ."manually." 604 | \ ) 605 | endif 606 | if vam#vcs#Checkout(a:targetDir, a:repository) 607 | " Successfully checked out a repository. Leaving a comment here to indicate 608 | " that an if condition has a side effect of checking out a repository. 609 | else 610 | " archive based repositories - no VCS 611 | 612 | if !isdirectory(a:targetDir) | call mkdir(a:targetDir.'/archive','p') | endif 613 | 614 | " basename VIM -> vim 615 | let archiveName = vam#install#ArchiveNameFromDict(a:repository) 616 | 617 | " archive will be downloaded to this location 618 | let archiveFile = a:targetDir.'/archive/'.archiveName 619 | 620 | call vam#utils#Download(a:repository.url, archiveFile) 621 | 622 | let opts = {'strip-components': get(a:repository,'strip-components',-1), 623 | \ 'script-type': tolower(get(a:repository, 'script-type', 'plugin')), 624 | \ 'unix_ff': get(a:repository, 'unix_ff', get(s:c, 'change_to_unix_ff')) } 625 | if (has_key(a:repository, 'target_dir')) 626 | let opts.target_dir = a:repository.target_dir 627 | endif 628 | 629 | call vam#utils#Unpack(archiveFile, a:targetDir, opts) 630 | 631 | call writefile([get(a:repository, 'version', '?')], a:targetDir.'/version', 'b') 632 | endif 633 | endfun 634 | 635 | " is there a library providing an OS abstraction? This breaks Winndows 636 | " xcopy or copy should be used there.. 637 | fun! vam#install#Copy(f,t) 638 | if g:is_win 639 | call vam#utils#RunShell('xcopy /e /i $ $', a:f, a:t) 640 | else 641 | call vam#utils#RunShell('cp -r $ $', a:f, a:t) 642 | endif 643 | endfun 644 | 645 | fun! vam#install#MergeTarget() 646 | return split(&runtimepath,",")[0].'/after/plugin/vim-addon-manager-merged.vim' 647 | endfun 648 | 649 | " if you machine is under IO load starting up Vim can take some time 650 | " This function tries to optimize this by reading all the plugin/*.vim 651 | " files joining them to one vim file. 652 | " 653 | " 1) rename plugin to plugin-merged (so that they are no longer sourced by Vim) 654 | " 2) read plugin/*.vim_merged files 655 | " 3) replace clashing s:name vars by uniq names 656 | " 4) rewrite the guards (everything containing finish) 657 | " 5) write final merged file to ~/.vim/after/plugin/vim-addon-manager-merged.vim 658 | " so that its sourced automatically 659 | " 660 | " TODO: take after plugins int account? 661 | fun! vam#install#MergePluginFiles(plugins, skip_pattern) 662 | if !filereadable('/bin/sh') 663 | throw "you should be using Linux.. This code is likely to break on other operating systems!" 664 | endif 665 | 666 | let target = vam#install#MergeTarget() 667 | 668 | for r in a:plugins 669 | if !has_key(s:c.activated_plugins, r) 670 | throw "JoinPluginFiles: all plugins must be activated (which ensures that they have been installed). This plugin is not active: ".r 671 | endif 672 | endfor 673 | 674 | let runtimepaths = map(copy(a:plugins), 'vam#PluginRuntimePath(vam#PluginDirFromName(v:val), vam#ReadAddonInfo(vam#AddonInfoFile(vam#PluginDirFromName(v:val), v:val)))') 675 | 676 | " 1) 677 | for r in runtimepaths 678 | if (isdirectory(r.'/plugin')) 679 | call vam#utils#RunShell('mv $ $', r.'/plugin', r.'/plugin-merged') 680 | endif 681 | endfor 682 | 683 | " 2) 684 | let file_local_vars = {} 685 | let uniq = 1 686 | let all_contents = "" 687 | for r in runtimepaths 688 | for file in vam#GlobInDir(r, 'plugin-merged/*.vim') 689 | 690 | if file =~ a:skip_pattern 691 | let all_contents .= "\" ignoring ".file."\n" 692 | continue 693 | endif 694 | 695 | let names_this_file = {} 696 | let contents =join(readfile(file, 'b'),"\n") 697 | for l in split("s:abc s:foobar",'\ze\ 10 744 | throw "something probably has gone wrong while removing guard for file".file." start at line: ".i 745 | endif 746 | call add(lines,'endif') 747 | let contents = join(lines,"\n") 748 | break 749 | endif 750 | endfor 751 | 752 | 753 | " comment remaining finish lines. This does not catch if .. | finish | endif and such 754 | " :-( 755 | " adding additional \n because not all scripts have a final \n.. 756 | let contents = substitute(contents, '\','" finish','g') 757 | let all_contents .= "\n" 758 | \ ."\"merged: ".file."\n" 759 | \ .contents 760 | \ ."\n" 761 | \ ."\"merged: ".file." end\n" 762 | endfor 763 | endfor 764 | 765 | let d =fnamemodify(target,':h') 766 | if !isdirectory(d) | call mkdir(d,'p') | endif 767 | call writefile(split(all_contents,"\n"), target) 768 | 769 | endfun 770 | 771 | fun! vam#install#UnmergePluginFiles() 772 | let path = fnamemodify(vam#PluginRuntimePath('vim-addon-manager', {}),':h') 773 | for merged in vam#GlobInDir(path, '{,*/}*/plugin-merged') 774 | echo "unmerging ".merged 775 | call rename(merged, substitute(merged,'-merged$','','')) 776 | endfor 777 | call delete(vam#install#MergeTarget()) 778 | endfun 779 | 780 | "{{{1 Pool 781 | " VAM does call this function for you when using {Activate/Install}Addon() or 782 | " one of those commands. Read doc/vim-addon-manager.txt to learn about the 783 | " pool of plugin sources. Also see option "known_repos_activation_policy" 784 | fun! vam#install#LoadKnownRepos() 785 | let known = s:c.known 786 | let reason = a:0 > 0 ? a:1 : 'get more plugin sources' 787 | if get(s:c.activated_plugins, known, 0) 788 | return 1 789 | else 790 | let policy=get(s:c, 'known_repos_activation_policy', 'autoload') 791 | if policy is? 'ask' 792 | let reply = s:confirm('Activate plugin '.known.' to '.reason."?", "&Yes\n&No\nN&ever (during session)") 793 | elseif policy is? 'never' 794 | let reply=2 795 | else 796 | let reply=1 797 | endif 798 | if reply == 3 799 | let s:c.known_repos_activation_policy = 'never' 800 | return 0 801 | elseif reply == 1 802 | " don't pass opts so that new_runtime_paths is not set which will 803 | " trigger topLevel adding -known-repos to rtp immediately 804 | call vam#ActivateAddons([known], {}) 805 | return 1 806 | else 807 | return 0 808 | endif 809 | endif 810 | endfun 811 | 812 | " The default pool of know plugins for VAM: vim-pi 813 | fun! vam#install#Pool() 814 | if vam#install#LoadKnownRepos() 815 | return vam_known_repositories#Pool() 816 | else 817 | return s:c.plugin_sources 818 | endif 819 | endfun 820 | 821 | " (re)loads pool of known plugins 822 | fun! vam#install#LoadPool(...) 823 | let force = a:0 > 0 ? a:1 : 0 824 | if force || !has_key(s:c, 'pool_loaded') 825 | " update plugin_sources 826 | let s:c.plugin_sources = call(s:c.pool_fun, [], {}) 827 | 828 | for F in s:c.pool_item_check_funs 829 | for k_v in items(s:c.plugin_sources) 830 | call call(F, k_v) 831 | endfor 832 | endfor 833 | 834 | let s:c.pool_loaded = 1 835 | endif 836 | endfun 837 | "}}}1 838 | 839 | 840 | if g:is_win 841 | fun! vam#install#FetchAdditionalWindowsTools() abort 842 | if !isdirectory(s:c.binary_utils.'\dist') 843 | call mkdir(s:c.binary_utils.'\dist','p') 844 | endif 845 | " we have curl, so we can fetch remaining deps using Download and Unpack 846 | let tools = { 847 | \ 'gzip': ['mirror://sourceforge/gnuwin32/gzip/1.3.12-1/', "gzip-1.3.12-1-bin.zip", ["gzip", "7z"]], 848 | \ 'bzip2':['mirror://sourceforge/gnuwin32/bzip2/1.0.5/', "bzip2-1.0.5-bin.zip", ["bzip2", "7z"] ], 849 | \ 'tar': ['mirror://sourceforge/gnuwin32/tar/1.13-1/',"tar-1.13-1-bin.zip", ["tar", "7z"] ], 850 | \ 'zip': ['mirror://sourceforge/gnuwin32/unzip/5.51-1/', "unzip-5.51-1-bin.zip", ["unzip","7z"] ], 851 | \ 'diffutils': ['mirror://sourceforge/gnuwin32/diffutils/2.8.7-1/',"diffutils-2.8.7-1-bin.zip", "diff"], 852 | \ 'patch': [ 'mirror://sourceforge/gnuwin32/patch/2.5.9-7/',"patch-2.5.9-7-bin.zip", "patch"] 853 | \ } 854 | for v in values(tools) 855 | echo "downloading ".v[1] 856 | for ex in v[2] 857 | if executable(ex) | continue | endif 858 | endfor 859 | if !filereadable(s:c.binary_utils.'\'.v[1]) 860 | call vam#utils#DownloadFromMirrors(v[0].v[1], s:c.binary_utils) 861 | endif 862 | endfor 863 | 864 | if !executable('unzip') 865 | " colorize this? 866 | echo "__ its your turn: __" 867 | 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' 868 | call getchar() 869 | exec "!".expand(s:c.binary_utils.'/'. tools.zip[1], 1) 870 | let $PATH=$PATH.';'.s:c.binary_utils_bin 871 | if !executable('unzip') 872 | throw "can't execute unzip. Something failed!" 873 | endif 874 | endif 875 | 876 | " now we have unzip and can do rest 877 | for k in ["gzip","bzip2","tar","diffutils","patch"] 878 | if !executable(tools[k][2]) 879 | call vam#utils#Unpack(s:c.binary_utils.'\'.tools[k][1], s:c.binary_utils.'\dist') 880 | endif 881 | endfor 882 | 883 | "if executable("7z") 884 | "echo "you already have 7z in PATH. Nothing to be done" 885 | "return 886 | "endif 887 | "let _7zurl = 'mirror://sourceforge/sevenzip/7-Zip/4.65/7z465.exe' 888 | "call vam#utils#DownloadFromMirrors(_7zurl, s:c.binary_utils.'/7z.exe') 889 | 890 | endfun 891 | endif 892 | 893 | fun! vam#install#ShowShortLog(info, repository, pluginDir, hook_opts) 894 | if has_key(a:hook_opts.sdescr, 'log') 895 | let c=a:hook_opts.sdescr.log 896 | call vam#Log('Changes', 'PreProc') 897 | " XXX wdrev() functions return result with trailing newline hence matchstr() 898 | " \S also matches newline hence double quotes and collection 899 | call vam#Log(call(c[0], get(c, 1, [])+[ 900 | \a:pluginDir, 901 | \matchstr(a:hook_opts.oldVersion, "[^ \t\r\n]*"), 902 | \matchstr(a:hook_opts.newVersion, "[^ \t\r\n]*")], get(c, 2, {})), 903 | \'Normal') 904 | endif 905 | endfun 906 | 907 | " vim: et ts=8 sts=2 sw=2 908 | -------------------------------------------------------------------------------- /autoload/vam/test.vim: -------------------------------------------------------------------------------- 1 | 2 | let s:plugin_root_dir = fnamemodify(expand('', 1),':h:h:h') 3 | 4 | " called by vim-addon-manager-test.sh 5 | fun! vam#test#Test() 6 | let test_dir = '/tmp/vim-addon-manager-test' 7 | 8 | exec '!rm -fr ' test_dir 9 | exec '!mkdir -p ' test_dir 10 | exec '!cp -r' s:plugin_root_dir test_dir 11 | 12 | " keep it simple: 13 | let g:vim_addon_manager.activated_plugins['vim-pi'] = 1 14 | let plugin_sources = g:vim_addon_manager.plugin_sources 15 | 16 | " test mercurial 17 | call feedkeys("y") 18 | let plugin_sources.vimstuff = {'type': 'hg', 'url': 'http://vimstuff.hg.sourceforge.net:8000/hgroot/vimstuff/vimstuff'} 19 | call vam#ActivateAddons(["vimstuff"]) 20 | 21 | " test git 22 | call feedkeys("y") 23 | let plugin_sources['vim-addon-views'] = { 'type' : 'git', 'url' : 'https://github.com/MarcWeber/vim-addon-views.git' } 24 | call vam#ActivateAddons(["vim-addon-views"]) 25 | 26 | " test subversion 27 | call feedkeys("y") 28 | let plugin_sources['vim-latex'] = { 'type': 'svn', 'url': 'https://vim-latex.svn.sourceforge.net/svnroot/vim-latex/trunk/vimfiles'} 29 | call vam#ActivateAddons(["vim-latex"]) 30 | 31 | endfun 32 | 33 | " vam#utils#Unpack tests 34 | 35 | " test: . = all tests 36 | " tar$ = onnly the tar test 37 | fun! vam#test#TestUnpack(test) abort 38 | let tests = { 39 | \ 'tar': ['autocorrect', ['README', 'archive', 'archive/autocorrect.tar', 'autocorrect.dat', 'autocorrect.vim', 'generator.rb', 'version'] ], 40 | \ 'tar.gz': ['ack', ['archive', 'archive/ack.tar.gz', 'doc', 'doc/ack.txt', 'plugin', 'plugin/ack.vim', 'version']], 41 | \ 'tgz': ['VIlisp', ['README', 'VIlisp-hyperspec.pl', 'VIlisp.vim', 'changelog', 'funnel.pl', 'lisp-thesaurus', 'make-lisp-thes.pl', 'archive', 'archive/VIlisp.2.3.tgz', 'version']], 42 | \ 'tar.bz2': ['DetectIndent', ['archive', 'archive/detectindent-1.0.tar.bz2', 'doc', 'doc/detectindent.txt', 'plugin', 'plugin/detectindent.vim', 'version']], 43 | \ 'tbz2': ['xterm16', ['ChangeLog', 'archive', 'archive/xterm16-2.43.tbz2', 'cpalette.pl', 'version', 'xterm16.ct', 'xterm16.schema', 'xterm16.txt', 'xterm16.vim']], 44 | \ 'vim_ftplugin': ['srec1008', ['archive', 'archive/srec.vim', 'ftplugin', 'ftplugin/srec.vim', 'version']], 45 | \ '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']], 46 | \ 'vba.gz': ['gitolite', ['archive', 'archive/gitolite.vba.gz', 'ftdetect', 'ftdetect/gitolite.vim', 'syntax', 'syntax/gitolite.vim', 'version']], 47 | \ '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']] 48 | \ } 49 | 50 | let tmpDir = vam#utils#TempDir("vim-addon-manager-test") 51 | 52 | call vam#install#LoadPool() 53 | 54 | for [k,v] in items(tests) 55 | if k !~ a:test | continue | endif 56 | call vam#utils#RmFR(tmpDir) 57 | let dict = g:vim_addon_manager.plugin_sources[v[0]] 58 | call vam#install#Checkout(tmpDir, dict) 59 | let files = vam#GlobInDir(tmpDir, '**') 60 | " replace \ by / on win and remove tmpDir prefix 61 | call map(files, 'substitute(v:val,'.string('\').',"/","g")['.(len(tmpDir)+1).':]') 62 | call sort(files) 63 | call sort(v[1]) 64 | if v[1] != files 65 | echoe "test failure :".k 66 | echoe 'expected :'.string(v[1]) 67 | echoe 'got : '.string(files) 68 | debug echoe 'continue' 69 | endif 70 | endfor 71 | endfun 72 | 73 | " tests that creating and applying diffs when updating archive plugins (found 74 | " on www.vim.org) works as expected. 75 | fun! vam#test#TestUpdate(case) abort 76 | call vam#install#LoadPool() 77 | let tmpDir = vam#utils#TempDir("vim-addon-manager-test") 78 | let plugin_name = "www_vim_org_update_test" 79 | let plugin_source_file = tmpDir.'/'.plugin_name.'.vim' 80 | let installDir = vam#PluginDirByName(plugin_name) 81 | let installCompareDir = vam#PluginDirByName(plugin_name.'-1.0') 82 | silent! unlet g:vim_addon_manager.activated_plugins[plugin_name] 83 | for dir in [tmpDir, installDir, installCompareDir] 84 | if isdirectory(dir) | call vam#utils#RmFR(dir) | endif 85 | endfor 86 | call mkdir(tmpDir.'/plugin','p') 87 | 88 | let file_v1 = ["version 1.0", "1", "2", "3", "4", "5" ] 89 | let file_v1_patched = ["version 1.0", "1", "2", "3", "4", "patched" ] 90 | let file_v2 = ["version 2.0", "1", "2", "3", "4", "5" ] 91 | let file_v2_patched = ["version 2.0", "1", "2", "3", "4", "patched" ] 92 | 93 | 94 | let file_v2_conflict = ["version 2.0", "1", "2", "3", "4", "conflicting line" ] 95 | 96 | " install v1 97 | call writefile( file_v1, plugin_source_file, 1) 98 | let g:vim_addon_manager.plugin_sources[plugin_name] = {'type': 'archive', 'url': 'file://'.plugin_source_file, 'version' : '1.0' , 'script-type': 'plugin' } 99 | exec 'ActivateAddons '.plugin_name 100 | 101 | " patch 102 | call writefile( file_v1_patched, installDir.'/plugin/'.plugin_name.'.vim', 1) 103 | 104 | if a:case == "normal" 105 | 106 | " update to v2 107 | call writefile( file_v2, plugin_source_file, 1) 108 | let g:vim_addon_manager.plugin_sources[plugin_name] = {'type': 'archive', 'url': 'file://'.plugin_source_file, 'version' : '2.0' , 'script-type': 'plugin' } 109 | exec 'UpdateAddons '.plugin_name 110 | 111 | " verify that the patch is still present 112 | if file_v2_patched != readfile( installDir.'/plugin/'.plugin_name.'.vim', 1) 113 | echoe "test failed" 114 | endif 115 | 116 | elseif a:case == "conflict" 117 | " manual test: diff file should be kept 118 | " update to v2 conflict 119 | call writefile( file_v2_conflict, plugin_source_file, 1) 120 | let g:vim_addon_manager.plugin_sources[plugin_name] = {'type': 'archive', 'url': 'file://'.plugin_source_file, 'version' : '2.0' , 'script-type': 'plugin' } 121 | exec 'UpdateAddons '.plugin_name 122 | else 123 | throw "unknown case" 124 | 125 | endif 126 | endfun 127 | " vim: et ts=8 sts=2 sw=2 128 | -------------------------------------------------------------------------------- /autoload/vam/utils.vim: -------------------------------------------------------------------------------- 1 | " vam#DefineAndBind('s:c','g:vim_addon_manager','{}') 2 | if !exists('g:vim_addon_manager') | let g:vim_addon_manager = {} | endif | let s:c = g:vim_addon_manager 3 | 4 | " Defaulting to 7z why or why not? 5 | let s:c.omit_7z=get(s:c, 'omit_7z', 0) 6 | 7 | " let users override curl command. Reuse netrw setting 8 | " Let's hope that nobody is using a dir called "curl " .. because 9 | " substitution will be wrong then 10 | let s:http_cmd = exists('g:netrw_http_cmd') ? 11 | \ substitute(g:netrw_http_cmd, '\c\vcurl(\.exe)?%(\ |$)', 'curl\1 --location --max-redirs 40 ', '') : 12 | \ executable('curl') ? 13 | \ 'curl -L --max-redirs 40 -o' : 14 | \ executable('wget') ? 15 | \ 'wget -O' 16 | \ : 17 | \ 0 18 | 19 | " for testing it is necessary to avoid the "Press enter to continue lines". 20 | " Thus provide an option making all shell commands use “system” 21 | let s:c.shell_commands_run_method = get(s:c, 'shell_commands_run_method', s:c.log_to_buf ? 'system' : 'bang') 22 | 23 | " insert arguments at placeholders $ shell escaping the value 24 | " usage: s:shellescape("rm --arg $ -fr $p $p $p", [string, file1, file2, file3]) 25 | " 26 | " the / \ annoyance of Windows is fixed by calling expand which replaces / by 27 | " \ on Windows. This only happens by the $p substitution 28 | " if $ is followed by a number its treated as index 29 | 30 | " Examples: 31 | " s:ShellDSL('$', 'escape this/\') == '''escape this/\''' 32 | " s:ShellDSL('$1 $[2p] $1p', 'escape this/\',\'other\') =='''escape this/'' ''other'' ''escape this/''' 33 | " s:ShellDSL('$.url $[1p.url] $1p.url', {'url':'URL'} ) =='''URL'' ''URL'' ''URL''' 34 | fun! s:ShellDSL(special, cmd, ...) abort 35 | let args = a:000 36 | let r = '' 37 | let l = split(a:cmd, '\V$', 1) 38 | let r = l[0] 39 | let i = 0 40 | for x in l[1:] 41 | let list = matchlist(x, '\v\[?(\d*)(p)?(\.[^ \t\]]*)?\]?') 42 | if empty(list) 43 | " should not happen 44 | throw 's:ShellDSL, bad : '.x 45 | endif 46 | if list[1] != '' 47 | let p= args[list[1]-1] 48 | else 49 | let p = args[i] 50 | let i += 1 51 | endif 52 | if list[3] != '' 53 | for path in split(list[3],'\.') 54 | let tmp = p[path] | unlet p | let p = tmp 55 | endfor 56 | endif 57 | if list[2] == 'p' 58 | let p = expand(fnameescape(p), 1) 59 | endif 60 | let r .= shellescape(p, a:special).x[len(list[0]):] 61 | unlet p 62 | endfor 63 | return r 64 | endfun 65 | 66 | fun! s:Cmd(expect_code_0, cmd) abort 67 | call vam#Log(a:cmd, 'PreProc') 68 | if s:c.shell_commands_run_method[-4:] is# 'bang' 69 | execute '!'.a:cmd 70 | elseif s:c.shell_commands_run_method is# 'system' 71 | call vam#Log(system(a:cmd), 'None') 72 | else 73 | throw 'Unknown run method: '.s:c.shell_commands_run_method 74 | endif 75 | if a:expect_code_0 && v:shell_error != 0 76 | let s:c.last_shell_command = a:cmd 77 | throw "Command “".a:cmd."” exited with error code ".v:shell_error 78 | endif 79 | return v:shell_error 80 | endfun 81 | 82 | " TODO improve this and move somewhere else? 83 | fun! vam#utils#RunShell(...) abort 84 | let special=(s:c.shell_commands_run_method[-4:] is# 'bang') 85 | let cmd = call('s:ShellDSL', [special]+a:000) 86 | return s:Cmd(0, cmd) 87 | endfun 88 | 89 | fun! vam#utils#ExecInDir(dir, ...) abort 90 | let special=(s:c.shell_commands_run_method[-4:] is# 'bang') 91 | if g:is_win 92 | " set different lcd in extra buffer: 93 | new 94 | try 95 | execute 'lcd' fnameescape(a:dir) 96 | let cmd=call('s:ShellDSL', [special]+a:000) 97 | call s:Cmd(1, cmd) 98 | finally 99 | bw! 100 | endtry 101 | else 102 | let cmd=s:ShellDSL(special, 'cd $p', a:dir).' && '. 103 | \ call('s:ShellDSL', [special]+a:000) 104 | call s:Cmd(1, cmd) 105 | endif 106 | endfun 107 | 108 | fun! vam#utils#System(...) 109 | let cmd=call('s:ShellDSL', [0]+a:000) 110 | let r=system(cmd) 111 | if v:shell_error 112 | return 0 113 | endif 114 | return r 115 | endfun 116 | 117 | "Usages: EndsWith('name.tar', '.tar', '.txt') returns 1 even if .tar was .txt 118 | fun! s:EndsWith(name, ...) 119 | return a:name =~? '\%('.substitute(join(a:000,'\|'),'\.','\\.','g').'\)$' 120 | endfun 121 | 122 | " Warning: Currently hooks should not depend on order of their execution 123 | let s:post_unpack_hooks={} 124 | fun s:post_unpack_hooks.fix_layout(opts, targetDir, fixDir) 125 | " if there are *.vim files but no */**/*.vim files they layout is likely to 126 | " be broken. Try fixing it 127 | let rtpvimfiles=vam#GlobInDir(a:targetDir, '*.vim') 128 | if !empty(rtpvimfiles) && empty(glob(fnameescape(a:targetDir).'/*/**/*.vim', 1)) 129 | " also see [fix-layout] 130 | 131 | " fixing .vim file locations was missed above. So fix it now 132 | " example plugin requiring this: sketch 133 | if (!isdirectory(a:fixDir)) 134 | call mkdir(a:fixDir, 'p') 135 | endif 136 | for f in map(rtpvimfiles, 'fnamemodify(v:val, ":t")') 137 | call rename(a:targetDir.'/'.f, a:fixDir.'/'.f) 138 | endfor 139 | endif 140 | endfun 141 | fun s:post_unpack_hooks.change_to_unix_ff(opts, targetDir, fixDir) 142 | if get(a:opts, 'unix_ff', 0) 143 | for f in filter(vam#GlobInDir(a:targetDir, '**/*.vim'), 'filewritable(v:val)==1') 144 | call writefile(map(readfile(f, 'b'), 145 | \'((v:val[-1:] is# "\r")?(v:val[:-2]):(v:val))'), f, 'b') 146 | endfor 147 | endif 148 | endfun 149 | 150 | fun! s:StripIfNeeded(opts, targetDir) 151 | let strip_components = get(a:opts, 'strip-components', -1) 152 | 153 | if strip_components!=0 154 | call vam#utils#StripComponents(a:targetDir, strip_components, [a:targetDir.'/archive']) 155 | endif 156 | endfun 157 | 158 | fun! vam#utils#GuessFixDir(type) 159 | if stridx(a:type, '/') != -1 || a:type =~# '\v^%(syntax|indent|%(ft)?plugin)$' 160 | return a:type 161 | elseif a:type is# 'color scheme' 162 | return 'colors' 163 | else 164 | return 'plugin' 165 | endif 166 | endfun 167 | 168 | " may throw EXCEPTION_UNPACK.* 169 | " most packages are shipped in a directory. Eg ADDON/plugin/* 170 | " strip-components=1 strips of this ADDON directory (implemented for tar.* " archives only) 171 | " 172 | " assumes the dir containing archive is writable to place tmp files in. eg 173 | " .tar when unpacking .tar.gz. because gunzip and bunzip2 remove the original 174 | " file a backup is made if del-source is not set. However file permissions may 175 | " no tbe preserved. I don't think its worth fixing. If you think different 176 | " contact me. 177 | 178 | " !! If you change this run the test, please: call vim_addon_manager_tests#Tests('.') 179 | fun! vam#utils#Unpack(archive, targetDir, ...) 180 | let opts = a:0 > 0 ? a:1 : {} 181 | let delSource = get(opts, 'del-source', 0) 182 | 183 | " [ ending, chars to strip, chars to add, command to do the unpacking ] 184 | let gzbzip2 = { 185 | \ '.xz': [-4, '', 'xz -d ' ], 186 | \ '.txz': [-3, 'ar', 'xz -d ' ], 187 | \ '.gz': [-4, '', 'gzip -d' ], 188 | \ '.tgz': [-3, 'ar', 'gzip -d' ], 189 | \ '.bz2': [-5, '', 'bzip2 -d'], 190 | \ '.tbz2': [-4, 'ar', 'bzip2 -d'], 191 | \ '.tbz': [-3, 'ar', 'bzip2 -d'], 192 | \ } 193 | 194 | 195 | let fixDir = a:targetDir.'/'. 196 | \ ( has_key(opts,'target_dir') 197 | \ ? opts.target_dir 198 | \ : vam#utils#GuessFixDir(get(opts, 'script-type', 'plugin'))) 199 | 200 | " 7z renames .tbz, .tbz2, .tar.bz2 to .tar, but it preserves names stored by 201 | " gzip (if any): if you do 202 | " tar -cf ../abc.tar . && gzip ../abc.tar && mv ../abc.tar.gz ../def.tar.gz 203 | " you will find that “7z x ../def.tar.gz” unpacks archive “abc.tar” because 204 | " gzip stored its name. 205 | let use_7z=(!s:c.omit_7z && executable('7z')) 206 | 207 | " .vim file and type syntax? 208 | if a:archive =~? '\.vim$' 209 | " hook for plugin / syntax files: Move into the correct direcotry: 210 | if (!isdirectory(fixDir)) 211 | call mkdir(fixDir, 'p') 212 | endif 213 | " also see [fix-layout] 214 | call writefile(readfile(a:archive,'b'), fixDir.'/'.fnamemodify(a:archive, ':t'), 'b') 215 | 216 | " .gz, .xz, .bz2 (or .vba.* or .tar.*) 217 | elseif call(function('s:EndsWith'), [a:archive] + keys(gzbzip2) ) 218 | " I was told tar on Windows is buggy and can't handle xj or xz correctly 219 | " so unpack in two phases: 220 | for [k,z] in items(gzbzip2) 221 | if s:EndsWith(a:archive, k) 222 | " without ext 223 | let unpacked = a:archive[:z[0]] 224 | " correct ext 225 | let renameTo = unpacked.z[1] 226 | 227 | " PHASE (1): gunzip or bunzip using gzip,bzip2 or 7z: 228 | if use_7z 229 | call vam#utils#RunShell('7z x -o$ $', fnamemodify(a:archive, ':h'), a:archive) 230 | else 231 | " make a backup. gunzip etc rm the original file 232 | if !delSource 233 | let b = a:archive.'.bak' 234 | call vam#utils#CopyFile(a:archive, b) 235 | endif 236 | 237 | " unpack 238 | call vam#utils#RunShell(z[2].' $', a:archive) 239 | 240 | " copy backup back: 241 | if !delSource | call rename(b, a:archive) | endif 242 | endif 243 | 244 | if !filereadable(renameTo) 245 | " Windows gzip does not rename .tgz to .tar ? 246 | call rename(unpacked, renameTo) 247 | endif 248 | 249 | " PHASE (2): now unpack .tar or .vba file and tidy up temp file: 250 | call vam#utils#Unpack(renameTo, a:targetDir, extend({'del-source': 1}, opts)) 251 | call delete(renameTo) 252 | break 253 | endif 254 | unlet k z 255 | endfor 256 | 257 | " .tar 258 | elseif s:EndsWith(a:archive, '.tar') 259 | if use_7z 260 | call vam#utils#RunShell('7z x -o$ $', a:targetDir, a:archive) 261 | else 262 | call vam#utils#ExecInDir(a:targetDir, 'tar -xf $', a:archive) 263 | endif 264 | call s:StripIfNeeded(opts, a:targetDir) 265 | 266 | " .zip 267 | elseif s:EndsWith(a:archive, '.zip') 268 | if use_7z 269 | call vam#utils#RunShell('7z x -o$ $', a:targetDir, a:archive) 270 | else 271 | call vam#utils#ExecInDir(a:targetDir, 'unzip $', a:archive) 272 | endif 273 | call s:StripIfNeeded(opts, a:targetDir) 274 | 275 | " .7z, .cab, .rar, .arj, .jar 276 | " (I have actually seen only .7z and .rar, but 7z supports other formats too) 277 | elseif s:EndsWith(a:archive, '.7z','.cab','.arj','.rar','.jar') 278 | call vam#utils#RunShell('7z x -o$ $', a:targetDir, a:archive) 279 | call s:StripIfNeeded(opts, a:targetDir) 280 | 281 | elseif s:EndsWith(a:archive, '.vba','.vmb') 282 | " .vba reuse vimball#Vimball() function 283 | exec 'sp '.fnameescape(a:archive) 284 | call vimball#Vimball(1,a:targetDir) 285 | " wipe out buffer 286 | bw! 287 | else 288 | throw "EXCEPTION_UNPACK: don't know how to unpack ". a:archive 289 | endif 290 | 291 | if delSource && filereadable(a:archive) 292 | call delete(a:archive) 293 | endif 294 | 295 | let hargs=[opts, a:targetDir, fixDir] 296 | for key in keys(s:post_unpack_hooks) 297 | call call(s:post_unpack_hooks[key], hargs, {}) 298 | endfor 299 | endfun 300 | 301 | 302 | " move */* one level up, then remove first * matches 303 | " if you don't want all dirs to be removed add them to keepdirs 304 | " Example: 305 | " 306 | " A/activte/file.tar 307 | " A/the-plugin/ftplugin/... 308 | " A/the-plugin/autoload/... 309 | " StripComponents(A, 1, "^activate") 310 | " will yield strip the-plugin directory off. 311 | " 312 | " This emulatios tar --strip-components option (which is not present in 7z or 313 | " unzip) 314 | " 315 | " If num==-1, then StripComponents will strip only if it finds that there is 316 | " only one directory that needs stripping 317 | fun! vam#utils#StripComponents(dir, num, keepdirs) 318 | let num = a:num 319 | let strip_single_dir = 0 320 | if num == -1 321 | let num = 1 322 | let strip_single_dir = 1 323 | endif 324 | for i in range(0, num-1) 325 | let tomove = [] 326 | let toremove = [] 327 | " for each a:dir/* 328 | for gdir in filter(vam#GlobInDir(a:dir, '*'),'isdirectory(v:val)') 329 | if index(a:keepdirs, gdir)!=-1 | continue | endif 330 | call add(toremove, gdir) 331 | if strip_single_dir && len(toremove)>=2 332 | return 333 | endif 334 | " for each gdir/* 335 | for path in vam#GlobInDir(gdir, '*') 336 | " move out of dir 337 | call add(tomove, [path, a:dir.'/'.fnamemodify(path, ':t')]) 338 | endfor 339 | endfor 340 | if strip_single_dir && !empty(toremove) && toremove[0]=~#'\v/%(autoload|colors|compiler|ftplugin|indent|keymap|lang|plugin|print|spell|syntax)$' 341 | return 342 | endif 343 | call map(tomove, 'rename(v:val[0], v:val[1])') 344 | call map(toremove, 'vam#utils#RmFR(v:val)') 345 | endfor 346 | endfun 347 | 348 | " also copies 0. May throw an exception on failure 349 | fun! vam#utils#CopyFile(a, b) abort 350 | let fc = readfile(a:a, 'b') 351 | if writefile(fc, a:b, 'b') != 0 352 | throw "copying file ".a:a." to ".a:b." failed" 353 | endif 354 | endfun 355 | 356 | fun! vam#utils#Download(url, targetFile) 357 | if s:http_cmd is 0 358 | throw "Neither curl nor wget was found. Either set g:netrw_http_cmd or put one of them in PATH" 359 | endif 360 | " allow redirection because of sourceforge mirrors: 361 | call vam#utils#RunShell(s:http_cmd.' $p $', a:targetFile, a:url) 362 | endfun 363 | 364 | fun! vam#utils#RmFR(dir_or_file) 365 | let cmd = "" 366 | if has('win32') || has('win64') 367 | if getftype(a:dir_or_file) == 'dir' 368 | let cmd = 'rmdir /S /Q' 369 | else 370 | let cmd = 'erase /F' 371 | endif 372 | elseif has('win16') || has('win95') 373 | " Dos-style COMMAND.COM. These are _UNTESTED_ 374 | if getftype(a:dir_or_file) == 'dir' 375 | let cmd = 'deltree /Y' 376 | else 377 | let cmd = 'erase /F' 378 | endif 379 | else 380 | let cmd = "rm -fr" 381 | endif 382 | if empty(cmd) 383 | throw "Don't know how to recursively remove directory on ".g:os." system" 384 | else 385 | call vam#utils#RunShell(cmd.' $', a:dir_or_file) 386 | endif 387 | endfun 388 | 389 | 390 | " a "direct link" (found on the download page) 391 | " such as "http://downloads.sourceforge.net/project/gnuwin32/gzip/1.3.12-1/gzip-1.3.12-1-bin.zip" 392 | " can be downloaded this way: 393 | " call vam#utils#DownloadFromMirrors("mirror://sourceforge/gnuwin32/gzip/1.3.12-1/gzip-1.3.12-1-bin.zip","/tmp") 394 | fun! vam#utils#DownloadFromMirrors(url, targetDir) 395 | let mirrors_sourceforge = [ 396 | \ 'http://heanet.dl.sourceforge.net/sourceforge/', 397 | \ 'http://surfnet.dl.sourceforge.net/sourceforge/', 398 | \ ] 399 | 400 | let m = matchlist(a:url, '^mirror:\/\/\([^/\\]\+\)\/\(.*\)') 401 | 402 | if len(m) > 3 403 | let url = mirrors_{m[1]}[0].m[2] 404 | endif 405 | " if target is a directory append basename of url 406 | let t = a:targetDir 407 | if isdirectory(t) 408 | let t = t .'/'.fnamemodify(url,':t') 409 | endif 410 | call vam#utils#Download(url, t) 411 | endfun 412 | 413 | 414 | let s:tmpDir = "" 415 | " this is not cleaned up on shutdown yet ! 416 | " tmpname(): 417 | " on windows C:\Users\NAME\AppData\Local\Temp\VIG3DB6.tmp 418 | " on linux /tmp/v106312/111 419 | " 420 | " on linux this returns /tmp/a:name 421 | " on windows it returns C:\Users\NAME\AppData\Local\Temp/a:name 422 | fun! vam#utils#TempDir(name) 423 | if s:tmpDir == "" 424 | let s:tmpDir = fnamemodify(tempname(), ":h".(g:is_win ? '': ':h')) 425 | endif 426 | " expand make \ out of / on Windows 427 | return expand(s:tmpDir.'/'.a:name, 1) 428 | endfun 429 | 430 | " tries finding a new name if a plugin was renamed. 431 | " Also tries to provide suggestions if you made trivial typos (case, 432 | " forgetting _ special characters and such) 433 | fun! vam#utils#TypoFix(name) 434 | return substitute(tolower(a:name), '[_/\-]*', '', 'g') 435 | endfun 436 | 437 | 438 | "{{{1 Completion 439 | " sample usage: 440 | " inoremap \start_completion vam#utils#CompleteWith("vam#install#CompleteAddonName")' 441 | let s:savedomnifuncs={} 442 | fun! vam#utils#CompleteWith(fun) 443 | if &l:omnifunc isnot# a:fun 444 | let s:savedomnifuncs[bufnr('%')]=&l:omnifunc 445 | call s:SetRestoringOmnifuncAutocommands() 446 | let &l:omnifunc=a:fun 447 | endif 448 | return "\\" 449 | endfun 450 | 451 | " Restore &omnifunc when different events are launched 452 | fun! s:SetRestoringOmnifuncAutocommands() 453 | let buf=bufnr('%') 454 | let restoreofcode='if has_key(s:savedomnifuncs, '.buf.') | '. 455 | \ 'let &l:omnifunc=remove(s:savedomnifuncs, '.buf.') | '. 456 | \ 'endif' 457 | let restoreofifnotpumvisible='if !pumvisible() | '.restoreofcode.' | endif' 458 | augroup VAM_restore_completion 459 | if exists('##InsertCharPre') 460 | execute 'autocmd! InsertCharPre '.restoreofifnotpumvisible 461 | else 462 | execute 'autocmd! CursorHoldI '.restoreofifnotpumvisible 463 | endif 464 | execute 'autocmd! InsertLeave '.restoreofcode 465 | augroup END 466 | endfun 467 | "}}}1 468 | 469 | " vim: et ts=8 sts=2 sw=2 470 | -------------------------------------------------------------------------------- /autoload/vam/vcs.vim: -------------------------------------------------------------------------------- 1 | " eventually this code will be moved into its own plugin in the future. Cause 2 | " its very short probably VAM will keep a copy 3 | 4 | exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}') 5 | let s:c.scms = get(s:c, 'scms', {}) 6 | 7 | " What's important about these configurations ? 8 | " 9 | " s:c.scms.{scm}.clone are called with additional (repository, targetDir), 10 | " absense of targetDir indicates failure 11 | " s:c.scms.{scm}.update are called with additional (repository), non-zero return 12 | " value indicates failure 13 | " 14 | " Both should contain list that looks like if you are going to do the job using 15 | " `call call("call", s:scms.{scm}.{key})'. 16 | " 17 | " You can explicitely set executable location using 18 | " 19 | " Thus you can overwrite them and implement whatever behaviour you like. 20 | " The default implemenation should be close to what users expect from the VCS 21 | " being used. However if you prefer mercurial overriding git_checkout is the 22 | " way to make mercurial checkout git repos instead (like ZyX ? :) 23 | " 24 | " Later we can even add additional implementations telling user that upstream 25 | " has changed etc .. (TODO) 26 | 27 | fun! vam#vcs#GitCheckoutFixDepth(repository, targetDir) 28 | " older git versions don't support shallow clone, check by reading --help 29 | " output 30 | " 31 | " Neither does google code support it (yet) 32 | let use_shallow_clone = s:c.scms.git.supports_shallow_clone 33 | 34 | if (use_shallow_clone is# 'auto') 35 | unlet use_shallow_clone 36 | let use_shallow_clone = g:is_win ? 1 : (executable('git') && stridx(system('git help --man clone'), '--depth')!=-1) 37 | endif 38 | let use_shallow_clone = use_shallow_clone && a:repository.url !~? 'code\.google\.com' 39 | 40 | let git_checkout='git clone --recursive '.(use_shallow_clone ? '--depth 1' : '').' $.url $p' 41 | return vam#utils#RunShell(git_checkout, a:repository, a:targetDir) 42 | endf 43 | 44 | let s:scm_defaults={ 45 | \ 'git': {'clone': ['vam#vcs#GitCheckoutFixDepth', []], 46 | \ 'update': ['vam#utils#RunShell', ['cd $p && git pull' ]], 47 | \ 'wdrev': ['vam#utils#System', ['git --git-dir=$p/.git rev-parse HEAD']], 48 | \ 'log': ['vam#utils#System', ['git --git-dir=$2p/.git log $1 $[3]..$[4]', '--pretty=format:%s%n']], 49 | \ 'supports_shallow_clone': 'auto', 50 | \ }, 51 | \ 'hg': {'clone': ['vam#utils#RunShell', ['hg clone $.url $p' ]], 52 | \ 'update': ['vam#utils#RunShell', ['hg pull -u -R $p' ]], 53 | \ 'wdrev': ['vam#utils#System', ['hg log --template $ -R $p -r .', '{rev}']], 54 | \ 'log': ['vam#vcs#MercurialLog', []],}, 55 | \ 'bzr': {'clone': ['vam#utils#RunShell', ['bzr branch $.url $p' ]], 56 | \ 'update': ['vam#utils#RunShell', ['bzr pull -d $p' ]], 57 | \ 'wdrev': ['vam#utils#System', ['bzr revno --tree $p' ]], 58 | \ 'log': ['vam#vcs#RunWithIncrementedRev', ['bzr log --short $p -r $[]..$[]']],}, 59 | \ 'svn': {'clone': ['vam#vcs#SVNCheckout',[]], 60 | \ 'update': ['vam#utils#RunShell', ['svn update $p' ]], 61 | \ 'wdrev': ['vam#vcs#SVNWdrev', []], 62 | \ 'log': ['vam#vcs#RunWithIncrementedRev', ['svn log $p -r $[]:$[]']],}, 63 | \'darcs': {'clone': ['vam#utils#RunShell', ['darcs get --lazy $.url $p']], 64 | \ 'update': ['vam#utils#RunShell', ['darcs pull --all --repodir $p' ]], 65 | \ 'wdrev': ['vam#vcs#DarcsWdrev', []], 66 | \ 'log': ['vam#vcs#DarcsLog', []],}, 67 | \'_bundle': {'update': ['vam#vcs#UpdateBundle', []],}, 68 | \} 69 | let s:c.scms=get(s:c, 'scms', {}) 70 | call map(filter(copy(s:c.scms), 'has_key(s:scm_defaults, v:key)'), 'extend(v:val, s:scm_defaults[v:key], "keep")') 71 | call extend(s:c.scms, s:scm_defaults, 'keep') 72 | call map(copy(s:c.scms), 'extend(v:val, {"dir": ".".v:key})') 73 | let s:c.scms.darcs.dir='_darcs' 74 | 75 | fun! vam#vcs#RunWithIncrementedRev(...) 76 | let args=copy(a:000) 77 | let args[-2]+=1 78 | return call('vam#utils#System', args) 79 | endfun 80 | 81 | fun! vam#vcs#MercurialLog(targetDir, oldVersion, newVersion) 82 | " Note: this will show nothing if oldVersion is not an ancestor of 83 | " a newVersion. Mercurial should not update with the above command in 84 | " this case though. 85 | return call('vam#utils#System', ['hg log --template $ -R $p -r $', '{desc}\n', a:targetDir, 86 | \ a:oldVersion.'..'.a:newVersion.' and not '.a:oldVersion]) 87 | endfun 88 | 89 | fun! vam#vcs#DarcsLog(targetDir, oldVersion, newVersion) 90 | return call('vam#utils#System', ['darcs log --repodir $p --last=$', a:targetDir, a:newVersion-a:oldVersion]) 91 | endfun 92 | 93 | fun! vam#vcs#DarcsWdrev(targetDir) 94 | let result=vam#utils#System('darcs show repo --repodir $p', a:targetDir) 95 | return substitute(result, '\v.*\n\s*Num\ Patches\:\ (\d+).*', '\1', '') 96 | endfun 97 | 98 | fun! vam#vcs#SVNWdrev(targetDir) 99 | let result=vam#utils#System('svn info $p', a:targetDir) 100 | return substitute(result, '\v.{-}\nRevision\:\ (\d+).*', '\1', '') 101 | endfun 102 | 103 | fun! s:WriteBundleDir(targetDir, url, archive) 104 | call mkdir(a:targetDir.'/._bundle') 105 | call writefile([a:url, a:archive], a:targetDir.'/._bundle/opts', 'b') 106 | endfun 107 | 108 | fun! vam#vcs#UrlFromRepository(repository) 109 | let [dummystr, protocol, user, domain, port, path; dummylst]= 110 | \matchlist(a:repository.url, '\v^%(([^:]+)\:\/\/)?'. 111 | \ '%(([^@/:]+)\@)?'. 112 | \ '([^/:]*)'. 113 | \ '%(\:(\d+))?'. 114 | \ '(.*)$') 115 | if domain is? 'github.com' 116 | let url='https://'.domain.'/'.substitute(path, '\v^[:/]|\.git$', '', 'g').'/zipball/master' 117 | let archive='master.zip' 118 | elseif domain is? 'bitbucket.org' 119 | let url='https://'.domain.path.'/get/default.zip' 120 | let archive='default.zip' 121 | elseif domain is? 'git.devnull.li' 122 | let url='http://'.domain.path.'/snapshot/master.tar.gz' 123 | let archive='master.tar.gz' 124 | else 125 | throw 'Don’t know how to get bundle from '.domain 126 | endif 127 | return {'archive': archive, 'url': url} 128 | endfun 129 | 130 | fun! vam#vcs#GetBundle(repository, targetDir) 131 | let x = vam#vcs#UrlFromRepository(a:repository) 132 | call vam#install#Checkout(a:targetDir, {'type': 'archive', 'url': x.url, 'archive_name': x.archive}) 133 | call s:WriteBundleDir(a:targetDir, url, archive) 134 | return 0 135 | endfun 136 | 137 | fun! vam#vcs#UpdateBundle(targetDir) 138 | let [url, archive]=readfile(a:targetDir.'/._bundle/opts', 'b') 139 | call vam#utils#RmFR(a:targetDir) 140 | call vam#install#Checkout(a:targetDir, {'type': 'archive', 'url': url, 'archive_name': archive}) 141 | call s:WriteBundleDir(a:targetDir, url, archive) 142 | return 0 143 | endfun 144 | 145 | fun! s:TryCmd(...) 146 | try 147 | return call('vam#utils#RunShell', a:000) 148 | catch 149 | return 1 150 | endtry 151 | endfun 152 | fun! s:TryCmdSilent(...) 153 | silent return call('s:TryCmd', a:000) 154 | endfun 155 | 156 | fun! vam#vcs#GitCheckout(repository, targetDir) 157 | if executable('git') 158 | return vam#vcs#GitCheckoutFixDepth(a:repository, a:targetDir) 159 | elseif executable('hg') && !s:TryCmdSilent('hg help gexport') 160 | call vam#Log('Trying to checkout git source '.a:repository.url.' using mercurial.', 'None') 161 | return s:TryCmd('hg clone $ $p', ((a:repository.url[:2] is# 'git')? 162 | \ (a:repository.url): 163 | \ ('git+'.a:repository.url)), 164 | \ a:targetDir) 165 | elseif executable('bzr') && !s:TryCmdSilent('bzr help git') 166 | call vam#Log('Trying to checkout git source '.a:repository.url.' using bazaar.', 'None') 167 | return s:TryCmd('bzr branch $.url $p', a:repository, a:targetDir) 168 | else 169 | call vam#Log('Trying to checkout git source '.a:repository.url." using site bundles.\n". 170 | \ 'Please consider installing git or mercurial with hg-git extension', 'WarningMsg') 171 | return vam#vcs#GetBundle(a:repository, a:targetDir) 172 | endif 173 | endfun 174 | 175 | fun! vam#vcs#MercurialCheckout(repository, targetDir) 176 | if executable('hg') 177 | return vam#utils#RunShell('hg clone $.url $p', a:repository, a:targetDir) 178 | else 179 | call vam#Log('Trying to checkout mercurial source '.a:repository.url." using site bundles.\n". 180 | \ 'Please consider installing git or mercurial with hg-git extension', 'WarningMsg') 181 | return vam#vcs#GetBundle(a:repository, a:targetDir) 182 | endif 183 | endfun 184 | 185 | fun! vam#vcs#SVNCheckout(repository, targetDir) 186 | let args=['svn checkout $.url $3p', a:repository, a:repository.url, a:targetDir] 187 | for key in filter(['username', 'password'], 'has_key(a:repository, v:val)') 188 | let args[0].=' --'.key.' $' 189 | let args+=[a:repository[key]] 190 | endfor 191 | call call('vam#utils#RunShell', args) 192 | endfun 193 | 194 | fun! vam#vcs#SubversionCheckout(repository, targetDir) 195 | " Both mercurial and bazaar are slow in this case because they request full 196 | " changeset history from the server, while subversion does not. 197 | if executable('svn') 198 | return vam#vcs#SVNCheckout(a:repository, a:targetDir) 199 | elseif executable('hg') && !s:TryCmdSilent('hg help svn') 200 | call vam#Log('Trying to checkout subversion source '.a:repository.url." using mercurial.\n". 201 | \ 'You may consider installing svn as using mercurial is slower', 'WarningMsg') 202 | return s:TryCmd('hg clone $.url $p', a:repository, a:targetDir) 203 | elseif executable('bzr') && !s:TryCmdSilent('bzr help svn') 204 | call vam#Log('Trying to checkout subversion source '.a:repository.url." using bazaar.\n". 205 | \ 'You may consider installing subversion as using bazaar is slower', 'WarningMsg') 206 | return s:TryCmd('bzr branch $.url $p', a:repository, a:targetDir) 207 | endif 208 | return 1 209 | endfun 210 | 211 | " Accepts VCS root 212 | " Returns a 4-tuple (status, old revision, new revision, scms.* dictionary) 213 | fun! vam#vcs#Update(dir) 214 | for [scm, sdescr] in items(s:c.scms) 215 | if isdirectory(a:dir.'/'.(sdescr.dir)) 216 | break 217 | endif 218 | unlet sdescr 219 | endfor 220 | 221 | if !exists('sdescr') 222 | return ['unknown', 0, 0, 0] 223 | endif 224 | 225 | if has_key(sdescr, 'wdrev') 226 | let w=sdescr.wdrev 227 | let wdrev=call(w[0], get(w, 1, [])+[a:dir], get(w, 2, {})) 228 | else 229 | let wdrev=0 230 | endif 231 | let c=sdescr.update 232 | if call(c[0], c[1] + [a:dir], get(c, 2, {})) 233 | call vam#Log('Updating '.a:dir.' failed. The :AddonInfo command may tell you about a new upstream source. If in doubt move the plugin directory somewhere else, install it from scratch and check the differences') 234 | return ['failed', wdrev, 0, sdescr] 235 | endif 236 | 237 | if exists('wdrev') && wdrev isnot 0 238 | let newwdrev=call(w[0], get(w, 1, [])+[a:dir], get(w, 2, {})) 239 | if newwdrev is 0 240 | return ['possibly updated', wdrev, 0, sdescr] 241 | elseif wdrev isnot# newwdrev 242 | return ['updated', wdrev, newwdrev, sdescr] 243 | else 244 | return ['up-to-date', wdrev, newwdrev, sdescr] 245 | endif 246 | else 247 | return ['possibly updated', 0, 0, sdescr] 248 | endif 249 | endfun 250 | 251 | " repository = {'type': git|hg|svn|bzr, 'url': .. } 252 | fun! vam#vcs#Checkout(targetDir, repository) 253 | if has_key(s:c.scms, a:repository.type) 254 | let c=s:c.scms[a:repository.type].clone 255 | if call(c[0], get(c, 1, [])+[a:repository, a:targetDir], get(c, 2, {})) 256 | throw "Failed to checkout addon to ".a:targetDir."." 257 | endif 258 | else 259 | " Keep old behavior: no throw for unknown repository type 260 | return 261 | endif 262 | if !isdirectory(a:targetDir) 263 | throw "Failure. Plugin directory ".a:targetDir." should have been created but does not exist." 264 | endif 265 | return 1 266 | endfun 267 | 268 | " vim: et ts=8 sts=2 sw=2 269 | -------------------------------------------------------------------------------- /autoload/vcs_checkouts.vim: -------------------------------------------------------------------------------- 1 | " Other functions were not mentioned in documentation 2 | for s:f in ['GitCheckout', 'MercurialCheckout', 'SubversionCheckout'] 3 | let s:old='vcs_checkouts#'.s:f 4 | let s:new='vam#vcs#'.s:f 5 | execute "function! ".s:old."(...)\n". 6 | \"call vam#Log('".s:old." is deprecated. Use ".s:new."')\n". 7 | \"return call('".s:new."', a:000)\n". 8 | \"endfunction" 9 | endfor 10 | unlet s:f s:old s:new 11 | -------------------------------------------------------------------------------- /autoload/vundle.vim: -------------------------------------------------------------------------------- 1 | exec vam#DefineAndBind('s:c','g:vim_addon_manager','{}') 2 | 3 | " VAM's bundle emulation: usage like vundle: 4 | " 5 | " set rtp+=~/.vim/bundle/vim-addon-manager 6 | " " let g:vim_addon_manager = {} 7 | " " let g:vim_addon_manager.option = ... 8 | " call vundle#rc() 9 | " Bundle ABC/FOO 10 | " Bundle Z 11 | 12 | func! vundle#rc(...) abort 13 | let g:bundle_dir = len(a:000) > 0 ? expand(a:1, 1) : expand('$HOME/.vim/bundle', 1) 14 | 15 | " TODO take care about these options ? 16 | " let g:updated_bundles = [] 17 | " let g:vundle_log = [] 18 | " let g:vundle_changelog = ['Updated Bundles:'] 19 | 20 | let s:c.plugin_root_dir = g:bundle_dir 21 | 22 | " adopt to vundles directory naming 23 | let s:c.plugin_dir_by_name = 'vundle#PluginDirFromName' 24 | 25 | command! -nargs=* Bundle call vundle#Bundle() 26 | " Some commands and options are missing, could be implemented trivially 27 | " If you hit such a case create an issue and we'll fix it. 28 | endf 29 | 30 | fun! vundle#BundleToVamName(name) 31 | " TODO file:// syntax and the like ? 32 | " TODO gh: syntax 33 | 34 | if a:name =~ '/' 35 | " assume github 36 | return 'github:'.a:name 37 | elseif a:name =~ '^gh:' 38 | return substitute(a:name, '^gh:','github:','') 39 | else 40 | " asume directory in bundle 41 | return a:name 42 | endif 43 | endfun 44 | 45 | fun! vundle#Bundle(...) 46 | let args = a:000 47 | if a:0 != 1 48 | throw "VAM's bundle emulation only supports simple arguments - create a github account at github.com/MarcWeber/vim-addon-manager/issues/new" 49 | endif 50 | let stripped = substitute(a:1, "['\"]", "", 'g') 51 | if stripped =~ '\ 69 | :h plugin 70 | tells you about the old manual way of installing plugins. VAM helps keeping 71 | ~/.vim clean by separating plugins from each other. 72 | 73 | Features: 74 | - Separate directories for each plugins 75 | - Dependency resolution 76 | - Popular VCS support: plugin supports fetching from Git, Mercurial, 77 | Subversion, Bazaar and Darcs repositories 78 | - maintained pool of addons (vim-pi) 79 | which warns you if you try to install an outdated plugin 80 | (have a look at it online : http://mawercer.de/~marc/vam/index.php) 81 | - replicate your Vim setup by copying your .vimrc (See SetupVAM) 82 | - load plugins lazily when Vim is already running. Some plugins require 83 | additional tweaks for this to work 84 | 85 | Dependencies: 86 | - Curl, wget or other program that can output URL contents to stdout (in 87 | order to get http protocol support) 88 | - Git, Mercurial, Subversion, Bazaar and Darcs (if you want to install 89 | plugins from appropriate repositories) 90 | - Either tar, gzip and zip or 7-zip (required for unpacking some addons) 91 | 92 | What does "Declarative package manager" mean? The final behaviour of Vim 93 | should be declared once. Your ~/.vimrc and |:UpdateAddons| should be enough 94 | to cause same Vim behaviour everywhere. 95 | 96 | Note: “Addon” here is a synonym for “plugin”: “a related collection of files 97 | enhancing vim functionality”. “Plugin” may also mean “a .vim file inside 98 | a plugin directory” hence using “addon”. 99 | 100 | ============================================================================== 101 | 2. Installation *VAM-installation* 102 | 103 | Windows users: skim |VAM-windows|. 104 | Gentoo users : skim |VAM-gentoo| which explains how to install VAM system-wide 105 | from the layman overlay. 106 | 107 | Rest (linux and everything able to run POSIX shell) users should keep reading 108 | here. 109 | 110 | Minimal setup ~ 111 | This is the minimal setup which makes VAM work. 112 | However you may want to use the longer commented version below because it 113 | also fetches VAM so that copying your .vimrc is enough to replicate your 114 | setup. 115 | 116 | Add to your .vimrc > 117 | set runtimepath+=PATH-TO-VAM 118 | call vam#ActivateAddons([.. list of plugin names ..], {'auto_install' : 0}) 119 | 120 | recommended setup ~ 121 | 1) Paste the following to your .vimrc. 122 | 2) Read the comments carefully. They help you getting started. Then you can 123 | remove them. 124 | 3) Add addon names to the ActivateAddons call, start Vim. That’s all. 125 | 126 | commented version ~ 127 | > 128 | " put this line first in ~/.vimrc 129 | set nocompatible | filetype indent plugin on | syn on 130 | 131 | fun! EnsureVamIsOnDisk(plugin_root_dir) 132 | " windows users may want to use http://mawercer.de/~marc/vam/index.php 133 | " to fetch VAM, VAM-known-repositories and the listed plugins 134 | " without having to install curl, 7-zip and git tools first 135 | " -> BUG [4] (git-less installation) 136 | let vam_autoload_dir = a:plugin_root_dir.'/vim-addon-manager/autoload' 137 | if isdirectory(vam_autoload_dir) 138 | return 1 139 | else 140 | if 1 == confirm("Clone VAM into ".a:plugin_root_dir."?","&Y\n&N") 141 | " I'm sorry having to add this reminder. Eventually it'll pay off. 142 | call confirm("Remind yourself that most plugins ship with ". 143 | \"documentation (README*, doc/*.txt). It is your ". 144 | \"first source of knowledge. If you can't find ". 145 | \"the info you're looking for in reasonable ". 146 | \"time ask maintainers to improve documentation") 147 | call mkdir(a:plugin_root_dir, 'p') 148 | execute '!git clone --depth=1 https://github.com/MarcWeber/vim-addon-manager '. 149 | \ shellescape(a:plugin_root_dir, 1).'/vim-addon-manager' 150 | " VAM runs helptags automatically when you install or update 151 | " plugins 152 | exec 'helptags '.fnameescape(a:plugin_root_dir.'/vim-addon-manager/doc') 153 | endif 154 | return isdirectory(vam_autoload_dir) 155 | endif 156 | endfun 157 | 158 | fun! SetupVAM() 159 | " Set advanced options like this: 160 | " let g:vim_addon_manager = {} 161 | " let g:vim_addon_manager.key = value 162 | " Pipe all output into a buffer which gets written to disk 163 | " let g:vim_addon_manager.log_to_buf =1 164 | 165 | " Example: drop git sources unless git is in PATH. Same plugins can 166 | " be installed from www.vim.org. Lookup MergeSources to get more control 167 | " let g:vim_addon_manager.drop_git_sources = !executable('git') 168 | " let g:vim_addon_manager.debug_activation = 1 169 | 170 | " VAM install location: 171 | let c = get(g:, 'vim_addon_manager', {}) 172 | let g:vim_addon_manager = c 173 | let c.plugin_root_dir = expand('$HOME/.vim/vim-addons', 1) 174 | if !EnsureVamIsOnDisk(c.plugin_root_dir) 175 | echohl ErrorMsg | echomsg "No VAM found!" | echohl NONE 176 | return 177 | endif 178 | let &rtp.=(empty(&rtp)?'':',').c.plugin_root_dir.'/vim-addon-manager' 179 | 180 | " Tell VAM which plugins to fetch & load: 181 | call vam#ActivateAddons([], {'auto_install' : 0}) 182 | " sample: call vam#ActivateAddons(['pluginA','pluginB', ...], {'auto_install' : 0}) 183 | " Also See "plugins-per-line" below 184 | 185 | " Addons are put into plugin_root_dir/plugin-name directory 186 | " unless those directories exist. Then they are activated. 187 | " Activating means adding addon dirs to rtp and do some additional 188 | " magic 189 | 190 | " How to find addon names? 191 | " - look up source from pool 192 | " - ( complete plugin names): 193 | " You can use name rewritings to point to sources: 194 | " ..ActivateAddons(["github:foo", .. => github://foo/vim-addon-foo 195 | " ..ActivateAddons(["github:user/repo", .. => github://user/repo 196 | " Also see section "2.2. names of addons and addon sources" in VAM's documentation 197 | endfun 198 | call SetupVAM() 199 | " experimental [E1]: load plugins lazily depending on filetype, See 200 | " NOTES 201 | " experimental [E2]: run after gui has been started (gvim) [3] 202 | " option1: au VimEnter * call SetupVAM() 203 | " option2: au GUIEnter * call SetupVAM() 204 | " See BUGS sections below [*] 205 | " Vim 7.0 users see BUGS section [3] 206 | 207 | minimal version ~ 208 | > 209 | " put this line first in ~/.vimrc 210 | set nocompatible | filetype indent plugin on | syn on 211 | 212 | fun! SetupVAM() 213 | let c = get(g:, 'vim_addon_manager', {}) 214 | let g:vim_addon_manager = c 215 | let c.plugin_root_dir = expand('$HOME', 1) . '/.vim/vim-addons' 216 | let &rtp.=(empty(&rtp)?'':',').c.plugin_root_dir.'/vim-addon-manager' 217 | " let g:vim_addon_manager = { your config here see "commented version" example and help 218 | if !isdirectory(c.plugin_root_dir.'/vim-addon-manager/autoload') 219 | execute '!git clone --depth=1 https://github.com/MarcWeber/vim-addon-manager ' 220 | \ shellescape(c.plugin_root_dir.'/vim-addon-manager', 1) 221 | endif 222 | call vam#ActivateAddons([the plugin names], {'auto_install' : 0}) 223 | " Also See "plugins-per-line" below 224 | endfun 225 | call SetupVAM() 226 | 227 | 228 | NOTES: ~ 229 | experimental: load plugins lazily depending on filetype [E1]~ 230 | > 231 | " on_ft: If Vim knows the filetype 232 | " on_name: If Vim does not know about the filetype (eg if the plugin you 233 | " want to load contains the ftdetect/* support code 234 | let ft_addons = [ 235 | \ {'on_ft': '^\%(c\|cpp\)$', 'activate': [ 'plugin-for-c-development' ]}, 236 | \ {'on_ft': 'javascript', 'activate': [ 'plugin-for-javascript' ]} 237 | \ {'on_name': '\.scad$', 'activate': [ 'plugin-for-javascript' ]} 238 | \ ] 239 | au FileType * for l in filter(copy(ft_addons), 'has_key(v:val, "on_ft") && '.string(expand('')).' =~ v:val.on_ft') | call vam#ActivateAddons(l.activate, {'force_loading_plugins_now':1}) | endfor 240 | au BufNewFile,BufRead * for l in filter(copy(ft_addons), 'has_key(v:val, "on_name") && '.string(expand('')).' =~ v:val.on_name') | call vam#ActivateAddons(l.activate, {'force_loading_plugins_now':1}) | endfor 241 | 242 | " Vim does not autodetect scad files, thus no filetype event gets 243 | " triggered. BufNewFile and BufRead solve this, but they would not work 244 | " for files without extension such as ".bashrc" which have filetype "sh" 245 | " usually. 246 | 247 | < Provide feedback about this. If it works we may add it as builtin 248 | 249 | Also see this text which was sent to the mailinglist (TODO tidy up) 250 | @skeept There are at least two projects that add extended autoloading support: 251 | [tplugin](http://www.vim.org/scripts/script.php?script_id=2917) and 252 | [AsNeeded](http://www.vim.org/scripts/script.php?script_id=915). They lack support from VAM though (to limit th 253 | number of plugins to be autoloaded), but the former has limited (and currently outdated) support for 254 | `addon-info` files. Neither will work for my own plugins though (they all use frawor API to define mappings and 255 | commands and, sometimes, autocommands), and (at least in tplugin) I see a bunch of other problems (like not 256 | supported short format for mapping commands, no support for mappings/commands defined in `:execute` and so on): 257 | it is really not possible to construct such autoloading by statically analyzing plugins without executing them. 258 | 259 | 260 | plugins-per-line ~ 261 | > 262 | call vam#ActivateAddons([]) 263 | ActivateAddons pluginA pluginB 264 | ActivateAddons pluginC 265 | < 266 | 267 | bundle emulation ~ 268 | > 269 | " after SetupVAM() add: 270 | call vam#bundle_emulation#ProvideVundlesBundleCommand({'info': 1}) 271 | < 272 | experimental: setup VAM when GUI has started [E2] ~ 273 | Depending on the option you choose to run ActivateAddons Vim may not be 274 | able to show the questions correctly asking you to install a plugin. 275 | If that's the case (for whatever reason) I recommend installing the plugin 276 | using |:InstallAddons| or |:ActivateAddons| before adding it to the list in 277 | .vimrc 278 | 279 | If you're annoyed by the message: > 280 | "Press enter to continue" 281 | < There are at least two solutions you can try: 282 | 283 | - press q once and Vim should stop asking 284 | - set |VAM-auto_install| to 1 (to make VAM stop asking you questions before 285 | installing anything) 286 | , set |VAM-shell_commands_run_method| to "system" (to make VAM use 287 | |system()| for running installation commands and thus avoid |hit-enter| 288 | prompts) 289 | and set 'nomore' before ActivateAddons call (to avoid |more-prompt|). 290 | 291 | 292 | Example how to patch vcs checkout functions (eg if you're behind a proxy 293 | and need to checkout github urls by http://): > 294 | let g:vim_addon_manager = {'scms': {'git': {}}} 295 | fun! MyGitCheckout(repository, targetDir) 296 | let a:repository.url = substitute(a:repository.url, '^https://github', 'http://github', '') 297 | return vam#utils#RunShell('git clone --depth=1 $.url $p', a:repository, a:targetDir) 298 | endfun 299 | let g:vim_addon_manager.scms.git.clone=['MyGitCheckout'] 300 | < 301 | 302 | Another example: replace git_update and show changelog > 303 | let g:vim_addon_manager = {'scms': {'git': {}}} 304 | fun! MyGitUpdate(targetDir) 305 | let cd = shellescape 306 | let oldHash = vam#utils#System('git --git-dir=$p/.git rev-list HEAD -1', a:targetDir) 307 | call vam#utils#RunShell('cd $p && git pull', a:targetDir) 308 | let newHash = vam#utils#System('git --git-dir=$p/.git rev-list HEAD -1', a:targetDir) 309 | if oldHash isnot# newHash 310 | silent enew 311 | setlocal buftype=nofile bufhidden=wipe 312 | call setline(1, a:targetDir) 313 | call append(1, split(system(vam#utils#ShellDSL('cd $; git log $[]..$[]', a:targetDir, oldHash, newHash)), "\n")) 314 | endif 315 | return 0 316 | endfun 317 | let g:vim_addon_manager.scms.git.update=['MyGitUpdate'] 318 | < 319 | 320 | Startup benchmarking ~ 321 | Some non-precise benchmarking can be done by > 322 | vim --startuptime startup.log -c q 323 | < . Timings will be printed to startup.log file. You can do it more precisely 324 | by using > 325 | vim --cmd 'profile start profile.log' \ 326 | --cmd 'profile func *' \ 327 | --cmd 'profile file *' \ 328 | -c 'profile pause' \ 329 | -c 'qa!' 330 | < Then it will output full profile information where time consumed by each 331 | line is shown, with a summary of function call times at the end. You can 332 | also get a summary of script file times if you open profile.log and do > 333 | let timings=[] 334 | g/^SCRIPT/call add(timings, [getline('.')[len('SCRIPT '):], matchstr(getline(line('.')+1), '^Sourced \zs\d\+')]+map(getline(line('.')+2, line('.')+3), 'matchstr(v:val, ''\d\+\.\d\+$'')')) 335 | call setline('.', ['count total (s) self (s) script']+map(copy(timings), 'printf("%5u %9s %8s %s", v:val[1], v:val[2], v:val[3], v:val[0])')) 336 | < . You can also get times of scripts activation if you run > 337 | tlib#cmd#Time('call vam#ActivateAddons(["A"])') 338 | < for plugins which were not already activated after vim has started. 339 | Requires tlib. Adds time which takes VAM to do activation to actual 340 | activation. For filetype, indent, syntax, compiler, colorscheme and 341 | autoload plugins time spend in VAM is likely to exceed time used to load 342 | plugin (because actual loading will take place later if required), so it is 343 | better to read |profiling| instead. 344 | 345 | ------------------------------------------------------------------------------ 346 | 2.2. Names of addons and addon sources *VAM-addon-names* 347 | 348 | Because we are human VAM uses readable names as unique identifier for plugins. 349 | Those identifieres (= plugin names) are passed to |vam#ActivateAddons()|, 350 | |:InstallAddons|, |:ActivateAddons| . The name is automatically derived from 351 | plugin titles at www.vim.org. In case two titles resolve to identical names 352 | “%{scriptID}” string is appended (e.g. “gam%2559”). 353 | 354 | types of names: 355 | 1) Plugin name looked up in pool. 356 | 357 | Determining addon names ~ 358 | - by using |:AddonsInfo| SCRIPT_ID/name/any-texet, pick the word right 359 | after string "Plugin: ". 360 | - Use |:InstallAddons|' name completion by typing some chars then pressing 361 | then . |c_CTRL-D| 362 | - Use completion while editing your vimrc. 363 | See |VAM-addon-completion_lhs| if you don’t like the lhs or the whole 364 | idea. 365 | 366 | 2) Name which gets rewritten internally (see |VAM-name_rewriting|) > 367 | github:{Name} => {"type": "git", "url": "https://github.com/{Name}/vim-addon-{Name}} 368 | github:{N}/{Repo} => {"type": "git", "url": "https://github.com/{N}/{Repo}"} 369 | git:{GIT_URL} => {"type": "git", "url": "GIT_URL"} 370 | < Don't use if you expect others to create plugins depending on yours. Add 371 | your plugin to |vim-pi| instead. 372 | 373 | 374 | Instead of telling us to add your plugin to |vim-pi| you can also patch 375 | the pool easily: vim-pi-patching| - however if you contribute to vim-pi 376 | the community will benefit much more. 377 | 378 | *vim-pi* is the default pool. VAM checks it out by default. Its long name is 379 | “vim plugin index”. 380 | 381 | *vim-pi-patching* 382 | vim-pi merges both sources (scm and www.vim.org ones), see |VAM-MergeSources|. 383 | The result is provided by vam_known_repositories#Pool() which is the only pool 384 | used by default. See example and default implementation of vam#install#Pool(). 385 | 386 | If you want to add your own sources consider submitting them to 387 | vim-pi as patch. If you don't there are two ways: 388 | 389 | WAY 1: (still supported) add to your .vimrc before activating VAM (BUG/TODO [5]): > 390 | let g:vim_addon_manager = {} 391 | let g:vim_addon_manager.plugin_sources = {} 392 | let g:vim_addon_manager.plugin_sources.your_plugin_name = { plugin dictionary } 393 | < 394 | WAY 2: define your own Pool function: > 395 | let g:vim_addon_manager = {} 396 | let g:vim_addon_manager.pool_fun = function('MyPoolFun') 397 | fun MyPoolFun() 398 | let d = vam#install#Pool() 399 | let d.my_plugin = { 'type' : 'git', 'url' : ' ... ' } 400 | return d 401 | endfun 402 | 403 | Plugin dictionaries are described in |addon-info-repository|. 404 | 405 | Example: overwriting the MergeSources function (vim-pi pool implementation): > 406 | Yes, you can do this in MyPoolFun shown above as well > 407 | fun! MyMergeSources(plugin_sources, www_vim_org, scm_plugin_sources, patch_function, snr_to_name) 408 | 409 | " run default: 410 | call vam_known_repositories#MergeSources(a:plugin_sources, a:www_vim_org, a:scm_plugin_sources, a:patch_function, a:snr_to_name) 411 | 412 | " patch sources the way you like. This example adds username and password 413 | " for SVN repositories. As alternative you could overwrite git urls etc .. 414 | for your_plugin in ['svn-driven-key1', ...] 415 | let a:plugin_sources[your_plugin]['username'] = 'svn user' 416 | let a:plugin_sources[your_plugin]['password'] = 'svn user' 417 | endfor 418 | 419 | let a:plugin_sources.your_plugin_name = { plugin dictionary } 420 | endfun 421 | " tell VAM to use your MergeSources function: 422 | let g:vim_addon_manager = {} 423 | let g:vim_addon_manager.MergeSources = function('MyMergeSources') 424 | < 425 | 426 | 427 | ------------------------------------------------------------------------------ 428 | 2.3. Example: configurable setup *VAM-complex-setup-sample* 429 | > 430 | call vam#ActivateAddons(["github:YOURNAME"],{'auto_install' : 0}) 431 | " this initializes Vim the way *you* want also loading more plugins: 432 | call vim_addon_YOURNAME#Activate(['c-dev','ruby-dev']) 433 | < 434 | My implementation looks like this: 435 | https://github.com/MarcWeber/vim-addon-MarcWeber/blob/master/autoload/vim_addon_MarcWeber.vim 436 | 437 | You can then load plugins depending on env vars: 438 | Example: > 439 | call vim_addon_YOURNAME#Activate(['always']+split($V,',')) 440 | < Then you can run vim like this from shell > 441 | V=c-dev,ruby-dev vim 442 | < 443 | This section was written to inspire you only. 444 | 445 | ------------------------------------------------------------------------------ 446 | 2.4. Unattended installation *VAM-unattended-installation* 447 | 448 | Note: You should always review foreign code before running it. That said this 449 | is how you can update or install unattended (without confirmations ..): 450 | 451 | redir! > /tmp/log-vim.txt 452 | silent! ACTION 453 | messages 454 | 455 | where ACTION is either UpdateActivatedAddons or vam#InstallAddons() 456 | 457 | This works for http://mawercer.de/~marc/vam/index.php. 458 | 459 | There is also the undocumented g:vim_addon_manager.dont_source option which 460 | should be used if you want to checkout eventually untrusted code! If you're 461 | going to use the plugins anyway its of no use. 462 | 463 | You may also want to set auto_install. 464 | 465 | Also see https://github.com/MarcWeber/vim-addon-manager/issues/77: 466 | > 467 | let g:vim_addon_manager = { 468 | \'shell_commands_run_method': 'system', 469 | \'auto_install': 1, 470 | \} 471 | < 472 | 473 | and possibly log_to_buf which will prevent you from having to deal with most 474 | of those "hit enter to continue" prompts while VAM downloads plugins 475 | 476 | Also see https://github.com/MarcWeber/vim-addon-manager/issues/79: 477 | > 478 | let g:vim_addon_manager = { 479 | \'shell_commands_run_method': 'system', 480 | \'auto_install': 1, 481 | \'log_to_buf': 1, 482 | \} 483 | < 484 | 485 | and if you wish, you may customize the default buffer name for the VAM log, 486 | just use the log_buffer_name option which defaults to a value of 487 | |VAM-plugin_root_dir|/VAM_LOG.txt e.g. 488 | ~/.vim/vim-addons/vim-addon-manager/VAM_LOG.txt 489 | > 490 | let g:vim_addon_manager = { 491 | \'shell_commands_run_method': 'system', 492 | \'auto_install': 1, 493 | \'log_to_buf': 1, 494 | \'log_buffer_name': '/tmp/vam_install.log', 495 | \} 496 | < 497 | ------------------------------------------------------------------------------ 498 | 2.5. Searching the plugins *VAM-plugins-search* 499 | 500 | VAM does not support searching plugins; you have to use one of the other 501 | options. Common ones: 502 | 1. use www.vim.org/search.php because still most plugins are also on 503 | www.vim.org. 504 | 2. Try google and github search (this time including "vim" as keyword) because 505 | most plugins are hosted on github today. 506 | 3. There is vim.wikia.com. Use its search. 507 | 4. Of course, there are google/bing/(any other web) search. 508 | 5. There are mailinglists. 509 | 510 | VAM does not support a search … 511 | - Because we still want you to visit vim's website (its a charity project 512 | after all). 513 | - Because we like the linux philosophy: One tool should do one task well and 514 | be responsible for that only. VAM is only responsible for isntaling and 515 | activating plugins thus for recreating your work environment form scratch. 516 | Thus this should be a "plugin" providing such a feature, not VAM. 517 | - It is not that easy. If you want to work on it get in touch, because there 518 | are multiple sources today unfortunately. Of course we could just dump the 519 | information from www.vim.org and allow you to grep it. I just think the 520 | whole plugin system on www.vim.org should be rewritten allowing github urls. 521 | I haven't had time to do it yet. I've been trying to do it for more than 12 522 | month and failed due to lack of time. If you want to sponsor such an effort 523 | get in touch. 524 | 525 | vim: tw=78:ts=8:ft=help:norl 526 | -------------------------------------------------------------------------------- /downloader/index.php: -------------------------------------------------------------------------------- 1 | log-vim.txt 104 | let g:vim_addon_manager.dont_source = 1 105 | let g:vim_addon_manager.auto_install = 1 106 | let g:vim_addon_manager.log_to_buf = 1 107 | 108 | \" activation is disabled manually enabling vim-pi 109 | exec 'set runtimepath+='.filter([\$HOME.'/.vim', \$HOME.'/vimfiles'],'isdirectory(v:val)')[0].'/vim-addons/vim-pi' 110 | " : "")." 111 | 112 | ".vimrc_win_hack()." 113 | 114 | \" use either windows or linux location - whichever exists 115 | exec 'set runtimepath+='.filter([\$HOME.'/.vim', \$HOME.'/vimfiles'],'isdirectory(v:val)')[0].'/vim-addons/vim-addon-manager' 116 | call vam#".$c."(".json_encode($names).", {'auto_install' : 1}) 117 | "; 118 | } 119 | 120 | function wrap_vimrc($s){ 121 | return ' 122 | try 123 | '.$s.' 124 | catch /.*/ 125 | call writefile([v:exception], "/tmp/vam-error") 126 | endtry 127 | '; 128 | } 129 | 130 | function vimrc2(){ 131 | return vimrc(array(), true) 132 | .' 133 | let info = {} 134 | for n in vam#install#KnownAddons(0) 135 | let repo = get(g:vim_addon_manager["plugin_sources"],n,{}) 136 | if repo != {} 137 | let info[n] = vam#DisplayAddonInfoLines(n, repo) 138 | endif 139 | endfor 140 | 141 | fun! Encode(thing, ...) 142 | let nl = a:0 > 0 ? (a:1 ? "\\n" : "") : "" 143 | if type(a:thing) == type("") 144 | return \'"\'.escape(a:thing,\'"\\\').\'"\' 145 | elseif type(a:thing) == type({}) && !has_key(a:thing, \'json_special_value\') 146 | let pairs = [] 147 | for [Key, Value] in items(a:thing) 148 | call add(pairs, Encode(Key).\':\'.Encode(Value)) 149 | unlet Key | unlet Value 150 | endfor 151 | return "{".nl.join(pairs, ",".nl)."}" 152 | elseif type(a:thing) == type(0) 153 | return a:thing 154 | elseif type(a:thing) == type([]) 155 | return \'[\'.join(map(copy(a:thing), "Encode(v:val)"),",").\']\' 156 | else 157 | throw "unexpected new thing: ".string(a:thing) 158 | endif 159 | endf 160 | 161 | call writefile( [Encode(info)], "names") 162 | '; 163 | } 164 | 165 | function aszip($names){ 166 | global $windows; 167 | 168 | set_time_limit(60*60); 169 | 170 | file_put_contents(HISTORY_FILE, date('Y-m-d H:m:s').'|'.json_encode($names)."\n", FILE_APPEND | LOCK_EX ); 171 | $dir = TMP.'/'.rand(1000,9999); 172 | system('mkdir -p '.$dir.'; chmod -R 777 '.$dir); 173 | # mkdir($dir, '', true); 174 | file_put_contents($dir.'/_vimrc', vimrc($names, false)); 175 | file_put_contents($dir.'/_vimrc-fetch', vimrc($names, true)); 176 | $cmd = ' 177 | dir='.$dir.' 178 | cd $dir 179 | exec > log.txt 180 | exec 2>&1 181 | set -x 182 | mkdir -p .vim/vim-addons 183 | export PATH=/var/run/current-system/sw/bin 184 | git clone --depth 1 https://github.com/MarcWeber/vim-addon-manager.git .vim/vim-addons/vim-addon-manager 185 | # ( cd vim-addon-manager; git chekout HEAD~20; ) 186 | # git clone --depth 1 https://bitbucket.org/vimcommunity/vim-pi .vim/vim-addons/vim-pi 187 | 188 | export HOME=$dir 189 | 190 | yes | vim -u ~/_vimrc-fetch -U NONE -N -c "qa!" &>/dev/null 191 | echo done >> /tmp/done 192 | 193 | '.($windows ? 'mv .vim vimfiles' : 'mv _vimrc .vimrc').' 194 | 195 | zip -r vam.zip * .vim* 196 | '; 197 | system("$cmd 2>&1"); 198 | downloadFile( $dir.'/vam.zip', $name = 'vam.zip'); 199 | system('rm -fr '.$dir); 200 | exit(); 201 | } 202 | 203 | if (isset($_GET['plugin_info'])){ 204 | $a = name_cache(); 205 | $s = implode("\n", $a[base64_decode($_GET['plugin_info'])]); 206 | 207 | if (strpos($s, "deprecated:") != false){ 208 | echo "PAY ATTENTION TO THE deprecated NOTICE!"; 209 | } 210 | 211 | echo '
';
212 |   echo _htmlentities($s);
213 |   echo '
'; 214 | 215 | 216 | echo ' 217 | 218 | 219 | '; 220 | exit(); 221 | } 222 | 223 | if (isset($_POST['names'])){ 224 | if ($_POST['spam_protection'] != 'V I M'){ 225 | echo 'you failed - SPAM protection. Reread instructions'; 226 | exit(); 227 | } else { 228 | $names = preg_split('/[ ,]+/', $_POST['names']); 229 | $errors = array(); 230 | $name_cache = name_cache(); 231 | foreach($names as &$n){ 232 | if (preg_match('/^((?i)VAM|vim-addon-manager|VAM-kr|vim-addon-manager-known-repositories|vim-pi)$/', $n)){ 233 | $errors[] = $n.' will be included automatically, retry'; 234 | } 235 | $n = preg_replace('/[[\]\'"]/', '', $n); 236 | if (!isset($name_cache[$n]) && !preg_match('/^(github|git|hg):/', $n)) 237 | $errors[] = 'name '.$n.' unkown. Check against list at the bottom of main page'; 238 | } 239 | if (count($errors) > 0){ 240 | foreach($errors as $err){ 241 | echo $err.'
'; 242 | } 243 | exit(); 244 | } else { 245 | aszip($names); 246 | } 247 | } 248 | } 249 | 250 | ?> 251 | 252 | 254 | 255 | 256 | VAM for Windows Downloader & VAM pool viewer 257 | 258 | 259 | 260 | 261 | 262 | 274 | 275 | 276 |

VAM downloader for Windows users

277 | 278 |
279 | Installing git, mercurial, zip commands can be tedious on windows. 280 | This page let's you download VAM and its plugins. 281 |
282 | 283 |

HOWTO

284 |

285 | Fill in the form, then copy the _vimrc and vimfiles into your user directory. https using self signed certificate is supported. 286 |

287 | 288 |
289 | Put in "V I M" (mind the spaces, spam protection):
290 |
291 | 292 | The plugin names you want separated by , or space (VAM-kr and VAM will be included always):
293 | Yes, from now one '"[] will be stripped so pasting a list is fine, also. This 294 | way you can update everyhting at once easily.
295 |
296 | 297 | target operating system:
298 |
299 |
300 | 301 |
302 | Be patient. Fetching repositories by mercurial, svn or git can take some time.
303 | [1] Linux users may want to use the sample code (section 2). 304 | 305 | 306 |
307 | 308 | 309 | If you have trouble contact Marc Weber by email (marco-oweber ATT gmx.de) 310 | or on irc.freenode.net (#vim). 311 | 312 | 313 |
314 |
315 |
316 |
317 |
318 | 319 | previous downloads 320 | 321 |
322 | You want to say thanks? Goto http://www.vim.org and visit some of the sponsors .. 323 | 324 | RECREATE_CACHE_HOURS)){ 328 | echo "\n
updating name cache ..
\n"; 329 | ob_end_flush(); 330 | flush(); 331 | $dir = TMP.'/'.rand(1000,9999); 332 | echo system('mkdir -p '.$dir.'; chmod -R 777 '.$dir); 333 | if (!is_dir($dir)){ 334 | echo "error creating $dir\n"; 335 | exit(); 336 | } 337 | 338 | file_put_contents($dir.'/_vimrc-fetch', wrap_vimrc(vimrc2())); 339 | $cmd = ' 340 | dir='.$dir.' 341 | cd $dir 342 | exec > log.txt 343 | exec 2>&1 344 | set -x 345 | export PATH=/var/run/current-system/sw/bin 346 | mkdir -p .vim/vim-addons 347 | git clone --depth 1 https://github.com/MarcWeber/vim-addon-manager.git .vim/vim-addons/vim-addon-manager 348 | export HOME=$dir 349 | yes | vim -u ~/_vimrc-fetch -U NONE -N -c "qa!" &>/dev/null 350 | '; 351 | system("$cmd"); 352 | file_put_contents(NAME_CACHE_FILE, file_get_contents($dir.'/names')); 353 | system('rm -fr $dir'); 354 | } 355 | $s = '"; 365 | return $s; 366 | } 367 | 368 | echo '


This list of known plugin names is updated every '.RECREATE_CACHE_HOURS.' hours:
'; 369 | echo known_names(); 370 | 371 | ?> 372 | 373 | 374 | 375 | -------------------------------------------------------------------------------- /test/README.txt: -------------------------------------------------------------------------------- 1 | How to run? 2 | See doc/vim-addon-manager-additional-documentation.txt, Section 9 3 | -------------------------------------------------------------------------------- /test/activate-hg.ok: -------------------------------------------------------------------------------- 1 | ::: In plugin {svn}/plugin/msgWrite.vim 2 | ::: In {hg}/runtimepath/plugin/writeMsg.vim -------------------------------------------------------------------------------- /test/activate-mhg.ok: -------------------------------------------------------------------------------- 1 | ::: In plugin {rtp}/plugin/rtp.vim -------------------------------------------------------------------------------- /test/activate-mis.ok: -------------------------------------------------------------------------------- 1 | ::: In plugin {rtp}/plugin/rtp.vim -------------------------------------------------------------------------------- /test/activate-svn.ok: -------------------------------------------------------------------------------- 1 | ::: In plugin {svn}/plugin/msgWrite.vim -------------------------------------------------------------------------------- /test/addmessages.vim: -------------------------------------------------------------------------------- 1 | redir => s:messages 2 | messages 3 | redir END 4 | let s:meslines=filter(split(s:messages, "\n")[1:], 'v:val=~#"\\v^E\\d"') 5 | if !empty(s:meslines) 6 | call WriteFile(['>>> Messages:']+ 7 | \ s:meslines+ 8 | \ ['<<< Messages^']) 9 | endif 10 | -------------------------------------------------------------------------------- /test/addoninfo.in: -------------------------------------------------------------------------------- 1 | :call vam#install#Install(["vam_test_hg"]) 2 | :call WriteFile(sort(map(items(vam#AddonInfo('vam_test_hg')), 'string(v:val)'))) 3 | -------------------------------------------------------------------------------- /test/addoninfo.ok: -------------------------------------------------------------------------------- 1 | ['dependencies', {'vam_test_svn': {}}] 2 | ['runtimepath', 'runtimepath'] -------------------------------------------------------------------------------- /test/bisect.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarcWeber/vim-addon-manager/585197500a4920c031467196e41335ca997aca6d/test/bisect.in -------------------------------------------------------------------------------- /test/bisect.ok: -------------------------------------------------------------------------------- 1 | The plugin vam-addon-2 or one of its dependencies is likely to cause the problem -------------------------------------------------------------------------------- /test/bisect.vim: -------------------------------------------------------------------------------- 1 | " See test/README.txt about how to run this 2 | if !exists('g:curtest') | echoe 'bad usage' | finish |endif 3 | 4 | let addons=map(range(4), '"vam-addon-".v:val') 5 | for addon in addons 6 | let addpath=g:vim_addon_manager.plugin_root_dir.'/'.addon.'/plugin' 7 | call mkdir(addpath, 'p') 8 | call writefile(['let g:v'.addon[-1:].'=1'], addpath.'/plugin.vim') 9 | endfor 10 | call vam#ActivateAddons(addons) 11 | 12 | let $MYVIMRC=$TESTDIR.'/'.g:curtest.'-vimrc' 13 | call writefile(readfile(fnamemodify($TESTDIR, ':h').'/vimrc', 'b')+ 14 | \ ['call vam#ActivateAddons('.string(addons).')'], 15 | \ $MYVIMRC) 16 | 17 | while getchar(1) 18 | call getchar(0) 19 | endwhile 20 | call feedkeys('YYYYYYYY', 't') 21 | redir => g:messages 22 | execute 'AddonsBisect '.v:progname.' --cmd let\ g:noexe=1 --cmd let\ g:curtest='.string(g:curtest).' -c if\ exists("g:v2")|BADVAMBisect|else|OKVAMBisect|endif' 23 | redir END 24 | let msglines=split(g:messages, "\n") 25 | call WriteFile(filter(msglines[:-2], 'v:val =~ "\\v^E\\d+\\:"')+msglines[-1:]) 26 | qa! 27 | -------------------------------------------------------------------------------- /test/comments-tgz2-dodiff.lst: -------------------------------------------------------------------------------- 1 | " Expands @... sequences at the start of plugin ID -------------------------------------------------------------------------------- /test/comments-tgz2-nodiff.lst: -------------------------------------------------------------------------------- 1 | "▶1 Header 2 | "▶1 Variable initialization 3 | "▶2 s: 4 | "▶2 Messages 5 | "▶1 s:Eval 6 | "▶1 expandplid :: String → plid 7 | " Expands @... sequences at the start of plugin ID 8 | "▶1 compareversions :: version, version → -1|0|1 9 | "▶1 normpath :: path + FS → path 10 | "▶1 parseplugpath :: filename + FS → (plugtype, plid, runtimepath) 11 | "▶1 recdictmap :: dict, expr[, path, processed] → dict + ? 12 | "▶1 createconsfunc :: efid, fname, consargs, suf → function 13 | "▶1 createcons :: plugdict, shadowdict, feature → dict 14 | "▶1 addcons :: plugdict + s:f.cons → + p:_f 15 | "▶1 featcomp :: feature, feature + s:selfdeps → -1|0|1 16 | " " Can't add s:FeatComp to _functions because it is required for unloadplugin 17 | " " to work and thus should not be removed by unloadpre event 18 | " let function('s:FeatComp')=function('s:FeatComp') 19 | "▶1 getfeatures :: plugdict, {: feature} → [feature] 20 | "▶1 runfeatures :: plugdict, fkey + shadowdict, +s:f → plugdict + shadowdict 21 | "▶1 initfeatures :: plugdict + shadowdict → + shadowdict 22 | "▶1 newplugin :: version, sid, file, dependencies, oneload, g → +s:pls, 23 | "▶1 addfeature :: plugdict, feature(ircl)[, load] → + shadowdict 24 | "▶1 getordereddeps :: plugdict + s:dependents → [plugdict] 25 | "▶1 loadplugin :: Either plugdict plid → 0|1|2 + plugdict, … 26 | "▶1 getdeps :: plugdict, hasdep::{plid: _} + s:dependents,… → [plugdict] 27 | "▶1 depcomp :: plugdict, plugdict + s:dependents → -1|0|1 28 | " Makes plugins which are being less depended on first in a list when passed as 29 | " a second argument to sort() 30 | "▶1 unloadplugin :: Either plugdict plid + … → [filename] 31 | " Returns a list of files that should be sourced to load plugin back 32 | "▶1 _unload 33 | "▶1 FraworRegister 34 | "▶1 FraworLoad 35 | "▶1 FraworUnload 36 | "▶1 isfunc :: funcref, key, fname, plid → + throw 37 | "▶1 features.newfeature.cons :: {f}, fid, fopts → + s:features, shadowdict, … 38 | "▶1 features.newfeature.unload :: {f} → + s:features, shadowdict, s:f 39 | "▶1 Plugin registration 40 | "▶1 warn feature :: {f}, msgid, … + p:_messages → message + echomsg 41 | "▶1 throw feature :: {f}, msgid, … → + throw 42 | "▶1 43 | " vim: fmr=▶,▲ sw=4 ts=4 sts=4 et tw=80 -------------------------------------------------------------------------------- /test/dependencies-hg.lst: -------------------------------------------------------------------------------- 1 | svn 2 | -------------------------------------------------------------------------------- /test/files-archive_name.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_archive_name 2 | ./vam_test_archive_name/README.markdown 3 | ./vam_test_archive_name/addons 4 | ./vam_test_archive_name/archive 5 | ./vam_test_archive_name/archive/vam_test_archive_name.tar.gz 6 | ./vam_test_archive_name/autoload 7 | ./vam_test_archive_name/autoload/frawor.vim 8 | ./vam_test_archive_name/doc 9 | ./vam_test_archive_name/doc/FWC.txt 10 | ./vam_test_archive_name/doc/frawor.txt 11 | ./vam_test_archive_name/doc/tags 12 | ./vam_test_archive_name/plugin 13 | ./vam_test_archive_name/plugin/frawor 14 | ./vam_test_archive_name/plugin/frawor/autocommands.vim 15 | ./vam_test_archive_name/plugin/frawor/base64.vim 16 | ./vam_test_archive_name/plugin/frawor/checks.vim 17 | ./vam_test_archive_name/plugin/frawor/commands.vim 18 | ./vam_test_archive_name/plugin/frawor/decorators 19 | ./vam_test_archive_name/plugin/frawor/decorators/altervars.vim 20 | ./vam_test_archive_name/plugin/frawor/decorators.vim 21 | ./vam_test_archive_name/plugin/frawor/functions.vim 22 | ./vam_test_archive_name/plugin/frawor/fwc 23 | ./vam_test_archive_name/plugin/frawor/fwc/compiler.vim 24 | ./vam_test_archive_name/plugin/frawor/fwc/constructor.vim 25 | ./vam_test_archive_name/plugin/frawor/fwc/intfuncs.vim 26 | ./vam_test_archive_name/plugin/frawor/fwc/parser.vim 27 | ./vam_test_archive_name/plugin/frawor/fwc/topconstructs.vim 28 | ./vam_test_archive_name/plugin/frawor/fwc.vim 29 | ./vam_test_archive_name/plugin/frawor/lua.vim 30 | ./vam_test_archive_name/plugin/frawor/mappings.vim 31 | ./vam_test_archive_name/plugin/frawor/options.vim 32 | ./vam_test_archive_name/plugin/frawor/os.vim 33 | ./vam_test_archive_name/plugin/frawor/perl.vim 34 | ./vam_test_archive_name/plugin/frawor/python.vim 35 | ./vam_test_archive_name/plugin/frawor/resources.vim 36 | ./vam_test_archive_name/plugin/frawor/ruby.vim 37 | ./vam_test_archive_name/plugin/frawor/signs.vim 38 | ./vam_test_archive_name/plugin/frawor/table.vim 39 | ./vam_test_archive_name/plugin/frawor/tcl.vim 40 | ./vam_test_archive_name/plugin/frawor.vim 41 | ./vam_test_archive_name/templates 42 | ./vam_test_archive_name/templates/oneload-frawor-plugin.vim 43 | ./vam_test_archive_name/version -------------------------------------------------------------------------------- /test/files-bzr.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_bzr 2 | ./vam_test_bzr/macros 3 | ./vam_test_bzr/macros/matchit.vim -------------------------------------------------------------------------------- /test/files-git.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_git 2 | ./vam_test_git/autoload 3 | ./vam_test_git/autoload/vam_known_repositories.vim -------------------------------------------------------------------------------- /test/files-hg.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_hg 2 | ./vam_test_hg/addon-info.json 3 | ./vam_test_hg/runtimepath 4 | ./vam_test_hg/runtimepath/plugin 5 | ./vam_test_hg/runtimepath/plugin/writeMsg.vim 6 | ./vam_test_svn 7 | ./vam_test_svn/plugin 8 | ./vam_test_svn/plugin/msgWrite.vim -------------------------------------------------------------------------------- /test/files-mhg.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_mhg 2 | ./vam_test_mhg/addon-info.json 3 | ./vam_test_mhg/plugin 4 | ./vam_test_mhg/plugin/rtp.vim 5 | ./vam_test_mhg/rtp 6 | ./vam_test_mhg/rtp/plugin 7 | ./vam_test_mhg/rtp/plugin/rtp.vim -------------------------------------------------------------------------------- /test/files-mis.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_mis 2 | ./vam_test_mis/addon-info.json 3 | ./vam_test_mis/archive 4 | ./vam_test_mis/archive/vam_test_mis.tar.bz2 5 | ./vam_test_mis/plugin 6 | ./vam_test_mis/plugin/rtp.vim 7 | ./vam_test_mis/rtp 8 | ./vam_test_mis/rtp/plugin 9 | ./vam_test_mis/rtp/plugin/rtp.vim 10 | ./vam_test_mis/version -------------------------------------------------------------------------------- /test/files-svn.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_svn 2 | ./vam_test_svn/plugin 3 | ./vam_test_svn/plugin/msgWrite.vim -------------------------------------------------------------------------------- /test/files-tar.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_tar 2 | ./vam_test_tar/archive 3 | ./vam_test_tar/archive/vam_test_tar.tar 4 | ./vam_test_tar/autoload 5 | ./vam_test_tar/autoload/frawor.vim 6 | ./vam_test_tar/doc 7 | ./vam_test_tar/doc/oop.txt 8 | ./vam_test_tar/doc/tags 9 | ./vam_test_tar/plugin 10 | ./vam_test_tar/plugin/frawor 11 | ./vam_test_tar/plugin/frawor/autocommands.vim 12 | ./vam_test_tar/plugin/frawor/checks.vim 13 | ./vam_test_tar/plugin/frawor/decorators 14 | ./vam_test_tar/plugin/frawor/decorators/altervars.vim 15 | ./vam_test_tar/plugin/frawor/decorators.vim 16 | ./vam_test_tar/plugin/frawor/functions.vim 17 | ./vam_test_tar/plugin/frawor/fwc 18 | ./vam_test_tar/plugin/frawor/fwc/compiler.vim 19 | ./vam_test_tar/plugin/frawor/fwc/constructor.vim 20 | ./vam_test_tar/plugin/frawor/fwc/intfuncs.vim 21 | ./vam_test_tar/plugin/frawor/fwc/parser.vim 22 | ./vam_test_tar/plugin/frawor/fwc/topconstructs.vim 23 | ./vam_test_tar/plugin/frawor/fwc.vim 24 | ./vam_test_tar/plugin/frawor/os.vim 25 | ./vam_test_tar/plugin/frawor/resources.vim 26 | ./vam_test_tar/plugin/frawor/signs.vim 27 | ./vam_test_tar/plugin/frawor.vim 28 | ./vam_test_tar/plugin/oop.vim 29 | ./vam_test_tar/test 30 | ./vam_test_tar/test/rtp 31 | ./vam_test_tar/test/rtp/plugin 32 | ./vam_test_tar/test/rtp/plugin/test1.vim 33 | ./vam_test_tar/test/test.vim 34 | ./vam_test_tar/test/test1.in 35 | ./vam_test_tar/test/test1.ok 36 | ./vam_test_tar/test/vimrc 37 | ./vam_test_tar/version 38 | ./vam_test_tar/vimoop-addon-info.txt -------------------------------------------------------------------------------- /test/files-tbz.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_tbz 2 | ./vam_test_tbz/README.markdown 3 | ./vam_test_tbz/addons 4 | ./vam_test_tbz/archive 5 | ./vam_test_tbz/archive/vam_test_tbz.tar.bz2 6 | ./vam_test_tbz/autoload 7 | ./vam_test_tbz/autoload/frawor.vim 8 | ./vam_test_tbz/doc 9 | ./vam_test_tbz/doc/FWC.txt 10 | ./vam_test_tbz/doc/frawor.txt 11 | ./vam_test_tbz/doc/oop.txt 12 | ./vam_test_tbz/doc/tags 13 | ./vam_test_tbz/doc/yaml.txt 14 | ./vam_test_tbz/plugin 15 | ./vam_test_tbz/plugin/frawor 16 | ./vam_test_tbz/plugin/frawor/autocommands.vim 17 | ./vam_test_tbz/plugin/frawor/base64.vim 18 | ./vam_test_tbz/plugin/frawor/checks.vim 19 | ./vam_test_tbz/plugin/frawor/commands.vim 20 | ./vam_test_tbz/plugin/frawor/decorators 21 | ./vam_test_tbz/plugin/frawor/decorators/altervars.vim 22 | ./vam_test_tbz/plugin/frawor/decorators.vim 23 | ./vam_test_tbz/plugin/frawor/functions.vim 24 | ./vam_test_tbz/plugin/frawor/fwc 25 | ./vam_test_tbz/plugin/frawor/fwc/compiler.vim 26 | ./vam_test_tbz/plugin/frawor/fwc/constructor.vim 27 | ./vam_test_tbz/plugin/frawor/fwc/intfuncs.vim 28 | ./vam_test_tbz/plugin/frawor/fwc/parser.vim 29 | ./vam_test_tbz/plugin/frawor/fwc/topconstructs.vim 30 | ./vam_test_tbz/plugin/frawor/fwc.vim 31 | ./vam_test_tbz/plugin/frawor/history.vim 32 | ./vam_test_tbz/plugin/frawor/lua.vim 33 | ./vam_test_tbz/plugin/frawor/mappings.vim 34 | ./vam_test_tbz/plugin/frawor/options.vim 35 | ./vam_test_tbz/plugin/frawor/os.vim 36 | ./vam_test_tbz/plugin/frawor/perl.vim 37 | ./vam_test_tbz/plugin/frawor/python.vim 38 | ./vam_test_tbz/plugin/frawor/resources.vim 39 | ./vam_test_tbz/plugin/frawor/ruby.vim 40 | ./vam_test_tbz/plugin/frawor/signs.vim 41 | ./vam_test_tbz/plugin/frawor/table.vim 42 | ./vam_test_tbz/plugin/frawor/tcl.vim 43 | ./vam_test_tbz/plugin/frawor.vim 44 | ./vam_test_tbz/plugin/oop.vim 45 | ./vam_test_tbz/plugin/yaml.vim 46 | ./vam_test_tbz/templates 47 | ./vam_test_tbz/templates/oneload-frawor-plugin.vim 48 | ./vam_test_tbz/version -------------------------------------------------------------------------------- /test/files-tbz2.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_tbz2 2 | ./vam_test_tbz2/README.markdown 3 | ./vam_test_tbz2/addons 4 | ./vam_test_tbz2/archive 5 | ./vam_test_tbz2/archive/vam_test_tbz_2.tbz2 6 | ./vam_test_tbz2/autoload 7 | ./vam_test_tbz2/autoload/frawor.vim 8 | ./vam_test_tbz2/doc 9 | ./vam_test_tbz2/doc/FWC.txt 10 | ./vam_test_tbz2/doc/frawor.txt 11 | ./vam_test_tbz2/doc/oop.txt 12 | ./vam_test_tbz2/doc/tags 13 | ./vam_test_tbz2/plugin 14 | ./vam_test_tbz2/plugin/frawor 15 | ./vam_test_tbz2/plugin/frawor/autocommands.vim 16 | ./vam_test_tbz2/plugin/frawor/base64.vim 17 | ./vam_test_tbz2/plugin/frawor/checks.vim 18 | ./vam_test_tbz2/plugin/frawor/commands.vim 19 | ./vam_test_tbz2/plugin/frawor/decorators 20 | ./vam_test_tbz2/plugin/frawor/decorators/altervars.vim 21 | ./vam_test_tbz2/plugin/frawor/decorators.vim 22 | ./vam_test_tbz2/plugin/frawor/functions.vim 23 | ./vam_test_tbz2/plugin/frawor/fwc 24 | ./vam_test_tbz2/plugin/frawor/fwc/compiler.vim 25 | ./vam_test_tbz2/plugin/frawor/fwc/constructor.vim 26 | ./vam_test_tbz2/plugin/frawor/fwc/intfuncs.vim 27 | ./vam_test_tbz2/plugin/frawor/fwc/parser.vim 28 | ./vam_test_tbz2/plugin/frawor/fwc/topconstructs.vim 29 | ./vam_test_tbz2/plugin/frawor/fwc.vim 30 | ./vam_test_tbz2/plugin/frawor/history.vim 31 | ./vam_test_tbz2/plugin/frawor/lua.vim 32 | ./vam_test_tbz2/plugin/frawor/mappings.vim 33 | ./vam_test_tbz2/plugin/frawor/options.vim 34 | ./vam_test_tbz2/plugin/frawor/os.vim 35 | ./vam_test_tbz2/plugin/frawor/perl.vim 36 | ./vam_test_tbz2/plugin/frawor/python.vim 37 | ./vam_test_tbz2/plugin/frawor/resources.vim 38 | ./vam_test_tbz2/plugin/frawor/ruby.vim 39 | ./vam_test_tbz2/plugin/frawor/signs.vim 40 | ./vam_test_tbz2/plugin/frawor/table.vim 41 | ./vam_test_tbz2/plugin/frawor/tcl.vim 42 | ./vam_test_tbz2/plugin/frawor.vim 43 | ./vam_test_tbz2/plugin/oop.vim 44 | ./vam_test_tbz2/templates 45 | ./vam_test_tbz2/templates/oneload-frawor-plugin.vim 46 | ./vam_test_tbz2/version -------------------------------------------------------------------------------- /test/files-tgz.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_tgz 2 | ./vam_test_tgz/README.markdown 3 | ./vam_test_tgz/addons 4 | ./vam_test_tgz/archive 5 | ./vam_test_tgz/archive/vam_test_tgz.tar.gz 6 | ./vam_test_tgz/autoload 7 | ./vam_test_tgz/autoload/frawor.vim 8 | ./vam_test_tgz/doc 9 | ./vam_test_tgz/doc/FWC.txt 10 | ./vam_test_tgz/doc/frawor.txt 11 | ./vam_test_tgz/doc/tags 12 | ./vam_test_tgz/plugin 13 | ./vam_test_tgz/plugin/frawor 14 | ./vam_test_tgz/plugin/frawor/autocommands.vim 15 | ./vam_test_tgz/plugin/frawor/base64.vim 16 | ./vam_test_tgz/plugin/frawor/checks.vim 17 | ./vam_test_tgz/plugin/frawor/commands.vim 18 | ./vam_test_tgz/plugin/frawor/decorators 19 | ./vam_test_tgz/plugin/frawor/decorators/altervars.vim 20 | ./vam_test_tgz/plugin/frawor/decorators.vim 21 | ./vam_test_tgz/plugin/frawor/functions.vim 22 | ./vam_test_tgz/plugin/frawor/fwc 23 | ./vam_test_tgz/plugin/frawor/fwc/compiler.vim 24 | ./vam_test_tgz/plugin/frawor/fwc/constructor.vim 25 | ./vam_test_tgz/plugin/frawor/fwc/intfuncs.vim 26 | ./vam_test_tgz/plugin/frawor/fwc/parser.vim 27 | ./vam_test_tgz/plugin/frawor/fwc/topconstructs.vim 28 | ./vam_test_tgz/plugin/frawor/fwc.vim 29 | ./vam_test_tgz/plugin/frawor/history.vim 30 | ./vam_test_tgz/plugin/frawor/lua.vim 31 | ./vam_test_tgz/plugin/frawor/mappings.vim 32 | ./vam_test_tgz/plugin/frawor/options.vim 33 | ./vam_test_tgz/plugin/frawor/os.vim 34 | ./vam_test_tgz/plugin/frawor/perl.vim 35 | ./vam_test_tgz/plugin/frawor/python.vim 36 | ./vam_test_tgz/plugin/frawor/resources.vim 37 | ./vam_test_tgz/plugin/frawor/ruby.vim 38 | ./vam_test_tgz/plugin/frawor/signs.vim 39 | ./vam_test_tgz/plugin/frawor/table.vim 40 | ./vam_test_tgz/plugin/frawor/tcl.vim 41 | ./vam_test_tgz/plugin/frawor.vim 42 | ./vam_test_tgz/templates 43 | ./vam_test_tgz/templates/oneload-frawor-plugin.vim 44 | ./vam_test_tgz/version -------------------------------------------------------------------------------- /test/files-tgz2-updated.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_tgz2 2 | ./vam_test_tgz2/README.markdown 3 | ./vam_test_tgz2/addons 4 | ./vam_test_tgz2/archive 5 | ./vam_test_tgz2/archive/vam_test_tgz_2-nodoc.tar.bz2 6 | ./vam_test_tgz2/autoload 7 | ./vam_test_tgz2/autoload/frawor.vim 8 | ./vam_test_tgz2/plugin 9 | ./vam_test_tgz2/plugin/frawor 10 | ./vam_test_tgz2/plugin/frawor/autocommands.vim 11 | ./vam_test_tgz2/plugin/frawor/base64.vim 12 | ./vam_test_tgz2/plugin/frawor/checks.vim 13 | ./vam_test_tgz2/plugin/frawor/commands.vim 14 | ./vam_test_tgz2/plugin/frawor/decorators 15 | ./vam_test_tgz2/plugin/frawor/decorators/altervars.vim 16 | ./vam_test_tgz2/plugin/frawor/decorators.vim 17 | ./vam_test_tgz2/plugin/frawor/functions.vim 18 | ./vam_test_tgz2/plugin/frawor/fwc 19 | ./vam_test_tgz2/plugin/frawor/fwc/compiler.vim 20 | ./vam_test_tgz2/plugin/frawor/fwc/constructor.vim 21 | ./vam_test_tgz2/plugin/frawor/fwc/intfuncs.vim 22 | ./vam_test_tgz2/plugin/frawor/fwc/parser.vim 23 | ./vam_test_tgz2/plugin/frawor/fwc/topconstructs.vim 24 | ./vam_test_tgz2/plugin/frawor/fwc.vim 25 | ./vam_test_tgz2/plugin/frawor/lua.vim 26 | ./vam_test_tgz2/plugin/frawor/mappings.vim 27 | ./vam_test_tgz2/plugin/frawor/options.vim 28 | ./vam_test_tgz2/plugin/frawor/os.vim 29 | ./vam_test_tgz2/plugin/frawor/perl.vim 30 | ./vam_test_tgz2/plugin/frawor/python.vim 31 | ./vam_test_tgz2/plugin/frawor/resources.vim 32 | ./vam_test_tgz2/plugin/frawor/ruby.vim 33 | ./vam_test_tgz2/plugin/frawor/signs.vim 34 | ./vam_test_tgz2/plugin/frawor/table.vim 35 | ./vam_test_tgz2/plugin/frawor/tcl.vim 36 | ./vam_test_tgz2/plugin/frawor.vim 37 | ./vam_test_tgz2/templates 38 | ./vam_test_tgz2/templates/oneload-frawor-plugin.vim 39 | ./vam_test_tgz2/version -------------------------------------------------------------------------------- /test/files-tgz2.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_tgz2 2 | ./vam_test_tgz2/README.markdown 3 | ./vam_test_tgz2/addons 4 | ./vam_test_tgz2/archive 5 | ./vam_test_tgz2/archive/vam_test_tgz_2.tgz 6 | ./vam_test_tgz2/autoload 7 | ./vam_test_tgz2/autoload/frawor.vim 8 | ./vam_test_tgz2/doc 9 | ./vam_test_tgz2/doc/FWC.txt 10 | ./vam_test_tgz2/doc/frawor.txt 11 | ./vam_test_tgz2/doc/tags 12 | ./vam_test_tgz2/plugin 13 | ./vam_test_tgz2/plugin/frawor 14 | ./vam_test_tgz2/plugin/frawor/autocommands.vim 15 | ./vam_test_tgz2/plugin/frawor/base64.vim 16 | ./vam_test_tgz2/plugin/frawor/checks.vim 17 | ./vam_test_tgz2/plugin/frawor/commands.vim 18 | ./vam_test_tgz2/plugin/frawor/decorators 19 | ./vam_test_tgz2/plugin/frawor/decorators/altervars.vim 20 | ./vam_test_tgz2/plugin/frawor/decorators.vim 21 | ./vam_test_tgz2/plugin/frawor/functions.vim 22 | ./vam_test_tgz2/plugin/frawor/fwc 23 | ./vam_test_tgz2/plugin/frawor/fwc/compiler.vim 24 | ./vam_test_tgz2/plugin/frawor/fwc/constructor.vim 25 | ./vam_test_tgz2/plugin/frawor/fwc/intfuncs.vim 26 | ./vam_test_tgz2/plugin/frawor/fwc/parser.vim 27 | ./vam_test_tgz2/plugin/frawor/fwc/topconstructs.vim 28 | ./vam_test_tgz2/plugin/frawor/fwc.vim 29 | ./vam_test_tgz2/plugin/frawor/lua.vim 30 | ./vam_test_tgz2/plugin/frawor/mappings.vim 31 | ./vam_test_tgz2/plugin/frawor/options.vim 32 | ./vam_test_tgz2/plugin/frawor/os.vim 33 | ./vam_test_tgz2/plugin/frawor/perl.vim 34 | ./vam_test_tgz2/plugin/frawor/python.vim 35 | ./vam_test_tgz2/plugin/frawor/resources.vim 36 | ./vam_test_tgz2/plugin/frawor/ruby.vim 37 | ./vam_test_tgz2/plugin/frawor/signs.vim 38 | ./vam_test_tgz2/plugin/frawor/table.vim 39 | ./vam_test_tgz2/plugin/frawor/tcl.vim 40 | ./vam_test_tgz2/plugin/frawor.vim 41 | ./vam_test_tgz2/templates 42 | ./vam_test_tgz2/templates/oneload-frawor-plugin.vim 43 | ./vam_test_tgz2/version -------------------------------------------------------------------------------- /test/files-vba.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_vba 2 | ./vam_test_vba/archive 3 | ./vam_test_vba/archive/vam_test_vba.vba 4 | ./vam_test_vba/autoload 5 | ./vam_test_vba/autoload/frawor.vim 6 | ./vam_test_vba/doc 7 | ./vam_test_vba/doc/json.rux 8 | ./vam_test_vba/doc/json.txt 9 | ./vam_test_vba/doc/tags 10 | ./vam_test_vba/doc/tags-ru 11 | ./vam_test_vba/plugin 12 | ./vam_test_vba/plugin/json.vim 13 | ./vam_test_vba/version -------------------------------------------------------------------------------- /test/files-vbz.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_vbz 2 | ./vam_test_vbz/archive 3 | ./vam_test_vbz/archive/vam_test_vbz.vba.bz2 4 | ./vam_test_vbz/autoload 5 | ./vam_test_vbz/autoload/frawor.vim 6 | ./vam_test_vbz/doc 7 | ./vam_test_vbz/doc/json.rux 8 | ./vam_test_vbz/doc/json.txt 9 | ./vam_test_vbz/doc/tags 10 | ./vam_test_vbz/doc/tags-ru 11 | ./vam_test_vbz/plugin 12 | ./vam_test_vbz/plugin/json.vim 13 | ./vam_test_vbz/version -------------------------------------------------------------------------------- /test/files-vgz.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_vgz 2 | ./vam_test_vgz/archive 3 | ./vam_test_vgz/archive/vam_test_vgz.vba.gz 4 | ./vam_test_vgz/autoload 5 | ./vam_test_vgz/autoload/frawor.vim 6 | ./vam_test_vgz/doc 7 | ./vam_test_vgz/doc/json.rux 8 | ./vam_test_vgz/doc/json.txt 9 | ./vam_test_vgz/doc/tags 10 | ./vam_test_vgz/doc/tags-ru 11 | ./vam_test_vgz/plugin 12 | ./vam_test_vgz/plugin/json.vim 13 | ./vam_test_vgz/version -------------------------------------------------------------------------------- /test/files-vmb.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_vmb 2 | ./vam_test_vmb/archive 3 | ./vam_test_vmb/archive/vam_test_vmb.vmb 4 | ./vam_test_vmb/autoload 5 | ./vam_test_vmb/autoload/frawor.vim 6 | ./vam_test_vmb/doc 7 | ./vam_test_vmb/doc/json.rux 8 | ./vam_test_vmb/doc/json.txt 9 | ./vam_test_vmb/doc/tags 10 | ./vam_test_vmb/doc/tags-ru 11 | ./vam_test_vmb/plugin 12 | ./vam_test_vmb/plugin/json.vim 13 | ./vam_test_vmb/version -------------------------------------------------------------------------------- /test/files-zip.lst: -------------------------------------------------------------------------------- 1 | ./vam_test_zip 2 | ./vam_test_zip/archive 3 | ./vam_test_zip/archive/vam_test_zip.zip 4 | ./vam_test_zip/autoload 5 | ./vam_test_zip/autoload/frawor.vim 6 | ./vam_test_zip/doc 7 | ./vam_test_zip/doc/json.rux 8 | ./vam_test_zip/doc/json.txt 9 | ./vam_test_zip/doc/tags 10 | ./vam_test_zip/doc/tags-ru 11 | ./vam_test_zip/jsonvim-addon-info.txt 12 | ./vam_test_zip/plugin 13 | ./vam_test_zip/plugin/json.vim 14 | ./vam_test_zip/test 15 | ./vam_test_zip/test/constants-nopython.ok 16 | ./vam_test_zip/test/constants.in 17 | ./vam_test_zip/test/constants.ok 18 | ./vam_test_zip/test/dump-nopython.ok 19 | ./vam_test_zip/test/dump.in 20 | ./vam_test_zip/test/dump.ok 21 | ./vam_test_zip/test/file-nopython.ok 22 | ./vam_test_zip/test/file.in 23 | ./vam_test_zip/test/file.ok 24 | ./vam_test_zip/test/gentests-nopython.zsh 25 | ./vam_test_zip/test/list-nopython.ok 26 | ./vam_test_zip/test/list.in 27 | ./vam_test_zip/test/list.json 28 | ./vam_test_zip/test/list.ok 29 | ./vam_test_zip/test/number-nopython.ok 30 | ./vam_test_zip/test/number.in 31 | ./vam_test_zip/test/number.ok 32 | ./vam_test_zip/test/object-nopython.ok 33 | ./vam_test_zip/test/object.in 34 | ./vam_test_zip/test/object.ok 35 | ./vam_test_zip/test/string-nopython.ok 36 | ./vam_test_zip/test/string.in 37 | ./vam_test_zip/test/string.ok 38 | ./vam_test_zip/test/vimrc 39 | ./vam_test_zip/version -------------------------------------------------------------------------------- /test/gentests-setuprtp.zsh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | emulate -L zsh 3 | cd ../rtp 4 | tar -xJf ../test/runtime.tar.xz 5 | rm ../test/runtime.tar.xz 6 | -------------------------------------------------------------------------------- /test/gentests-test-repos.zsh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | emulate -L zsh 3 | #▶1 Clone vam-test-known 4 | function clone-vtk() 5 | { 6 | local -x FOREGROUND=1 7 | mkdir vam-init 8 | vimcmd -u $VIMRC \ 9 | --cmd 'let g:curtest="init"' \ 10 | -c 'call vam#ActivateAddons("vam-test-known")' \ 11 | -c 'qa!' 12 | } 13 | clone-vtk 14 | function addtofile() 15 | { 16 | target=$1 17 | shift 18 | (( $# )) || return 19 | if ! test -e $1 ; then 20 | shift 21 | addtofile $target $@ 22 | return 23 | fi 24 | if test -e $target ; then 25 | echo >> $target 26 | cat $1 >> $target 27 | else 28 | cp $1 $target 29 | fi 30 | shift 31 | for file in $@ ; do 32 | test -e $file || continue 33 | echo >> $target 34 | cat $file >> $target 35 | done 36 | } 37 | #▶1 Simple unpack tests 38 | typeset -a TESTS 39 | (( ISWINE )) || TESTS+=( git bzr ) 40 | (( ISWINE )) && sed -r -i -e 's:/:\\:g' files-*.lst 41 | TESTS+=( hg svn tar tgz tgz2 tbz tbz2 zip vba vmb vgz vbz archive_name ) 42 | TESTS+=( mis mhg ) 43 | for t in $TESTS ; do 44 | local ANAME=vam_test_$t 45 | #▶2 activate 46 | cat > activate-$t.in < activate-vimrc-$t.vim << EOF 53 | call vam#ActivateAddons("$ANAME") 54 | EOF 55 | cat > activate-vimrc-$t.in << EOF 56 | :call WriteGlob() 57 | EOF 58 | cp activate-$t.ok activate-vimrc-$t.ok 59 | #▶2 install 60 | cat > install-$t.in <> uninstall-$t.in << EOF 69 | :UninstallNotLoadedAddons $ANAME 70 | y 71 | :call WriteGlob() 72 | EOF 73 | addtofile uninstall-$t.ok install-$t.ok init.ok 74 | if test -e dependencies-$t.lst ; then 75 | for dep in $(< dependencies-$t.lst) ; do 76 | addtofile uninstall-$t.ok files-$dep.lst 77 | done 78 | fi 79 | #▲2 80 | done 81 | #▶1 Update 82 | UPDATETGZ2HEADER="\ 83 | :let desc=copy(g:vim_addon_manager.plugin_sources.vam_test_tgz2) 84 | :let desc.version='0.1.8' 85 | :let desc.url=desc.url[:-5].'-nodoc.tar.bz2' 86 | :let patch={'vam_test_tgz2': desc}" 87 | #▶2 Update activate plugin 88 | T=update-tgz2 89 | cp activate-tgz2.in $T.in 90 | cat >> $T.in << EOF 91 | $UPDATETGZ2HEADER 92 | :UpdateAddons 93 | y 94 | :call WriteGlob() 95 | EOF 96 | addtofile $T.ok install-tgz2.ok init.ok files-tgz2-updated.lst 97 | #▶2 Update not activated plugin 98 | T=update-tgz2-not_active 99 | cp install-tgz2.in $T.in 100 | cat >> $T.in << EOF 101 | $UPDATETGZ2HEADER 102 | :UpdateAddons vam_test_tgz2 103 | :call WriteGlob() 104 | EOF 105 | addtofile $T.ok install-tgz2.ok init.ok files-tgz2-updated.lst 106 | #▶2 Be sure that not active plugin is not updated 107 | T=noupdate-tgz2-not_active 108 | cp install-tgz2.in $T.in 109 | cat >> $T.in << EOF 110 | $UPDATETGZ2HEADER 111 | :UpdateAddons 112 | y 113 | :call WriteGlob() 114 | EOF 115 | addtofile $T.ok install-tgz2.ok install-tgz2.ok 116 | #▶2 Check do_diff: 1 117 | T=update-tgz2-dodiff 118 | cp activate-tgz2.in $T.in 119 | cat >> $T.in << EOF 120 | :let desc=copy(g:vim_addon_manager.plugin_sources.vam_test_tgz2) 121 | :let desc.version='0.1.8' 122 | :let desc.archive_name=matchstr(desc.url, '\v[^/]+$') 123 | :let desc.url=desc.url[:-5].'-2.tgz' 124 | :let patch={'vam_test_tgz2': desc} 125 | :let file=g:vim_addon_manager.plugin_root_dir."/vam_test_tgz2/plugin/frawor.vim" 126 | :let g:vim_addon_manager.do_diff=1 127 | :execute "edit ".fnameescape(file) 128 | :%s/^"/#! 129 | :write! 130 | :set autoread 131 | :UpdateAddons 132 | y 133 | :call WriteGlob() 134 | :edit! 135 | qaq 136 | :g/^"/yank A 137 | :call WriteFile(split(@a, "\n")) 138 | EOF 139 | addtofile $T.ok install-tgz2.ok <(cat install-tgz2.ok | \ 140 | perl -pe '$_.="$1.orig\n"if/^(.*plugin.frawor\.vim)$/') \ 141 | comments-tgz2-dodiff.lst 142 | # addtofile $T.ok install-tgz2.ok install-tgz2.ok comments-tgz2-dodiff.lst 143 | #▶2 Check do_diff: 0 144 | T=update-tgz2-nodiff 145 | cat update-tgz2-dodiff.in | grep -v 'do_diff' > $T.in 146 | addtofile $T.ok install-tgz2.ok install-tgz2.ok comments-tgz2-nodiff.lst 147 | #▶1 Use cloned vam-test-known 148 | for test in *.in ; do 149 | cp -r vam-init vam-$test:r 150 | done 151 | #▲1 152 | cat > init.in << EOF 153 | :call WriteGlob() 154 | EOF 155 | #▶1 Add `:source addmessages.vim' 156 | for f in *.in ; do 157 | cat >> $f <<< $':source addmessages.vim\n' 158 | done 159 | #▲1 160 | # vim: fmr=▶,▲ fenc=utf-8 et ts=4 sts=4 sw=4 ft=zsh cms=#%s 161 | -------------------------------------------------------------------------------- /test/gwine: -------------------------------------------------------------------------------- 1 | wine -------------------------------------------------------------------------------- /test/hooks.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarcWeber/vim-addon-manager/585197500a4920c031467196e41335ca997aca6d/test/hooks.in -------------------------------------------------------------------------------- /test/hooks.ok: -------------------------------------------------------------------------------- 1 | Hook: post-install 2 | info: [] 3 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_tgz_2.tgz'], ['version', '0.1.7']] 4 | pdir: 'vam-hooks/vam_test_tgz2' 5 | opts: {} 6 | Hook: pre-update 7 | info: [] 8 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_tgz_2-nodoc.tar.bz2'], ['version', '0.1.8']] 9 | pdir: 'vam-hooks/vam_test_tgz2' 10 | opts: {'newVersion': '0.1.8', 'oldVersion': '0.1.7'} 11 | Hook: post-update 12 | info: [] 13 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_tgz_2-nodoc.tar.bz2'], ['version', '0.1.8']] 14 | pdir: 'vam-hooks/vam_test_tgz2' 15 | opts: {'newVersion': '0.1.8', 'oldVersion': '0.1.7'} 16 | Hook: post-install 17 | info: [['post-install-hook', 'call Hook(''post-install'', %i, %r, %d, %o)'], ['post-scms-update-hook', 'call Hook(''post-scms-update'', %i, %r, %d, %o)'], ['post-update-hook', 'call Hook(''post-update'', %i, %r, %d, %o)'], ['pre-update-hook', 'call Hook(''pre-update'', %i, %r, %d, %o)']] 18 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_hook.tar.bz2']] 19 | pdir: 'vam-hooks/vam_test_hook' 20 | opts: {} 21 | Plugin hook: post-install 22 | info: [['post-install-hook', 'call Hook(''post-install'', %i, %r, %d, %o)'], ['post-scms-update-hook', 'call Hook(''post-scms-update'', %i, %r, %d, %o)'], ['post-update-hook', 'call Hook(''post-update'', %i, %r, %d, %o)'], ['pre-update-hook', 'call Hook(''pre-update'', %i, %r, %d, %o)']] 23 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_hook.tar.bz2']] 24 | pdir: 'vam-hooks/vam_test_hook' 25 | opts: {} 26 | Hook: pre-update 27 | info: [['post-install-hook', 'call Hook(''post-install'', %i, %r, %d, %o)'], ['post-scms-update-hook', 'call Hook(''post-scms-update'', %i, %r, %d, %o)'], ['post-update-hook', 'call Hook(''post-update'', %i, %r, %d, %o)'], ['pre-update-hook', 'call Hook(''pre-update'', %i, %r, %d, %o)']] 28 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_hook.tar-copy.tar.bz2'], ['version', 'new']] 29 | pdir: 'vam-hooks/vam_test_hook' 30 | opts: {'newVersion': 'new', 'oldVersion': '?'} 31 | Plugin hook: pre-update 32 | info: [['post-install-hook', 'call Hook(''post-install'', %i, %r, %d, %o)'], ['post-scms-update-hook', 'call Hook(''post-scms-update'', %i, %r, %d, %o)'], ['post-update-hook', 'call Hook(''post-update'', %i, %r, %d, %o)'], ['pre-update-hook', 'call Hook(''pre-update'', %i, %r, %d, %o)']] 33 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_hook.tar-copy.tar.bz2'], ['version', 'new']] 34 | pdir: 'vam-hooks/vam_test_hook' 35 | opts: {'newVersion': 'new', 'oldVersion': '?'} 36 | Hook: post-update 37 | info: [] 38 | repo: [['type', 'archive'], ['url', 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam_test_hook.tar-copy.tar.bz2'], ['version', 'new']] 39 | pdir: 'vam-hooks/vam_test_hook' 40 | opts: {'newVersion': 'new', 'oldVersion': '?'} -------------------------------------------------------------------------------- /test/hooks.vim: -------------------------------------------------------------------------------- 1 | let s:F={} 2 | function s:F.hook_fun(info, repository, pluginDir, opts) 3 | let pdir=fnamemodify(a:pluginDir, ':h:t').'/'. 4 | \fnamemodify(a:pluginDir, ':t') 5 | call WriteFile('info: '.string(sort(items(a:info))), 6 | \ 'repo: '.string(sort(items(a:repository))), 7 | \ 'pdir: '.string(pdir), 8 | \ 'opts: '.string(a:opts)) 9 | endfunction 10 | function s:F.pihook(...) 11 | call WriteFile('Hook: post-install') 12 | return call(s:F.hook_fun, a:000, {}) 13 | endfunction 14 | function s:F.puhook(...) 15 | call WriteFile('Hook: post-update') 16 | return call(s:F.hook_fun, a:000, {}) 17 | endfunction 18 | function s:F.Puhook(...) 19 | call WriteFile('Hook: pre-update') 20 | return call(s:F.hook_fun, a:000, {}) 21 | endfunction 22 | function s:F.pUhook(...) 23 | call WriteFile('Hook: post-scms-update') 24 | return call(s:F.hook_fun, a:000, {}) 25 | endfunction 26 | function Hook(hook, ...) 27 | call WriteFile('Plugin hook: '.a:hook) 28 | return call(s:F.hook_fun, a:000, {}) 29 | endfunction 30 | let g:vim_addon_manager.post_install_hook_functions=[s:F.pihook] 31 | let g:vim_addon_manager.post_update_hook_functions=[s:F.puhook] 32 | let g:vim_addon_manager.pre_update_hook_functions=[s:F.Puhook] 33 | let g:vim_addon_manager.post_scms_update_hook_functions=[s:F.pUhook] 34 | call vam#ActivateAddons('vam_test_tgz2') 35 | UpdateActivatedAddons 36 | let desc=copy(g:vim_addon_manager.plugin_sources.vam_test_tgz2) 37 | let desc.version='0.1.8' 38 | let desc.url=desc.url[:-5].'-nodoc.tar.bz2' 39 | let patch={'vam_test_tgz2': desc} 40 | UpdateActivatedAddons 41 | call vam#ActivateAddons('vam_test_hook') 42 | let desc=copy(g:vim_addon_manager.plugin_sources.vam_test_hook) 43 | let desc.version='new' 44 | let desc.url=desc.url[:-5].'-copy.tar.bz2' 45 | let patch.vam_test_hook=desc 46 | UpdateActivatedAddons 47 | -------------------------------------------------------------------------------- /test/init.ok: -------------------------------------------------------------------------------- 1 | ./vam-test-known 2 | ./vam-test-known/autoload 3 | ./vam-test-known/autoload/vam_known_repositories.vim -------------------------------------------------------------------------------- /test/lineendings.in: -------------------------------------------------------------------------------- 1 | :call Try('call vam#ActivateAddons(["vam_test_dos"])') 2 | :source addmessages.vim 3 | -------------------------------------------------------------------------------- /test/lineendings.ok: -------------------------------------------------------------------------------- 1 | ::: In {unix_ff}/plugin/writeMsg.vim -------------------------------------------------------------------------------- /test/runtime.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarcWeber/vim-addon-manager/585197500a4920c031467196e41335ca997aca6d/test/runtime.tar.xz -------------------------------------------------------------------------------- /test/vimrc: -------------------------------------------------------------------------------- 1 | let g:vim_addon_manager={} 2 | let g:vim_addon_manager.known='vam-test-known' 3 | if executable('git') 4 | let g:vim_addon_manager.plugin_sources={ 5 | \'vam-test-known': {'type': 'git', 6 | \ 'url': 'https://vimpluginloader.git.sourceforge.net/gitroot/vimpluginloader/vam-test-repository/',}, 7 | \} 8 | else 9 | let g:vim_addon_manager.plugin_sources={ 10 | \'vam-test-known': {'type': 'archive', 11 | \ 'url': 'http://downloads.sourceforge.net/project/vimpluginloader/vam-test/vam-test-repository.tar.gz', 12 | \ 'version': '9999', 13 | \ 'archive_name': 'vam-test-known.tar.gz'}, 14 | \} 15 | endif 16 | let g:vim_addon_manager.auto_install=1 17 | let g:vim_addon_manager.do_diff=0 18 | let g:vim_addon_manager.plugin_root_dir=fnamemodify('./vam-'.g:curtest, ':p')[:-2] 19 | let g:vim_addon_manager.shell_commands_run_method='system' 20 | let s:outfile=fnamemodify(g:outfile, ':p') 21 | let s:errfile=fnamemodify(g:outfile, ':p:r').'.fail' 22 | function WriteFile(...) 23 | let r=[] 24 | if filereadable(s:outfile) 25 | let r+=readfile(s:outfile, 'b') 26 | endif 27 | if type(a:1)==type([]) 28 | let r+=a:1 29 | else 30 | let r+=a:000 31 | endif 32 | call writefile(r, s:outfile, 'b') 33 | return '' 34 | endfunction 35 | command -bar -nargs=1 W :call WriteFile() 36 | function WriteGlob() 37 | cd `="vam-".g:curtest` 38 | call WriteFile(split(glob('./**', 1), "\n")) 39 | cd .. 40 | endfunction 41 | function Try(cmd) 42 | let failed=1 43 | try 44 | execute a:cmd 45 | let failed=0 46 | finally 47 | " Unlike :catch this won't loose trace 48 | if failed 49 | call writefile([], s:errfile, 'b') 50 | endif 51 | endtry 52 | endfunction 53 | command -nargs=1 Try :call Try() 54 | if !exists('g:noexe') && filereadable(g:curtest.'.vim') 55 | source `=g:curtest.".vim"` 56 | endif 57 | -------------------------------------------------------------------------------- /test/wine/init.ok: -------------------------------------------------------------------------------- 1 | .\vam-test-known 2 | .\vam-test-known\archive 3 | .\vam-test-known\archive\vam-test-known.tar.gz 4 | .\vam-test-known\pax_global_header 5 | .\vam-test-known\plugin 6 | .\vam-test-known\plugin\vim-addon-manager-known-repositories.vim 7 | .\vam-test-known\version -------------------------------------------------------------------------------- /vim-addon-manager-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case "$1" in 4 | test) 5 | ;; 6 | *) 7 | echo "this tests installation of various plugins" 8 | echo "usage: vim-addon-manager-test.sh test" 9 | exit 1 10 | ;; 11 | esac 12 | 13 | set -e -x 14 | 15 | root=$(dirname $0) 16 | test_dir='/tmp/vim-addon-manager-test' 17 | 18 | [ -e $test_dir ] && rm -fr $test_dir || true 19 | mkdir -p $test_dir 20 | 21 | cp -r $root $test_dir/vim-addon-manager 22 | 23 | cat >> $test_dir/.vimrc << EOF 24 | set nocompatible 25 | set runtimepath+=${test_dir}/vim-addon-manager 26 | call sample_vimrc_for_new_users#Load() 27 | 28 | let opts = {'auto_install' : 1 } 29 | 30 | " test mercurial 31 | " test git 32 | " test subversion 33 | call vam#ActivateAddons(["Translit3","vim-addon-views","vim-latex"], opts) 34 | 35 | function CheckAll() 36 | let res = [ 37 | \ exists(':Tr3Command') > 0, 38 | \ exists('g:vim_views_config'), 39 | \ exists('*AddSyntaxFoldItem') 40 | \ ] 41 | echoe string(res) 42 | call writefile(res, '${test_dir}/result.txt') 43 | endfun 44 | 45 | EOF 46 | 47 | # yes necessary for enabling known repositories and 48 | # continuing after nasty "press enter to continue lines .." 49 | test_dir='/tmp/vim-addon-manager-test' 50 | yes | vim -u $test_dir/.vimrc -U /dev/null -c ':call CheckAll()|qa!' 51 | 52 | echo "should be an aray cotaining 1 values only. 0 means failure" 53 | cat ${test_dir}/result.txt 54 | --------------------------------------------------------------------------------