diff --git a/README.md b/README.md index b8a7fdbc..337e0b5e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [Vundle] is undergoing an [interface change], please stay up to date to get latest changes. -[![Gitter-chat](https://badges.gitter.im/gmarik/Vundle.vim.png)](https://gitter.im/gmarik/Vundle.vim) for discussion and support. +[![Gitter-chat](https://badges.gitter.im/gmarik/Vundle.vim.svg)](https://gitter.im/gmarik/Vundle.vim) for discussion and support. ![Vundle-installer](http://i.imgur.com/Rueh7Cc.png) @@ -34,6 +34,8 @@ If you are using Windows, go directly to [Windows setup]. If you run into any issues, please consult the [FAQ]. See [Tips] for some advanced configurations. + Using non-POSIX shells, such as the popular Fish shell, requires additional setup. Please check the [FAQ]. + 2. Set up [Vundle]: `$ git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim` @@ -78,10 +80,10 @@ "filetype plugin on " " Brief help - " :PluginList - list configured plugins - " :PluginInstall(!) - install (update) plugins - " :PluginSearch(!) foo - search (or refresh cache first) for foo - " :PluginClean(!) - confirm (or auto-approve) removal of unused plugins + " :PluginList - lists configured plugins + " :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate + " :PluginSearch foo - searches for foo; append `!` to refresh local cache + " :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal " " see :h vundle for more details or wiki for FAQ " Put your non-Plugin stuff after this line diff --git a/autoload/vundle.vim b/autoload/vundle.vim index 29390483..e0472ef7 100644 --- a/autoload/vundle.vim +++ b/autoload/vundle.vim @@ -8,8 +8,8 @@ com! -nargs=+ -bar Plugin \ call vundle#config#bundle() -com! -nargs=? -bang -complete=custom,vundle#scripts#complete PluginInstall -\ call vundle#installer#new('!' == '', ) +com! -nargs=* -bang -complete=custom,vundle#scripts#complete PluginInstall +\ call vundle#installer#new('!' == '', ) com! -nargs=? -bang -complete=custom,vundle#scripts#complete PluginSearch \ call vundle#scripts#all('!' == '', ) @@ -21,17 +21,21 @@ com! -nargs=? -bang PluginClean \ call vundle#installer#clean('!' == '') com! -nargs=0 PluginDocs -\ call vundle#installer#helptags(g:bundles) +\ call vundle#installer#helptags(g:vundle#bundles) + +com! -nargs=? -complete=custom,vundle#scripts#complete PluginExplore +\ call vundle#scripts#explore() " Aliases -com! PluginUpdate PluginInstall! +com! -nargs=* -complete=custom,vundle#scripts#complete PluginUpdate PluginInstall! " Vundle Aliases com! -nargs=? -bang -complete=custom,vundle#scripts#complete VundleInstall PluginInstall com! -nargs=? -bang -complete=custom,vundle#scripts#complete VundleSearch PluginSearch com! -nargs=? -bang VundleClean PluginClean com! -nargs=0 VundleDocs PluginDocs -com! VundleUpdate PluginInstall! +com! -nargs=* -complete=custom,vundle#scripts#complete VundleUpdate PluginInstall! +com! -nargs=? -complete=custom,vundle#scripts#complete VundleExplore PluginExplore " Deprecated Commands com! -nargs=+ Bundle call vundle#config#bundle() @@ -60,24 +64,30 @@ endif " :Plugin command in the vimrc. It is not possible to do this automatically " because when loading the vimrc file no plugins where loaded yet. func! vundle#rc(...) abort - let g:bundle_dir = len(a:000) > 0 ? expand(a:1, 1) : expand('$HOME/.vim/bundle', 1) - let g:updated_bundles = [] - let g:vundle_log = [] - let g:vundle_changelog = ['Updated Plugins:'] + if a:0 > 0 + let g:vundle#bundle_dir = expand(a:1, 1) + endif call vundle#config#init() endf " Alternative to vundle#rc, offers speed up by modifying rtp only when end() " called later. func! vundle#begin(...) abort - let g:vundle_lazy_load = 1 + let g:vundle#lazy_load = 1 call call('vundle#rc', a:000) endf " Finishes putting plugins on the rtp. func! vundle#end(...) abort - unlet g:vundle_lazy_load + unlet g:vundle#lazy_load call vundle#config#activate_bundles() endf +" Initialize some global variables used by Vundle. +let vundle#bundle_dir = expand('$HOME/.vim/bundle', 1) +let vundle#bundles = [] +let vundle#lazy_load = 0 +let vundle#log = [] +let vundle#updated_bundles = [] + " vim: set expandtab sts=2 ts=2 sw=2 tw=78 norl: diff --git a/autoload/vundle/config.vim b/autoload/vundle/config.vim index 5ecb30ba..0e02b112 100644 --- a/autoload/vundle/config.vim +++ b/autoload/vundle/config.vim @@ -10,11 +10,11 @@ func! vundle#config#bundle(arg, ...) if !s:check_bundle_name(bundle) return endif - if exists('g:vundle_lazy_load') && g:vundle_lazy_load - call add(g:bundles, bundle) + if exists('g:vundle#lazy_load') && g:vundle#lazy_load + call add(g:vundle#bundles, bundle) else call s:rtp_rm_a() - call add(g:bundles, bundle) + call add(g:vundle#bundles, bundle) call s:rtp_add_a() call s:rtp_add_defaults() endif @@ -40,10 +40,10 @@ endf " once. " --------------------------------------------------------------------------- func! vundle#config#init() - if !exists('g:bundles') | let g:bundles = [] | endif + if !exists('g:vundle#bundles') | let g:vundle#bundles = [] | endif call s:rtp_rm_a() - let g:bundles = [] - let g:bundle_names = {} + let g:vundle#bundles = [] + let s:bundle_names = {} endf @@ -55,11 +55,11 @@ endf func! vundle#config#require(bundles) abort for b in a:bundles call s:rtp_add(b.rtpath) - call s:rtp_add(g:bundle_dir) + call s:rtp_add(g:vundle#bundle_dir) " TODO: it has to be relative rtpath, not bundle.name exec 'runtime! '.b.name.'/plugin/*.vim' exec 'runtime! '.b.name.'/after/*.vim' - call s:rtp_rm(g:bundle_dir) + call s:rtp_rm(g:vundle#bundle_dir) endfor call s:rtp_add_defaults() endf @@ -91,14 +91,17 @@ endf " return -- 0 if the bundle's name has been seen before, 1 otherwise " --------------------------------------------------------------------------- funct! s:check_bundle_name(bundle) - if has_key(g:bundle_names, a:bundle.name) + if has_key(s:bundle_names, a:bundle.name) echoerr 'Vundle error: Name collision for Plugin ' . a:bundle.name_spec . - \ '. Plugin ' . g:bundle_names[a:bundle.name] . + \ '. Plugin ' . s:bundle_names[a:bundle.name] . \ ' previously used the name "' . a:bundle.name . '"' . \ '. Skipping Plugin ' . a:bundle.name_spec . '.' return 0 + elseif a:bundle.name !~ '\v^[A-Za-z0-9_-]%(\.?[A-Za-z0-9_-])*$' + echoerr 'Invalid plugin name: ' . a:bundle.name + return 0 endif - let g:bundle_names[a:bundle.name] = a:bundle.name_spec + let s:bundle_names[a:bundle.name] = a:bundle.name_spec return 1 endf @@ -180,7 +183,7 @@ endf " runtimepath. " --------------------------------------------------------------------------- func! s:rtp_rm_a() - let paths = map(copy(g:bundles), 'v:val.rtpath') + let paths = map(copy(g:vundle#bundles), 'v:val.rtpath') let prepends = join(paths, ',') let appends = join(paths, '/after,').'/after' exec 'set rtp-='.fnameescape(prepends) @@ -193,7 +196,7 @@ endf " runtimepath. " --------------------------------------------------------------------------- func! s:rtp_add_a() - let paths = map(copy(g:bundles), 'v:val.rtpath') + let paths = map(copy(g:vundle#bundles), 'v:val.rtpath') let prepends = join(paths, ',') let appends = join(paths, '/after,').'/after' exec 'set rtp^='.fnameescape(prepends) @@ -262,7 +265,7 @@ let s:bundle = {} " return -- the target location to clone this bundle to " --------------------------------------------------------------------------- func! s:bundle.path() - return s:expand_path(g:bundle_dir.'/'.self.name) + return s:expand_path(g:vundle#bundle_dir.'/') . self.name endf diff --git a/autoload/vundle/installer.vim b/autoload/vundle/installer.vim index 614b64bd..472271a3 100644 --- a/autoload/vundle/installer.vim +++ b/autoload/vundle/installer.vim @@ -1,17 +1,30 @@ " --------------------------------------------------------------------------- -" Try to clone all new bundles given (or all bundles in g:bundles by default) -" to g:bundle_dir. If a:bang is 1 it will also update all plugins (git pull). +" Try to clone all new bundles given (or all bundles in g:vundle#bundles by +" default) to g:vundle#bundle_dir. If a:bang is 1 it will also update all +" plugins (git pull). " " bang -- 1 or 0 " ... -- any number of bundle specifications (separate arguments) " --------------------------------------------------------------------------- func! vundle#installer#new(bang, ...) abort - let bundles = (a:1 == '') ? - \ g:bundles : - \ map(copy(a:000), 'vundle#config#bundle(v:val, {})') + " No specific plugins are specified. Operate on all plugins. + if a:0 == 0 + let bundles = g:vundle#bundles + " Specific plugins are specified for update. Update them. + elseif (a:bang) + let bundles = filter(copy(g:vundle#bundles), 'index(a:000, v:val.name) > -1') + " Specific plugins are specified for installation. Install them. + else + let bundles = map(copy(a:000), 'vundle#config#bundle(v:val, {})') + endif + + if empty(bundles) + echoerr 'No bundles were selected for operation' + return + endif let names = vundle#scripts#bundle_names(map(copy(bundles), 'v:val.name_spec')) - call vundle#scripts#view('Installer',['" Installing plugins to '.expand(g:bundle_dir, 1)], names + ['Helptags']) + call vundle#scripts#view('Installer',['" Installing plugins to '.expand(g:vundle#bundle_dir, 1)], names + ['Helptags']) " This calls 'add' as a normal mode command. This is a buffer local mapping " defined in vundle#scripts#view(). The mapping will call a buffer local @@ -43,11 +56,11 @@ func! s:process(bang, cmd) exec ':norm '.a:cmd - if 'error' == g:vundle_last_status + if 'error' == s:last_status let msg = 'With errors; press l to view log' endif - if 'updated' == g:vundle_last_status && empty(msg) + if 'updated' == s:last_status && empty(msg) let msg = 'Plugins updated; press u to view changelog' endif @@ -106,7 +119,7 @@ func! vundle#installer#run(func_name, name, ...) abort throw 'whoops, unknown status:'.status endif - let g:vundle_last_status = status + let s:last_status = status return status endf @@ -151,10 +164,10 @@ endf " return -- the return value from s:sync() " --------------------------------------------------------------------------- func! vundle#installer#install(bang, name) abort - if !isdirectory(g:bundle_dir) | call mkdir(g:bundle_dir, 'p') | endif + if !isdirectory(g:vundle#bundle_dir) | call mkdir(g:vundle#bundle_dir, 'p') | endif let n = substitute(a:name,"['".'"]\+','','g') - let matched = filter(copy(g:bundles), 'v:val.name_spec == n') + let matched = filter(copy(g:vundle#bundles), 'v:val.name_spec == n') if len(matched) > 0 let b = matched[0] @@ -167,12 +180,12 @@ endf " --------------------------------------------------------------------------- -" Call :helptags for all bundles in g:bundles. +" Call :helptags for all bundles in g:vundle#bundles. " " return -- 'error' if an error occurred, else return 'helptags' " --------------------------------------------------------------------------- func! vundle#installer#docs() abort - let error_count = vundle#installer#helptags(g:bundles) + let error_count = vundle#installer#helptags(g:vundle#bundles) if error_count > 0 return 'error' endif @@ -210,10 +223,10 @@ endf " bang -- not used " --------------------------------------------------------------------------- func! vundle#installer#list(bang) abort - let bundles = vundle#scripts#bundle_names(map(copy(g:bundles), 'v:val.name_spec')) + let bundles = vundle#scripts#bundle_names(map(copy(g:vundle#bundles), 'v:val.name_spec')) call vundle#scripts#view('list', ['" My Plugins'], bundles) redraw - echo len(g:bundles).' plugins configured' + echo len(g:vundle#bundles).' plugins configured' endf @@ -225,10 +238,10 @@ endf " should be removed unconditionally " --------------------------------------------------------------------------- func! vundle#installer#clean(bang) abort - let bundle_dirs = map(copy(g:bundles), 'v:val.path()') + let bundle_dirs = map(copy(g:vundle#bundles), 'v:val.path()') let all_dirs = (v:version > 702 || (v:version == 702 && has("patch51"))) - \ ? split(globpath(g:bundle_dir, '*', 1), "\n") - \ : split(globpath(g:bundle_dir, '*'), "\n") + \ ? split(globpath(g:vundle#bundle_dir, '*', 1), "\n") + \ : split(globpath(g:vundle#bundle_dir, '*'), "\n") let x_dirs = filter(all_dirs, '0 > index(bundle_dirs, v:val)') if empty(x_dirs) @@ -453,7 +466,7 @@ func! s:sync(bang, bundle) abort return 'todate' endif - call add(g:updated_bundles, [initial_sha, updated_sha, a:bundle]) + call add(g:vundle#updated_bundles, [initial_sha, updated_sha, a:bundle]) return 'updated' endf @@ -515,7 +528,7 @@ func! s:log(str, ...) abort let lines = split(a:str, '\n', 1) let time = strftime(fmt) for line in lines - call add(g:vundle_log, '['. time .'] '. prefix . line) + call add(g:vundle#log, '['. time .'] '. prefix . line) endfor return a:str endf diff --git a/autoload/vundle/scripts.vim b/autoload/vundle/scripts.vim index d7409a10..3b5b0efd 100644 --- a/autoload/vundle/scripts.vim +++ b/autoload/vundle/scripts.vim @@ -36,10 +36,17 @@ endf " " a, c, d -- see :h command-completion-custom " return -- all valid plugin names from vim-scripts.org as completion -" candidates, see also :h command-completion-custom +" candidates, or all installed plugin names when running an 'Update +" variant'. see also :h command-completion-custom " --------------------------------------------------------------------------- func! vundle#scripts#complete(a,c,d) - return join(s:load_scripts(0),"\n") + if match(a:c, '\v^%(Plugin|Vundle)%(Install!|Update)') == 0 + " Only installed plugins if updating + return join(map(copy(g:vundle#bundles), 'v:val.name'), "\n") + else + " Or all known plugins otherwise + return join(s:load_scripts(0),"\n") + endif endf @@ -47,12 +54,15 @@ endf " View the logfile after an update or installation. " --------------------------------------------------------------------------- func! s:view_log() - if !exists('g:vundle_log_file') - let g:vundle_log_file = tempname() + if !exists('s:log_file') + let s:log_file = tempname() endif - call writefile(g:vundle_log, g:vundle_log_file) - execute 'silent pedit ' . g:vundle_log_file + if bufloaded(s:log_file) + execute 'silent bdelete' s:log_file + endif + call writefile(g:vundle#log, s:log_file) + execute 'silent pedit ' . s:log_file wincmd P | wincmd H endf @@ -63,7 +73,8 @@ endf " user. " --------------------------------------------------------------------------- func! s:create_changelog() abort - for bundle_data in g:updated_bundles + let changelog = ['Updated Plugins:'] + for bundle_data in g:vundle#updated_bundles let initial_sha = bundle_data[0] let updated_sha = bundle_data[1] let bundle = bundle_data[2] @@ -76,18 +87,19 @@ func! s:create_changelog() abort let updates = system(cmd) - call add(g:vundle_changelog, '') - call add(g:vundle_changelog, 'Updated Plugin: '.bundle.name) + call add(changelog, '') + call add(changelog, 'Updated Plugin: '.bundle.name) if bundle.uri =~ "https://github.com" - call add(g:vundle_changelog, 'Compare at: '.bundle.uri[0:-5].'/compare/'.initial_sha.'...'.updated_sha) + call add(changelog, 'Compare at: '.bundle.uri[0:-5].'/compare/'.initial_sha.'...'.updated_sha) endif for update in split(updates, '\n') let update = substitute(update, '\s\+$', '', '') - call add(g:vundle_changelog, ' '.update) + call add(changelog, ' '.update) endfor endfor + return changelog endf @@ -95,14 +107,15 @@ endf " View the change log after an update or installation. " --------------------------------------------------------------------------- func! s:view_changelog() - call s:create_changelog() - - if !exists('g:vundle_changelog_file') - let g:vundle_changelog_file = tempname() + if !exists('s:changelog_file') + let s:changelog_file = tempname() endif - call writefile(g:vundle_changelog, g:vundle_changelog_file) - execute 'silent pedit ' . g:vundle_changelog_file + if bufloaded(s:changelog_file) + execute 'silent bdelete' s:changelog_file + endif + call writefile(s:create_changelog(), s:changelog_file) + execute 'silent pedit' s:changelog_file wincmd P | wincmd H endf @@ -129,15 +142,15 @@ endf " strings) " --------------------------------------------------------------------------- func! vundle#scripts#view(title, headers, results) - if exists('g:vundle_view') && bufloaded(g:vundle_view) - exec g:vundle_view.'bd!' + if exists('s:view') && bufloaded(s:view) + exec s:view.'bd!' endif exec 'silent pedit [Vundle] '.a:title wincmd P | wincmd H - let g:vundle_view = bufnr('%') + let s:view = bufnr('%') " " make buffer modifiable " to append without errors @@ -199,6 +212,22 @@ func! vundle#scripts#view(title, headers, results) endf +" --------------------------------------------------------------------------- +" Explore the folder of a given bundle or g:bundle_dir. +" +" bundle -- either a bundle object or a bundle specification string. +" --------------------------------------------------------------------------- +func! vundle#scripts#explore(bundle) + if empty(a:bundle) + exec 'Vexplore' g:bundle_dir + elseif type(a:bundle) == type({}) + exec 'Vexplore' a:bundle.rtpath + elseif type(a:bundle) == type('') + exec 'Vexplore' vundle#config#init_bundle(a:bundle, {}).rtpath + endif +endf + + " --------------------------------------------------------------------------- " Load the plugin database from vim-scripts.org . " @@ -245,7 +274,7 @@ endf " specifications) of all plugins from vim-scripts.org " --------------------------------------------------------------------------- func! s:load_scripts(bang) - let f = expand(g:bundle_dir.'/.vundle/script-names.vim-scripts.org.json', 1) + let f = expand(g:vundle#bundle_dir.'/.vundle/script-names.vim-scripts.org.json', 1) if a:bang || !filereadable(f) if 0 != s:fetch_scripts(f) return [] diff --git a/doc/vundle.txt b/doc/vundle.txt index 198584bc..9a2670a4 100644 --- a/doc/vundle.txt +++ b/doc/vundle.txt @@ -244,8 +244,16 @@ PluginInstall allows installation of plugins by name: > :PluginInstall unite.vim -Installs and activates unite.vim. You can use Tab to auto-complete known -script names. Note that the installation just described isn't permanent. To +Installs and activates unite.vim. + +PluginInstall also allows installation of several plugins separated by space. +> + :PluginInstall tpope/vim-surround tpope/vim-fugitive + +Installs both tpope/vim-surround and tpope/vim-fugitive from GitHub. + +You can use Tab to auto-complete known script names. +Note that the installation just described isn't permanent. To finish, you must put `Plugin 'unite.vim'` at the appropriate place in your `.vimrc` to tell Vundle to load the plugin at startup. @@ -263,6 +271,12 @@ Installs or updates the configured plugins. Press 'u' after updates complete to see the change log of all updated bundles. Press 'l' (lowercase 'L') to see the log of commands if any errors occurred. +To update specific plugins, write their names separated by space: +> + :PluginInstall! vim-surround vim-fugitive +or > + :PluginUpdate vim-surround vim-fugitive + 3.5 SEARCHING PLUGINS ~ *vundle-plugins-search* *:PluginSearch* > diff --git a/test/minirc.vim b/test/minirc.vim index 3c24395b..7b48d132 100644 --- a/test/minirc.vim +++ b/test/minirc.vim @@ -2,7 +2,8 @@ set nocompatible syntax on filetype off set rtp+=~/.vim/bundle/Vundle.vim/ -call vundle#rc() -Bundle 'gmarik/Vundle.vim' +call vundle#begin() +Plugin 'gmarik/Vundle.vim' +call vundle#end() filetype plugin indent on