diff --git a/README.md b/README.md index 37806f1..d864566 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,10 @@ Reload .vimrc and `:PlugInstall` to install plugins. - `S` - `PlugStatus` - `R` - Retry failed update or installation tasks - `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 diff --git a/plug.vim b/plug.vim index e916109..e94d7f3 100644 --- a/plug.vim +++ b/plug.vim @@ -69,7 +69,7 @@ let s:cpo_save = &cpo set cpo&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:is_win = has('win32') || has('win64') let s:me = expand(':p') @@ -468,6 +468,7 @@ function! s:prepare() else execute winnr . 'wincmd w' endif + setlocal modifiable silent %d _ else vertical topleft new @@ -483,7 +484,8 @@ function! s:prepare() endif silent! unmap silent! unmap L - setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline + silent! unmap X + setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable setf vim-plug call s:syntax() endfunction @@ -1112,6 +1114,7 @@ function! s:status() endfor call setline(1, 'Finished. '.ecnt.' error(s).') normal! gg + setlocal nomodifiable if unloaded echo "Press 'L' on each line to load plugin" nnoremap L :call status_load(line('.')) @@ -1125,7 +1128,9 @@ function! s:status_load(lnum) 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 @@ -1138,34 +1143,43 @@ function! s:is_preview_window_open() return 0 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() if b:plug_preview < 0 let b:plug_preview = !s:is_preview_window_open() endif let sha = matchstr(getline('.'), '\(^ \)\@<=[0-9a-z]\{7}') - if !empty(sha) - let lnum = line('.') - 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 + if empty(sha) + return 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 function! s:section(flags) @@ -1199,7 +1213,28 @@ function! s:diff() call setline(1, cnt == 0 ? 'No updates.' : 'Last update:') nnoremap :silent! call preview_commit() + nnoremap X :call revert() 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 let s:first_rtp = s:esc(get(split(&rtp, ','), 0, '')) diff --git a/test/workflow.vader b/test/workflow.vader index 5c93a89..9c3ec78 100644 --- a/test/workflow.vader +++ b/test/workflow.vader @@ -307,6 +307,13 @@ Execute (Rollback recent updates, PlugUpdate, then PlugDiff): AssertEqual lnum, line('.') AssertEqual 3, col('.') + " X key to revert the update + AssertExpect '^- ', 2 + execute "normal Xn\" + AssertExpect '^- ', 2 + execute "normal Xy\" + AssertExpect '^- ', 1 + " q will close preview window as well normal q @@ -317,6 +324,7 @@ Execute (Rollback recent updates, PlugUpdate, then PlugDiff): " q should not close preview window if it's already open pedit PlugDiff + AssertExpect '^- ', 1 execute "normal ]]j\" normal q @@ -330,8 +338,8 @@ Execute (Plug window in a new tab): set buftype=nofile PlugUpdate normal D - AssertEqual 'No updates.', getline(1) - q + AssertExpect '^- ', 1 + normal q AssertEqual 'new-tab', expand('%') q q @@ -798,12 +806,12 @@ Execute (PlugStatus reports (not loaded)): q Execute (plug#load to load it): - setf xxx - f test.rs - Log &filetype - + 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