update vim-plug

This commit is contained in:
Thomas Ruoff
2016-09-02 23:24:13 +02:00
parent 2b813d1e09
commit 30d9042631

View File

@@ -28,6 +28,9 @@
" " Using a non-master branch " " Using a non-master branch
" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } " Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
" "
" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
" Plug 'fatih/vim-go', { 'tag': '*' }
"
" " Plugin options " " Plugin options
" Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' } " Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' }
" "
@@ -128,7 +131,7 @@ function! plug#begin(...)
endfunction endfunction
function! s:define_commands() function! s:define_commands()
command! -nargs=+ -bar Plug call s:Plug(<args>) command! -nargs=+ -bar Plug call plug#(<args>)
if !executable('git') if !executable('git')
return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.')
endif endif
@@ -168,14 +171,22 @@ function! s:assoc(dict, key, val)
let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
endfunction endfunction
function! s:ask(message) function! s:ask(message, ...)
call inputsave() call inputsave()
echohl WarningMsg echohl WarningMsg
let proceed = input(a:message.' (y/N) ') =~? '^y' let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
echohl None echohl None
call inputrestore() call inputrestore()
echo "\r" echo "\r"
return proceed return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0
endfunction
function! s:ask_no_interrupt(...)
try
return call('s:ask', a:000)
catch
return 0
endtry
endfunction endfunction
function! plug#end() function! plug#end()
@@ -193,6 +204,9 @@ function! plug#end()
filetype off filetype off
for name in g:plugs_order for name in g:plugs_order
if !has_key(g:plugs, name)
continue
endif
let plug = g:plugs[name] let plug = g:plugs[name]
if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for') if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for')
let s:loaded[name] = 1 let s:loaded[name] = 1
@@ -222,7 +236,9 @@ function! plug#end()
if has_key(plug, 'for') if has_key(plug, 'for')
let types = s:to_a(plug.for) let types = s:to_a(plug.for)
if !empty(types) if !empty(types)
augroup filetypedetect
call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim')
augroup END
endif endif
for type in types for type in types
call s:assoc(lod.ft, type, name) call s:assoc(lod.ft, type, name)
@@ -259,7 +275,7 @@ function! plug#end()
syntax enable syntax enable
end end
else else
call s:reload() call s:reload_plugins()
endif endif
endfunction endfunction
@@ -267,9 +283,13 @@ function! s:loaded_names()
return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)')
endfunction endfunction
function! s:reload() function! s:load_plugin(spec)
call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
endfunction
function! s:reload_plugins()
for name in s:loaded_names() for name in s:loaded_names()
call s:source(s:rtp(g:plugs[name]), 'plugin/**/*.vim', 'after/plugin/**/*.vim') call s:load_plugin(g:plugs[name])
endfor endfor
endfunction endfunction
@@ -392,7 +412,20 @@ function! s:reorg_rtp()
endfunction endfunction
function! s:doautocmd(...) function! s:doautocmd(...)
if exists('#'.join(a:000, '#'))
execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '<nomodeline>' : '') join(a:000) execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '<nomodeline>' : '') join(a:000)
endif
endfunction
function! s:dobufread(names)
for name in a:names
let path = s:rtp(g:plugs[name]).'/**'
for dir in ['ftdetect', 'ftplugin']
if len(finddir(dir, path))
return s:doautocmd('BufRead')
endif
endfor
endfor
endfunction endfunction
function! plug#load(...) function! plug#load(...)
@@ -410,9 +443,7 @@ function! plug#load(...)
for name in a:000 for name in a:000
call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
endfor endfor
if exists('#BufRead') call s:dobufread(a:000)
doautocmd BufRead
endif
return 1 return 1
endfunction endfunction
@@ -448,9 +479,7 @@ function! s:lod(names, types, ...)
endif endif
call s:source(rtp, a:2) call s:source(rtp, a:2)
endif endif
if exists('#User#'.name)
call s:doautocmd('User', name) call s:doautocmd('User', name)
endif
endfor endfor
endfunction endfunction
@@ -458,21 +487,19 @@ function! s:lod_ft(pat, names)
let syn = 'syntax/'.a:pat.'.vim' let syn = 'syntax/'.a:pat.'.vim'
call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn)
execute 'autocmd! PlugLOD FileType' a:pat execute 'autocmd! PlugLOD FileType' a:pat
if exists('#filetypeplugin#FileType') call s:doautocmd('filetypeplugin', 'FileType')
doautocmd filetypeplugin FileType call s:doautocmd('filetypeindent', 'FileType')
endif
if exists('#filetypeindent#FileType')
doautocmd filetypeindent FileType
endif
endfunction endfunction
function! s:lod_cmd(cmd, bang, l1, l2, args, names) function! s:lod_cmd(cmd, bang, l1, l2, args, names)
call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:dobufread(a:names)
execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args)
endfunction endfunction
function! s:lod_map(map, names, prefix) function! s:lod_map(map, names, prefix)
call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:dobufread(a:names)
let extra = '' let extra = ''
while 1 while 1
let c = getchar(0) let c = getchar(0)
@@ -481,10 +508,17 @@ function! s:lod_map(map, names, prefix)
endif endif
let extra .= nr2char(c) let extra .= nr2char(c)
endwhile endwhile
if v:count
call feedkeys(v:count, 'n')
endif
call feedkeys('"'.v:register, 'n')
if mode(1) == 'no'
call feedkeys(v:operator)
endif
call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra) call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
endfunction endfunction
function! s:Plug(repo, ...) function! plug#(repo, ...)
if a:0 > 1 if a:0 > 1
return s:err('Invalid number of arguments (1..2)') return s:err('Invalid number of arguments (1..2)')
endif endif
@@ -583,6 +617,7 @@ function! s:syntax()
syn match plugRelDate /([^)]*)$/ contained syn match plugRelDate /([^)]*)$/ contained
syn match plugNotLoaded /(not loaded)$/ syn match plugNotLoaded /(not loaded)$/
syn match plugError /^x.*/ syn match plugError /^x.*/
syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
syn match plugH2 /^.*:\n-\+$/ syn match plugH2 /^.*:\n-\+$/
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
hi def link plug1 Title hi def link plug1 Title
@@ -602,6 +637,7 @@ function! s:syntax()
hi def link plugUpdate Type hi def link plugUpdate Type
hi def link plugError Error hi def link plugError Error
hi def link plugDeleted Ignore
hi def link plugRelDate Comment hi def link plugRelDate Comment
hi def link plugEdge PreProc hi def link plugEdge PreProc
hi def link plugSha Identifier hi def link plugSha Identifier
@@ -679,6 +715,12 @@ function! s:prepare(...)
throw 'Invalid current working directory. Cannot proceed.' throw 'Invalid current working directory. Cannot proceed.'
endif endif
for evar in ['$GIT_DIR', '$GIT_WORK_TREE']
if exists(evar)
throw evar.' detected. Cannot proceed.'
endif
endfor
call s:job_abort() call s:job_abort()
if s:switch_in() if s:switch_in()
normal q normal q
@@ -694,10 +736,9 @@ function! s:prepare(...)
let s:plug_buf = winbufnr(0) let s:plug_buf = winbufnr(0)
call s:assign_name() call s:assign_name()
silent! unmap <buffer> <cr> for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
silent! unmap <buffer> L execute 'silent! unmap <buffer>' k
silent! unmap <buffer> o endfor
silent! unmap <buffer> X
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
setf vim-plug setf vim-plug
if exists('g:syntax_on') if exists('g:syntax_on')
@@ -717,15 +758,25 @@ function! s:assign_name()
silent! execute 'f' fnameescape(name) silent! execute 'f' fnameescape(name)
endfunction endfunction
function! s:chsh(swap)
let prev = [&shell, &shellredir]
if !s:is_win && a:swap
set shell=sh shellredir=>%s\ 2>&1
endif
return prev
endfunction
function! s:bang(cmd, ...) function! s:bang(cmd, ...)
try try
let [sh, shrd] = s:chsh(a:0)
" FIXME: Escaping is incomplete. We could use shellescape with eval, " FIXME: Escaping is incomplete. We could use shellescape with eval,
" but it won't work on Windows. " but it won't work on Windows.
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
let g:_plug_bang = '!'.escape(cmd, '#!%') let g:_plug_bang = '!'.escape(cmd, '#!%')
execute "normal! :execute g:_plug_bang\<cr>\<cr>" execute "normal! :execute g:_plug_bang\<cr>\<cr>"
finally finally
unlet g:_plug_bang unlet g:_plug_bang
let [&shell, &shellredir] = [sh, shrd]
endtry endtry
return v:shell_error ? 'Exit status: ' . v:shell_error : '' return v:shell_error ? 'Exit status: ' . v:shell_error : ''
endfunction endfunction
@@ -753,7 +804,12 @@ function! s:do(pull, force, todo)
let error = '' let error = ''
let type = type(spec.do) let type = type(spec.do)
if type == s:TYPE.string if type == s:TYPE.string
if spec.do[0] == ':'
call s:load_plugin(spec)
execute spec.do[1:]
else
let error = s:bang(spec.do) let error = s:bang(spec.do)
endif
elseif type == s:TYPE.funcref elseif type == s:TYPE.funcref
try try
let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged')
@@ -764,6 +820,7 @@ function! s:do(pull, force, todo)
else else
let error = 'Invalid hook type' let error = 'Invalid hook type'
endif endif
call s:switch_in()
call setline(4, empty(error) ? (getline(4) . 'OK') call setline(4, empty(error) ? (getline(4) . 'OK')
\ : ('x' . getline(4)[1:] . error)) \ : ('x' . getline(4)[1:] . error))
if !empty(error) if !empty(error)
@@ -831,13 +888,14 @@ function! s:names(...)
endfunction endfunction
function! s:check_ruby() function! s:check_ruby()
silent! ruby require 'thread'; VIM::command('let g:plug_ruby = 1') silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'")
if get(g:, 'plug_ruby', 0) if !exists('g:plug_ruby')
unlet g:plug_ruby
return 1
endif
redraw! redraw!
return s:warn('echom', 'Warning: Ruby interface is broken') return s:warn('echom', 'Warning: Ruby interface is broken')
endif
let ruby_version = split(g:plug_ruby, '\.')
unlet g:plug_ruby
return s:version_requirement(ruby_version, [1, 8, 7])
endfunction endfunction
function! s:update_impl(pull, force, args) abort function! s:update_impl(pull, force, args) abort
@@ -964,8 +1022,17 @@ function! s:update_finish()
call s:log4(name, 'Checking out '.spec.commit) call s:log4(name, 'Checking out '.spec.commit)
let out = s:checkout(spec) let out = s:checkout(spec)
elseif has_key(spec, 'tag') elseif has_key(spec, 'tag')
call s:log4(name, 'Checking out '.spec.tag) let tag = spec.tag
let out = s:system('git checkout -q '.s:esc(spec.tag).' 2>&1', spec.dir) if tag =~ '\*'
let tags = s:lines(s:system('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir))
if !v:shell_error && !empty(tags)
let tag = tags[0]
call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
call append(3, '')
endif
endif
call s:log4(name, 'Checking out '.tag)
let out = s:system('git checkout -q '.s:esc(tag).' 2>&1', spec.dir)
else else
let branch = s:esc(get(spec, 'branch', 'master')) let branch = s:esc(get(spec, 'branch', 'master'))
call s:log4(name, 'Merging origin/'.branch) call s:log4(name, 'Merging origin/'.branch)
@@ -977,18 +1044,18 @@ function! s:update_finish()
call s:log4(name, 'Updating submodules. This may take a while.') call s:log4(name, 'Updating submodules. This may take a while.')
let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir) let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir)
endif endif
let msg = printf('%s %s: %s', v:shell_error ? 'x': '-', name, get(s:lines(out), -1, '')) let msg = s:format_message(v:shell_error ? 'x': '-', name, out)
if v:shell_error if v:shell_error
call add(s:update.errors, name) call add(s:update.errors, name)
call s:regress_bar() call s:regress_bar()
execute pos 'd _' silent execute pos 'd _'
call append(4, msg) | 4 call append(4, msg) | 4
elseif !empty(out) elseif !empty(out)
call setline(pos, msg) call setline(pos, msg[0])
endif endif
redraw redraw
endfor endfor
4 d _ silent 4 d _
call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")'))
call s:finish(s:update.pull) call s:finish(s:update.pull)
call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.')
@@ -1105,7 +1172,7 @@ function! s:log(bullet, name, lines)
if s:switch_in() if s:switch_in()
let pos = s:logpos(a:name) let pos = s:logpos(a:name)
if pos > 0 if pos > 0
execute pos 'd _' silent execute pos 'd _'
if pos > winheight('.') if pos > winheight('.')
let pos = 4 let pos = 4
endif endif
@@ -1145,7 +1212,7 @@ while 1 " Without TCO, Vim stack is bound to explode
let has_tag = has_key(spec, 'tag') let has_tag = has_key(spec, 'tag')
if !new if !new
let error = s:git_validate(spec, 0) let [error, _] = s:git_validate(spec, 0)
if empty(error) if empty(error)
if pull if pull
let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : ''
@@ -1809,10 +1876,7 @@ endfunction
function! s:system(cmd, ...) function! s:system(cmd, ...)
try try
let [sh, shrd] = [&shell, &shellredir] let [sh, shrd] = s:chsh(1)
if !s:is_win
set shell=sh shellredir=>%s\ 2>&1
endif
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
return system(s:is_win ? '('.cmd.')' : cmd) return system(s:is_win ? '('.cmd.')' : cmd)
finally finally
@@ -1860,11 +1924,18 @@ function! s:git_validate(spec, check_branch)
let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.',
\ branch, a:spec.branch) \ branch, a:spec.branch)
endif endif
if empty(err)
let commits = len(s:lines(s:system(printf('git rev-list origin/%s..HEAD', a:spec.branch), a:spec.dir)))
if !v:shell_error && commits
let err = join([printf('Diverged from origin/%s by %d commit(s).', a:spec.branch, commits),
\ 'Reinstall after PlugClean.'], "\n")
endif
endif
endif endif
else else
let err = 'Not found' let err = 'Not found'
endif endif
return err return [err, err =~# 'PlugClean']
endfunction endfunction
function! s:rm_rf(dir) function! s:rm_rf(dir)
@@ -1875,15 +1946,23 @@ endfunction
function! s:clean(force) function! s:clean(force)
call s:prepare() call s:prepare()
call append(0, 'Searching for unused plugins in '.g:plug_home) call append(0, 'Searching for invalid plugins in '.g:plug_home)
call append(1, '') call append(1, '')
" List of valid directories " List of valid directories
let dirs = [] let dirs = []
let errs = {}
let [cnt, total] = [0, len(g:plugs)] let [cnt, total] = [0, len(g:plugs)]
for [name, spec] in items(g:plugs) for [name, spec] in items(g:plugs)
if !s:is_managed(name) || empty(s:git_validate(spec, 0)) if !s:is_managed(name)
call add(dirs, spec.dir) call add(dirs, spec.dir)
else
let [err, clean] = s:git_validate(spec, 1)
if clean
let errs[spec.dir] = s:lines(err)[0]
else
call add(dirs, spec.dir)
endif
endif endif
let cnt += 1 let cnt += 1
call s:progress_bar(2, repeat('=', cnt), total) call s:progress_bar(2, repeat('=', cnt), total)
@@ -1907,25 +1986,60 @@ function! s:clean(force)
if !has_key(allowed, f) && isdirectory(f) if !has_key(allowed, f) && isdirectory(f)
call add(todo, f) call add(todo, f)
call append(line('$'), '- ' . f) call append(line('$'), '- ' . f)
if has_key(errs, f)
call append(line('$'), ' ' . errs[f])
endif
let found = filter(found, 'stridx(v:val, f) != 0') let found = filter(found, 'stridx(v:val, f) != 0')
end end
endwhile endwhile
normal! G 4
redraw redraw
if empty(todo) if empty(todo)
call append(line('$'), 'Already clean.') call append(line('$'), 'Already clean.')
else else
if a:force || s:ask('Proceed?') let s:clean_count = 0
for dir in todo call append(3, ['Directories to delete:', ''])
call s:rm_rf(dir) redraw!
endfor if a:force || s:ask_no_interrupt('Delete all directories?')
call append(line('$'), 'Removed.') call s:delete([6, line('$')], 1)
else else
call append(line('$'), 'Cancelled.') call setline(4, 'Cancelled.')
nnoremap <silent> <buffer> d :set opfunc=<sid>delete_op<cr>g@
nmap <silent> <buffer> dd d_
xnoremap <silent> <buffer> d :<c-u>call <sid>delete_op(visualmode(), 1)<cr>
echo 'Delete the lines (d{motion}) to delete the corresponding directories'
endif endif
endif endif
normal! G 4
setlocal nomodifiable
endfunction
function! s:delete_op(type, ...)
call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0)
endfunction
function! s:delete(range, force)
let [l1, l2] = a:range
let force = a:force
while l1 <= l2
let line = getline(l1)
if line =~ '^- ' && isdirectory(line[2:])
execute l1
redraw!
let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1)
let force = force || answer > 1
if answer
call s:rm_rf(line[2:])
setlocal modifiable
call setline(l1, '~'.line[1:])
let s:clean_count += 1
call setline(4, printf('Removed %d directories.', s:clean_count))
setlocal nomodifiable
endif
endif
let l1 += 1
endwhile
endfunction endfunction
function! s:upgrade() function! s:upgrade()
@@ -1972,7 +2086,7 @@ function! s:status()
for [name, spec] in items(g:plugs) for [name, spec] in items(g:plugs)
if has_key(spec, 'uri') if has_key(spec, 'uri')
if isdirectory(spec.dir) if isdirectory(spec.dir)
let err = s:git_validate(spec, 1) let [err, _] = s:git_validate(spec, 1)
let [valid, msg] = [empty(err), empty(err) ? 'OK' : err] let [valid, msg] = [empty(err), empty(err) ? 'OK' : err]
else else
let [valid, msg] = [0, 'Not found. Try PlugInstall.'] let [valid, msg] = [0, 'Not found. Try PlugInstall.']
@@ -2067,11 +2181,15 @@ function! s:preview_commit()
return return
endif endif
if exists('g:plug_pwindow') && !s:is_preview_window_open()
execute g:plug_pwindow
execute 'e' sha
else
execute 'pedit' sha execute 'pedit' sha
wincmd P wincmd P
setlocal filetype=git buftype=nofile nobuflisted modifiable endif
execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
normal! gg"_dd execute 'silent %!cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha
setlocal nomodifiable setlocal nomodifiable
nnoremap <silent> <buffer> q :q<cr> nnoremap <silent> <buffer> q :q<cr>
wincmd p wincmd p
@@ -2157,7 +2275,7 @@ function! s:revert()
setlocal modifiable setlocal modifiable
normal! "_dap normal! "_dap
setlocal nomodifiable setlocal nomodifiable
echo 'Reverted.' echo 'Reverted'
endfunction endfunction
function! s:snapshot(force, ...) abort function! s:snapshot(force, ...) abort
@@ -2207,4 +2325,3 @@ endif
let &cpo = s:cpo_save let &cpo = s:cpo_save
unlet s:cpo_save unlet s:cpo_save