45 Commits
0.2.0 ... 0.3.4

Author SHA1 Message Date
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
Junegunn Choi
6ddee62977 Ensure ftplugin files are loaded (#24) 2014-06-22 13:09:18 +09:00
Junegunn Choi
8cf5fca9ca Revert "Ensure ftplugin files are loaded (#24)"
This reverts commit a026eb39c4.

Conflicts:
	plug.vim
2014-06-22 12:49:22 +09:00
Junegunn Choi
347fccb030 Revert "Remove FileType autocmd after loaded"
This reverts commit db3f5ad5c3.

Conflicts:
	plug.vim
2014-06-22 12:45:21 +09:00
Junegunn Choi
a026eb39c4 Ensure ftplugin files are loaded (#24)
If `filetype plugin on` is called before `plug#end()`, filetype
plugin handler is invoked before ODL autocmd from vim-plug which
updates runtimepath and ftplugin files are not loaded.
2014-06-22 10:27:15 +09:00
Junegunn Choi
4d352e1849 Revert "Clear #filetypeplugin for filetype-based ODL (#24)"
This reverts commit 1d477a1a01.
2014-06-22 10:21:58 +09:00
Junegunn Choi
db3f5ad5c3 Remove FileType autocmd after loaded 2014-06-22 09:58:14 +09:00
Junegunn Choi
1d477a1a01 Clear #filetypeplugin for filetype-based ODL (#24) 2014-06-22 04:24:19 +09:00
Junegunn Choi
288a4f72ce Add pending test case on dependency resolution 2014-06-20 21:35:42 +09:00
Junegunn Choi
5168cd50db Allow updating subset of plugins
This commit extends `PlugInstall` and `PlugUpdate` command to allow
updating only a subset of plugins as follows:

    " With tab completion of plugin names
    :PlugInstall vim-easy-align seoul256
    :PlugUpdate vim-easy-align seoul256
2014-06-20 20:53:57 +09:00
Junegunn Choi
4d32762432 Allow -range in on-demand loading commands 2014-06-20 20:35:33 +09:00
Junegunn Choi
8dff1dae37 Allow trailing comment after Plug declaration (#23) 2014-06-20 09:58:50 +09:00
Junegunn Choi
b5b687ad9a On-demand loading on filetypes (#21) 2014-06-17 11:59:42 +09:00
Junegunn Choi
7e69a50890 Fix on-demand loading: load ftdetect and **/*.vim as well 2014-06-17 11:45:42 +09:00
Junegunn Choi
476a613746 Fix #19: install error 2014-06-06 00:16:57 +09:00
Junegunn Choi
12b5dcb903 git submodule update --init --recursive (#18) 2014-06-03 18:51:01 +09:00
Junegunn Choi
de81f95f69 Use black hole register when emptying buffer 2014-04-15 02:01:47 +09:00
Junegunn Choi
b7cf1ca65a Echo "Press 'D'" message only on PlugUpdate 2014-04-15 02:00:39 +09:00
Junegunn Choi
7fa22a6927 PlugDiff: Display commit info in preview window 2014-04-14 21:20:21 +09:00
Junegunn Choi
6f487f1579 Explicitly return 0 2014-04-14 20:27:23 +09:00
Junegunn Choi
f8fcc81783 Use s:esc function 2014-04-09 15:25:21 +09:00
Junegunn Choi
32dc4ca93f Change PlugDiff message (suggested by @beloglazov in #17) 2014-04-09 11:59:46 +09:00
Junegunn Choi
7047eda149 Change PlugDiff message (thanks to @beloglazov) 2014-04-09 11:22:20 +09:00
Junegunn Choi
5679540a2a Less LOC 2014-04-09 01:03:43 +09:00
Junegunn Choi
d2f6c09c7a Fix syntax highlighting (#17) 2014-04-09 00:53:37 +09:00
Junegunn Choi
acbba74fe2 Fix output format (#17) 2014-04-09 00:40:19 +09:00
Junegunn Choi
47a3bebb30 Fix test case for PlugStatus 2014-04-08 21:47:57 +09:00
Junegunn Choi
f00dacd7bd Add PlugDiff command (#17) 2014-04-08 21:43:49 +09:00
Junegunn Choi
8986f87b83 Change PlugStatus output to match those of other commands 2014-04-08 21:33:38 +09:00
Junegunn Choi
ae6f3254d8 Place cursor on the 2nd line during PlugClean 2014-04-08 21:32:29 +09:00
Junegunn Choi
0c1744a819 Merge pull request #16 from CD3/load-order
Respect plug load order (for dependencies)
2014-03-30 12:08:33 +09:00
C.D. Clark III
b763cae81a added plug load order (for dependencies)
plugin directories now appear in the runtime path in the same order they
are listed. this allows plugs that depend on other plugins to be loaded
after their dependencies.
2014-03-29 21:29:54 -05:00
Junegunn Choi
358363eefc Support paths with spaces (#15 [, #14]) 2014-03-27 01:07:09 +09:00
Junegunn Choi
c827d2fa05 Merge pull request #13 from junegunn/shellesc
Replace shellescape function to avoid error when &shellslash is set
2014-03-19 12:22:30 +09:00
Junegunn Choi
2ef9b8a492 Replace shellescape function to avoid error when &shellslash is set 2014-03-19 12:15:26 +09:00
Junegunn Choi
2a3a40dd42 Fix PlugStatus/PlugClean on Windows 2014-03-19 00:43:37 +09:00
Junegunn Choi
411bb2bef9 Update README (Related: #12) 2014-03-14 01:32:08 +09:00
Junegunn Choi
ff01c54720 Remove unnecessary code 2014-03-13 01:04:17 +09:00
14 changed files with 526 additions and 124 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/vim-plug.gif)
### Pros.
@@ -38,7 +39,8 @@ call plug#begin('~/.vim/plugged')
Plug 'junegunn/seoul256.vim'
Plug 'junegunn/vim-easy-align'
Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
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'
@@ -59,13 +61,14 @@ before the call.
### Commands
| Command | Description |
| ---------------------- | ------------------------------------------------------------------ |
| PlugInstall [#threads] | Install plugins |
| PlugUpdate [#threads] | Install or update plugins |
| PlugClean[!] | Remove unused directories (bang version will clean without prompt) |
| PlugUpgrade | Upgrade vim-plug itself |
| PlugStatus | Check the status of plugins |
| Command | Description |
| --------------------------------- | ------------------------------------------------------------------ |
| PlugInstall [name ...] [#threads] | Install plugins |
| PlugUpdate [name ...] [#threads] | Install or update plugins |
| PlugClean[!] | Remove unused directories (bang version will clean without prompt) |
| PlugUpgrade | Upgrade vim-plug itself |
| PlugStatus | Check the status of plugins |
| PlugDiff | See the updated changes from the previous PlugUpdate |
### Options for parallel installer
@@ -74,6 +77,12 @@ before the call.
| `g:plug_threads` | 16 | Default number of threads to use |
| `g:plug_timeout` | 60 | Time limit of each task in seconds |
### Keybindings
- `D` - `PlugDiff`
- `S` - `PlugStatus`
- `q` - Close the window
### Example: A small [sensible](https://github.com/tpope/vim-sensible) Vim configuration
```vim
@@ -90,6 +99,12 @@ Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
" Multiple commands
Plug 'junegunn/vim-github-dashboard', { 'on': ['GHDashboard', 'GHActivity'] }
" Loaded when clojure file is opened
Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" On-demand loading on both conditions
Plug 'junegunn/vader.vim', { 'on': 'Vader', 'for': 'vader' }
```
### Dependency resolution
@@ -132,6 +147,15 @@ removed that version of Ruby.
resolve the problem. In the meantime, you can set `g:plug_threads` to 1, so that
Ruby installer is not used at all.
#### Errors on fish shell
If vim-plug doesn't work correctly on fish shell, you might need to add `set
shell=/bin/sh` to your .vimrc.
Refer to the following links for the details:
- http://badsimplicity.com/vim-fish-e484-cant-open-file-tmpvrdnvqe0-error/
- https://github.com/junegunn/vim-plug/issues/12
#### Freezing plugin version with commit hash
vim-plug does not allow you to freeze the version of a plugin with its commit

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

334
plug.vim
View File

@@ -24,7 +24,7 @@
" You can change the location of the plugins with plug#begin(path) call.
"
"
" Copyright (c) 2013 Junegunn Choi
" Copyright (c) 2014 Junegunn Choi
"
" MIT License
"
@@ -57,7 +57,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_win = 0
let s:plug_buf = -1
let s:is_win = has('win32') || has('win64')
let s:me = expand('<sfile>:p')
@@ -70,7 +70,7 @@ function! plug#begin(...)
let home = s:path(split(&rtp, ',')[0]) . '/plugged'
else
echoerr "Unable to determine plug home. Try calling plug#begin() with a path argument."
return
return 0
endif
if !isdirectory(home)
@@ -88,17 +88,24 @@ function! plug#begin(...)
let g:plug_home = home
let g:plugs = {}
" we want to keep track of the order plugins where registered.
let g:plugs_order = []
command! -nargs=+ Plug call s:add(1, <args>)
command! -nargs=* PlugInstall call s:install(<f-args>)
command! -nargs=* PlugUpdate call s:update(<f-args>)
command! -nargs=+ -bar Plug call s:add(1, <args>)
command! -nargs=* -complete=customlist,s:names PlugInstall call s:install(<f-args>)
command! -nargs=* -complete=customlist,s:names PlugUpdate call s:update(<f-args>)
command! -nargs=0 -bang PlugClean call s:clean('<bang>' == '!')
command! -nargs=0 PlugUpgrade if s:upgrade() | execute "source ". s:me | endif
command! -nargs=0 PlugStatus call s:status()
command! -nargs=0 PlugDiff call s:diff()
return 1
endfunction
function! s:to_a(v)
return type(a:v) == 3 ? a:v : [a:v]
endfunction
function! plug#end()
if !exists('g:plugs')
echoerr 'Call plug#begin() first'
@@ -109,10 +116,28 @@ function! plug#end()
let keys = keys(s:extend(keys))
endwhile
if exists('#PlugLOD')
augroup PlugLOD
autocmd!
augroup END
augroup! PlugLOD
endif
let lod = {}
filetype off
for plug in values(g:plugs)
" we want to make sure the plugin directories are added to rtp in the same
" order that they are registered with the Plug command. since the s:add_rtp
" function uses ^= to add plugin directories to the front of the rtp, we
" need to loop through the plugins in reverse
for name in reverse(copy(g:plugs_order))
let plug = g:plugs[name]
if !has_key(plug, 'on') && !has_key(plug, 'for')
call s:add_rtp(s:rtp(plug))
continue
endif
if has_key(plug, 'on')
let commands = type(plug.on) == 1 ? [plug.on] : plug.on
let commands = s:to_a(plug.on)
for cmd in commands
if cmd =~ '^<Plug>.\+'
if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i'))
@@ -124,13 +149,30 @@ function! plug#end()
endif
elseif !exists(':'.cmd)
execute printf(
\ "command! -nargs=* -bang %s call s:lod_cmd(%s, '<bang>', <q-args>, %s)",
\ "command! -nargs=* -range -bang %s call s:lod_cmd(%s, '<bang>', <line1>, <line2>, <q-args>, %s)",
\ cmd, string(cmd), string(plug))
endif
endfor
else
call s:add_rtp(s:rtp(plug))
endif
if has_key(plug, 'for')
for vim in split(globpath(s:rtp(plug), 'ftdetect/**/*.vim'), '\n')
execute 'source '.vim
endfor
for key in s:to_a(plug.for)
if !has_key(lod, key)
let lod[key] = []
endif
call add(lod[key], name)
endfor
endif
endfor
for [key, names] in items(lod)
augroup PlugLOD
execute printf('autocmd FileType %s call <SID>lod_ft(%s, %s)',
\ key, string(key), string(reverse(names)))
augroup END
endfor
filetype plugin indent on
syntax on
@@ -144,33 +186,45 @@ function! s:rtp(spec)
return rtp
endfunction
function! s:esc(path)
return substitute(a:path, ' ', '\\ ', 'g')
endfunction
function! s:add_rtp(rtp)
execute "set rtp^=".a:rtp
execute "set rtp^=".s:esc(a:rtp)
if isdirectory(a:rtp.'after')
execute "set rtp+=".a:rtp.'after'
execute "set rtp+=".s:esc(a:rtp.'after')
endif
endfunction
function! s:lod(plug)
function! s:lod(plug, types)
let rtp = s:rtp(a:plug)
call s:add_rtp(rtp)
for dir in ['plugin', 'after']
for vim in split(globpath(rtp, dir.'/*.vim'), '\n')
for dir in a:types
for vim in split(globpath(rtp, dir.'/**/*.vim'), '\n')
execute 'source '.vim
endfor
endfor
endfunction
function! s:lod_cmd(cmd, bang, args, plug)
function! s:lod_ft(pat, names)
for name in a:names
call s:lod(g:plugs[name], ['plugin', 'after'])
endfor
execute 'autocmd! PlugLOD FileType ' . a:pat
let &l:filetype = &l:filetype
endfunction
function! s:lod_cmd(cmd, bang, l1, l2, args, plug)
execute 'delc '.a:cmd
call s:lod(a:plug)
execute printf("%s%s %s", a:cmd, a:bang, a:args)
call s:lod(a:plug, ['plugin', 'ftdetect', 'after'])
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)
execute 'unmap '.a:map
execute 'iunmap '.a:map
call s:lod(a:plug)
call s:lod(a:plug, ['plugin', 'ftdetect', 'after'])
let extra = ''
while 1
let c = getchar(0)
@@ -217,6 +271,7 @@ function! s:add(...)
let dir = s:dirpath( fnamemodify(join([g:plug_home, name], '/'), ':p') )
let spec = extend(opts, { 'dir': dir, 'uri': uri })
let g:plugs[name] = spec
let g:plugs_order += [name]
endfunction
function! s:install(...)
@@ -241,13 +296,16 @@ endfunction
function! s:syntax()
syntax clear
syntax region plug1 start=/\%1l/ end=/\%2l/ contains=ALL
syntax region plug2 start=/\%2l/ end=/\%3l/ contains=ALL
syn match plugNumber /[0-9]\+[0-9.]*/ containedin=plug1 contained
syn match plugBracket /[[\]]/ containedin=plug2 contained
syn match plugX /x/ containedin=plug2 contained
syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber
syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX
syn match plugNumber /[0-9]\+[0-9.]*/ contained
syn match plugBracket /[[\]]/ contained
syn match plugX /x/ contained
syn match plugDash /^-/
syn match plugName /\(^- \)\@<=[^:]*/
syn match plugCommit /^ [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha
syn match plugSha /\(^ \)\@<=[0-9a-z]\{7}/ contained
syn match plugRelDate /([^)]*)$/ contained
syn match plugError /^x.*/
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
hi def link plug1 Title
@@ -258,6 +316,8 @@ function! s:syntax()
hi def link plugDash Special
hi def link plugName Label
hi def link plugError Error
hi def link plugRelDate Comment
hi def link plugSha Identifier
endfunction
function! s:lpad(str, len)
@@ -270,16 +330,27 @@ function! s:lastline(msg)
endfunction
function! s:prepare()
execute s:plug_win . 'wincmd w'
if exists('b:plug')
%d
if bufexists(s:plug_buf)
let winnr = bufwinnr(s:plug_buf)
if winnr < 0
vertical topleft new
execute 'buffer ' . s:plug_buf
else
execute winnr . 'wincmd w'
endif
silent %d _
else
vertical topleft new
noremap <silent> <buffer> q :q<cr>
let b:plug = 1
let s:plug_win = winnr()
nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>q<cr>
nnoremap <silent> <buffer> D :PlugDiff<cr>
nnoremap <silent> <buffer> S :PlugStatus<cr>
nnoremap <silent> <buffer> ]] :silent! call <SID>section('')<cr>
nnoremap <silent> <buffer> [[ :silent! call <SID>section('b')<cr>
let b:plug_preview = -1
let s:plug_buf = winbufnr(0)
call s:assign_name()
endif
silent! unmap <buffer> <cr>
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline
setf vim-plug
call s:syntax()
@@ -297,30 +368,54 @@ function! s:assign_name()
silent! execute "f ".fnameescape(name)
endfunction
function! s:finish()
function! s:finish(pull)
call append(3, '- Finishing ... ')
redraw
call s:apply()
call s:syntax()
call setline(4, getline(4) . 'Done!')
normal! gg
redraw
if a:pull
echo "Press 'D' to see the updated changes."
endif
endfunction
function! s:update_impl(pull, args)
let threads = len(a:args) > 0 ? a:args[0] : get(g:, 'plug_threads', 16)
function! s:names(...)
return filter(keys(g:plugs), 'stridx(v:val, a:1) == 0')
endfunction
function! s:update_impl(pull, args) abort
let args = copy(a:args)
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')
if empty(todo)
echohl WarningMsg
echo 'No plugin to '. (a:pull ? 'update' : 'install') . '.'
echohl None
return
endif
call s:prepare()
call append(0, a:pull ? 'Updating plugins' : 'Installing plugins')
call append(1, '['. s:lpad('', len(g:plugs)) .']')
call append(1, '['. s:lpad('', len(todo)) .']')
normal! 2G
redraw
let len = len(g:plugs)
if has('ruby') && threads > 1
call s:update_parallel(a:pull, threads)
call s:update_parallel(a:pull, todo, threads)
else
call s:update_serial(a:pull)
call s:update_serial(a:pull, todo)
endif
call s:finish()
if len(g:plugs) > len
call plug#end()
endif
call s:finish(a:pull)
endfunction
function! s:extend(names)
@@ -330,7 +425,7 @@ function! s:extend(names)
for name in a:names
let plugfile = s:rtp(g:plugs[name]) . s:plug_file
if filereadable(plugfile)
execute "source ". plugfile
execute "source ". s:esc(plugfile)
endif
endfor
finally
@@ -347,10 +442,10 @@ function! s:update_progress(pull, cnt, bar, total)
redraw
endfunction
function! s:update_serial(pull)
function! s:update_serial(pull, todo)
let st = reltime()
let base = g:plug_home
let todo = copy(g:plugs)
let todo = copy(a:todo)
let total = len(todo)
let done = {}
let bar = ''
@@ -359,13 +454,13 @@ function! s:update_serial(pull)
for [name, spec] in items(todo)
let done[name] = 1
if isdirectory(spec.dir)
execute 'cd '.spec.dir
execute 'cd '.s:esc(spec.dir)
let [valid, msg] = s:git_valid(spec, 0, 0)
if valid
let result = a:pull ?
\ system(
\ printf('git checkout -q %s 2>&1 && git pull origin %s 2>&1',
\ spec.branch, spec.branch)) : 'Already installed'
\ s:system(
\ printf('git checkout -q %s 2>&1 && git pull 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
@@ -376,10 +471,12 @@ function! s:update_serial(pull)
call mkdir(base, 'p')
endif
execute 'cd '.base
let d = shellescape(substitute(spec.dir, '[\/]\+$', '', ''))
let result = system(
\ printf('git clone --recursive %s -b %s %s 2>&1',
\ shellescape(spec.uri), shellescape(spec.branch), d))
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(substitute(spec.dir, '[\/]\+$', '', '')),
\ s:shellesc(spec.dir)))
let error = v:shell_error != 0
endif
cd -
@@ -400,8 +497,12 @@ function! s:update_serial(pull)
call setline(1, "Updated. Elapsed time: " . split(reltimestr(reltime(st)))[0] . ' sec.')
endfunction
function! s:update_parallel(pull, threads)
function! s:update_parallel(pull, todo, threads)
ruby << EOF
def esc arg
%["#{arg.gsub('"', '\"')}"]
end
st = Time.now
require 'thread'
require 'fileutils'
@@ -410,7 +511,7 @@ function! s:update_parallel(pull, threads)
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(g:plugs)')
all = VIM::evaluate('copy(a:todo)')
limit = VIM::evaluate('get(g:, "plug_timeout", 60)')
nthr = VIM::evaluate('a:threads').to_i
cd = iswin ? 'cd /d' : 'cd'
@@ -422,7 +523,7 @@ function! s:update_parallel(pull, threads)
take1 = proc { mtx.synchronize { running && all.shift } }
logh = proc {
cnt = done.length
tot = VIM::evaluate('len(g:plugs)') || tot
tot = VIM::evaluate('len(a:todo)') || tot
$curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})"
$curbuf[2] = '[' + bar.ljust(tot) + ']'
VIM::command('normal! 2G')
@@ -502,8 +603,10 @@ function! s:update_parallel(pull, threads)
while pair = take1.call
name = pair.first
dir, uri, branch = pair.last.values_at *%w[dir uri branch]
branch = esc branch
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"
current_uri = data.lines.to_a.last
if !ret
@@ -518,15 +621,15 @@ function! s:update_parallel(pull, threads)
"PlugClean required."].join($/)]
else
if pull
bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && git pull origin #{branch} 2>&1"
bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && git pull origin #{branch} 2>&1 && git submodule update --init --recursive 2>&1"
else
[true, skip]
end
end
else
FileUtils.mkdir_p(base)
d = dir.sub(%r{[\\/]+$}, '')
bt.call "#{cd} #{base} && git clone --recursive #{uri} -b #{branch} #{d} 2>&1"
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"
end
log.call name, result, ok
end
@@ -557,6 +660,10 @@ function! s:dirpath(path)
endif
endfunction
function! s:shellesc(arg)
return '"'.substitute(a:arg, '"', '\\"', 'g').'"'
endfunction
function! s:glob_dir(path)
return map(filter(split(globpath(a:path, '**'), '\n'), 'isdirectory(v:val)'), 's:dirpath(v:val)')
endfunction
@@ -580,14 +687,23 @@ function! s:format_message(ok, name, message)
endif
endfunction
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'
if isdirectory(a:spec.dir)
if a:cd | execute "cd " . a:spec.dir | endif
let result = split(system("git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url"), '\n')
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)
@@ -597,9 +713,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
@@ -624,6 +744,7 @@ function! s:clean(force)
endif
let cnt += 1
call s:progress_bar(2, repeat('=', cnt), total)
normal! 2G
redraw
endfor
@@ -657,7 +778,7 @@ function! s:clean(force)
if yes
for dir in todo
if isdirectory(dir)
call system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . dir)
call system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(dir))
endif
endfor
call append(line('$'), 'Removed.')
@@ -670,8 +791,8 @@ endfunction
function! s:upgrade()
if executable('curl')
let mee = shellescape(s:me)
let new = shellescape(s:me . '.new')
let mee = s:shellesc(s:me)
let new = s:shellesc(s:me . '.new')
echo "Downloading ". s:plug_source
redraw
let mv = s:is_win ? 'move /Y' : 'mv -f'
@@ -713,25 +834,100 @@ endfunction
function! s:status()
call s:prepare()
call append(0, 'Checking plugins')
call append(1, '')
let ecnt = 0
let [cnt, total] = [0, len(g:plugs)]
for [name, spec] in items(g:plugs)
if isdirectory(spec.dir)
execute 'cd '.spec.dir
let [valid, msg] = s:git_valid(spec, 1, 0)
cd -
let [valid, msg] = s:git_valid(spec, 1, 1)
else
let [valid, msg] = [0, 'Not found. Try PlugInstall.']
endif
let cnt += 1
let ecnt += !valid
call append(2, s:format_message(valid, name, msg))
call cursor(3, 1)
call s:progress_bar(2, repeat('=', cnt), total)
call append(3, s:format_message(valid, name, msg))
normal! 2G
redraw
endfor
call setline(1, 'Finished. '.ecnt.' error(s).')
normal! gg
endfunction
function! s:is_preview_window_open()
silent! wincmd P
if &previewwindow
wincmd p
return 1
endif
return 0
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
endif
endfunction
function! s:section(flags)
call search('\(^- \)\@<=.', a:flags)
endfunction
function! s:diff()
call s:prepare()
call append(0, 'Collecting updated changes ...')
normal! gg
redraw
let cnt = 0
for [k, v] in items(g:plugs)
if !isdirectory(v.dir)
continue
endif
execute 'cd '.s:esc(v.dir)
let diff = system('git log --pretty=format:"%h %s (%cr)" "HEAD@{0}...HEAD@{1}"')
if !v:shell_error && !empty(diff)
call append(1, '')
call append(2, '- '.k.':')
call append(3, map(split(diff, '\n'), '" ". v:val'))
let cnt += 1
normal! gg
redraw
endif
cd -
endfor
call setline(1, cnt == 0 ? 'No updates.' : 'Last update:')
nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr>
normal! gg
endfunction
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,18 @@ 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)
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
else
/usr/local/bin/vim -Nu /tmp/mini-vimrc -c 'Vader workflow.vader'
fi
vim -u $MINI_VIMRC +Vader*

View File

@@ -1,5 +1,5 @@
Execute (Initialize test environment):
Save &rtp, g:plug_home, $MYVIMRC
Save &rtp, g:plugs, g:plug_home, $MYVIMRC
let vader = fnamemodify(globpath(&rtp, 'autoload/vader.vim'), ':h:h')
let plug = fnamemodify(globpath(&rtp, 'autoload/plug.vim'), ':h:h')
@@ -13,6 +13,16 @@ Execute (Initialize test environment):
set t_Co=256
colo default
pclose
function! PlugStatusSorted()
PlugStatus
%y
q
normal! P
%sort
g/^$/d
endfunction
let g:vimrc_reloaded = 0
let vimrc = tempname()
@@ -63,9 +73,15 @@ Execute (Test Plug command):
AssertEqual join([temp_plugged, 'seoul256.vim/'], '/'), g:plugs['seoul256.vim'].dir
AssertEqual 'no-t_co', g:plugs['seoul256.vim'].branch
" Git repo with tag
Plug 'junegunn/goyo.vim', '1.5.3'
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.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
@@ -74,18 +90,20 @@ 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"'))
AssertEqual 4, len(filter(getline(1, line('$')), 'v:val =~ "Not found"'))
q
Execute (PlugClean before installation):
@@ -115,42 +133,57 @@ Execute (PlugClean after installation):
Execute (PlugStatus after installation):
PlugStatus
AssertEqual 3, len(filter(getline(1, line('$')), 'v:val =~ "OK"'))
AssertEqual 4, len(filter(getline(1, line('$')), 'v:val =~ "OK"'))
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).
[==]
x seoul256.vim:
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
@@ -158,6 +191,7 @@ Expect:
PlugClean required.
- vim-emoji: OK
Finished. 1 error(s).
[==]
x seoul256.vim:
# TODO: does not work due to inputsave()
@@ -169,6 +203,8 @@ Expect:
Execute (PlugClean! to remove seoul256.vim):
PlugClean!
" Three removed, emoji left
AssertEqual 3, len(filter(getline(1, line('$')), 'v:val =~ "^- "'))
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "Removed"'))
Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
@@ -181,24 +217,21 @@ 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).
[==]
x seoul256.vim:
x vim-emoji:
Execute (PlugClean! to remove vim-emoji):
PlugClean!
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "^- "'))
AssertEqual 1, len(filter(getline(1, line('$')), 'v:val =~ "Removed"'))
Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
@@ -207,24 +240,157 @@ Execute (PlugClean! to remove vim-emoji):
Execute (PlugUpdate to install both again):
PlugUpdate
AssertEqual 2, len(filter(getline(1, line('$')), 'v:val =~ "Cloning into"'))
AssertEqual 2, g:vimrc_reloaded
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):
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
AssertEqual 4, g:vimrc_reloaded
normal D
AssertEqual 'No updates.', getline(1)
q
Execute (PlugDiff - 'No updates.'):
PlugDiff
AssertEqual 'No updates.', getline(1)
q
Execute (Rollback recent updates, PlugUpdate, then PlugDiff):
for repo in ['seoul256.vim', 'vim-emoji']
call system(printf('cd %s/%s && git reset HEAD^^ --hard', g:plug_home, repo))
endfor
PlugUpdate
" Now we have updates
normal D
AssertEqual 'Last update:', getline(1)
" Preview commit
silent! wincmd P
AssertEqual 0, &previewwindow
" ]] motion
execute 'normal ]]'
let lnum = line('.')
AssertEqual 3, col('.')
" Open commit preview
execute "normal j\<cr>"
wincmd P
AssertEqual 1, &previewwindow
AssertEqual 'git', &filetype
" Back to plug window
wincmd p
" ]] motion
execute 'normal $]]'
AssertEqual lnum + 4, line('.')
AssertEqual 3, col('.')
" [[ motion
execute 'normal 0[['
AssertEqual lnum, line('.')
AssertEqual 3, col('.')
" q will close preview window as well
normal q
" We no longer have preview window
silent! wincmd P
AssertEqual 0, &previewwindow
" q should not close preview window if it's already open
pedit
PlugDiff
execute "normal ]]j\<cr>"
normal q
silent! wincmd P
AssertEqual 1, &previewwindow
pclose
Execute (Plug window in a new tab):
PlugDiff
tab new new-tab
set buftype=nofile
PlugUpdate
normal D
AssertEqual 'No updates.', getline(1)
q
AssertEqual 'new-tab', expand('%')
q
q
**********************************************************************
~ On-demand loading / Partial installation/update ~
**********************************************************************
Execute (Trying to execute on-demand commands when plugin is not installed):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'on': ['EasyAlign', 'LiveEasyAlign'] }
call plug#end()
Assert exists(':EasyAlign')
Assert exists(':LiveEasyAlign')
AssertThrows EasyAlign
AssertThrows LiveEasyAlign
Assert !exists(':EasyAlign')
Assert !exists(':LiveEasyAlign')
Execute (New set of plugins):
call plug#begin()
Plug 'junegunn/vim-fnr' " Depends on vim-pseudocl
Plug 'junegunn/vim-easy-align', { 'on': 'EasyAlign' }
Plug 'junegunn/vim-redis', { 'for': 'redis' }
call plug#end()
Execute (Check commands):
Assert !exists(':FNR'), 'FNR command should not be found'
Assert !exists(':RedisExecute'), 'RedisExecute command should not be found'
Execute (Partial PlugInstall):
PlugInstall vim-fnr vim-easy-align
PlugInstall vim-fnr vim-easy-align 1
q
Execute (Check dependent plugin):
Assert &rtp =~ 'pseudocl', &rtp
Given (Unaligned code):
a=1
aa=2
Execute (Check installed plugins):
Assert exists(':FNR'), 'FNR command should be found'
Assert exists(':EasyAlign'), 'EasyAlign command should be found'
Assert !exists(':RedisExecute'), 'RedisExecute command still should not be found'
%EasyAlign=
Expect (Aligned code):
a = 1
aa = 2
Given (nothing):
Execute (Partial PlugUpdate):
PlugUpdate vim-redis
q
Execute (On-demand loading based on filetypes):
Assert !exists(':RedisExecute'), 'RedisExecute command still should not be found'
set ft=redis
Assert exists(':RedisExecute'), 'RedisExecute command is now found'
Execute (Cleanup):
call system('rm -rf '.temp_plugged)
unlet g:plugs
unlet g:plug_home
unlet g:vimrc_reloaded
unlet temp_plugged vader plug basertp save_rtp
unlet temp_plugged vader plug basertp save_rtp repo lnum
delf PlugStatusSorted
Restore
source $MYVIMRC