6 Commits
0.5.3 ... 0.5.4

Author SHA1 Message Date
Junegunn Choi
f7ebba7b9e Improve PlugDiff: 'X' key to revert the update 2014-08-10 16:52:26 +09:00
Junegunn Choi
6272f5e289 Improve PlugStatus
- Display load status
- Load plugin with 'L' key

(This commit also allows not loading a plugin with `'for': []`. It used
to load ftdetect files.)
2014-08-10 13:46:46 +09:00
Junegunn Choi
f43067c7a5 Merge pull request #51 from junegunn/public-api
Add plug#helptags and plug#load (#48)
2014-08-09 23:44:59 +09:00
Junegunn Choi
e6cba28997 Fix error messages 2014-08-09 13:11:41 +09:00
Junegunn Choi
f1b8832a13 Add plug#load() (#48) 2014-08-09 12:59:20 +09:00
Junegunn Choi
d0c94a9b08 Add plug#helptags() 2014-08-09 12:58:16 +09:00
4 changed files with 229 additions and 41 deletions

View File

@@ -96,6 +96,10 @@ Reload .vimrc and `:PlugInstall` to install plugins.
- `S` - `PlugStatus` - `S` - `PlugStatus`
- `R` - Retry failed update or installation tasks - `R` - Retry failed update or installation tasks
- `q` - Close the window - `q` - Close the window
- `:PlugStatus`
- `L` - Load plugin
- `:PlugDiff`
- `X` - Revert the update
### Example: A small [sensible](https://github.com/tpope/vim-sensible) Vim configuration ### Example: A small [sensible](https://github.com/tpope/vim-sensible) Vim configuration

160
plug.vim
View File

@@ -69,7 +69,7 @@ let s:cpo_save = &cpo
set cpo&vim set cpo&vim
let s:plug_source = 'https://raw.github.com/junegunn/vim-plug/master/plug.vim' let s:plug_source = 'https://raw.github.com/junegunn/vim-plug/master/plug.vim'
let s:plug_buf = -1 let s:plug_buf = get(s:, 'plug_buf', -1)
let s:mac_gui = has('gui_macvim') && has('gui_running') let s:mac_gui = has('gui_macvim') && has('gui_running')
let s:is_win = has('win32') || has('win64') let s:is_win = has('win32') || has('win64')
let s:me = expand('<sfile>:p') let s:me = expand('<sfile>:p')
@@ -80,6 +80,7 @@ let s:TYPE = {
\ 'dict': type({}), \ 'dict': type({}),
\ 'funcref': type(function('call')) \ 'funcref': type(function('call'))
\ } \ }
let s:loaded = get(s:, 'loaded', {})
function! plug#begin(...) function! plug#begin(...)
if a:0 > 0 if a:0 > 0
@@ -148,9 +149,8 @@ function! plug#end()
" need to loop through the plugins in reverse " need to loop through the plugins in reverse
for name in reverse(copy(g:plugs_order)) for name in reverse(copy(g:plugs_order))
let plug = g:plugs[name] let plug = g:plugs[name]
if !has_key(plug, 'on') && !has_key(plug, 'for') if get(s:loaded, plug.dir, 0) || !has_key(plug, 'on') && !has_key(plug, 'for')
let rtp = s:rtp(plug) let rtp = s:add_rtp(plug)
call s:add_rtp(rtp)
if reload if reload
call s:source(rtp, 'plugin/**/*.vim', 'after/plugin/**/*.vim') call s:source(rtp, 'plugin/**/*.vim', 'after/plugin/**/*.vim')
endif endif
@@ -177,8 +177,11 @@ function! plug#end()
endif endif
if has_key(plug, 'for') if has_key(plug, 'for')
call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim') let types = s:to_a(plug.for)
for key in s:to_a(plug.for) if !empty(types)
call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim')
endif
for key in types
if !has_key(lod, key) if !has_key(lod, key)
let lod[key] = [] let lod[key] = []
endif endif
@@ -247,12 +250,15 @@ function! s:esc(path)
return substitute(a:path, ' ', '\\ ', 'g') return substitute(a:path, ' ', '\\ ', 'g')
endfunction endfunction
function! s:add_rtp(rtp) function! s:add_rtp(plug)
execute 'set rtp^='.s:esc(a:rtp) let rtp = s:rtp(a:plug)
let after = globpath(a:rtp, 'after') execute 'set rtp^='.s:esc(rtp)
let after = globpath(rtp, 'after')
if isdirectory(after) if isdirectory(after)
execute 'set rtp+='.s:esc(after) execute 'set rtp+='.s:esc(after)
endif endif
let s:loaded[a:plug.dir] = 1
return rtp
endfunction endfunction
function! s:reorg_rtp() function! s:reorg_rtp()
@@ -266,9 +272,28 @@ function! s:reorg_rtp()
endif endif
endfunction endfunction
function! plug#load(...)
if a:0 == 0
return s:err('Argument missing: plugin name(s) required')
endif
if !exists('g:plugs')
return s:err('plug#begin was not called')
endif
let unknowns = filter(copy(a:000), '!has_key(g:plugs, v:val)')
if !empty(unknowns)
let s = len(unknowns) > 1 ? 's' : ''
return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', ')))
end
for name in a:000
call s:lod(g:plugs[name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
endfor
call s:reorg_rtp()
silent! doautocmd BufRead
return 1
endfunction
function! s:lod(plug, types) function! s:lod(plug, types)
let rtp = s:rtp(a:plug) let rtp = s:add_rtp(a:plug)
call s:add_rtp(rtp)
for dir in a:types for dir in a:types
call s:source(rtp, dir.'/**/*.vim') call s:source(rtp, dir.'/**/*.vim')
endfor endfor
@@ -319,6 +344,7 @@ function! s:add(repo, ...)
\ a:0 == 1 ? s:parse_options(a:1) : s:base_spec) \ a:0 == 1 ? s:parse_options(a:1) : s:base_spec)
let g:plugs[name] = spec let g:plugs[name] = spec
let g:plugs_order += [name] let g:plugs_order += [name]
let s:loaded[spec.dir] = 0
catch catch
return s:err(v:exception) return s:err(v:exception)
endtry endtry
@@ -369,13 +395,17 @@ function! s:update(force, ...)
call s:update_impl(1, a:force, a:000) call s:update_impl(1, a:force, a:000)
endfunction endfunction
function! s:helptags() function! plug#helptags()
if !exists('g:plugs')
return s:err('plug#begin was not called')
endif
for spec in values(g:plugs) for spec in values(g:plugs)
let docd = join([spec.dir, 'doc'], '/') let docd = join([spec.dir, 'doc'], '/')
if isdirectory(docd) if isdirectory(docd)
silent! execute 'helptags '. s:esc(docd) silent! execute 'helptags '. s:esc(docd)
endif endif
endfor endfor
return 1
endfunction endfunction
function! s:syntax() function! s:syntax()
@@ -395,6 +425,7 @@ function! s:syntax()
syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha
syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained
syn match plugRelDate /([^)]*)$/ contained syn match plugRelDate /([^)]*)$/ contained
syn match plugNotLoaded /(not loaded)$/
syn match plugError /^x.*/ syn match plugError /^x.*/
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
hi def link plug1 Title hi def link plug1 Title
@@ -415,6 +446,8 @@ function! s:syntax()
hi def link plugError Error hi def link plugError Error
hi def link plugRelDate Comment hi def link plugRelDate Comment
hi def link plugSha Identifier hi def link plugSha Identifier
hi def link plugNotLoaded Comment
endfunction endfunction
function! s:lpad(str, len) function! s:lpad(str, len)
@@ -435,6 +468,7 @@ function! s:prepare()
else else
execute winnr . 'wincmd w' execute winnr . 'wincmd w'
endif endif
setlocal modifiable
silent %d _ silent %d _
else else
vertical topleft new vertical topleft new
@@ -449,7 +483,9 @@ function! s:prepare()
call s:assign_name() call s:assign_name()
endif endif
silent! unmap <buffer> <cr> silent! unmap <buffer> <cr>
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline silent! unmap <buffer> L
silent! unmap <buffer> X
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
setf vim-plug setf vim-plug
call s:syntax() call s:syntax()
endfunction endfunction
@@ -508,7 +544,7 @@ endfunction
function! s:finish(pull) function! s:finish(pull)
call append(3, '- Finishing ... ') call append(3, '- Finishing ... ')
redraw redraw
call s:helptags() call plug#helptags()
call plug#end() call plug#end()
call setline(4, getline(4) . 'Done!') call setline(4, getline(4) . 'Done!')
normal! gg normal! gg
@@ -1048,6 +1084,7 @@ function! s:status()
call append(1, '') call append(1, '')
let ecnt = 0 let ecnt = 0
let unloaded = 0
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 has_key(spec, 'uri') if has_key(spec, 'uri')
@@ -1065,6 +1102,11 @@ function! s:status()
endif endif
let cnt += 1 let cnt += 1
let ecnt += !valid let ecnt += !valid
" `s:loaded` entry can be missing if PlugUpgraded
if valid && get(s:loaded, spec.dir, -1) == 0
let unloaded = 1
let msg .= ' (not loaded)'
endif
call s:progress_bar(2, repeat('=', cnt), total) call s:progress_bar(2, repeat('=', cnt), total)
call append(3, s:format_message(valid, name, msg)) call append(3, s:format_message(valid, name, msg))
normal! 2G normal! 2G
@@ -1072,6 +1114,24 @@ function! s:status()
endfor endfor
call setline(1, 'Finished. '.ecnt.' error(s).') call setline(1, 'Finished. '.ecnt.' error(s).')
normal! gg normal! gg
setlocal nomodifiable
if unloaded
echo "Press 'L' on each line to load plugin"
nnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr>
xnoremap <silent> <buffer> L :call <SID>status_load(line('.'))<cr>
end
endfunction
function! s:status_load(lnum)
let line = getline(a:lnum)
let matches = matchlist(line, '^- \([^:]*\):.*(not loaded)$')
if !empty(matches)
let name = matches[1]
call plug#load(name)
setlocal modifiable
call setline(a:lnum, substitute(line, ' (not loaded)$', '', ''))
setlocal nomodifiable
endif
endfunction endfunction
function! s:is_preview_window_open() function! s:is_preview_window_open()
@@ -1083,34 +1143,43 @@ function! s:is_preview_window_open()
return 0 return 0
endfunction endfunction
function! s:find_name(lnum)
for lnum in reverse(range(1, a:lnum))
let line = getline(lnum)
if empty(line)
return ''
endif
let name = matchstr(line, '\(^- \)\@<=[^:]\+')
if !empty(name)
return name
endif
endfor
return ''
endfunction
function! s:preview_commit() function! s:preview_commit()
if b:plug_preview < 0 if b:plug_preview < 0
let b:plug_preview = !s:is_preview_window_open() let b:plug_preview = !s:is_preview_window_open()
endif endif
let sha = matchstr(getline('.'), '\(^ \)\@<=[0-9a-z]\{7}') let sha = matchstr(getline('.'), '\(^ \)\@<=[0-9a-z]\{7}')
if !empty(sha) if empty(sha)
let lnum = line('.') return
while lnum > 1
let lnum -= 1
let line = getline(lnum)
let name = matchstr(line, '\(^- \)\@<=[^:]\+')
if !empty(name)
let dir = g:plugs[name].dir
if isdirectory(dir)
execute 'cd '.s:esc(dir)
execute 'pedit '.sha
wincmd P
setlocal filetype=git buftype=nofile nobuflisted
execute 'silent read !git show '.sha
normal! ggdd
wincmd p
cd -
endif
break
endif
endwhile
endif endif
let name = s:find_name(line('.'))
if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir)
return
endif
execute 'cd '.s:esc(g:plugs[name].dir)
execute 'pedit '.sha
wincmd P
setlocal filetype=git buftype=nofile nobuflisted
execute 'silent read !git show '.sha
normal! ggdd
wincmd p
cd -
endfunction endfunction
function! s:section(flags) function! s:section(flags)
@@ -1144,7 +1213,28 @@ function! s:diff()
call setline(1, cnt == 0 ? 'No updates.' : 'Last update:') call setline(1, cnt == 0 ? 'No updates.' : 'Last update:')
nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr> nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr>
nnoremap <silent> <buffer> X :call <SID>revert()<cr>
normal! gg normal! gg
setlocal nomodifiable
if cnt > 0
echo "Press 'X' on each block to revert the update"
endif
endfunction
function! s:revert()
let name = s:find_name(line('.'))
if empty(name) || !has_key(g:plugs, name) ||
\ input(printf('Revert the update of %s? (Y/N) ', name)) !~? '^y'
return
endif
execute 'cd '.s:esc(g:plugs[name].dir)
call system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch))
cd -
setlocal modifiable
normal! dap
setlocal nomodifiable
echo 'Reverted.'
endfunction endfunction
let s:first_rtp = s:esc(get(split(&rtp, ','), 0, '')) let s:first_rtp = s:esc(get(split(&rtp, ','), 0, ''))

View File

@@ -21,15 +21,23 @@ make_dirs() {
for d in *; do for d in *; do
cat > $d/xxx.vim << EOF cat > $d/xxx.vim << EOF
" echom expand('<sfile>') " echom expand('<sfile>')
let g:xxx = get(g:, 'xxx', []) let g:$2 = get(g:, '$2', [])
call add(g:xxx, '${1:4}/$d') call add(g:$2, '${1:4}/$d')
EOF EOF
done done
cd - > /dev/null cd - > /dev/null
} }
make_dirs xxx/ make_dirs xxx/ xxx
make_dirs xxx/after make_dirs xxx/after xxx
mkdir xxx/doc
cat > xxx/doc/xxx.txt << DOC
hello *xxx*
DOC
make_dirs yyy/ yyy
make_dirs z1/ z1
make_dirs z2/ z2
cat > /tmp/mini-vimrc << VIMRC cat > /tmp/mini-vimrc << VIMRC
set rtp+=vader.vim set rtp+=vader.vim

View File

@@ -307,6 +307,13 @@ Execute (Rollback recent updates, PlugUpdate, then PlugDiff):
AssertEqual lnum, line('.') AssertEqual lnum, line('.')
AssertEqual 3, col('.') AssertEqual 3, col('.')
" X key to revert the update
AssertExpect '^- ', 2
execute "normal Xn\<cr>"
AssertExpect '^- ', 2
execute "normal Xy\<cr>"
AssertExpect '^- ', 1
" q will close preview window as well " q will close preview window as well
normal q normal q
@@ -317,6 +324,7 @@ Execute (Rollback recent updates, PlugUpdate, then PlugDiff):
" q should not close preview window if it's already open " q should not close preview window if it's already open
pedit pedit
PlugDiff PlugDiff
AssertExpect '^- ', 1
execute "normal ]]j\<cr>" execute "normal ]]j\<cr>"
normal q normal q
@@ -330,8 +338,8 @@ Execute (Plug window in a new tab):
set buftype=nofile set buftype=nofile
PlugUpdate PlugUpdate
normal D normal D
AssertEqual 'No updates.', getline(1) AssertExpect '^- ', 1
q normal q
AssertEqual 'new-tab', expand('%') AssertEqual 'new-tab', expand('%')
q q
q q
@@ -762,6 +770,84 @@ Execute (Filetype-based on-demand loading):
AssertEqual ['/ftdetect', 'after/ftdetect', '/plugin', 'after/plugin', '/ftplugin', 'after/ftplugin', '/indent', 'after/indent', '/syntax', 'after/syntax'], g:xxx AssertEqual ['/ftdetect', 'after/ftdetect', '/plugin', 'after/plugin', '/ftplugin', 'after/ftplugin', '/indent', 'after/indent', '/syntax', 'after/syntax'], g:xxx
Before: Before:
**********************************************************************
~ plug#helptags()
**********************************************************************
Execute (plug#helptags):
silent! call delete(expand('$PWD/xxx/doc/tags'))
Assert !filereadable(expand('$PWD/xxx/doc/tags'))
AssertEqual 1, plug#helptags()
Assert filereadable(expand('$PWD/xxx/doc/tags'))
**********************************************************************
~ Manual loading
**********************************************************************
Execute (plug#load - invalid arguments):
AssertEqual 0, plug#load()
AssertEqual 0, plug#load('non-existent-plugin')
AssertEqual 0, plug#load('non-existent-plugin', 'another-non-existent-plugin')
AssertEqual 1, plug#load('xxx')
AssertEqual 0, plug#load('xxx', 'non-existent-plugin')
AssertEqual 0, plug#load('non-existent-plugin', 'xxx')
Execute (on: []):
call plug#begin()
Plug 'junegunn/rust.vim', { 'on': [] }
call plug#end()
PlugInstall
q
Execute (PlugStatus reports (not loaded)):
PlugStatus
AssertExpect 'not loaded', 1
q
Execute (plug#load to load it):
tabnew test.rs
" Vader will switch tab to [Vader-workbench] after Log
" Log &filetype
AssertEqual 1, plug#load('rust.vim')
AssertEqual 'rust', &filetype
q
Execute (PlugStatus should not contain (not loaded)):
PlugStatus
AssertExpect 'not loaded', 0
q
Execute (Load plugin from PlugStatus screen with L key in normal mode):
call plug#begin()
Plug '$PWD/yyy', { 'on': [] }
call plug#end()
PlugStatus
AssertExpect 'not loaded', 1
Assert !exists('g:yyy'), 'yyy not loaded'
/not loaded
normal L
AssertExpect 'not loaded', 0
Assert exists('g:yyy'), 'yyy loaded'
q
Execute (Load plugin from PlugStatus screen with L key in visual mode):
call plug#begin()
Plug '$PWD/z1', { 'on': [] }
Plug '$PWD/z2', { 'for': [] }
call plug#end()
PlugStatus
AssertExpect 'not loaded', 2
Assert !exists('g:z1'), 'z1 not loaded'
Assert !exists('g:z2'), 'z2 not loaded'
normal ggVGL
AssertExpect 'not loaded', 0
Assert exists('g:z1'), 'z1 loaded'
Assert exists('g:z2'), 'z2 loaded'
q
Execute (Cleanup): Execute (Cleanup):
silent! call system('rm -rf '.temp_plugged) silent! call system('rm -rf '.temp_plugged)
silent! call rename('fzf', 'fzf-staged') silent! call rename('fzf', 'fzf-staged')