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 endf
" Clear all bundles from rtp, create the bundles holder
"
func! vundle#config#init() 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 endf
" Add each bundle to rtp and run their plugins, similarly to what vim does at
" startup.
"
func! vundle#config#require(bundles) abort 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) call s:rtp_add(g:bundle_dir)
" TODO: it has to be relative rtpath, not bundle.name " 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) call s:rtp_rm(g:bundle_dir)
endfor endfor
endf 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)) return extend(opts, copy(s:bundle))
endf endf
@ -38,35 +55,28 @@ func! s:parse_options(opts)
endif endif
endf 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$' if uri !~? '\.git$'
let uri .= '.git' let uri .= '.git'
endif endif
let name = substitute(split(uri,'\/')[-1], '\.git\s*$','','i') 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] let name = split( substitute(uri,'/\?\.git\s*$','','i') ,'\/')[-1]
else else
let name = arg
let name = spec
let uri = 'https://github.com/vim-scripts/'.name.'.git' let uri = 'https://github.com/vim-scripts/'.name.'.git'
endif endif
return {'name': name, 'uri': uri, 'name_spec': arg }
return {'name': name, 'uri': uri, 'spec': spec }
endf 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 func! s:rtp_rm(dir) abort
exec 'set rtp-='.fnameescape(expand(a:dir)) exec 'set rtp-='.fnameescape(expand(a:dir))
@ -82,6 +92,9 @@ func! s:expand_path(path) abort
return simplify(expand(a:path)) return simplify(expand(a:path))
endf endf
" Bundle object
" ---------------------------------------------------------------------------
let s:bundle = {} let s:bundle = {}
func! s:bundle.path() func! s:bundle.path()
@ -91,3 +104,54 @@ endf
func! s:bundle.rtpath() func! s:bundle.rtpath()
return has_key(self, 'rtp') ? s:expand_path(self.path().'/'.self.rtp) : self.path() return has_key(self, 'rtp') ? s:expand_path(self.path().'/'.self.rtp) : self.path()
endf 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 func! vundle#installer#new(bang, ...) abort
let bundles = (a:1 == '') ? let bundles = (a:1 == '') ?
\ g:bundles :
\ g:bundles.get_sorted_list() :
\ map(copy(a:000), 'vundle#config#init_bundle(v:val, {})') \ 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 vundle#scripts#view('Installer',['" Installing bundles to '.expand(g:bundle_dir)], names + ['Helptags'])
call s:process(a:bang, (a:bang ? 'add!' : 'add')) call s:process(a:bang, (a:bang ? 'add!' : 'add'))
@ -53,7 +53,7 @@ func! vundle#installer#run(func_name, name, ...) abort
redraw redraw
if 'updated' == status
if 'updated' == status
echo n.' installed' echo n.' installed'
elseif 'todate' == status elseif 'todate' == status
echo n.' already installed' echo n.' already installed'
@ -73,7 +73,7 @@ func! vundle#installer#run(func_name, name, ...) abort
return status return status
endf endf
func! s:sign(status)
func! s:sign(status)
if (!has('signs')) if (!has('signs'))
return return
endif endif
@ -88,10 +88,12 @@ func! vundle#installer#install_and_require(bang, name) abort
return result return result
endf 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 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) return s:sync(a:bang, b)
endf endf
@ -102,7 +104,7 @@ func! vundle#installer#docs() abort
endf endf
func! vundle#installer#helptags(bundles) abort 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)') let help_dirs = filter(bundle_dirs, 's:has_doc(v:val)')
call s:log('') call s:log('')
@ -116,15 +118,15 @@ func! vundle#installer#helptags(bundles) abort
endf endf
func! vundle#installer#list(bang) abort 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) call vundle#scripts#view('list', ['" My Bundles'], bundles)
redraw redraw
echo len(g:bundles).' bundles configured'
echo g:bundles.size().' bundles configured'
endf endf
func! vundle#installer#clean(bang) abort 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 all_dirs = split(globpath(g:bundle_dir, '*'), "\n")
let x_dirs = filter(all_dirs, '0 > index(bundle_dirs, v:val)') 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) let out = s:system(cmd)
call s:log('') 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('$ '.cmd)
call s:log('> '.out) call s:log('> '.out)


Loading…
Cancel
Save