27 Commits
0.5.7 ... 0.6.1

Author SHA1 Message Date
Junegunn Choi
425ef39db2 Fix #114 - &rtp should not contain empty path 2014-10-22 13:36:57 +09:00
Junegunn Choi
bd2cb9d2de Install frozen plugin if it's not found (#113) 2014-10-22 13:05:10 +09:00
Junegunn Choi
0263370bd1 Fix #112: Do not suppress messages from ftplugin 2014-10-19 14:45:19 +09:00
Junegunn Choi
4b3fbd1592 Workaround for PlugUpgrade error on Neovim (#111) 2014-10-18 11:26:05 +09:00
Junegunn Choi
396a534a0a Update README
g:plug_timeout and g:plug_retries are only for Ruby installer
2014-10-10 23:18:40 +09:00
Junegunn Choi
a45c3834f8 Merge pull request #103 from junegunn/neuevim
Parallel installer for Neovim
2014-10-10 23:11:40 +09:00
Junegunn Choi
a5c3952380 Sort auto-completion candidates 2014-10-10 17:36:54 +09:00
Junegunn Choi
60bda7322f Improve ]]/[[ movement 2014-10-10 17:35:07 +09:00
Junegunn Choi
05008e7a82 Use s:extract_name instead of matchstr 2014-10-10 17:34:39 +09:00
Junegunn Choi
2889cb4739 Minor refactoring 2014-10-10 15:50:43 +09:00
Junegunn Choi
61b21068ee Update test case (related: #8c915a5) 2014-10-10 10:54:00 +09:00
Junegunn Choi
15da7eb78a Code cleanup 2014-10-10 10:39:49 +09:00
Junegunn Choi
385a1eb350 Detect abnormal process exit using 'Error' line 2014-10-10 10:28:15 +09:00
Junegunn Choi
8c915a5271 Reuse plug window even if it's in another tab 2014-10-10 10:23:00 +09:00
Junegunn Choi
ee9f0e55b8 Use s:lines instead of split 2014-10-10 10:10:52 +09:00
Junegunn Choi
018adb2aef Disable NVim parallel installer on Windows 2014-10-10 10:06:29 +09:00
Junegunn Choi
da47e6ee56 Avoid unnecessary tab/window switch 2014-10-10 04:39:38 +09:00
Junegunn Choi
662274e617 Stabilize Neovim installer
- Abort running jobs when plug windows is reset
- Multi-line error report
- Retain window view
2014-10-10 01:10:34 +09:00
Junegunn Choi
4eeff535fa Parallel installer for Neovim 2014-10-09 19:55:36 +09:00
Junegunn Choi
c3669836d3 Fix Travis CI build 2014-10-02 01:32:23 +09:00
Junegunn Choi
eb38fe3d32 Fix Travis CI build 2014-10-02 01:21:52 +09:00
Junegunn Choi
e7704e6cb3 PlugSnapshot to use unexpanded plug home
/cc @andreicristianpetcu

plug#begin expands its path argument and converts it to the absolute
path by default. However, it makes sense to use the unexpanded form in
case of PlugSnapshot as described in
https://github.com/junegunn/vim-plug/issues/97#issuecomment-57421483

For example, for the following cases,

- call plug#begin('~/.vim/plugged')
- call plug#begin('$HOME/.vim/plugged')

PlugSnapshot will use the exact arguments, `~/.vim/plugged` or
`$HOME/.vim/plugged`, instead of the absolute paths such as
`/home/jg/.vim/plugged`.
2014-10-01 23:14:27 +09:00
Junegunn Choi
e1e04cabd5 Minor refactoring
/cc @vheon
2014-10-01 11:37:58 +09:00
Junegunn Choi
afc20ecff3 Implement PlugSnapshot (#97)
Known issue: After running the script, PlugDiff will show "future"
commits.
2014-10-01 03:10:24 +09:00
Junegunn Choi
38510a8788 Remove unnecessary submodule command after recursive clone 2014-09-29 02:12:33 +09:00
Junegunn Choi
a34b06dd54 Fix Travis-CI build 2014-09-27 15:30:58 +09:00
Junegunn Choi
5d910fc9ea Allow unmanaged plugins inside g:plug_home (#95) 2014-09-27 14:41:57 +09:00
6 changed files with 540 additions and 196 deletions

View File

@@ -11,7 +11,8 @@ A minimalist Vim plugin manager.
- Easier to use: Concise, intuitive syntax - Easier to use: Concise, intuitive syntax
- [Super-fast](https://raw.githubusercontent.com/junegunn/i/master/vim-plug/40-in-4.gif) - [Super-fast](https://raw.githubusercontent.com/junegunn/i/master/vim-plug/40-in-4.gif)
parallel installation/update (requires parallel installation/update (requires
[+ruby](https://github.com/junegunn/vim-plug/wiki/ruby)) [+ruby](https://github.com/junegunn/vim-plug/wiki/ruby) or
[Neovim](http://neovim.org/))
- On-demand loading to achieve - On-demand loading to achieve
[fast startup time](http://junegunn.kr/images/vim-startup-time.png) [fast startup time](http://junegunn.kr/images/vim-startup-time.png)
- Post-update hooks - Post-update hooks
@@ -69,28 +70,29 @@ Reload .vimrc and `:PlugInstall` to install plugins.
| `PlugUpgrade` | Upgrade vim-plug itself | | `PlugUpgrade` | Upgrade vim-plug itself |
| `PlugStatus` | Check the status of plugins | | `PlugStatus` | Check the status of plugins |
| `PlugDiff` | See the updated changes from the previous PlugUpdate | | `PlugDiff` | See the updated changes from the previous PlugUpdate |
| `PlugSnapshot [output path]` | Generate script for restoring the current snapshot of the plugins |
### `Plug` options ### `Plug` options
| Option | Description | | Option | Description |
| -------------- | -------------------------------------------------------------------- | | -------------- | ------------------------------------------------ |
| `branch`/`tag` | Branch or tag of the repository to use | | `branch`/`tag` | Branch or tag of the repository to use |
| `rtp` | Subdirectory that contains Vim plugin | | `rtp` | Subdirectory that contains Vim plugin |
| `dir` | Custom directory for the plugin | | `dir` | Custom directory for the plugin |
| `do` | Post-update hook (string or funcref) | | `do` | Post-update hook (string or funcref) |
| `on` | On-demand loading: Commands or `<Plug>`-mappings | | `on` | On-demand loading: Commands or `<Plug>`-mappings |
| `for` | On-demand loading: File types | | `for` | On-demand loading: File types |
| `frozen` | Do not install/update plugin unless explicitly given as the argument | | `frozen` | Do not update unless explicitly specified |
### Global options ### Global options
| Flag | Default | Description | | Flag | Default | Description |
| ------------------- | --------------------------------- | ------------------------------------ | | ------------------- | --------------------------------- | ----------------------------------------------------------- |
| `g:plug_threads` | 16 | Default number of threads to use | | `g:plug_threads` | 16 | Default number of threads to use |
| `g:plug_timeout` | 60 | Time limit of each task in seconds | | `g:plug_timeout` | 60 | Time limit of each task in seconds (*for Ruby installer*) |
| `g:plug_retries` | 2 | Number of retries in case of timeout | | `g:plug_retries` | 2 | Number of retries in case of timeout (*for Ruby installer*) |
| `g:plug_window` | `vertical topleft new` | Command to open plug window | | `g:plug_window` | `vertical topleft new` | Command to open plug window |
| `g:plug_url_format` | `https://git::@github.com/%s.git` | `printf` format to build repo URL | | `g:plug_url_format` | `https://git::@github.com/%s.git` | `printf` format to build repo URL |
### Keybindings ### Keybindings

517
plug.vim
View File

@@ -68,10 +68,12 @@ let g:loaded_plug = 1
let s:cpo_save = &cpo let s:cpo_save = &cpo
set cpo&vim set cpo&vim
let s:plug_source = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' let s:plug_src = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
let s:plug_tab = get(s:, 'plug_tab', -1)
let s:plug_buf = get(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:nvim = exists('##JobActivity') && !s:is_win
let s:me = resolve(expand('<sfile>:p')) let s:me = resolve(expand('<sfile>:p'))
let s:base_spec = { 'branch': 'master', 'frozen': 0 } let s:base_spec = { 'branch': 'master', 'frozen': 0 }
let s:TYPE = { let s:TYPE = {
@@ -84,6 +86,7 @@ let s:loaded = get(s:, 'loaded', {})
function! plug#begin(...) function! plug#begin(...)
if a:0 > 0 if a:0 > 0
let s:plug_home_org = a:1
let home = s:path(fnamemodify(expand(a:1), ':p')) let home = s:path(fnamemodify(expand(a:1), ':p'))
elseif exists('g:plug_home') elseif exists('g:plug_home')
let home = s:path(g:plug_home) let home = s:path(g:plug_home)
@@ -95,7 +98,6 @@ function! plug#begin(...)
let g:plug_home = home let g:plug_home = home
let g:plugs = {} let g:plugs = {}
" we want to keep track of the order plugins where registered.
let g:plugs_order = [] let g:plugs_order = []
call s:define_commands() call s:define_commands()
@@ -113,6 +115,7 @@ function! s:define_commands()
command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:me | endif command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:me | endif
command! -nargs=0 -bar PlugStatus call s:status() command! -nargs=0 -bar PlugStatus call s:status()
command! -nargs=0 -bar PlugDiff call s:diff() command! -nargs=0 -bar PlugDiff call s:diff()
command! -nargs=? -bar PlugSnapshot call s:snapshot(<f-args>)
endfunction endfunction
function! s:to_a(v) function! s:to_a(v)
@@ -121,7 +124,7 @@ endfunction
function! s:source(from, ...) function! s:source(from, ...)
for pattern in a:000 for pattern in a:000
for vim in split(globpath(a:from, pattern), '\n') for vim in s:lines(globpath(a:from, pattern))
execute 'source' vim execute 'source' vim
endfor endfor
endfor endfor
@@ -286,9 +289,10 @@ function! s:reorg_rtp()
let s:middle = get(s:, 'middle', &rtp) let s:middle = get(s:, 'middle', &rtp)
let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])') let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])')
let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), 'isdirectory(v:val)') let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), 'isdirectory(v:val)')
let &rtp = join(map(rtps, 's:escrtp(v:val)'), ',') let rtp = join(map(rtps, 's:escrtp(v:val)'), ',')
\ . substitute(','.s:middle.',', '^,,$', ',', '') \ . ','.s:middle.','
\ . join(map(afters, 's:escrtp(v:val)'), ',') \ . join(map(afters, 's:escrtp(v:val)'), ',')
let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g')
let s:prtp = &rtp let s:prtp = &rtp
if !empty(s:first_rtp) if !empty(s:first_rtp)
@@ -312,7 +316,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
silent! doautocmd BufRead doautocmd BufRead
return 1 return 1
endfunction endfunction
@@ -333,8 +337,8 @@ endfunction
function! s:lod_ft(pat, names) function! s:lod_ft(pat, names)
call s:lod(a:names, ['plugin', 'after/plugin']) call s:lod(a:names, ['plugin', 'after/plugin'])
execute 'autocmd! PlugLOD FileType' a:pat execute 'autocmd! PlugLOD FileType' a:pat
silent! doautocmd filetypeplugin FileType doautocmd filetypeplugin FileType
silent! doautocmd filetypeindent FileType doautocmd filetypeindent FileType
endfunction endfunction
function! s:lod_cmd(cmd, bang, l1, l2, args, name) function! s:lod_cmd(cmd, bang, l1, l2, args, name)
@@ -481,25 +485,59 @@ function! s:lpad(str, len)
return a:str . repeat(' ', a:len - len(a:str)) return a:str . repeat(' ', a:len - len(a:str))
endfunction endfunction
function! s:lines(msg)
return split(a:msg, "[\r\n]")
endfunction
function! s:lastline(msg) function! s:lastline(msg)
let lines = split(a:msg, '\n') return get(s:lines(a:msg), -1, '')
return get(lines, -1, '')
endfunction endfunction
function! s:new_window() function! s:new_window()
execute get(g:, 'plug_window', 'vertical topleft new') execute get(g:, 'plug_window', 'vertical topleft new')
endfunction endfunction
function! s:prepare() function! s:plug_window_exists()
if bufexists(s:plug_buf) let buflist = tabpagebuflist(s:plug_tab)
return !empty(buflist) && index(buflist, s:plug_buf) >= 0
endfunction
function! s:switch_in()
if !s:plug_window_exists()
return 0
endif
if winbufnr(0) != s:plug_buf
let s:pos = [tabpagenr(), winnr(), winsaveview()]
execute 'normal!' s:plug_tab.'gt'
let winnr = bufwinnr(s:plug_buf) let winnr = bufwinnr(s:plug_buf)
if winnr < 0 execute winnr.'wincmd w'
call s:new_window() call add(s:pos, winsaveview())
execute 'buffer' s:plug_buf else
else let s:pos = [winsaveview()]
execute winnr . 'wincmd w' endif
endif
setlocal modifiable setlocal modifiable
return 1
endfunction
function! s:switch_out(...)
call winrestview(s:pos[-1])
setlocal nomodifiable
if a:0 > 0
execute a:1
endif
if len(s:pos) > 1
execute 'normal!' s:pos[0].'gt'
execute s:pos[1] 'wincmd w'
call winrestview(s:pos[2])
endif
endfunction
function! s:prepare()
call s:job_abort()
if s:switch_in()
silent %d _ silent %d _
else else
call s:new_window() call s:new_window()
@@ -512,6 +550,7 @@ function! s:prepare()
nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr> nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr>
nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr> nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr>
let b:plug_preview = -1 let b:plug_preview = -1
let s:plug_tab = tabpagenr()
let s:plug_buf = winbufnr(0) let s:plug_buf = winbufnr(0)
call s:assign_name() call s:assign_name()
endif endif
@@ -540,11 +579,11 @@ function! s:do(pull, force, todo)
if !isdirectory(spec.dir) if !isdirectory(spec.dir)
continue continue
endif endif
execute 'cd' s:esc(spec.dir) let installed = has_key(s:update.new, name)
let installed = has_key(s:prev_update.new, name)
let updated = installed ? 0 : let updated = installed ? 0 :
\ (a:pull && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"'))) \ (a:pull && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', spec.dir)))
if a:force || installed || updated if a:force || installed || updated
execute 'cd' s:esc(spec.dir)
call append(3, '- Post-update hook for '. name .' ... ') call append(3, '- Post-update hook for '. name .' ... ')
let type = type(spec.do) let type = type(spec.do)
if type == s:TYPE.string if type == s:TYPE.string
@@ -569,22 +608,25 @@ function! s:do(pull, force, todo)
let result = 'Error: Invalid type!' let result = 'Error: Invalid type!'
endif endif
call setline(4, getline(4) . result) call setline(4, getline(4) . result)
cd -
endif endif
cd -
endfor endfor
endfunction endfunction
function! s:finish(pull) function! s:finish(pull)
let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen'))
if new_frozen
let s = new_frozen > 1 ? 's' : ''
call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s))
endif
call append(3, '- Finishing ... ') call append(3, '- Finishing ... ')
redraw redraw
call plug#helptags() call plug#helptags()
call plug#end() call plug#end()
call setline(4, getline(4) . 'Done!') call setline(4, getline(4) . 'Done!')
normal! gg
call s:syntax()
redraw redraw
let msgs = [] let msgs = []
if !empty(s:prev_update.errors) if !empty(s:update.errors)
call add(msgs, "Press 'R' to retry.") call add(msgs, "Press 'R' to retry.")
endif endif
if a:pull && !empty(filter(getline(5, '$'), if a:pull && !empty(filter(getline(5, '$'),
@@ -595,11 +637,11 @@ function! s:finish(pull)
endfunction endfunction
function! s:retry() function! s:retry()
if empty(s:prev_update.errors) if empty(s:update.errors)
return return
endif endif
call s:update_impl(s:prev_update.pull, s:prev_update.force, call s:update_impl(s:update.pull, s:update.force,
\ extend(copy(s:prev_update.errors), [s:prev_update.threads])) \ extend(copy(s:update.errors), [s:update.threads]))
endfunction endfunction
function! s:is_managed(name) function! s:is_managed(name)
@@ -607,17 +649,16 @@ function! s:is_managed(name)
endfunction endfunction
function! s:names(...) function! s:names(...)
return filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)') return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)'))
endfunction endfunction
function! s:update_impl(pull, force, args) abort function! s:update_impl(pull, force, args) abort
let st = reltime()
let args = copy(a:args) let args = copy(a:args)
let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ?
\ remove(args, -1) : get(g:, 'plug_threads', 16) \ remove(args, -1) : get(g:, 'plug_threads', 16)
let managed = filter(copy(g:plugs), 's:is_managed(v:key)') let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
let todo = empty(args) ? filter(managed, '!v:val.frozen') : let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') :
\ filter(managed, 'index(args, v:key) >= 0') \ filter(managed, 'index(args, v:key) >= 0')
if empty(todo) if empty(todo)
@@ -632,102 +673,254 @@ function! s:update_impl(pull, force, args) abort
call mkdir(g:plug_home, 'p') call mkdir(g:plug_home, 'p')
catch catch
return s:err(printf('Invalid plug directory: %s.' return s:err(printf('Invalid plug directory: %s.'
\ 'Try to call plug#begin with a valid directory', g:plug_home)) \ 'Try to call plug#begin with a valid directory', g:plug_home))
endtry endtry
endif endif
call s:prepare() let s:update = {
call append(0, a:pull ? 'Updating plugins' : 'Installing plugins') \ 'start': reltime(),
call append(1, '['. s:lpad('', len(todo)) .']') \ 'all': todo,
normal! 2G \ 'todo': copy(todo),
redraw \ 'errors': [],
\ 'pull': a:pull,
\ 'force': a:force,
\ 'new': {},
\ 'threads': (has('ruby') || s:nvim) ? min([len(todo), threads]) : 1,
\ 'bar': '',
\ 'fin': 0
\ }
let s:prev_update = { 'errors': [], 'pull': a:pull, 'force': a:force, 'new': {}, 'threads': threads } call s:prepare()
if has('ruby') && threads > 1 call append(0, ['', ''])
normal! 2G
if has('ruby') && s:update.threads > 1
try try
let imd = &imd let imd = &imd
if s:mac_gui if s:mac_gui
set noimd set noimd
endif endif
call s:update_parallel(a:pull, todo, threads) call s:update_ruby()
catch catch
let lines = getline(4, '$') let lines = getline(4, '$')
let printed = {} let printed = {}
silent 4,$d _ silent 4,$d _
for line in lines for line in lines
let name = matchstr(line, '^. \zs[^:]\+\ze:') let name = s:extract_name(line, '.', '')
if empty(name) || !has_key(printed, name) if empty(name) || !has_key(printed, name)
call append('$', line) call append('$', line)
if !empty(name) if !empty(name)
let printed[name] = 1 let printed[name] = 1
if line[0] == 'x' && index(s:prev_update.errors, name) < 0 if line[0] == 'x' && index(s:update.errors, name) < 0
call add(s:prev_update.errors, name) call add(s:update.errors, name)
end end
endif endif
endif endif
endfor endfor
finally finally
let &imd = imd let &imd = imd
call s:update_finish()
endtry endtry
else else
call s:update_serial(a:pull, todo) call s:update_vim()
endif endif
call s:do(a:pull, a:force, filter(copy(todo), 'has_key(v:val, "do")'))
call s:finish(a:pull)
call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(st)))[0] . ' sec.')
endfunction endfunction
function! s:update_progress(pull, cnt, bar, total) function! s:update_finish()
call setline(1, (a:pull ? 'Updating' : 'Installing'). if s:switch_in()
\ ' plugins ('.a:cnt.'/'.a:total.')') call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'has_key(v:val, "do")'))
call s:progress_bar(2, a:bar, a:total) call s:finish(s:update.pull)
normal! 2G call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.')
redraw call s:switch_out('normal! gg')
endif
endfunction endfunction
function! s:update_serial(pull, todo) function! s:job_abort()
let base = g:plug_home if !s:nvim || !exists('s:jobs')
let todo = copy(a:todo) return
let total = len(todo) endif
let done = {} augroup PlugJobControl
let bar = '' autocmd!
augroup END
for [name, spec] in items(todo) for [name, j] in items(s:jobs)
let done[name] = 1 silent! call jobstop(j.jobid)
if isdirectory(spec.dir) if j.new
execute 'cd' s:esc(spec.dir) call system('rm -rf ' . s:shellesc(g:plugs[name].dir))
let [valid, msg] = s:git_valid(spec, 0, 0)
if valid
let result = a:pull ?
\ s:system(
\ printf('git checkout -q %s 2>&1 && git pull --no-rebase origin %s 2>&1 && git submodule update --init --recursive 2>&1',
\ s:shellesc(spec.branch), s:shellesc(spec.branch))) : 'Already installed'
let error = a:pull ? v:shell_error != 0 : 0
else
let result = msg
let error = 1
endif
cd -
else
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),
\ s:shellesc(spec.branch),
\ s:shellesc(s:trim(spec.dir)),
\ s:shellesc(spec.dir)))
let error = v:shell_error != 0
if !error | let s:prev_update.new[name] = 1 | endif
endif endif
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 endfor
let s:jobs = {}
let s:jobs_idx = {}
endfunction endfunction
function! s:update_parallel(pull, todo, threads) function! s:job_handler() abort
if !s:plug_window_exists() " plug window closed
return s:job_abort()
endif
let name = get(s:jobs_idx, v:job_data[0], '')
if empty(name) " stale task
return
endif
let job = s:jobs[name]
if v:job_data[1] == 'exit'
let job.running = 0
if s:lastline(job.result) ==# 'Error'
let job.error = 1
let job.result = substitute(job.result, "Error[\r\n]$", '', '')
endif
call s:reap(name)
call s:tick()
else
let job.result .= v:job_data[2]
" To reduce the number of buffer updates
let job.tick = get(job, 'tick', -1) + 1
if job.tick % len(s:jobs) == 0
call s:log(job.new ? '+' : '*', name, job.result)
endif
endif
endfunction
function! s:spawn(name, cmd, opts)
let job = { 'running': 1, 'new': get(a:opts, 'new', 0),
\ 'error': 0, 'result': '' }
let s:jobs[a:name] = job
if s:nvim
let x = jobstart(a:name, 'sh', ['-c',
\ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd)
\ . ' || echo Error'])
if x > 0
let s:jobs_idx[x] = a:name
let job.jobid = x
augroup PlugJobControl
execute 'autocmd JobActivity' a:name 'call s:job_handler()'
augroup END
else
let job.running = 0
let job.error = 1
let job.result = x < 0 ? 'sh is not executable' :
\ 'Invalid arguments (or job table is full)'
endif
else
let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]
let job.result = call('s:system', params)
let job.error = v:shell_error != 0
let job.running = 0
endif
endfunction
function! s:reap(name)
if s:nvim
silent! execute 'autocmd! PlugJobControl JobActivity' a:name
endif
let job = s:jobs[a:name]
if job.error
call add(s:update.errors, a:name)
elseif get(job, 'new', 0)
let s:update.new[a:name] = 1
endif
let s:update.bar .= job.error ? 'x' : '='
call s:log(job.error ? 'x' : '-', a:name, job.result)
call s:bar()
call remove(s:jobs, a:name)
endfunction
function! s:bar()
if s:switch_in()
let total = len(s:update.all)
call setline(1, (s:update.pull ? 'Updating' : 'Installing').
\ ' plugins ('.len(s:update.bar).'/'.total.')')
call s:progress_bar(2, s:update.bar, total)
call s:switch_out()
endif
endfunction
function! s:logpos(name)
for i in range(1, line('$'))
if getline(i) =~# '^[-+x*] '.a:name.':'
return i
endif
endfor
return 0
endfunction
function! s:log(bullet, name, lines)
if s:switch_in()
let pos = s:logpos(a:name)
if pos > 0
execute pos 'd _'
if pos > winheight('.')
let pos = 4
endif
else
let pos = 4
endif
call append(pos - 1, s:format_message(a:bullet, a:name, a:lines))
call s:switch_out()
endif
endfunction
function! s:update_vim()
let s:jobs = {}
let s:jobs_idx = {}
call s:bar()
call s:tick()
endfunction
function! s:tick()
while 1 " Without TCO, Vim stack is bound to explode
if empty(s:update.todo)
if empty(s:jobs) && !s:update.fin
let s:update.fin = 1
call s:update_finish()
endif
return
endif
let name = keys(s:update.todo)[0]
let spec = remove(s:update.todo, name)
let pull = s:update.pull
let new = !isdirectory(spec.dir)
call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
redraw
if !new
let [valid, msg] = s:git_valid(spec, 0)
if valid
if pull
call s:spawn(name,
\ printf('git checkout -q %s 2>&1 && git pull --progress --no-rebase origin %s 2>&1 && git submodule update --init --recursive 2>&1',
\ s:shellesc(spec.branch), s:shellesc(spec.branch)), { 'dir': spec.dir })
else
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 }
endif
else
let s:jobs[name] = { 'running': 0, 'result': msg, 'error': 1 }
endif
else
call s:spawn(name,
\ printf('git clone --progress --recursive %s -b %s %s 2>&1',
\ s:shellesc(spec.uri),
\ s:shellesc(spec.branch),
\ s:shellesc(s:trim(spec.dir))), { 'new': 1 })
endif
if !s:jobs[name].running
call s:reap(name)
endif
if len(s:jobs) >= s:update.threads
break
endif
endwhile
endfunction
function! s:update_ruby()
ruby << EOF ruby << EOF
module PlugStream module PlugStream
SEP = ["\r", "\n", nil] SEP = ["\r", "\n", nil]
@@ -769,15 +962,15 @@ function! s:update_parallel(pull, todo, threads)
require 'timeout' require 'timeout'
running = true running = true
iswin = VIM::evaluate('s:is_win').to_i == 1 iswin = VIM::evaluate('s:is_win').to_i == 1
pull = VIM::evaluate('a:pull').to_i == 1 pull = VIM::evaluate('s:update.pull').to_i == 1
base = VIM::evaluate('g:plug_home') base = VIM::evaluate('g:plug_home')
all = VIM::evaluate('a:todo') all = VIM::evaluate('s:update.todo')
limit = VIM::evaluate('get(g:, "plug_timeout", 60)') limit = VIM::evaluate('get(g:, "plug_timeout", 60)')
tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1 tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1
nthr = VIM::evaluate('a:threads').to_i nthr = VIM::evaluate('s:update.threads').to_i
maxy = VIM::evaluate('winheight(".")').to_i maxy = VIM::evaluate('winheight(".")').to_i
cd = iswin ? 'cd /d' : 'cd' cd = iswin ? 'cd /d' : 'cd'
tot = VIM::evaluate('len(a:todo)') || 0 tot = VIM::evaluate('len(s:update.todo)') || 0
bar = '' bar = ''
skip = 'Already installed' skip = 'Already installed'
mtx = Mutex.new mtx = Mutex.new
@@ -797,7 +990,7 @@ function! s:update_parallel(pull, todo, threads)
b = case type b = case type
when :install then '+' when :update then '*' when :install then '+' when :update then '*'
when true, nil then '-' else when true, nil then '-' else
VIM::command("call add(s:prev_update.errors, '#{name}')") VIM::command("call add(s:update.errors, '#{name}')")
'x' 'x'
end end
result = result =
@@ -886,7 +1079,7 @@ function! s:update_parallel(pull, todo, threads)
} if VIM::evaluate('s:mac_gui') == 1 } if VIM::evaluate('s:mac_gui') == 1
progress = iswin ? '' : '--progress' progress = iswin ? '' : '--progress'
[all.length, nthr].min.times do nthr.times do
mtx.synchronize do mtx.synchronize do
threads << Thread.new { threads << Thread.new {
while pair = take1.call while pair = take1.call
@@ -921,11 +1114,11 @@ function! s:update_parallel(pull, todo, threads)
else else
d = esc dir.sub(%r{[\\/]+$}, '') d = esc dir.sub(%r{[\\/]+$}, '')
log.call name, 'Installing ...', :install log.call name, 'Installing ...', :install
bt.call "(git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1 && cd #{esc dir} && #{subm})", name, :install, proc { bt.call "git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1", name, :install, proc {
FileUtils.rm_rf dir FileUtils.rm_rf dir
} }
end end
mtx.synchronize { VIM::command("let s:prev_update.new['#{name}'] = 1") } if !exists && ok mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok
log.call name, result, ok log.call name, result, ok
end end
} if running } if running
@@ -943,7 +1136,7 @@ function! s:shellesc(arg)
endfunction endfunction
function! s:glob_dir(path) function! s:glob_dir(path)
return map(filter(split(globpath(a:path, '**'), '\n'), 'isdirectory(v:val)'), 's:dirpath(v:val)') return map(filter(s:lines(globpath(a:path, '**')), 'isdirectory(v:val)'), 's:dirpath(v:val)')
endfunction endfunction
function! s:progress_bar(line, bar, total) function! s:progress_bar(line, bar, total)
@@ -956,30 +1149,34 @@ function! s:compare_git_uri(a, b)
return a ==# b return a ==# b
endfunction endfunction
function! s:format_message(ok, name, message) function! s:format_message(bullet, name, message)
if a:ok if a:bullet != 'x'
return [printf('- %s: %s', a:name, s:lastline(a:message))] return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))]
else else
let lines = map(split(a:message, '\n'), '" ".v:val') let lines = map(s:lines(a:message), '" ".v:val')
return extend([printf('x %s:', a:name)], lines) return extend([printf('x %s:', a:name)], lines)
endif endif
endfunction endfunction
function! s:system(cmd) function! s:with_cd(cmd, dir)
return system(s:is_win ? '('.a:cmd.')' : a:cmd) return 'cd '.s:esc(a:dir).' && '.a:cmd
endfunction endfunction
function! s:system_chomp(str) function! s:system(cmd, ...)
let ret = s:system(a:str) let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
return system(s:is_win ? '('.cmd.')' : cmd)
endfunction
function! s:system_chomp(...)
let ret = call('s:system', a:000)
return v:shell_error ? '' : substitute(ret, '\n$', '', '') return v:shell_error ? '' : substitute(ret, '\n$', '', '')
endfunction endfunction
function! s:git_valid(spec, check_branch, cd) function! s:git_valid(spec, check_branch)
let ret = 1 let ret = 1
let msg = 'OK' let msg = 'OK'
if isdirectory(a:spec.dir) if isdirectory(a:spec.dir)
if a:cd | execute 'cd' s:esc(a:spec.dir) | endif let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url', a:spec.dir))
let result = split(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url'), '\n')
let remote = result[-1] let remote = result[-1]
if v:shell_error if v:shell_error
let msg = join([remote, 'PlugClean required.'], "\n") let msg = join([remote, 'PlugClean required.'], "\n")
@@ -992,7 +1189,7 @@ function! s:git_valid(spec, check_branch, cd)
elseif a:check_branch elseif a:check_branch
let branch = result[0] let branch = result[0]
if a:spec.branch !=# branch if a:spec.branch !=# branch
let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1') let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
if a:spec.branch !=# tag if a:spec.branch !=# tag
let msg = printf('Invalid branch/tag: %s (expected: %s). Try PlugUpdate.', let msg = printf('Invalid branch/tag: %s (expected: %s). Try PlugUpdate.',
\ (empty(tag) ? branch : tag), a:spec.branch) \ (empty(tag) ? branch : tag), a:spec.branch)
@@ -1000,7 +1197,6 @@ function! s:git_valid(spec, check_branch, cd)
endif endif
endif endif
endif endif
if a:cd | cd - | endif
else else
let msg = 'Not found' let msg = 'Not found'
let ret = 0 let ret = 0
@@ -1015,10 +1211,9 @@ function! s:clean(force)
" List of valid directories " List of valid directories
let dirs = [] let dirs = []
let managed = filter(copy(g:plugs), 's:is_managed(v:key)') let [cnt, total] = [0, len(g:plugs)]
let [cnt, total] = [0, len(managed)] for [name, spec] in items(g:plugs)
for spec in values(managed) if !s:is_managed(name) || s:git_valid(spec, 0)[0]
if s:git_valid(spec, 0, 1)[0]
call add(dirs, spec.dir) call add(dirs, spec.dir)
endif endif
let cnt += 1 let cnt += 1
@@ -1070,21 +1265,16 @@ endfunction
function! s:upgrade() function! s:upgrade()
let new = s:me . '.new' let new = s:me . '.new'
echo 'Downloading '. s:plug_source echo 'Downloading '. s:plug_src
redraw redraw
try try
if executable('curl') if executable('curl')
let output = system(printf('curl -fLo %s %s', s:shellesc(new), s:plug_source)) let output = system(printf('curl -fLo %s %s', s:shellesc(new), s:plug_src))
if v:shell_error if v:shell_error
throw get(split(output, '\n'), -1, v:shell_error) throw get(s:lines(output), -1, v:shell_error)
endif endif
elseif has('ruby') elseif has('ruby')
ruby << EOF call s:upgrade_using_ruby(new)
require 'open-uri'
File.open(VIM::evaluate('new'), 'w') do |f|
f << open(VIM::evaluate('s:plug_source')).read
end
EOF
else else
return s:err('curl executable or ruby support not found') return s:err('curl executable or ruby support not found')
endif endif
@@ -1105,6 +1295,15 @@ EOF
endif endif
endfunction endfunction
function! s:upgrade_using_ruby(new)
ruby << EOF
require 'open-uri'
File.open(VIM::evaluate('a:new'), 'w') do |f|
f << open(VIM::evaluate('s:plug_src')).read
end
EOF
endfunction
function! s:upgrade_specs() function! s:upgrade_specs()
for spec in values(g:plugs) for spec in values(g:plugs)
let spec.frozen = get(spec, 'frozen', 0) let spec.frozen = get(spec, 'frozen', 0)
@@ -1122,7 +1321,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 [valid, msg] = s:git_valid(spec, 1, 1) let [valid, msg] = s:git_valid(spec, 1)
else else
let [valid, msg] = [0, 'Not found. Try PlugInstall.'] let [valid, msg] = [0, 'Not found. Try PlugInstall.']
endif endif
@@ -1141,7 +1340,7 @@ function! s:status()
let msg .= ' (not loaded)' let msg .= ' (not loaded)'
endif 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 ? '-' : 'x', name, msg))
normal! 2G normal! 2G
redraw redraw
endfor endfor
@@ -1194,7 +1393,7 @@ function! s:find_name(lnum)
if empty(line) if empty(line)
return '' return ''
endif endif
let name = matchstr(line, '\(^- \)\@<=[^:]\+') let name = s:extract_name(line, '-', '')
if !empty(name) if !empty(name)
return name return name
endif endif
@@ -1220,15 +1419,13 @@ function! s:preview_commit()
execute 'pedit' sha execute 'pedit' sha
wincmd P wincmd P
setlocal filetype=git buftype=nofile nobuflisted setlocal filetype=git buftype=nofile nobuflisted
execute 'cd' s:esc(g:plugs[name].dir) execute 'silent read !cd' s:esc(g:plugs[name].dir) '&& git show' sha
execute 'silent read !git show' sha
cd -
normal! gg"_dd normal! gg"_dd
wincmd p wincmd p
endfunction endfunction
function! s:section(flags) function! s:section(flags)
call search('\(^- \)\@<=.', a:flags) call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
endfunction endfunction
function! s:diff() function! s:diff()
@@ -1243,17 +1440,15 @@ function! s:diff()
continue continue
endif endif
execute 'cd' s:esc(v.dir) let diff = s:system_chomp('git log --pretty=format:"%h %s (%cr)" "HEAD...HEAD@{1}"', v.dir)
let diff = system('git log --pretty=format:"%h %s (%cr)" "HEAD...HEAD@{1}"') if !empty(diff)
if !v:shell_error && !empty(diff)
call append(1, '') call append(1, '')
call append(2, '- '.k.':') call append(2, '- '.k.':')
call append(3, map(split(diff, '\n'), '" ". v:val')) call append(3, map(s:lines(diff), '" ". v:val'))
let cnt += 1 let cnt += 1
normal! gg normal! gg
redraw redraw
endif endif
cd -
endfor endfor
call setline(1, cnt == 0 ? 'No updates.' : 'Last update:') call setline(1, cnt == 0 ? 'No updates.' : 'Last update:')
@@ -1273,15 +1468,51 @@ function! s:revert()
return return
endif endif
execute 'cd' s:esc(g:plugs[name].dir) call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch), g:plugs[name].dir)
call system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch))
cd -
setlocal modifiable setlocal modifiable
normal! "_dap normal! "_dap
setlocal nomodifiable setlocal nomodifiable
echo 'Reverted.' echo 'Reverted.'
endfunction endfunction
function! s:snapshot(...) abort
let home = get(s:, 'plug_home_org', g:plug_home)
let [type, var, header] = s:is_win ?
\ ['dosbatch', '%PLUG_HOME%',
\ ['@echo off', ':: Generated by vim-plug', ':: '.strftime("%c"), '',
\ ':: Make sure to PlugUpdate first', '', 'set PLUG_HOME='.s:esc(home)]] :
\ ['sh', '$PLUG_HOME',
\ ['#!/bin/bash', '# Generated by vim-plug', '# '.strftime("%c"), '',
\ 'vim +PlugUpdate +qa', '', 'PLUG_HOME='.s:esc(home)]]
call s:prepare()
execute 'setf' type
call append(0, header)
call append('$', '')
1
redraw
let dirs = sort(map(values(filter(copy(g:plugs),
\'has_key(v:val, "uri") && isdirectory(v:val.dir)')), 'v:val.dir'))
let anchor = line('$') - 1
for dir in reverse(dirs)
let sha = s:system_chomp('git rev-parse --short HEAD', dir)
if !empty(sha)
call append(anchor, printf('cd %s && git reset --hard %s',
\ substitute(dir, '^'.g:plug_home, var, ''), sha))
redraw
endif
endfor
if a:0 > 0
let fn = s:esc(expand(a:1))
call writefile(getline(1, '$'), fn)
if !s:is_win | call system('chmod +x ' . fn) | endif
echo 'Saved to '.a:1
silent execute 'e' fn
endif
endfunction
function! s:split_rtp() function! s:split_rtp()
return split(&rtp, '\\\@<!,') return split(&rtp, '\\\@<!,')
endfunction endfunction

5
test/fixtures/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
fzf*
xxx
yyy
z1
z2

View File

@@ -0,0 +1 @@
echomsg 'ftplugin'

View File

@@ -5,18 +5,20 @@ cd ..
PLUG_SRC=$(pwd)/plug.vim PLUG_SRC=$(pwd)/plug.vim
cd - > /dev/null cd - > /dev/null
export PLUG_FIXTURES=$(pwd)/fixtures
if [ ! -d vader.vim ]; then if [ ! -d vader.vim ]; then
git clone https://github.com/junegunn/vader.vim.git git clone https://github.com/junegunn/vader.vim.git
fi fi
rm -rf fzf rm -rf $PLUG_FIXTURES/fzf
if [ ! -d fzf-staged ]; then if [ ! -d fzf-staged ]; then
git clone https://github.com/junegunn/fzf.git fzf-staged git clone https://github.com/junegunn/fzf.git $PLUG_FIXTURES/fzf-staged
fi fi
make_dirs() { make_dirs() {
mkdir -p "$1" mkdir -p "$PLUG_FIXTURES/$1"
cd "$1" cd "$PLUG_FIXTURES/$1"
mkdir -p autoload colors ftdetect ftplugin indent plugin syntax mkdir -p autoload colors ftdetect ftplugin indent plugin syntax
for d in *; do for d in *; do
[ -d $d ] || continue [ -d $d ] || continue
@@ -32,18 +34,22 @@ EOF
cd - > /dev/null cd - > /dev/null
} }
make_dirs xxx/ xxx init() {
make_dirs xxx/after xxx rm -rf $PLUG_FIXTURES/{xxx,yyy,z1,z2}
mkdir -p xxx/doc
cat > xxx/doc/xxx.txt << DOC make_dirs xxx/ xxx
make_dirs xxx/after xxx
mkdir -p $PLUG_FIXTURES/xxx/doc
cat > $PLUG_FIXTURES/xxx/doc/xxx.txt << DOC
hello *xxx* hello *xxx*
DOC DOC
make_dirs yyy/ yyy make_dirs yyy/ yyy
make_dirs yyy/after yyy make_dirs yyy/after yyy
make_dirs z1/ z1 make_dirs z1/ z1
make_dirs z2/ z2 make_dirs z2/ z2
}
cat > /tmp/mini-vimrc << VIMRC cat > /tmp/mini-vimrc << VIMRC
set rtp+=vader.vim set rtp+=vader.vim
@@ -51,8 +57,11 @@ set shell=/bin/bash
source $PLUG_SRC source $PLUG_SRC
VIMRC VIMRC
[ -z "$TMPDIR" ] && export TMPDIR=/tmp/
init
if [ "$1" = '!' ]; then 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 'Vader! workflow.vader' > /dev/null &&
init &&
/usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'let g:plug_threads = 1 | 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 else
/usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'Vader workflow.vader' /usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'Vader workflow.vader'

View File

@@ -337,7 +337,8 @@ Execute (Rollback recent updates, PlugUpdate, then PlugDiff):
AssertEqual 1, &previewwindow AssertEqual 1, &previewwindow
pclose pclose
Execute (Plug window in a new tab): Execute (Reuse Plug window in another tab):
let tabnr = tabpagenr()
PlugDiff PlugDiff
tab new new-tab tab new new-tab
set buftype=nofile set buftype=nofile
@@ -345,8 +346,8 @@ Execute (Plug window in a new tab):
normal D normal D
AssertExpect '^- ', 1 AssertExpect '^- ', 1
normal q normal q
AssertEqual 'new-tab', expand('%') AssertEqual tabnr, tabpagenr()
q normal! gt
q q
********************************************************************** **********************************************************************
@@ -420,7 +421,7 @@ Execute (On-demand loading based on filetypes):
********************************************************************** **********************************************************************
Execute (Add unmanaged plugin): Execute (Add unmanaged plugin):
let fzf = fnamemodify(g:vader_file, ':h') . '/fzf' let fzf = expand('$PLUG_FIXTURES/fzf')
Log fzf Log fzf
call plug#begin() call plug#begin()
@@ -478,7 +479,7 @@ Execute (PlugStatus should point out that the plugin is missing):
Execute (Deploy unmanaged plugin): Execute (Deploy unmanaged plugin):
Assert !exists(':FZF'), ':FZF command should not exist' Assert !exists(':FZF'), ':FZF command should not exist'
call rename('fzf-staged', 'fzf') call rename(expand('$PLUG_FIXTURES/fzf-staged'), fzf)
Execute (PlugUpdate still should not care): Execute (PlugUpdate still should not care):
PlugUpdate PlugUpdate
@@ -516,12 +517,37 @@ Execute (Common parent):
********************************************************************** **********************************************************************
~ Frozen plugins ~ Frozen plugins
********************************************************************** **********************************************************************
- We've decided to install plugins that are frozen: see #113
Execute (Frozen plugin are not ~~installed nor~~ updated):
" Remove plugins
call plug#begin()
call plug#end()
PlugClean!
q
Execute (Frozen plugin are not installed nor updated): " vim-easy-align is not found, so it will be installed even though it's frozen
call plug#begin() call plug#begin()
Plug 'junegunn/vim-easy-align', { 'frozen': 1 } Plug 'junegunn/vim-easy-align', { 'frozen': 1 }
call plug#end() call plug#end()
PlugInstall
AssertEqual 1, len(filter(getline(1, '$'), 'v:val =~ "vim-easy-align"'))
q
" Remove plugins again
call plug#begin()
call plug#end()
PlugClean!
q
" PlugUpdate will do the same
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'frozen': 1 }
call plug#end()
PlugInstall
AssertEqual 1, len(filter(getline(1, '$'), 'v:val =~ "vim-easy-align"'))
q
" Since vim-easy-align already exists, PlugInstall or PlugUpdate will skip it
redir => out redir => out
silent PlugInstall silent PlugInstall
redir END redir END
@@ -731,12 +757,12 @@ Execute (Using custom dir):
********************************************************************** **********************************************************************
Before (Clear global vars): Before (Clear global vars):
let g:xxx = [] let g:xxx = []
set rtp-=$PWD/xxx/ set rtp-=$PLUG_FIXTURES/xxx/
set rtp-=$PWD/xxx/after set rtp-=$PLUG_FIXTURES/xxx/after
Execute (Immediate loading): Execute (Immediate loading):
call plug#begin() call plug#begin()
Plug '$PWD/xxx' Plug '$PLUG_FIXTURES/xxx'
call plug#end() call plug#end()
" FIXME: " FIXME:
@@ -750,7 +776,7 @@ Execute (Immediate loading):
Execute (Command-based on-demand loading): Execute (Command-based on-demand loading):
call plug#begin() call plug#begin()
Plug '$PWD/xxx', { 'on': 'XXX' } Plug '$PLUG_FIXTURES/xxx', { 'on': 'XXX' }
call plug#end() call plug#end()
AssertEqual [], g:xxx AssertEqual [], g:xxx
@@ -763,7 +789,7 @@ Execute (Command-based on-demand loading):
Execute (Filetype-based on-demand loading): Execute (Filetype-based on-demand loading):
call plug#begin() call plug#begin()
Plug '$PWD/xxx', { 'for': 'xxx' } Plug '$PLUG_FIXTURES/xxx', { 'for': 'xxx' }
call plug#end() call plug#end()
AssertEqual ['xxx/ftdetect', 'xxx/after/ftdetect'], g:xxx AssertEqual ['xxx/ftdetect', 'xxx/after/ftdetect'], g:xxx
@@ -778,10 +804,10 @@ Before:
********************************************************************** **********************************************************************
Execute (plug#helptags): Execute (plug#helptags):
silent! call delete(expand('$PWD/xxx/doc/tags')) silent! call delete(expand('$PLUG_FIXTURES/xxx/doc/tags'))
Assert !filereadable(expand('$PWD/xxx/doc/tags')) Assert !filereadable(expand('$PLUG_FIXTURES/xxx/doc/tags'))
AssertEqual 1, plug#helptags() AssertEqual 1, plug#helptags()
Assert filereadable(expand('$PWD/xxx/doc/tags')) Assert filereadable(expand('$PLUG_FIXTURES/xxx/doc/tags'))
********************************************************************** **********************************************************************
~ Manual loading ~ Manual loading
@@ -822,7 +848,7 @@ Execute (PlugStatus should not contain (not loaded)):
Execute (Load plugin from PlugStatus screen with L key in normal mode): Execute (Load plugin from PlugStatus screen with L key in normal mode):
call plug#begin() call plug#begin()
Plug '$PWD/yyy', { 'on': [] } Plug '$PLUG_FIXTURES/yyy', { 'on': [] }
call plug#end() call plug#end()
PlugStatus PlugStatus
@@ -836,8 +862,8 @@ Execute (Load plugin from PlugStatus screen with L key in normal mode):
Execute (Load plugin from PlugStatus screen with L key in visual mode): Execute (Load plugin from PlugStatus screen with L key in visual mode):
call plug#begin() call plug#begin()
Plug '$PWD/z1', { 'on': [] } Plug '$PLUG_FIXTURES/z1', { 'on': [] }
Plug '$PWD/z2', { 'for': [] } Plug '$PLUG_FIXTURES/z2', { 'for': [] }
call plug#end() call plug#end()
PlugStatus PlugStatus
@@ -963,8 +989,8 @@ Execute (Plug directory with comma):
Execute (Strict load order): Execute (Strict load order):
let g:total_order = [] let g:total_order = []
call plug#begin() call plug#begin()
Plug '$PWD/xxx' Plug '$PLUG_FIXTURES/xxx'
Plug '$PWD/yyy', { 'for': ['xxx'] } Plug '$PLUG_FIXTURES/yyy', { 'for': ['xxx'] }
call plug#end() call plug#end()
call EnsureLoaded() call EnsureLoaded()
setf xxx setf xxx
@@ -976,8 +1002,8 @@ Execute (Strict load order):
let g:total_order = [] let g:total_order = []
call plug#begin() call plug#begin()
Plug '$PWD/xxx', { 'for': ['xxx'] } Plug '$PLUG_FIXTURES/xxx', { 'for': ['xxx'] }
Plug '$PWD/yyy' Plug '$PLUG_FIXTURES/yyy'
call plug#end() call plug#end()
call EnsureLoaded() call EnsureLoaded()
set rtp^=manually-prepended set rtp^=manually-prepended
@@ -993,8 +1019,8 @@ Execute (Strict load order):
let g:total_order = [] let g:total_order = []
call plug#begin() call plug#begin()
Plug '$PWD/xxx', { 'for': ['xxx'] } Plug '$PLUG_FIXTURES/xxx', { 'for': ['xxx'] }
Plug '$PWD/yyy', { 'for': ['xxx'] } Plug '$PLUG_FIXTURES/yyy', { 'for': ['xxx'] }
call plug#end() call plug#end()
call EnsureLoaded() call EnsureLoaded()
setf xxx setf xxx
@@ -1004,9 +1030,79 @@ Execute (Strict load order):
Assert index(g:total_order, 'xxx/after/plugin') < index(g:total_order, 'yyy/after/plugin') Assert index(g:total_order, 'xxx/after/plugin') < index(g:total_order, 'yyy/after/plugin')
AssertEqual len + 2, len(split(&rtp, ',')) AssertEqual len + 2, len(split(&rtp, ','))
**********************************************************************
Execute (PlugClean should not try to remove unmanaged plugins inside g:plug_home):
call plug#begin('$PLUG_FIXTURES')
Plug '$PLUG_FIXTURES/ftplugin-msg', { 'for': [] }
Plug '$PLUG_FIXTURES/fzf'
Plug '$PLUG_FIXTURES/xxx'
Plug '$PLUG_FIXTURES/yyy'
call plug#end()
" Remove z1, z2
PlugClean!
AssertExpect '^- ', 2
AssertExpect 'Already clean', 0
PlugClean!
AssertExpect '^- ', 0
AssertExpect 'Already clean', 1
q
**********************************************************************
Execute (#112 On-demand loading should not suppress messages from ftplugin):
call plug#begin('$PLUG_FIXTURES')
Plug '$PLUG_FIXTURES/ftplugin-msg', { 'for': 'c' }
call plug#end()
redir => out
tabnew a.c
redir END
Assert stridx(out, 'ftplugin') >= 0
* The same applies to plug#load())
redir => out
call plug#load('ftplugin-msg')
redir END
Assert stridx(out, 'ftplugin') >= 0
q
**********************************************************************
Execute (PlugSnapshot):
call plug#begin('$TMPDIR/plugged')
Plug 'junegunn/vim-emoji'
Plug 'junegunn/seoul256.vim'
call plug#end()
PlugInstall
PlugSnapshot
AssertEqual '#!/bin/bash', getline(1)
AssertEqual '# Generated by vim-plug', getline(2)
AssertEqual 'vim +PlugUpdate +qa', getline(5)
AssertEqual 'PLUG_HOME=$TMPDIR/plugged', getline(7)
AssertEqual 0, stridx(getline(9), 'cd $PLUG_HOME/seoul256.vim/ && git reset --hard')
AssertEqual 0, stridx(getline(10), 'cd $PLUG_HOME/vim-emoji/ && git reset --hard')
AssertEqual 'sh', &filetype
execute 'PlugSnapshot' g:plug_home.'/snapshot.sh'
AssertEqual 'sh', &filetype
AssertEqual 'snapshot.sh', fnamemodify(expand('%'), ':t')
q
**********************************************************************
Execute (#114 Should not contain empty path in &rtp):
call plug#begin('$TMPDIR/plugged')
call plug#end()
Log &rtp
Assert &rtp !~ ',,', 'Commas'
Assert &rtp !~ '^,', 'Comma prefix'
Assert &rtp !~ ',$', 'Comma suffix'
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 system('rm -rf '.temp_plugged)
silent! call rename(fzf, expand('$PLUG_FIXTURES/fzf-staged'))
silent! unlet g:plugs silent! unlet g:plugs
silent! unlet g:plug_home silent! unlet g:plug_home
silent! unlet g:plug_url_format silent! unlet g:plug_url_format