Browse Source

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
pull/109/head
Jacobo de Vera 14 years ago
parent
commit
ddf9132f46
2 changed files with 109 additions and 43 deletions
  1. +96
    -32
      autoload/vundle/config.vim
  2. +13
    -11
      autoload/vundle/installer.vim

+ 96
- 32
autoload/vundle/config.vim View File

@ -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
" ---------------------------------------------------------------------------

+ 13
- 11
autoload/vundle/installer.vim View File

@ -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)


Loading…
Cancel
Save