From ddf9132f460a01e787d2d073a3daf9429e4fe460 Mon Sep 17 00:00:00 2001 From: Jacobo de Vera Date: Mon, 7 Nov 2011 16:47:21 +0000 Subject: [PATCH 1/2] Store bundles in a sorted dictionary By storing bundles in a sorted dictionary (dictionary + list of keys), the bundle does not need to be reparsed during installation if it has already been initialised, and any additional options passed in the original command are kept. This changeset is also an initial attempt to stabilise the name vs spec naming convention, where a bundle spec is whatever is used to specify a bundle, be it a name, user/name, full uri, etc., and name is the name of the bundle that will become a directory under the bundles directory. closes #1 --- autoload/vundle/config.vim | 128 +++++++++++++++++++++++++--------- autoload/vundle/installer.vim | 24 ++++--- 2 files changed, 109 insertions(+), 43 deletions(-) diff --git a/autoload/vundle/config.vim b/autoload/vundle/config.vim index e8443c1..5023385 100644 --- a/autoload/vundle/config.vim +++ b/autoload/vundle/config.vim @@ -1,29 +1,46 @@ -func! vundle#config#bundle(arg, ...) - let bundle = vundle#config#init_bundle(a:arg, a:000) - call s:rtp_rm_a() - call add(g:bundles, bundle) - call s:rtp_add_a() +func! vundle#config#bundle(spec, ...) + let bundle = vundle#config#init_bundle(a:spec, a:000) + " All bundles are removed from rtp and re-added in inverse order so that + " they appear in rtp in the same order as they appear in vimrc + call g:bundles.rm_from_rtp() + call g:bundles.add(bundle) + call g:bundles.add_to_rtp() endf +" Clear all bundles from rtp, create the bundles holder +" func! vundle#config#init() - if !exists('g:bundles') | let g:bundles = [] | endif - call s:rtp_rm_a() - let g:bundles = [] + if exists('g:bundles') + call g:bundles.rm_from_rtp() + endif + let g:bundles = s:bundles.new() endf + +" Add each bundle to rtp and run their plugins, similarly to what vim does at +" startup. +" func! vundle#config#require(bundles) abort - for b in a:bundles - call s:rtp_add(b.rtpath()) + for bundle in a:bundles + call s:rtp_add(bundle.rtpath()) call s:rtp_add(g:bundle_dir) " TODO: it has to be relative rtpath, not bundle.name - exec 'runtime! '.b.name.'/plugin/*.vim' - exec 'runtime! '.b.name.'/after/*.vim' + exec 'runtime! ' . bundle.name . '/plugin/*.vim' + exec 'runtime! ' . bundle.name . '/after/*.vim' call s:rtp_rm(g:bundle_dir) endfor endf -func! vundle#config#init_bundle(name, opts) - let opts = extend(s:parse_options(a:opts), s:parse_name(substitute(a:name,"['".'"]\+','','g'))) + +" Create a bundle object based on a given spec and options +func! vundle#config#init_bundle(spec, opts) + let spec = substitute(a:spec,"['".'"]\+','','g') + + " Combine info derived from the spec with the options from the Bundle + " command. + let opts = extend(s:parse_options(a:opts), s:parse_spec(spec)) + + " Include generic bundle methods return extend(opts, copy(s:bundle)) endf @@ -38,35 +55,28 @@ func! s:parse_options(opts) endif endf -func! s:parse_name(arg) - let arg = a:arg +func! s:parse_spec(spec) + let spec = a:spec - if arg =~? '^\s*\(gh\|github\):\S\+' - \ || arg =~? '^[a-z0-9][a-z0-9-]*/[^/]\+$' - let uri = 'https://github.com/'.split(arg, ':')[-1] + if spec =~? '^\s*\(gh\|github\):\S\+' + \ || spec =~? '^[a-z0-9][a-z0-9-]*/[^/]\+$' + let uri = 'https://github.com/'.split(spec, ':')[-1] if uri !~? '\.git$' let uri .= '.git' endif let name = substitute(split(uri,'\/')[-1], '\.git\s*$','','i') - elseif arg =~? '^\s*\(git@\|git://\)\S\+' - \ || arg =~? '\(file\|https\?\)://' - \ || arg =~? '\.git\s*$' - let uri = arg + elseif spec =~? '^\s*\(git@\|git://\)\S\+' + \ || spec =~? '\(file\|https\?\)://' + \ || spec =~? '\.git\s*$' + let uri = spec let name = split( substitute(uri,'/\?\.git\s*$','','i') ,'\/')[-1] else - let name = arg + let name = spec let uri = 'https://github.com/vim-scripts/'.name.'.git' endif - return {'name': name, 'uri': uri, 'name_spec': arg } + return {'name': name, 'uri': uri, 'spec': spec } endf -func! s:rtp_rm_a() - call filter(copy(g:bundles), 's:rtp_rm(v:val.rtpath())') -endf - -func! s:rtp_add_a() - call filter(reverse(copy(g:bundles)), 's:rtp_add(v:val.rtpath())') -endf func! s:rtp_rm(dir) abort exec 'set rtp-='.fnameescape(expand(a:dir)) @@ -82,6 +92,9 @@ func! s:expand_path(path) abort return simplify(expand(a:path)) endf + +" Bundle object +" --------------------------------------------------------------------------- let s:bundle = {} func! s:bundle.path() @@ -91,3 +104,54 @@ endf func! s:bundle.rtpath() return has_key(self, 'rtp') ? s:expand_path(self.path().'/'.self.rtp) : self.path() endf + +func! s:bundle.command() + return printf("Bundle '%s'", self.spec) +endf + +" --------------------------------------------------------------------------- + + +" Bundle collection object +" --------------------------------------------------------------------------- +" +let s:bundles = { 'list' : [], 'dict' : {} } + +function! s:bundles.add(bundle) + call add(self.list, a:bundle.spec ) + let self.dict[ a:bundle.spec ] = a:bundle +endf + +func! s:bundles.new() + return deepcopy(self) +endf + +func! s:bundles.keys() + return copy(self.list) +endf + +func! s:bundles.has_bundle(spec) + return has_key(self.dict, a:spec) +endf + +func! s:bundles.get(bundle_spec) + return get(self.dict, a:bundle_spec) +endf + +func! s:bundles.rm_from_rtp() + call map(copy(self.list), 's:rtp_rm(self.dict[v:val].rtpath())') +endf + +func! s:bundles.add_to_rtp() + call map(reverse(copy(self.list)), 's:rtp_add(self.dict[v:val].rtpath())') +endf + +func! s:bundles.get_sorted_list() + return map(copy(self.list), 'self.dict[v:val]') +endf + +func! s:bundles.size() + return len(self.list) +endf + +" --------------------------------------------------------------------------- diff --git a/autoload/vundle/installer.vim b/autoload/vundle/installer.vim index 5fb371e..ab0144a 100644 --- a/autoload/vundle/installer.vim +++ b/autoload/vundle/installer.vim @@ -1,9 +1,9 @@ func! vundle#installer#new(bang, ...) abort let bundles = (a:1 == '') ? - \ g:bundles : + \ g:bundles.get_sorted_list() : \ map(copy(a:000), 'vundle#config#init_bundle(v:val, {})') - let names = vundle#scripts#bundle_names(map(copy(bundles), 'v:val.name_spec')) + let names = vundle#scripts#bundle_names(map(copy(bundles), 'v:val.spec')) call vundle#scripts#view('Installer',['" Installing bundles to '.expand(g:bundle_dir)], names + ['Helptags']) call s:process(a:bang, (a:bang ? 'add!' : 'add')) @@ -53,7 +53,7 @@ func! vundle#installer#run(func_name, name, ...) abort redraw - if 'updated' == status + if 'updated' == status echo n.' installed' elseif 'todate' == status echo n.' already installed' @@ -73,7 +73,7 @@ func! vundle#installer#run(func_name, name, ...) abort return status endf -func! s:sign(status) +func! s:sign(status) if (!has('signs')) return endif @@ -88,10 +88,12 @@ func! vundle#installer#install_and_require(bang, name) abort return result endf -func! vundle#installer#install(bang, name) abort +func! vundle#installer#install(bang, spec) abort if !isdirectory(g:bundle_dir) | call mkdir(g:bundle_dir, 'p') | endif - let b = vundle#config#init_bundle(a:name, {}) + let spec = substitute(a:spec,"['".'"]\+','','g') + + let b = g:bundles.has_bundle(spec) ? g:bundles.get(spec) : vundle#config#init_bundle(a:spec, {}) return s:sync(a:bang, b) endf @@ -102,7 +104,7 @@ func! vundle#installer#docs() abort endf func! vundle#installer#helptags(bundles) abort - let bundle_dirs = map(copy(a:bundles),'v:val.rtpath()') + let bundle_dirs = map(a:bundles.get_sorted_list(),'v:val.rtpath()') let help_dirs = filter(bundle_dirs, 's:has_doc(v:val)') call s:log('') @@ -116,15 +118,15 @@ func! vundle#installer#helptags(bundles) abort endf 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(g:bundles.get_sorted_list(), 'v:val.spec')) call vundle#scripts#view('list', ['" My Bundles'], bundles) redraw - echo len(g:bundles).' bundles configured' + echo g:bundles.size().' bundles configured' endf func! vundle#installer#clean(bang) abort - let bundle_dirs = map(copy(g:bundles), 'v:val.path()') + let bundle_dirs = map(copy(g:bundles.get_sorted_list()), 'v:val.path()') let all_dirs = split(globpath(g:bundle_dir, '*'), "\n") let x_dirs = filter(all_dirs, '0 > index(bundle_dirs, v:val)') @@ -207,7 +209,7 @@ func! s:sync(bang, bundle) abort let out = s:system(cmd) call s:log('') - call s:log('Bundle '.a:bundle.name_spec) + call s:log('Bundle '.a:bundle.spec) call s:log('$ '.cmd) call s:log('> '.out) From 69ad8439de18a42622438bab03fb0c812a727724 Mon Sep 17 00:00:00 2001 From: Jacobo de Vera Date: Thu, 10 Nov 2011 00:37:40 +0000 Subject: [PATCH 2/2] Allow overriding bundle name This changeset allows the second parameter of the Bundle command (a dictionary) to override bundle object fields that come from parsing the bundle spec. This means that Bundle 'abolish.vim', {'name' : 'abo'} will be installed in a bundle directory named 'abo', rather than 'abolish.vim', which is the name parsed from the bundle spec. --- autoload/vundle/config.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoload/vundle/config.vim b/autoload/vundle/config.vim index 5023385..8fd1450 100644 --- a/autoload/vundle/config.vim +++ b/autoload/vundle/config.vim @@ -38,7 +38,7 @@ func! vundle#config#init_bundle(spec, opts) " Combine info derived from the spec with the options from the Bundle " command. - let opts = extend(s:parse_options(a:opts), s:parse_spec(spec)) + let opts = extend(s:parse_options(a:opts), s:parse_spec(spec), 'keep') " Include generic bundle methods return extend(opts, copy(s:bundle))