37 Commits
0.3.3 ... 0.4.0

Author SHA1 Message Date
Junegunn Choi
5b2c03d3a8 R to retry interrupted tasks as well 2014-07-23 11:46:29 +09:00
Junegunn Choi
0b31be49cf Update README 2014-07-22 12:47:34 +09:00
Junegunn Choi
74fa6ab9df 'R' to retry failed update/installation tasks 2014-07-22 12:46:59 +09:00
Junegunn Choi
0d7e20c984 Merge pull request #37 from junegunn/retries
Retry in case of timeout
2014-07-21 23:13:43 +09:00
Junegunn Choi
e2714fb56e Retry in 3 seconds 2014-07-21 23:09:16 +09:00
Junegunn Choi
3b83a22ea4 Avoid InsertEnter/InsertLeave events in GUI MacVim workaround 2014-07-21 14:27:38 +09:00
Junegunn Choi
cd418369bc Use gui_macvim instead of mac (#36) 2014-07-21 11:42:27 +09:00
Junegunn Choi
279a334c8b Temporarily disable &imd on GUI MacVim (#36) 2014-07-21 11:35:48 +09:00
Junegunn Choi
9132e9d50d Workaround for screen freeze in MacVim GUI (#36) 2014-07-21 02:49:47 +09:00
Junegunn Choi
3323163e04 Retry in case of timeout (#35)
while gradually increasing the time limit
2014-07-20 02:14:15 +09:00
Junegunn Choi
e4671eaf9e Do not assume that frozen key exists
To avoid possible error after PlugUpgrade
2014-07-18 01:27:41 +09:00
Junegunn Choi
9afa356fb3 Exclude unmanaged plugins from PlugDiff output 2014-07-17 10:28:59 +09:00
Junegunn Choi
e04f696682 Ignore errors during :helptags
https://github.com/junegunn/vim-plug/issues/31#issuecomment-49058031
2014-07-17 02:20:00 +09:00
Junegunn Choi
4cb5fd04a6 Note on single quotes (#33) 2014-07-16 20:40:49 +09:00
Junegunn Choi
c16743e8fc License 2014-07-16 20:39:39 +09:00
Junegunn Choi
46a6e8441f Pin first and last path in &rtp (#34) 2014-07-16 20:26:42 +09:00
Junegunn Choi
466d1839b3 Add support for local plugins. Add frozen option (#32) 2014-07-16 19:52:58 +09:00
Junegunn Choi
c3cf35abb5 Ignore occasional error from Ruby 1.8.7
Related: https://bugs.ruby-lang.org/issues/1471
2014-07-13 22:02:11 +09:00
Junegunn Choi
344f80aedb Fix Ruby installer for Ruby 1.8.7 (#31) 2014-07-13 20:18:56 +09:00
Junegunn Choi
dae0540a11 Change gif 2014-07-13 17:39:19 +09:00
Junegunn Choi
af89938633 Real-time progress report
This commit is almost identical to the reverted
60b907c87f, but it tries to avoid high CPU load
by not printing every line.
2014-07-13 03:58:16 +09:00
Junegunn Choi
35c5f2830b Revert "Real-time progress report"
This reverts commit 60b907c87f.
2014-07-13 03:22:25 +09:00
Junegunn Choi
60b907c87f Real-time progress report 2014-07-13 03:05:54 +09:00
Junegunn Choi
9ceb9caa09 Minor refactoring 2014-07-10 00:44:09 +09:00
Junegunn Choi
42a42e7e71 Fix after directory and Plugfile on Windows 2014-07-10 00:13:32 +09:00
Junegunn Choi
8885b1086f Minor refactoring in ODL: no need to pass full dict 2014-07-09 01:14:03 +09:00
Junegunn Choi
90c07f269c Fix <Plug>-based ODL on visual range spanning multiple lines 2014-07-07 22:55:44 +09:00
Junegunn Choi
f1c5157e35 Fix <Plug>-based on-demand-loading on visual mode 2014-07-07 19:06:20 +09:00
Junegunn Choi
7f1ec7b12b Load ftplugins while avoiding extraneous FileType events (#24, #25) 2014-07-04 14:20:48 +09:00
Junegunn Choi
f90afc9081 Remove images from repo 2014-06-23 23:39:48 +09:00
Junegunn Choi
612b9b3afd Fix test cases for travis-ci 2014-06-23 13:16:14 +09:00
Junegunn Choi
58891e05be Travis-CI integration 2014-06-23 12:57:46 +09:00
Junegunn Choi
baf7b18f73 Update test runner script 2014-06-23 12:53:51 +09:00
Junegunn Choi
cc37ed48be Improve PlugStatus message
Invalid branch/tag: %s (expected: %s). Try PlugUpdate.
2014-06-23 12:22:25 +09:00
Junegunn Choi
afe7dc6f8f Use case-sensitive match 2014-06-23 04:04:03 +09:00
Junegunn Choi
8863a3a53c Fix #28: False alarm from PlugStatus when tag used 2014-06-23 04:02:49 +09:00
Junegunn Choi
ee04a646d3 Fix: dependent plugins not loaded after initial installaion 2014-06-22 21:49:51 +09:00
14 changed files with 624 additions and 192 deletions

12
.travis.yml Normal file
View File

@@ -0,0 +1,12 @@
language: vim
before_script: |
hg clone https://code.google.com/p/vim/
cd vim
./configure --with-features=huge --enable-rubyinterp
make
sudo make install
cd -
script: |
test/run !

View File

@@ -1,11 +1,12 @@
![vim-plug](https://raw.github.com/junegunn/vim-plug/master/plug.png)
![travis-ci](https://travis-ci.org/junegunn/vim-plug.svg?branch=master)
A single-file Vim plugin manager.
Somewhere between [Pathogen](https://github.com/tpope/vim-pathogen) and
[Vundle](https://github.com/gmarik/vundle), but with faster parallel installer.
![](https://raw.github.com/junegunn/vim-plug/master/gif/vim-plug.gif)
![](https://raw.github.com/junegunn/i/master/vim-plug/installer.gif)
### Pros.
@@ -36,28 +37,28 @@ Edit your .vimrc
```vim
call plug#begin('~/.vim/plugged')
" Make sure you use single quotes
Plug 'junegunn/seoul256.vim'
Plug 'junegunn/vim-easy-align'
" On-demand loading
Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" Plug 'user/repo1', 'branch_or_tag'
" Plug 'user/repo2', { 'rtp': 'vim/plugin/dir', 'branch': 'devel' }
" Plug 'git@github.com:junegunn/vim-github-dashboard.git'
" ...
" Using git URL
Plug 'https://github.com/junegunn/vim-github-dashboard.git'
" Plugin options
Plug 'nsf/gocode', { 'tag': 'go.weekly.2012-03-13', 'rtp': 'vim' }
" Locally-managed plugin
Plug '~/.fzf'
call plug#end()
```
Reload .vimrc and `:PlugInstall` to install plugins.
### Plugin directory
If you omit the path argument to `plug#begin()`, plugins are installed in
`plugged` directory under the first path in `runtimepath` at the point when
`plug#begin()` is called. This is usually `~/.vim/plugged` (or
`$HOME/vimfiles/plugged` on Windows) given that you didn't touch runtimepath
before the call.
### Commands
| Command | Description |
@@ -69,17 +70,29 @@ before the call.
| PlugStatus | Check the status of plugins |
| PlugDiff | See the updated changes from the previous PlugUpdate |
### `Plug` options
| Option | Description |
| -------------- | -------------------------------------------------------------------- |
| `branch`/`tag` | Branch or tag of the repository to use |
| `rtp` | Subdirectory that contains Vim plugin |
| `on` | On-demand loading: Commands or <Plug>-mappings |
| `for` | On-demand loading: File types |
| `frozen` | Do not install/update plugin unless explicitly given as the argument |
### Options for parallel installer
| Flag | Default | Description |
| ---------------- | ------- | --------------------------------- |
| `g:plug_threads` | 16 | Default number of threads to use |
| `g:plug_timeout` | 60 | Time limit of each task in seconds |
| Flag | Default | Description |
| ---------------- | ------- | ------------------------------------ |
| `g:plug_threads` | 16 | Default number of threads to use |
| `g:plug_timeout` | 60 | Time limit of each task in seconds |
| `g:plug_retries` | 2 | Number of retries in case of timeout |
### Keybindings
- `D` - `PlugDiff`
- `S` - `PlugStatus`
- `R` - Retry failed update or installation tasks
- `q` - Close the window
### Example: A small [sensible](https://github.com/tpope/vim-sensible) Vim configuration
@@ -172,17 +185,7 @@ it as "unstable" or "in development", and always use its latest revision.
If you really must choose a certain untagged revision, consider forking the
repository.
### Regarding feature request
### License
You may submit a request for a new feature by [creating an
issue](https://github.com/junegunn/vim-plug/issues). However, please be minded
that this is an opinionated software and I want to keep the feature set as small
as possible. So I may not agree with you on the necessity of the suggested
feature. If that happens, I suggest the following options.
1. Check out [Vundle](https://github.com/gmarik/vundle) or
[NeoBundle](https://github.com/Shougo/neobundle.vim).
They offer broader feature sets.
2. Create a fork of this project and let it be your own plugin manager.
There's no need for us to have a single canonical branch.
MIT

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 922 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

399
plug.vim
View File

@@ -58,6 +58,7 @@ set cpo&vim
let s:plug_source = 'https://raw.github.com/junegunn/vim-plug/master/plug.vim'
let s:plug_file = 'Plugfile'
let 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('<sfile>:p')
@@ -141,16 +142,17 @@ function! plug#end()
for cmd in commands
if cmd =~ '^<Plug>.\+'
if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i'))
for [mode, prefix] in [['i', "<C-O>"], ['', '']]
for [mode, map_prefix, key_prefix] in
\ [['i', "<C-O>", ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
execute printf(
\ "%snoremap <silent> %s %s:call <SID>lod_map(%s, %s)<CR>",
\ mode, cmd, prefix, string(cmd), string(plug))
\ "%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, '%s')<CR>",
\ mode, cmd, map_prefix, string(cmd), string(name), key_prefix)
endfor
endif
elseif !exists(':'.cmd)
execute printf(
\ "command! -nargs=* -range -bang %s call s:lod_cmd(%s, '<bang>', <line1>, <line2>, <q-args>, %s)",
\ cmd, string(cmd), string(plug))
\ cmd, string(cmd), string(name))
endif
endfor
endif
@@ -174,17 +176,37 @@ function! plug#end()
\ key, string(key), string(reverse(names)))
augroup END
endfor
call s:reorg_rtp()
filetype plugin indent on
syntax on
endfunction
function! s:rtp(spec)
let rtp = s:dirpath(a:spec.dir . get(a:spec, 'rtp', ''))
if s:is_win
let rtp = substitute(rtp, '\\*$', '', '')
endif
return rtp
endfunction
if s:is_win
function! s:rtp(spec)
let rtp = s:dirpath(a:spec.dir . get(a:spec, 'rtp', ''))
return substitute(rtp, '\\*$', '', '')
endfunction
function! s:path(path)
return substitute(substitute(a:path, '/', '\', 'g'), '[/\\]*$', '', '')
endfunction
function! s:dirpath(path)
return s:path(a:path) . '\'
endfunction
else
function! s:rtp(spec)
return s:dirpath(a:spec.dir . get(a:spec, 'rtp', ''))
endfunction
function! s:path(path)
return substitute(a:path, '[/\\]*$', '', '')
endfunction
function! s:dirpath(path)
return s:path(a:path) . '/'
endfunction
endif
function! s:esc(path)
return substitute(a:path, ' ', '\\ ', 'g')
@@ -192,8 +214,20 @@ endfunction
function! s:add_rtp(rtp)
execute "set rtp^=".s:esc(a:rtp)
if isdirectory(a:rtp.'after')
execute "set rtp+=".s:esc(a:rtp.'after')
let after = globpath(a:rtp, 'after')
if isdirectory(after)
execute "set rtp+=".s:esc(after)
endif
endfunction
function! s:reorg_rtp()
if !empty(s:first_rtp)
execute 'set rtp-='.s:first_rtp
execute 'set rtp^='.s:first_rtp
endif
if s:last_rtp !=# s:first_rtp
execute 'set rtp-='.s:last_rtp
execute 'set rtp+='.s:last_rtp
endif
endfunction
@@ -211,20 +245,23 @@ function! s:lod_ft(pat, names)
for name in a:names
call s:lod(g:plugs[name], ['plugin', 'after'])
endfor
call s:reorg_rtp()
execute 'autocmd! PlugLOD FileType ' . a:pat
let &l:filetype = &l:filetype
silent! doautocmd filetypeplugin FileType
endfunction
function! s:lod_cmd(cmd, bang, l1, l2, args, plug)
function! s:lod_cmd(cmd, bang, l1, l2, args, name)
execute 'delc '.a:cmd
call s:lod(a:plug, ['plugin', 'ftdetect', 'after'])
call s:lod(g:plugs[a:name], ['plugin', 'ftdetect', 'after'])
call s:reorg_rtp()
execute printf("%s%s%s %s", (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args)
endfunction
function! s:lod_map(map, plug)
function! s:lod_map(map, name, prefix)
execute 'unmap '.a:map
execute 'iunmap '.a:map
call s:lod(a:plug, ['plugin', 'ftdetect', 'after'])
call s:lod(g:plugs[a:name], ['plugin', 'ftdetect', 'after'])
call s:reorg_rtp()
let extra = ''
while 1
let c = getchar(0)
@@ -233,20 +270,22 @@ function! s:lod_map(map, plug)
endif
let extra .= nr2char(c)
endwhile
call feedkeys(substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
endfunction
function! s:add(...)
let force = a:1
let opts = { 'branch': 'master' }
if a:0 == 2
let plugin = a:2
elseif a:0 == 3
let plugin = a:2
if type(a:3) == 1
let opts.branch = a:3
elseif type(a:3) == 4
call extend(opts, a:3)
function! s:add(force, ...)
let opts = { 'branch': 'master', 'frozen': 0 }
if a:0 == 1
let plugin = a:1
elseif a:0 == 2
let plugin = a:1
if type(a:2) == 1
let opts.branch = a:2
elseif type(a:2) == 4
call extend(opts, a:2)
if has_key(opts, 'tag')
let opts.branch = remove(opts, 'tag')
endif
else
echoerr "Invalid argument type (expected: string or dictionary)"
return
@@ -256,21 +295,32 @@ function! s:add(...)
return
endif
if plugin =~ ':'
let uri = plugin
else
if plugin !~ '/'
let plugin = 'vim-scripts/'. plugin
endif
let uri = 'https://git:@github.com/' . plugin . '.git'
let plugin = substitute(plugin, '[/\\]*$', '', '')
let name = substitute(split(plugin, '/')[-1], '\.git$', '', '')
if !a:force && has_key(g:plugs, name)
let s:extended[name] = g:plugs[name]
return
endif
let name = substitute(split(plugin, '/')[-1], '\.git$', '', '')
if !force && has_key(g:plugs, name) | return | endif
if plugin[0] =~ '[/$~]' || plugin =~? '^[a-z]:'
let spec = extend(opts, { 'dir': s:dirpath(expand(plugin)) })
else
if plugin =~ ':'
let uri = plugin
else
if plugin !~ '/'
let plugin = 'vim-scripts/'. plugin
endif
let uri = 'https://git:@github.com/' . plugin . '.git'
endif
let dir = s:dirpath( fnamemodify(join([g:plug_home, name], '/'), ':p') )
let spec = extend(opts, { 'dir': dir, 'uri': uri })
endif
let dir = s:dirpath( fnamemodify(join([g:plug_home, name], '/'), ':p') )
let spec = extend(opts, { 'dir': dir, 'uri': uri })
let g:plugs[name] = spec
if !a:force
let s:extended[name] = spec
endif
let g:plugs_order += [name]
endfunction
@@ -286,7 +336,7 @@ function! s:apply()
for spec in values(g:plugs)
let docd = join([spec.dir, 'doc'], '/')
if isdirectory(docd)
execute "helptags ". join([spec.dir, 'doc'], '/')
silent! execute "helptags ". join([spec.dir, 'doc'], '/')
endif
endfor
runtime! plugin/*.vim
@@ -302,7 +352,11 @@ function! s:syntax()
syn match plugBracket /[[\]]/ contained
syn match plugX /x/ contained
syn match plugDash /^-/
syn match plugPlus /^+/
syn match plugStar /^*/
syn match plugName /\(^- \)\@<=[^:]*/
syn match plugInstall /\(^+ \)\@<=[^:]*/
syn match plugUpdate /\(^* \)\@<=[^:]*/
syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha
syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained
syn match plugRelDate /([^)]*)$/ contained
@@ -313,8 +367,15 @@ function! s:syntax()
hi def link plugX Exception
hi def link plugBracket Structure
hi def link plugNumber Number
hi def link plugDash Special
hi def link plugPlus Constant
hi def link plugStar Boolean
hi def link plugName Label
hi def link plugInstall Function
hi def link plugUpdate Type
hi def link plugError Error
hi def link plugRelDate Comment
hi def link plugSha Identifier
@@ -342,6 +403,7 @@ function! s:prepare()
else
vertical topleft new
nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>q<cr>
nnoremap <silent> <buffer> R :silent! call <SID>retry()<cr>
nnoremap <silent> <buffer> D :PlugDiff<cr>
nnoremap <silent> <buffer> S :PlugStatus<cr>
nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr>
@@ -376,13 +438,30 @@ function! s:finish(pull)
call setline(4, getline(4) . 'Done!')
normal! gg
redraw
if a:pull
echo "Press 'D' to see the updated changes."
let msgs = []
if !empty(s:prev_update.errors)
call add(msgs, "Press 'R' to retry.")
endif
if a:pull
call add(msgs, "Press 'D' to see the updated changes.")
endif
echo join(msgs, ' ')
endfunction
function! s:retry()
if empty(s:prev_update.errors)
return
endif
call s:update_impl(s:prev_update.pull,
\ extend(copy(s:prev_update.errors), [s:prev_update.threads]))
endfunction
function! s:is_managed(name)
return has_key(g:plugs[a:name], 'uri')
endfunction
function! s:names(...)
return filter(keys(g:plugs), 'stridx(v:val, a:1) == 0')
return filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)')
endfunction
function! s:update_impl(pull, args) abort
@@ -390,8 +469,9 @@ function! s:update_impl(pull, args) abort
let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ?
\ remove(args, -1) : get(g:, 'plug_threads', 16)
let todo = empty(args) ? g:plugs :
\ filter(copy(g:plugs), 'index(args, v:key) >= 0')
let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
let todo = empty(args) ? filter(managed, '!get(v:val, "frozen", 0)') :
\ filter(managed, 'index(args, v:key) >= 0')
if empty(todo)
echohl WarningMsg
@@ -406,20 +486,49 @@ function! s:update_impl(pull, args) abort
normal! 2G
redraw
let len = len(g:plugs)
let s:prev_update = { 'errors': [], 'pull': a:pull, 'threads': threads }
if has('ruby') && threads > 1
call s:update_parallel(a:pull, todo, threads)
try
let imd = &imd
if s:mac_gui
set noimd
endif
call s:update_parallel(a:pull, todo, threads)
catch
let lines = getline(4, '$')
let printed = {}
silent 4,$d
for line in lines
let name = get(matchlist(line, '^. \([^:]\+\):'), 1, '')
if empty(name) || !has_key(printed, name)
call append('$', line)
if !empty(name)
let printed[name] = 1
if line[0] == 'x' && index(s:prev_update.errors, name) < 0
call add(s:prev_update.errors, name)
end
endif
endif
endfor
finally
let &imd = imd
endtry
else
call s:update_serial(a:pull, todo)
endif
if len(g:plugs) > len
call plug#end()
endif
call s:finish(a:pull)
endfunction
function! s:extend(names)
let prev = copy(g:plugs)
let s:extended = {}
try
command! -nargs=+ Plug call s:add(0, <args>)
for name in a:names
let plugfile = s:rtp(g:plugs[name]) . s:plug_file
let plugfile = globpath(s:rtp(g:plugs[name]), s:plug_file)
if filereadable(plugfile)
execute "source ". s:esc(plugfile)
endif
@@ -427,7 +536,7 @@ function! s:extend(names)
finally
command! -nargs=+ Plug call s:add(1, <args>)
endtry
return filter(copy(g:plugs), '!has_key(prev, v:key)')
return s:extended
endfunction
function! s:update_progress(pull, cnt, bar, total)
@@ -462,11 +571,11 @@ function! s:update_serial(pull, todo)
let result = msg
let error = 1
endif
cd -
else
if !isdirectory(base)
call mkdir(base, 'p')
endif
execute 'cd '.base
let result = s:system(
\ printf('git clone --recursive %s -b %s %s 2>&1 && cd %s && git submodule update --init --recursive 2>&1',
\ s:shellesc(spec.uri),
@@ -475,14 +584,17 @@ function! s:update_serial(pull, todo)
\ s:shellesc(spec.dir)))
let error = v:shell_error != 0
endif
cd -
let bar .= error ? 'x' : '='
if error
call add(s:prev_update.errors, name)
endif
call append(3, s:format_message(!error, name, result))
call s:update_progress(a:pull, len(done), bar, total)
endfor
if !empty(s:extend(keys(todo)))
let todo = filter(copy(g:plugs), '!has_key(done, v:key)')
let extended = s:extend(keys(todo))
if !empty(extended)
let todo = filter(extended, '!has_key(done, v:key)')
let total += len(todo)
call s:update_progress(a:pull, len(done), bar, total)
else
@@ -495,70 +607,109 @@ endfunction
function! s:update_parallel(pull, todo, threads)
ruby << EOF
module PlugStream
SEP = ["\r", "\n", nil]
def get_line
buffer = ''
loop do
char = readchar rescue return
if SEP.include? char.chr
buffer << $/
break
else
buffer << char
end
end
buffer
end
end unless defined?(PlugStream)
def esc arg
%["#{arg.gsub('"', '\"')}"]
end
st = Time.now
require 'set'
require 'thread'
require 'fileutils'
require 'timeout'
running = true
st = Time.now
iswin = VIM::evaluate('s:is_win').to_i == 1
pull = VIM::evaluate('a:pull').to_i == 1
base = VIM::evaluate('g:plug_home')
all = VIM::evaluate('copy(a:todo)')
limit = VIM::evaluate('get(g:, "plug_timeout", 60)')
tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1
nthr = VIM::evaluate('a:threads').to_i
maxy = VIM::evaluate('winheight(".")').to_i
cd = iswin ? 'cd /d' : 'cd'
done = {}
tot = 0
tot = VIM::evaluate('len(a:todo)') || 0
bar = ''
skip = 'Already installed'
mtx = Mutex.new
take1 = proc { mtx.synchronize { running && all.shift } }
logh = proc {
cnt = done.length
tot = VIM::evaluate('len(a:todo)') || tot
cnt = bar.length
$curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})"
$curbuf[2] = '[' + bar.ljust(tot) + ']'
VIM::command('normal! 2G')
VIM::command('redraw') unless iswin
}
log = proc { |name, result, ok|
where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } }
log = proc { |name, result, type|
mtx.synchronize do
bar += ok ? '=' : 'x'
done[name] = true
ing = ![true, false].include?(type)
bar += type ? '=' : 'x' unless ing
b = case type
when :install then '+' when :update then '*'
when true, nil then '-' else
VIM::command("call add(s:prev_update.errors, '#{name}')")
'x'
end
result =
if ok
["- #{name}: #{result.lines.to_a.last.strip}"]
if type || type.nil?
["#{b} #{name}: #{result.lines.to_a.last}"]
elsif result =~ /^Interrupted|^Timeout/
["x #{name}: #{result}"]
["#{b} #{name}: #{result}"]
else
["x #{name}"] + result.lines.map { |l| " " << l }
["#{b} #{name}"] + result.lines.map { |l| " " << l }
end
if lnum = where.call(name)
$curbuf.delete lnum
lnum = 4 if ing && lnum > maxy
end
result.each_with_index do |line, offset|
$curbuf.append 3 + offset, line.chomp
$curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp)
end
logh.call
end
}
bt = proc { |cmd|
bt = proc { |cmd, name, type|
tried = timeout = 0
begin
tried += 1
timeout += limit
fd = nil
Timeout::timeout(limit) do
if iswin
data = ''
if iswin
Timeout::timeout(timeout) do
tmp = VIM::evaluate('tempname()')
system("#{cmd} > #{tmp}")
data = File.read(tmp).chomp
File.unlink tmp rescue nil
else
fd = IO.popen(cmd)
data = fd.read.chomp
fd.close
end
[$? == 0, data]
else
fd = IO.popen(cmd).extend(PlugStream)
first_line = true
log_prob = 1.0 / nthr
while line = Timeout::timeout(timeout) { fd.get_line }
data << line
log.call name, line.chomp, type if name && (first_line || rand < log_prob)
first_line = false
end
fd.close
end
[$? == 0, data.chomp]
rescue Timeout::Error, Interrupt => e
if fd && !fd.closed?
pids = [fd.pid]
@@ -566,7 +717,7 @@ function! s:update_parallel(pull, todo, threads)
children = pids
until children.empty?
children = children.map { |pid|
`pgrep -P #{pid}`.lines.map(&:chomp)
`pgrep -P #{pid}`.lines.map { |l| l.chomp }
}.flatten
pids += children
end
@@ -574,6 +725,15 @@ function! s:update_parallel(pull, todo, threads)
pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil }
fd.close
end
if e.is_a?(Timeout::Error) && tried < tries
3.downto(1) do |countdown|
s = countdown > 1 ? 's' : ''
log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type
sleep 1
end
log.call name, 'Retrying ...', type
retry
end
[false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"]
end
}
@@ -590,9 +750,21 @@ function! s:update_parallel(pull, todo, threads)
threads.each { |t| t.join rescue nil }
main.kill
}
refresh = Thread.new {
while true
mtx.synchronize do
break unless running
VIM::command('noautocmd normal! a')
end
sleep 0.2
end
} if VIM::evaluate('s:mac_gui') == 1
processed = Set.new
progress = iswin ? '' : '--progress'
until all.empty?
names = all.keys
processed.merge names
[names.length, nthr].min.times do
mtx.synchronize do
threads << Thread.new {
@@ -600,10 +772,11 @@ function! s:update_parallel(pull, todo, threads)
name = pair.first
dir, uri, branch = pair.last.values_at *%w[dir uri branch]
branch = esc branch
subm = "git submodule update --init --recursive 2>&1"
ok, result =
if File.directory? dir
dir = esc dir
ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url"
ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil
current_uri = data.lines.to_a.last
if !ret
if data =~ /^Interrupted|^Timeout/
@@ -617,7 +790,8 @@ function! s:update_parallel(pull, todo, threads)
"PlugClean required."].join($/)]
else
if pull
bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && git pull origin #{branch} 2>&1 && git submodule update --init --recursive 2>&1"
log.call name, 'Updating ...', :update
bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && (git pull origin #{branch} #{progress} 2>&1 && #{subm})", name, :update
else
[true, skip]
end
@@ -625,37 +799,29 @@ function! s:update_parallel(pull, todo, threads)
else
FileUtils.mkdir_p(base)
d = esc dir.sub(%r{[\\/]+$}, '')
bt.call "#{cd} #{base} && git clone --recursive #{uri} -b #{branch} #{d} 2>&1 && cd #{esc dir} && git submodule update --init --recursive 2>&1"
log.call name, 'Installing ...', :install
bt.call "(git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1 && cd #{esc dir} && #{subm})", name, :install
end
log.call name, result, ok
end
} if running
end
end
threads.each(&:join)
threads.each { |t| t.join rescue nil }
mtx.synchronize { threads.clear }
all.merge!(VIM::evaluate("s:extend(#{names.inspect})") || {})
extended = Hash[(VIM::evaluate("s:extend(#{names.inspect})") || {}).reject { |k, _|
processed.include? k
}]
tot += extended.length
all.merge!(extended)
logh.call
end
refresh.kill if refresh
watcher.kill
$curbuf[1] = "Updated. Elapsed time: #{"%.6f" % (Time.now - st)} sec."
EOF
endfunction
function! s:path(path)
return substitute(s:is_win ? substitute(a:path, '/', '\', 'g') : a:path,
\ '[/\\]*$', '', '')
endfunction
function! s:dirpath(path)
let path = s:path(a:path)
if s:is_win
return path !~ '\\$' ? path.'\' : path
else
return path !~ '/$' ? path.'/' : path
endif
endfunction
function! s:shellesc(arg)
return '"'.substitute(a:arg, '"', '\\"', 'g').'"'
endfunction
@@ -687,6 +853,11 @@ function! s:system(cmd)
return system(s:is_win ? '('.a:cmd.')' : a:cmd)
endfunction
function! s:system_chomp(str)
let ret = s:system(a:str)
return v:shell_error ? '' : substitute(ret, '\n$', '', '')
endfunction
function! s:git_valid(spec, check_branch, cd)
let ret = 1
let msg = 'OK'
@@ -694,7 +865,7 @@ function! s:git_valid(spec, check_branch, cd)
if a:cd | execute "cd " . s:esc(a:spec.dir) | endif
let result = split(s:system("git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url"), '\n')
let remote = result[-1]
if v:shell_error != 0
if v:shell_error
let msg = join([remote, "PlugClean required."], "\n")
let ret = 0
elseif !s:compare_git_uri(remote, a:spec.uri)
@@ -704,9 +875,13 @@ function! s:git_valid(spec, check_branch, cd)
let ret = 0
elseif a:check_branch
let branch = result[0]
if a:spec.branch != branch
let msg = 'Invalid branch: '.branch.'. Try PlugUpdate.'
let ret = 0
if a:spec.branch !=# branch
let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1')
if a:spec.branch !=# tag
let msg = printf('Invalid branch/tag: %s (expected: %s). Try PlugUpdate.',
\ (empty(tag) ? branch : tag), a:spec.branch)
let ret = 0
endif
endif
endif
if a:cd | cd - | endif
@@ -724,8 +899,9 @@ function! s:clean(force)
" List of valid directories
let dirs = []
let [cnt, total] = [0, len(g:plugs)]
for spec in values(g:plugs)
let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
let [cnt, total] = [0, len(managed)]
for spec in values(managed)
if s:git_valid(spec, 0, 1)[0]
call add(dirs, spec.dir)
endif
@@ -826,10 +1002,18 @@ function! s:status()
let ecnt = 0
let [cnt, total] = [0, len(g:plugs)]
for [name, spec] in items(g:plugs)
if isdirectory(spec.dir)
let [valid, msg] = s:git_valid(spec, 1, 1)
if has_key(spec, 'uri')
if isdirectory(spec.dir)
let [valid, msg] = s:git_valid(spec, 1, 1)
else
let [valid, msg] = [0, 'Not found. Try PlugInstall.']
endif
else
let [valid, msg] = [0, 'Not found. Try PlugInstall.']
if isdirectory(spec.dir)
let [valid, msg] = [1, 'OK']
else
let [valid, msg] = [0, 'Not found.']
endif
endif
let cnt += 1
let ecnt += !valid
@@ -893,7 +1077,7 @@ function! s:diff()
let cnt = 0
for [k, v] in items(g:plugs)
if !isdirectory(v.dir)
if !isdirectory(v.dir) || !s:is_managed(k)
continue
endif
@@ -915,6 +1099,9 @@ function! s:diff()
normal! gg
endfunction
let s:first_rtp = s:esc(get(split(&rtp, ','), 0, ''))
let s:last_rtp = s:esc(get(split(&rtp, ','), -1, ''))
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@@ -7,8 +7,10 @@ Test cases for vim-plug
### Run
```vim
:e workflow.vader | Vader
```
./run
./run !
```
### TODO
@@ -18,7 +20,6 @@ Test cases for the following features are currently missing:
- Output formatting
- Timeout or interrupt cleaning up git processes
- User prompt in PlugClean command
- Automatic dependency resolution using Plugfile
- Single-threaded installer
- Windows support

View File

@@ -5,15 +5,24 @@ cd ..
PLUG_SRC=$(pwd)/plug.vim
cd - > /dev/null
export VADER_RTP=$TMPDIR/vader-rtp
vim -e +Vader -c ':call writefile([fnamemodify(globpath(&rtp, "autoload/vader.vim"), ":h:h")], $VADER_RTP)' +q
if [ ! -d vader.vim ]; then
git clone https://github.com/junegunn/vader.vim.git
fi
MINI_VIMRC=$TMPDIR/mini-vimrc
cat > $MINI_VIMRC << EOF
let \$MYVIMRC = '$MINI_VIMRC'
set nocompatible
set rtp=$(cat $VADER_RTP)
rm -rf fzf
if [ ! -d fzf-staged ]; then
git clone https://github.com/junegunn/fzf.git fzf-staged
fi
cat > /tmp/mini-vimrc << VIMRC
set rtp+=vader.vim
source $PLUG_SRC
EOF
VIMRC
if [ "$1" = '!' ]; then
/usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'Vader! workflow.vader' > /dev/null &&
/usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'let g:plug_threads = 1 | Vader! workflow.vader' > /dev/null
else
/usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'Vader workflow.vader'
fi
vim -u $MINI_VIMRC +Vader*

View File

@@ -1,5 +1,8 @@
Execute (Initialize test environment):
Save &rtp, g:plug_home, $MYVIMRC
Save &rtp, g:plugs, g:plug_home, $MYVIMRC
let first_rtp = split(&rtp, ',')[0]
let last_rtp = split(&rtp, ',')[-1]
let vader = fnamemodify(globpath(&rtp, 'autoload/vader.vim'), ':h:h')
let plug = fnamemodify(globpath(&rtp, 'autoload/plug.vim'), ':h:h')
@@ -15,6 +18,21 @@ Execute (Initialize test environment):
colo default
pclose
function! PlugStatusSorted()
PlugStatus
%y
q
normal! P
%sort
g/^$/d
endfunction
function! AssertExpect(bang, pat, cnt)
let op = a:bang ? '==' : '=~'
AssertEqual a:cnt, len(filter(getline(1, '$'), "v:val ".op." '".a:pat."'"))
endfunction
command! -nargs=+ -bang AssertExpect call AssertExpect('<bang>' == '!', <args>)
let g:vimrc_reloaded = 0
let vimrc = tempname()
call writefile(['let g:vimrc_reloaded += 1'], vimrc)
@@ -59,14 +77,26 @@ Execute (Subsequent plug#begin() calls will reuse g:plug_home):
Execute (Test Plug command):
" Git repo with branch
Plug 'junegunn/seoul256.vim', 'no-t_co'
Plug 'junegunn/seoul256.vim', 'yes-t_co'
AssertEqual 'https://git:@github.com/junegunn/seoul256.vim.git', g:plugs['seoul256.vim'].uri
AssertEqual join([temp_plugged, 'seoul256.vim/'], '/'), g:plugs['seoul256.vim'].dir
AssertEqual 'yes-t_co', g:plugs['seoul256.vim'].branch
Plug 'junegunn/seoul256.vim', { 'branch': 'no-t_co' } " Using branch option
AssertEqual 'no-t_co', g:plugs['seoul256.vim'].branch
" Git repo with tag
Plug 'junegunn/goyo.vim', '1.5.2'
AssertEqual 'https://git:@github.com/junegunn/goyo.vim.git', g:plugs['goyo.vim'].uri
AssertEqual join([temp_plugged, 'goyo.vim/'], '/'), g:plugs['goyo.vim'].dir
AssertEqual '1.5.2', g:plugs['goyo.vim'].branch
Plug 'junegunn/goyo.vim', { 'tag': '1.5.3' } " Using tag option
AssertEqual '1.5.3', g:plugs['goyo.vim'].branch
" Git URI
Plug 'git@github.com:junegunn/vim-emoji.git'
AssertEqual 'git@github.com:junegunn/vim-emoji.git', g:plugs['vim-emoji'].uri
Plug 'https://bitbucket.org/junegunn/vim-emoji.git'
AssertEqual 'https://bitbucket.org/junegunn/vim-emoji.git', g:plugs['vim-emoji'].uri
AssertEqual 'master', g:plugs['vim-emoji'].branch
AssertEqual join([temp_plugged, 'vim-emoji/'], '/'), g:plugs['vim-emoji'].dir
@@ -75,28 +105,32 @@ Execute (Test Plug command):
AssertEqual 'https://git:@github.com/vim-scripts/beauty256.git', g:plugs.beauty256.uri
AssertEqual 'master', g:plugs.beauty256.branch
AssertEqual 3, len(g:plugs)
AssertEqual 4, len(g:plugs)
Execute (Plug command with dictionary option):
Log string(g:plugs)
Plug 'junegunn/seoul256.vim', { 'branch': 'no-t_co', 'rtp': '././' }
AssertEqual join([temp_plugged, 'seoul256.vim/'], '/'), g:plugs['seoul256.vim'].dir
AssertEqual '././', g:plugs['seoul256.vim'].rtp
AssertEqual 3, len(g:plugs)
Log string(g:plugs)
AssertEqual 4, len(g:plugs)
Execute (PlugStatus before installation):
PlugStatus
AssertEqual 3, len(filter(getline(1, line('$')), 'v:val =~ "Not found"'))
AssertExpect 'Not found', 4
q
Execute (PlugClean before installation):
PlugClean
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "Already clean"'))
AssertExpect 'Already clean', 1
q
Execute (plug#end() updates &rtp):
call plug#end()
Assert len(&rtp) > len(basertp)
AssertEqual first_rtp, split(&rtp, ',')[0]
AssertEqual last_rtp, split(&rtp, ',')[-1]
Execute (Yet, plugins are not available):
Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
@@ -111,30 +145,50 @@ Execute (Plugin available after installation):
Execute (PlugClean after installation):
PlugClean
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "Already clean"'))
AssertExpect 'Already clean', 1
q
Execute (PlugStatus after installation):
PlugStatus
AssertEqual 3, len(filter(getline(1, line('$')), 'v:val =~ "OK"'))
Log getline(1, '$')
AssertExpect 'OK', 4
q
Execute (Change tag of goyo.vim):
call plug#begin()
Plug 'junegunn/goyo.vim'
call plug#end()
Execute (PlugStatus):
call PlugStatusSorted()
Expect:
Invalid branch/tag: 1.5.3 (expected: master). Try PlugUpdate.
Finished. 1 error(s).
[=]
x goyo.vim:
Execute (PlugUpdate to set the right branch):
PlugUpdate
call PlugStatusSorted()
AssertEqual 2, g:vimrc_reloaded
Expect:
- goyo.vim: OK
Finished. 0 error(s).
[=]
Execute (Change branch of seoul256.vim):
call plug#begin()
Plug 'junegunn/seoul256.vim'
Plug 'git@github.com:junegunn/vim-emoji.git'
Plug 'https://bitbucket.org/junegunn/vim-emoji.git'
call plug#end()
Execute (PlugStatus):
PlugStatus
%y
q
normal! P
%sort
g/^$/d
call PlugStatusSorted()
Expect:
Invalid branch: no-t_co. Try PlugUpdate.
Invalid branch/tag: no-t_co (expected: master). Try PlugUpdate.
- vim-emoji: OK
Finished. 1 error(s).
[==]
@@ -143,16 +197,11 @@ Expect:
Execute (Change URI of seoul256.vim):
call plug#begin()
Plug 'junegunn.choi/seoul256.vim'
Plug 'git@github.com:junegunn/vim-emoji.git'
Plug 'https://bitbucket.org/junegunn/vim-emoji.git'
call plug#end()
Execute (PlugStatus):
PlugStatus
%y
q
normal! P
%sort
g/^$/d
call PlugStatusSorted()
Expect:
Expected: https://git:@github.com/junegunn.choi/seoul256.vim.git
@@ -172,7 +221,9 @@ Expect:
Execute (PlugClean! to remove seoul256.vim):
PlugClean!
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "Removed"'))
" Three removed, emoji left
AssertExpect '^- ', 3
AssertExpect 'Removed', 1
Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
q
@@ -184,16 +235,11 @@ Execute (Change GIT URI of vim-emoji):
call plug#end()
Execute (PlugStatus):
PlugStatus
%y
q
normal! P
%sort
g/^$/d
call PlugStatusSorted()
Expect:
Expected: https://git:@github.com/junegunn/vim-emoji.git
Invalid URI: git@github.com:junegunn/vim-emoji.git
Invalid URI: https://bitbucket.org/junegunn/vim-emoji.git
Not found. Try PlugInstall.
PlugClean required.
Finished. 2 error(s).
@@ -203,23 +249,24 @@ Expect:
Execute (PlugClean! to remove vim-emoji):
PlugClean!
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "Removed"'))
AssertExpect '^- ', 1
AssertExpect 'Removed', 1
Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
q
Execute (PlugUpdate to install both again):
PlugUpdate
AssertEqual 2, len(filter(getline(1, line('$')), 'v:val =~ "Cloning into"'))
AssertEqual 2, g:vimrc_reloaded
AssertExpect '^- [^:]*:', 2
AssertEqual 3, g:vimrc_reloaded
Assert !empty(globpath(&rtp, 'colors/seoul256.vim')), 'seoul256.vim should be found'
Assert !empty(globpath(&rtp, 'autoload/emoji.vim')), 'vim-emoji should be found'
q
Execute (PlugUpdate only to find out plugins are up-to-date, D key to check):
PlugUpdate
AssertEqual 2, len(filter(getline(1, line('$')), 'v:val =~ "Already up-to-date"'))
AssertEqual 3, g:vimrc_reloaded
AssertExpect 'Already up-to-date', 2
AssertEqual 4, g:vimrc_reloaded
normal D
AssertEqual 'No updates.', getline(1)
q
@@ -325,15 +372,15 @@ Execute (Check commands):
Execute (Partial PlugInstall):
PlugInstall vim-fnr vim-easy-align
AssertExpect 'vim-pseudocl', 1
PlugInstall vim-fnr vim-easy-align 1
AssertExpect 'vim-pseudocl', 1
q
Execute (TODO Check dependent plugin):
^ It is a known issue that when a dependent plugin is installed, it is not
^ immediately added to runtimepath. It only becomes available when
^ plug#end() is called.
Execute (Check dependent plugin):
Assert &rtp =~ 'pseudocl', &rtp
AssertEqual first_rtp, split(&rtp, ',')[0]
AssertEqual last_rtp, split(&rtp, ',')[-1]
Given (Unaligned code):
a=1
@@ -359,13 +406,186 @@ Execute (On-demand loading based on filetypes):
set ft=redis
Assert exists(':RedisExecute'), 'RedisExecute command is now found'
**********************************************************************
~ Local (unmanaged) plugins
**********************************************************************
Execute (Add unmanaged plugin):
let fzf = fnamemodify(g:vader_file, ':h') . '/fzf'
Log fzf
call plug#begin()
Plug fzf, { 'on': 'SomeCommand' }
call plug#end()
" Check uri field
Assert !has_key(g:plugs.fzf, 'uri'), 'Should not have uri field'
" Check dir field
AssertEqual fzf.'/', g:plugs.fzf.dir
" Trailing slashes and backslashes should be stripped
for suffix in ['///', '/\/\/']
call plug#begin()
Plug fzf.suffix, { 'on': 'SomeCommand' }
call plug#end()
" Check dir field
AssertEqual fzf.'/', g:plugs.fzf.dir
endfor
Execute (Plug block for following tests):
call plug#begin()
Plug 'junegunn/vim-easy-align'
Plug fzf, { 'on': 'SomeCommand' }
call plug#end()
" Remove plugins from previous tests
PlugClean!
Execute (PlugInstall will only install vim-easy-align):
PlugInstall
Log getline(1, '$')
AssertExpect 'fzf', 0
q
Execute (PlugUpdate will only update vim-easy-align):
PlugUpdate
Log getline(1, '$')
AssertExpect 'fzf', 0
q
Execute (PlugClean should not care about unmanaged plugins):
PlugClean
Log getline(1, '$')
AssertExpect 'fzf', 0
q
Execute (PlugStatus should point out that the plugin is missing):
PlugStatus
Log getline(1, '$')
AssertExpect 'x fzf', 1
AssertExpect 'Not found', 1
q
Execute (Deploy unmanaged plugin):
Assert !exists(':FZF'), ':FZF command should not exist'
call rename('fzf-staged', 'fzf')
Execute (PlugUpdate still should not care):
PlugUpdate
Log getline(1, '$')
AssertExpect 'fzf', 0
q
Execute (PlugStatus with no error):
PlugStatus
Log getline(1, '$')
AssertExpect 'x fzf', 0
AssertExpect 'Not found', 0
q
Execute (Check &rtp after SomeCommand):
Log &rtp
Assert &rtp !~ 'fzf'
silent! SomeCommand
Assert &rtp =~ 'fzf'
AssertEqual first_rtp, split(&rtp, ',')[0]
AssertEqual last_rtp, split(&rtp, ',')[-1]
Execute (Common parent):
call plug#begin()
Plug 'junegunn/vim-pseudocl'
Plug 'junegunn/vim-fnr'
Plug 'junegunn/vim-oblique'
call plug#end()
PlugInstall
Log getline(1, '$')
AssertExpect! '[===]', 1
q
**********************************************************************
~ Frozen plugins
**********************************************************************
Execute (Frozen plugin are not installed nor updated):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'frozen': 1 }
call plug#end()
redir => output
silent PlugInstall
redir END
Assert output =~ 'No plugin to install'
redir => output
silent PlugUpdate
redir END
Assert output =~ 'No plugin to update'
Execute (But you can still install it if the name is given as the argument):
PlugInstall vim-easy-align
Log getline(1, '$')
AssertEqual 1, len(filter(getline(1, '$'), 'v:val =~ "vim-easy-align"'))
q
PlugUpdate vim-easy-align
Log getline(1, '$')
AssertEqual 1, len(filter(getline(1, '$'), 'v:val =~ "vim-easy-align"'))
q
**********************************************************************
~ Retry
**********************************************************************
Execute (Retry failed tasks):
call plug#begin()
Plug 'junegunn/vim-easy-align'
Plug 'junegunn/aaaaaaaaaaaaaa'
call plug#end()
PlugInstall
Log getline(1, '$')
AssertExpect 'x aaa', 1
AssertExpect '- vim-easy-align', 1
normal R
Log getline(1, '$')
AssertExpect 'x aaa', 1
AssertExpect '- vim-easy-align', 0
AssertExpect! '[x]', 1
q
call plug#begin()
Plug 'junegunn/vim-easy-align'
Plug 'junegunn/aaaaaaaaaaaaaa'
Plug 'junegunn/bbbbbbbbbbbbbb'
Plug 'junegunn/cccccccccccccc'
call plug#end()
" Ruby installer
PlugUpdate
normal R
AssertExpect '- vim-easy-align', 0
AssertExpect! '[xxx]', 1
q
" Vim installer
PlugUpdate 1
normal R
AssertExpect '- vim-easy-align', 0
AssertExpect! '[xxx]', 1
q
Execute (Cleanup):
call system('rm -rf '.temp_plugged)
call rename('fzf', 'fzf-staged')
unlet g:plugs
unlet g:plug_home
unlet g:vimrc_reloaded
unlet temp_plugged vader plug basertp save_rtp repo lnum
unlet temp_plugged vader plug basertp save_rtp repo lnum fzf
delf PlugStatusSorted
delf AssertExpect
delc AssertExpect
Restore
source $MYVIMRC