47 Commits

Author SHA1 Message Date
Junegunn Choi
d7f1846932 Deferred loading on autocmd (#event[#pattern])
e.g.
    Plug 'SirVer/ultisnips',  { 'on': '#InsertEnter' }
    Plug 'junegunn/goyo.vim', { 'on': ['Goyo', '#BufEnter#README'] }
2016-10-29 18:00:58 +09:00
Junegunn Choi
abbbe914f0 Remove unnecessary operations 2016-10-29 04:46:58 +09:00
Junegunn Choi
1f4e3eb063 No need for filetype off unless g:did_load_filetypes exists
Reference: https://github.com/tpope/vim-pathogen/pull/26
2016-10-28 00:13:12 +09:00
Junegunn Choi
2fa2761b99 Merge pull request #545 from srstevenson/set-nolist
Set nolist in vim-plug buffers
2016-10-27 12:48:26 +09:00
Scott Stevenson
078f32142d Set nolist in vim-plug buffers 2016-10-26 22:30:41 +01:00
Junegunn Choi
49c6b781e0 Do not prepend COUNT"REGISTER when feeding keys in insert mode
Close #543
2016-10-25 23:12:05 +09:00
Junegunn Choi
f4427b97f1 Merge pull request #541 from junegunn/vim8
Asynchronous +job installer on Vim 8
2016-10-19 08:10:20 +09:00
Junegunn Choi
6287ba88d5 Fix installer output
- Same output format across different installers
- Avoid unnecessary construction of result string
- Fix multi-line error logging when exit_cb is called before out_cb
2016-10-18 14:30:48 +09:00
Junegunn Choi
1bbb7a55e3 Update Vim 8 requirement
https://github.com/junegunn/vim-plug/issues/498#issuecomment-254239466
2016-10-18 00:32:27 +09:00
Junegunn Choi
d1022e948e Address out-of-order invocation of out_cb and exit_cb 2016-10-18 00:31:36 +09:00
Junegunn Choi
b94607b172 Update README: +job 2016-10-17 18:00:20 +09:00
Junegunn Choi
6bff19c2a9 Set out_mode to raw for progress report 2016-10-17 17:52:13 +09:00
Junegunn Choi
759103d074 Refactor job callbacks with partial 2016-10-17 17:51:42 +09:00
Yasuhiro Matsumoto
b32169ff30 Use job_start on vim
Close #498
Close #534
2016-10-17 16:16:03 +09:00
Junegunn Choi
3f7344d2cc Set up Travis CI build for Neovim 2016-10-17 15:34:20 +09:00
Junegunn Choi
7928057108 Make Neovim installer synchronous during startup
Close #104

This allows for `nvim +PlugUpdate +qa` without Python.
2016-10-17 12:34:09 +09:00
Junegunn Choi
c66e264d41 Fix Ruby installer on Vim 8.0.0036 (#538)
This could be a bug of Vim, but the new method should be safer in the
long run though it doesn't work on Ruby 1.8.
2016-10-17 12:22:20 +09:00
Junegunn Choi
01e4e9170a Update git URI validation in Ruby and Python installers
Contd. #530
2016-10-14 13:44:56 +09:00
Junegunn Choi
0662b5f4cc Fix Travis CI failure 2016-10-09 05:17:34 +09:00
Junegunn Choi
a2f1ea481d Reuse existing plug window
Close #532
2016-10-09 04:48:53 +09:00
Junegunn Choi
7bad3e7802 Merge pull request #531 from junegunn/fix-530
Improve git URI validation
2016-10-08 23:48:52 +09:00
Junegunn Choi
6575bd65b1 Improve git URI validation
Close #530
2016-10-08 23:32:48 +09:00
Junegunn Choi
5d8c4bfc1f Print exception from post-update hook with : prefix 2016-10-08 23:22:06 +09:00
Junegunn Choi
c0a83826f9 Print warning message when plug window is closed 2016-10-08 23:06:24 +09:00
Junegunn Choi
6454158846 Merge pull request #522 from jmatth/fix-visualhostkey
Fixing E684 when VisualHostKey is enabled for ssh
2016-09-16 14:12:41 +09:00
Josh Matthews
1f206db965 Fixing E684 when VisualHostKey is enabled for ssh
Having VisualHostKey enabled for ssh can cause lines containing a single
"^M" character to appear in the git output, which causes E684 to be
thrown if not filtered out.
2016-09-15 16:35:11 -04:00
Junegunn Choi
f4381fb748 Fix loading on c-operator
Close #518
2016-09-11 12:04:08 +09:00
Junegunn Choi
561518fd8c Print post-processing error in multi-line paragraph
Related #510
2016-08-15 00:46:10 +09:00
Junegunn Choi
b44ea685aa Merge pull request #508 from mhinz/silence-deletions
Silence :delete commands
2016-08-01 09:52:29 +09:00
Marco Hinz
9df0580eff Silence :delete commands
Add :silence to all :delete commands to avoid filling up the message history
with "1 line less" messages, in case 'report' is set to 0.
2016-07-31 22:50:50 +02:00
Junegunn Choi
e15598fe45 Add g:plug_pwindow for customizing preview window layout
Close #504
2016-07-23 18:36:30 +09:00
Junegunn Choi
326cb71a2a No period in echo message 2016-07-23 18:07:12 +09:00
Junegunn Choi
c9a7ca1e9e Define d operator for selectively removing invalid directories
Fix #503
2016-07-23 18:02:00 +09:00
Junegunn Choi
5695fb8474 Do not proceed if $GIT_DIR or $GIT_WORK_TREE is found
Close #506
2016-07-23 10:13:25 +09:00
Junegunn Choi
f68a4fddae Update example: youcompleteme#Enable is no longer needed
Close #501
2016-07-15 12:18:21 +09:00
Junegunn Choi
17996cedce Support { 'do': ':VimCommand' } notation
Close #450
2016-07-13 23:01:41 +09:00
Junegunn Choi
460fbe82e0 Ignore inconsistencies between g:plugs and g:plugs_order
https://github.com/junegunn/vim-plug/issues/469#issuecomment-226965736
2016-06-19 11:18:20 +09:00
Junegunn Choi
05a1620bb1 Put cursor inside the installer window after post-update hook
https://github.com/chrisbra/unicode.vim/issues/16
2016-06-16 22:17:21 +09:00
Junegunn Choi
cb5bed0e35 Always set register in map-based ODL 2016-05-31 15:27:27 +09:00
Junegunn Choi
44893a1901 Fix #491 - Lazy-loading with omaps 2016-05-31 12:44:48 +09:00
Junegunn Choi
765a2d21d3 Do not trigger BufRead if not necessary
Close #490
2016-05-23 22:22:43 +09:00
Junegunn Choi
eb25f320a0 Fix travis CI build 2016-05-23 13:15:57 +09:00
Junegunn Choi
7c7ef8cf2f Trigger BufRead when a plugin is loaded by on condition
Close #489
2016-05-23 13:11:06 +09:00
Junegunn Choi
a8b09617f9 Clarify that function call requires call
Close #487
2016-05-23 01:12:09 +09:00
Junegunn Choi
bf1e0fb8eb Do not use Ruby older than 1.8.7
Close #482
2016-05-13 02:06:00 +09:00
Junegunn Choi
656ccef8dc Switch &shell during submodule update
Fix #481
2016-04-29 13:39:17 +09:00
Junegunn Choi
41de3c713c Export Plug command as plug# function
https://github.com/junegunn/vim-plug/issues/477#issuecomment-212746298

One can directly use it to redefine Plug command:

    function! s:plug_with_default(...)
      call plug#(a:1, extend(get(g:, 'plug_opts', {}), get(a:000, 1, {})))
    endfunction
    command! -nargs=+ Plug call s:plug_with_default(<args>)
2016-04-22 02:50:04 +09:00
7 changed files with 594 additions and 236 deletions

View File

@@ -1,12 +1,12 @@
language: ruby language: ruby
sudo: false sudo: required
env: env:
global: global:
- DEPS=$HOME/deps - DEPS=$HOME/deps
- PATH=$DEPS/bin:$PATH - PATH=$DEPS/bin:$PATH
matrix: matrix:
include: include:
- env: ENV=nox - env: ENV=vim72
rvm: 1.8.7 rvm: 1.8.7
addons: { apt: { packages: [vim-nox] } } addons: { apt: { packages: [vim-nox] } }
- env: ENV=python - env: ENV=python
@@ -15,18 +15,29 @@ matrix:
- env: ENV=python3 - env: ENV=python3
rvm: 1.8.7 rvm: 1.8.7
addons: { apt: { packages: [python3-dev] } } addons: { apt: { packages: [python3-dev] } }
- env: ENV=ruby - env: ENV=ruby18
rvm: 1.8.7 rvm: 1.8.7
- env: ENV=ruby - env: ENV=ruby20
rvm: 2.0.0 rvm: 2.0.0
- env: ENV=neovim
- env: ENV=vim8
install: | install: |
git config --global user.email "you@example.com" git config --global user.email "you@example.com"
git config --global user.name "Your Name" git config --global user.name "Your Name"
if [ "$ENV" == "nox" ]; then if [ "$ENV" == "vim72" ]; then
mkdir -p ${DEPS}/bin mkdir -p ${DEPS}/bin
ln -s /usr/bin/vim.nox ${DEPS}/bin/vim ln -s /usr/bin/vim.nox ${DEPS}/bin/vim
return return
elif [ "$ENV" == "neovim" ]; then
# https://github.com/neovim/neovim/wiki/Installing-Neovim
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:neovim-ppa/unstable
sudo apt-get update -y
sudo apt-get install -y neovim
mkdir -p ${DEPS}/bin
ln -s /usr/bin/nvim ${DEPS}/bin/vim
return
fi fi
C_OPTS="--prefix=$DEPS --with-features=huge --disable-gui " C_OPTS="--prefix=$DEPS --with-features=huge --disable-gui "
@@ -37,7 +48,7 @@ install: |
python3) python3)
C_OPTS+=--enable-python3interp C_OPTS+=--enable-python3interp
;; ;;
ruby) ruby*)
C_OPTS+=--enable-rubyinterp C_OPTS+=--enable-rubyinterp
;; ;;
esac esac

View File

@@ -10,7 +10,7 @@ A minimalist Vim plugin manager.
- Easier to setup: Single file. No boilerplate code required. - Easier to setup: Single file. No boilerplate code required.
- Easier to use: Concise, intuitive syntax - Easier to use: Concise, intuitive syntax
- [Super-fast][40/4] parallel installation/update - [Super-fast][40/4] parallel installation/update
(with any of `+python`, `+python3`, `+ruby`, or [Neovim][nv]) (with any of `+job`, `+python`, `+python3`, `+ruby`, or [Neovim][nv])
- Creates shallow clones to minimize disk space usage and download time - Creates shallow clones to minimize disk space usage and download time
- On-demand loading for [faster startup time][startup-time] - On-demand loading for [faster startup time][startup-time]
- Can review and rollback updates - Can review and rollback updates
@@ -62,9 +62,9 @@ $uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
Add a vim-plug section to your `~/.vimrc` (or `~/.config/nvim/init.vim` for Neovim): Add a vim-plug section to your `~/.vimrc` (or `~/.config/nvim/init.vim` for Neovim):
1. Begin the section with `plug#begin()` 1. Begin the section with `call plug#begin()`
1. List the plugins with `Plug` commands 1. List the plugins with `Plug` commands
1. `plug#end()` to update `&runtimepath` and initialize plugin system 1. `call plug#end()` to update `&runtimepath` and initialize plugin system
#### Example #### Example
@@ -121,16 +121,16 @@ Reload .vimrc and `:PlugInstall` to install plugins.
### `Plug` options ### `Plug` options
| Option | Description | | Option | Description |
| ----------------------- | ------------------------------------------------ | | ----------------------- | ----------------------------------------------------------- |
| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use | | `branch`/`tag`/`commit` | Branch/tag/commit 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 |
| `as` | Use different name for the plugin | | `as` | Use different name 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, `<Plug>`-mappings, or #autocmds |
| `for` | On-demand loading: File types | | `for` | On-demand loading: File types |
| `frozen` | Do not update unless explicitly specified | | `frozen` | Do not update unless explicitly specified |
### Global options ### Global options
@@ -141,6 +141,7 @@ Reload .vimrc and `:PlugInstall` to install plugins.
| `g:plug_retries` | 2 | Number of retries in case of timeout (*Ruby & Python*) | | `g:plug_retries` | 2 | Number of retries in case of timeout (*Ruby & Python*) |
| `g:plug_shallow` | 1 | Use shallow clone | | `g:plug_shallow` | 1 | Use shallow clone |
| `g:plug_window` | `vertical topleft new` | Command to open plug window | | `g:plug_window` | `vertical topleft new` | Command to open plug window |
| `g:plug_pwindow` | `above 12new` | Command to open preview window in `PlugDiff` |
| `g:plug_url_format` | `https://git::@github.com/%s.git` | `printf` format to build repo URL (Only applies to the subsequent `Plug` commands) | | `g:plug_url_format` | `https://git::@github.com/%s.git` | `printf` format to build repo URL (Only applies to the subsequent `Plug` commands) |
@@ -179,12 +180,15 @@ Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" Multiple file types " Multiple file types
Plug 'kovisoft/paredit', { 'for': ['clojure', 'scheme'] } Plug 'kovisoft/paredit', { 'for': ['clojure', 'scheme'] }
" On autocmd
Plug 'SirVer/ultisnips', { 'on': '#InsertEnter' }
" On-demand loading on both conditions " On-demand loading on both conditions
Plug 'junegunn/vader.vim', { 'on': 'Vader', 'for': 'vader' } Plug 'junegunn/vader.vim', { 'on': 'Vader', 'for': 'vader' }
" Code to execute when the plugin is loaded on demand " Code to execute when the plugin is lazily loaded on demand
Plug 'Valloric/YouCompleteMe', { 'for': 'cpp' } Plug 'junegunn/goyo.vim', { 'for': 'markdown' }
autocmd! User YouCompleteMe if !has('vim_starting') | call youcompleteme#Enable() | endif autocmd! User goyo.vim echom 'Goyo is now loaded!'
``` ```
`for` option is generally not needed as most plugins for specific file types `for` option is generally not needed as most plugins for specific file types
@@ -201,6 +205,12 @@ Plug 'Shougo/vimproc.vim', { 'do': 'make' }
Plug 'Valloric/YouCompleteMe', { 'do': './install.py' } Plug 'Valloric/YouCompleteMe', { 'do': './install.py' }
``` ```
If the value starts with `:`, it will be recognized as a Vim command.
```vim
Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries' }
```
If you need more control, you can pass a reference to a Vim function that If you need more control, you can pass a reference to a Vim function that
takes a single argument. takes a single argument.

458
plug.vim
View File

@@ -98,6 +98,7 @@ 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 = has('nvim') && exists('*jobwait') && !s:is_win let s:nvim = has('nvim') && exists('*jobwait') && !s:is_win
let s:vim8 = has('patch-8.0.0039') && exists('*job_start')
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 = {
@@ -131,7 +132,7 @@ function! plug#begin(...)
endfunction endfunction
function! s:define_commands() function! s:define_commands()
command! -nargs=+ -bar Plug call s:Plug(<args>) command! -nargs=+ -bar Plug call plug#(<args>)
if !executable('git') if !executable('git')
return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.')
endif endif
@@ -171,14 +172,22 @@ function! s:assoc(dict, key, val)
let a:dict[a:key] = add(get(a:dict, a:key, []), a:val) let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
endfunction endfunction
function! s:ask(message) function! s:ask(message, ...)
call inputsave() call inputsave()
echohl WarningMsg echohl WarningMsg
let proceed = input(a:message.' (y/N) ') =~? '^y' let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
echohl None echohl None
call inputrestore() call inputrestore()
echo "\r" echo "\r"
return proceed return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0
endfunction
function! s:ask_no_interrupt(...)
try
return call('s:ask', a:000)
catch
return 0
endtry
endfunction endfunction
function! plug#end() function! plug#end()
@@ -194,8 +203,13 @@ function! plug#end()
endif endif
let lod = { 'ft': {}, 'map': {}, 'cmd': {} } let lod = { 'ft': {}, 'map': {}, 'cmd': {} }
filetype off if exists('g:did_load_filetypes')
filetype off
endif
for name in g:plugs_order for name in g:plugs_order
if !has_key(g:plugs, name)
continue
endif
let plug = g:plugs[name] let plug = g:plugs[name]
if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for') if get(s:loaded, name, 0) || !has_key(plug, 'on') && !has_key(plug, 'for')
let s:loaded[name] = 1 let s:loaded[name] = 1
@@ -215,9 +229,16 @@ function! plug#end()
call s:assoc(lod.cmd, cmd, name) call s:assoc(lod.cmd, cmd, name)
endif endif
call add(s:triggers[name].cmd, cmd) call add(s:triggers[name].cmd, cmd)
elseif cmd[0] == '#' && exists('##'.split(cmd, '#')[0])
let tokens = split(cmd, '#')
let group = 'Plug/'.name
execute 'augroup' group
autocmd!
execute 'autocmd' tokens[0] get(tokens, 1, '*') printf('call s:lod_autocmd(%s)', string(name))
execute 'augroup END'
else else
call s:err('Invalid `on` option: '.cmd. call s:err('Invalid `on` option: '.cmd.
\ '. Should start with an uppercase letter or `<Plug>`.') \ '. Should start with an uppercase letter, `<Plug>`, or `#`.')
endif endif
endfor endfor
endif endif
@@ -245,8 +266,8 @@ function! plug#end()
for [mode, map_prefix, key_prefix] in for [mode, map_prefix, key_prefix] in
\ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']] \ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
execute printf( execute printf(
\ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, "%s")<CR>', \ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>',
\ mode, map, map_prefix, string(map), string(names), key_prefix) \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix)
endfor endfor
endfor endfor
@@ -264,7 +285,7 @@ function! plug#end()
syntax enable syntax enable
end end
else else
call s:reload() call s:reload_plugins()
endif endif
endfunction endfunction
@@ -272,9 +293,13 @@ function! s:loaded_names()
return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)') return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)')
endfunction endfunction
function! s:reload() function! s:load_plugin(spec)
call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
endfunction
function! s:reload_plugins()
for name in s:loaded_names() for name in s:loaded_names()
call s:source(s:rtp(g:plugs[name]), 'plugin/**/*.vim', 'after/plugin/**/*.vim') call s:load_plugin(g:plugs[name])
endfor endfor
endfunction endfunction
@@ -383,7 +408,7 @@ 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")'), '!empty(v:val)')
let rtp = join(map(rtps, 'escape(v:val, ",")'), ',') let rtp = join(map(rtps, 'escape(v:val, ",")'), ',')
\ . ','.s:middle.',' \ . ','.s:middle.','
\ . join(map(afters, 'escape(v:val, ",")'), ',') \ . join(map(afters, 'escape(v:val, ",")'), ',')
@@ -397,7 +422,20 @@ function! s:reorg_rtp()
endfunction endfunction
function! s:doautocmd(...) function! s:doautocmd(...)
execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '<nomodeline>' : '') join(a:000) if exists('#'.join(a:000, '#'))
execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '<nomodeline>' : '') join(a:000)
endif
endfunction
function! s:dobufread(names)
for name in a:names
let path = s:rtp(g:plugs[name]).'/**'
for dir in ['ftdetect', 'ftplugin']
if len(finddir(dir, path))
return s:doautocmd('BufRead')
endif
endfor
endfor
endfunction endfunction
function! plug#load(...) function! plug#load(...)
@@ -412,12 +450,8 @@ function! plug#load(...)
let s = len(unknowns) > 1 ? 's' : '' let s = len(unknowns) > 1 ? 's' : ''
return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', '))) return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', ')))
end end
for name in a:000 call s:lod(a:000, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) call s:dobufread(a:000)
endfor
if exists('#BufRead')
doautocmd BufRead
endif
return 1 return 1
endfunction endfunction
@@ -453,9 +487,7 @@ function! s:lod(names, types, ...)
endif endif
call s:source(rtp, a:2) call s:source(rtp, a:2)
endif endif
if exists('#User#'.name) call s:doautocmd('User', name)
call s:doautocmd('User', name)
endif
endfor endfor
endfunction endfunction
@@ -463,21 +495,19 @@ function! s:lod_ft(pat, names)
let syn = 'syntax/'.a:pat.'.vim' let syn = 'syntax/'.a:pat.'.vim'
call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn) call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn)
execute 'autocmd! PlugLOD FileType' a:pat execute 'autocmd! PlugLOD FileType' a:pat
if exists('#filetypeplugin#FileType') call s:doautocmd('filetypeplugin', 'FileType')
doautocmd filetypeplugin FileType call s:doautocmd('filetypeindent', 'FileType')
endif
if exists('#filetypeindent#FileType')
doautocmd filetypeindent FileType
endif
endfunction endfunction
function! s:lod_cmd(cmd, bang, l1, l2, args, names) function! s:lod_cmd(cmd, bang, l1, l2, args, names)
call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:dobufread(a:names)
execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args) execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args)
endfunction endfunction
function! s:lod_map(map, names, prefix) function! s:lod_map(map, names, with_prefix, prefix)
call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin']) call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:dobufread(a:names)
let extra = '' let extra = ''
while 1 while 1
let c = getchar(0) let c = getchar(0)
@@ -486,10 +516,30 @@ function! s:lod_map(map, names, prefix)
endif endif
let extra .= nr2char(c) let extra .= nr2char(c)
endwhile endwhile
call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
if a:with_prefix
let prefix = v:count ? v:count : ''
let prefix .= '"'.v:register.a:prefix
if mode(1) == 'no'
if v:operator == 'c'
let prefix = "\<esc>" . prefix
endif
let prefix .= v:operator
endif
call feedkeys(prefix, 'n')
endif
call feedkeys(substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
endfunction endfunction
function! s:Plug(repo, ...) function! s:lod_autocmd(name)
call s:lod([a:name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:dobufread([a:name])
let group = 'Plug/'.a:name
execute 'autocmd!' group
execute 'augroup!' group
endfunction
function! plug#(repo, ...)
if a:0 > 1 if a:0 > 1
return s:err('Invalid number of arguments (1..2)') return s:err('Invalid number of arguments (1..2)')
endif endif
@@ -539,8 +589,7 @@ function! s:infer_properties(name, repo)
let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git') let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git')
let uri = printf(fmt, repo) let uri = printf(fmt, repo)
endif endif
let dir = s:dirpath( fnamemodify(join([g:plug_home, a:name], '/'), ':p') ) return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri }
return { 'dir': dir, 'uri': uri }
endif endif
endfunction endfunction
@@ -588,6 +637,7 @@ function! s:syntax()
syn match plugRelDate /([^)]*)$/ contained syn match plugRelDate /([^)]*)$/ contained
syn match plugNotLoaded /(not loaded)$/ syn match plugNotLoaded /(not loaded)$/
syn match plugError /^x.*/ syn match plugError /^x.*/
syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
syn match plugH2 /^.*:\n-\+$/ syn match plugH2 /^.*:\n-\+$/
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
hi def link plug1 Title hi def link plug1 Title
@@ -607,6 +657,7 @@ function! s:syntax()
hi def link plugUpdate Type hi def link plugUpdate Type
hi def link plugError Error hi def link plugError Error
hi def link plugDeleted Ignore
hi def link plugRelDate Comment hi def link plugRelDate Comment
hi def link plugEdge PreProc hi def link plugEdge PreProc
hi def link plugSha Identifier hi def link plugSha Identifier
@@ -684,12 +735,22 @@ function! s:prepare(...)
throw 'Invalid current working directory. Cannot proceed.' throw 'Invalid current working directory. Cannot proceed.'
endif endif
for evar in ['$GIT_DIR', '$GIT_WORK_TREE']
if exists(evar)
throw evar.' detected. Cannot proceed.'
endif
endfor
call s:job_abort() call s:job_abort()
if s:switch_in() if s:switch_in()
normal q if b:plug_preview == 1
pc
endif
enew
else
call s:new_window()
endif endif
call s:new_window()
nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>bd<cr> nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>bd<cr>
if a:0 == 0 if a:0 == 0
call s:finish_bindings() call s:finish_bindings()
@@ -699,11 +760,10 @@ function! s:prepare(...)
let s:plug_buf = winbufnr(0) let s:plug_buf = winbufnr(0)
call s:assign_name() call s:assign_name()
silent! unmap <buffer> <cr> for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
silent! unmap <buffer> L execute 'silent! unmap <buffer>' k
silent! unmap <buffer> o endfor
silent! unmap <buffer> X setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
setf vim-plug setf vim-plug
if exists('g:syntax_on') if exists('g:syntax_on')
call s:syntax() call s:syntax()
@@ -722,15 +782,25 @@ function! s:assign_name()
silent! execute 'f' fnameescape(name) silent! execute 'f' fnameescape(name)
endfunction endfunction
function! s:chsh(swap)
let prev = [&shell, &shellredir]
if !s:is_win && a:swap
set shell=sh shellredir=>%s\ 2>&1
endif
return prev
endfunction
function! s:bang(cmd, ...) function! s:bang(cmd, ...)
try try
let [sh, shrd] = s:chsh(a:0)
" FIXME: Escaping is incomplete. We could use shellescape with eval, " FIXME: Escaping is incomplete. We could use shellescape with eval,
" but it won't work on Windows. " but it won't work on Windows.
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
let g:_plug_bang = '!'.escape(cmd, '#!%') let g:_plug_bang = '!'.escape(cmd, '#!%')
execute "normal! :execute g:_plug_bang\<cr>\<cr>" execute "normal! :execute g:_plug_bang\<cr>\<cr>"
finally finally
unlet g:_plug_bang unlet g:_plug_bang
let [&shell, &shellredir] = [sh, shrd]
endtry endtry
return v:shell_error ? 'Exit status: ' . v:shell_error : '' return v:shell_error ? 'Exit status: ' . v:shell_error : ''
endfunction endfunction
@@ -758,7 +828,20 @@ function! s:do(pull, force, todo)
let error = '' let error = ''
let type = type(spec.do) let type = type(spec.do)
if type == s:TYPE.string if type == s:TYPE.string
let error = s:bang(spec.do) if spec.do[0] == ':'
call s:load_plugin(spec)
try
execute spec.do[1:]
catch
let error = v:exception
endtry
if !s:plug_window_exists()
cd -
throw 'Warning: vim-plug was terminated by the post-update hook of '.name
endif
else
let error = s:bang(spec.do)
endif
elseif type == s:TYPE.funcref elseif type == s:TYPE.funcref
try try
let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged')
@@ -769,6 +852,7 @@ function! s:do(pull, force, todo)
else else
let error = 'Invalid hook type' let error = 'Invalid hook type'
endif endif
call s:switch_in()
call setline(4, empty(error) ? (getline(4) . 'OK') call setline(4, empty(error) ? (getline(4) . 'OK')
\ : ('x' . getline(4)[1:] . error)) \ : ('x' . getline(4)[1:] . error))
if !empty(error) if !empty(error)
@@ -836,13 +920,14 @@ function! s:names(...)
endfunction endfunction
function! s:check_ruby() function! s:check_ruby()
silent! ruby require 'thread'; VIM::command('let g:plug_ruby = 1') silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'")
if get(g:, 'plug_ruby', 0) if !exists('g:plug_ruby')
unlet g:plug_ruby redraw!
return 1 return s:warn('echom', 'Warning: Ruby interface is broken')
endif endif
redraw! let ruby_version = split(g:plug_ruby, '\.')
return s:warn('echom', 'Warning: Ruby interface is broken') unlet g:plug_ruby
return s:version_requirement(ruby_version, [1, 8, 7])
endfunction endfunction
function! s:update_impl(pull, force, args) abort function! s:update_impl(pull, force, args) abort
@@ -880,8 +965,9 @@ function! s:update_impl(pull, force, args) abort
call s:warn('echom', '[vim-plug] Update Neovim for parallel installer') call s:warn('echom', '[vim-plug] Update Neovim for parallel installer')
endif endif
let python = (has('python') || has('python3')) && (!s:nvim || has('vim_starting')) let use_job = s:nvim || s:vim8
let ruby = has('ruby') && !s:nvim && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && s:check_ruby() let python = (has('python') || has('python3')) && !use_job
let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && s:check_ruby()
let s:update = { let s:update = {
\ 'start': reltime(), \ 'start': reltime(),
@@ -891,7 +977,7 @@ function! s:update_impl(pull, force, args) abort
\ 'pull': a:pull, \ 'pull': a:pull,
\ 'force': a:force, \ 'force': a:force,
\ 'new': {}, \ 'new': {},
\ 'threads': (python || ruby || s:nvim) ? min([len(todo), threads]) : 1, \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1,
\ 'bar': '', \ 'bar': '',
\ 'fin': 0 \ 'fin': 0
\ } \ }
@@ -905,7 +991,7 @@ function! s:update_impl(pull, force, args) abort
\ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : ''
" Python version requirement (>= 2.7) " Python version requirement (>= 2.7)
if python && !has('python3') && !ruby && !s:nvim && s:update.threads > 1 if python && !has('python3') && !ruby && !use_job && s:update.threads > 1
redir => pyv redir => pyv
silent python import platform; print platform.python_version() silent python import platform; print platform.python_version()
redir END redir END
@@ -946,6 +1032,12 @@ function! s:update_impl(pull, force, args) abort
endtry endtry
else else
call s:update_vim() call s:update_vim()
while use_job && has('vim_starting')
sleep 100m
if s:update.fin
break
endif
endwhile
endif endif
endfunction endfunction
@@ -961,7 +1053,7 @@ function! s:update_finish()
if s:switch_in() if s:switch_in()
call append(3, '- Updating ...') | 4 call append(3, '- Updating ...') | 4
for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))')) for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))'))
let pos = s:logpos(name) let [pos, _] = s:logpos(name)
if !pos if !pos
continue continue
endif endif
@@ -991,19 +1083,25 @@ function! s:update_finish()
call s:log4(name, 'Updating submodules. This may take a while.') call s:log4(name, 'Updating submodules. This may take a while.')
let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir) let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir)
endif endif
let msg = printf('%s %s: %s', v:shell_error ? 'x': '-', name, s:lastline(out)) let msg = s:format_message(v:shell_error ? 'x': '-', name, out)
if v:shell_error if v:shell_error
call add(s:update.errors, name) call add(s:update.errors, name)
call s:regress_bar() call s:regress_bar()
execute pos 'd _' silent execute pos 'd _'
call append(4, msg) | 4 call append(4, msg) | 4
elseif !empty(out) elseif !empty(out)
call setline(pos, msg) call setline(pos, msg[0])
endif endif
redraw redraw
endfor endfor
4 d _ silent 4 d _
call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")')) try
call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")'))
catch
call s:warn('echom', v:exception)
call s:warn('echo', '')
return
endtry
call s:finish(s:update.pull) call s:finish(s:update.pull)
call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.') call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.')
call s:switch_out('normal! gg') call s:switch_out('normal! gg')
@@ -1011,12 +1109,16 @@ function! s:update_finish()
endfunction endfunction
function! s:job_abort() function! s:job_abort()
if !s:nvim || !exists('s:jobs') if (!s:nvim && !s:vim8) || !exists('s:jobs')
return return
endif endif
for [name, j] in items(s:jobs) for [name, j] in items(s:jobs)
silent! call jobstop(j.jobid) if s:nvim
silent! call jobstop(j.jobid)
elseif s:vim8
silent! call job_stop(j.jobid)
endif
if j.new if j.new
call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir))
endif endif
@@ -1024,59 +1126,88 @@ function! s:job_abort()
let s:jobs = {} let s:jobs = {}
endfunction endfunction
" When a:event == 'stdout', data = list of strings function! s:last_non_empty_line(lines)
" When a:event == 'exit', data = returncode let len = len(a:lines)
function! s:job_handler(job_id, data, event) abort for idx in range(len)
if !s:plug_window_exists() " plug window closed let line = a:lines[len-idx-1]
return s:job_abort() if !empty(line)
endif return line
endif
endfor
return ''
endfunction
if a:event == 'stdout' function! s:job_out_cb(self, data) abort
let complete = empty(a:data[-1]) let self = a:self
let lines = map(filter(a:data, 'len(v:val) > 0'), 'split(v:val, "[\r\n]")[-1]') let data = remove(self.lines, -1) . a:data
call extend(self.lines, lines) let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]')
let self.result = join(self.lines, "\n") call extend(self.lines, lines)
if !complete " To reduce the number of buffer updates
call remove(self.lines, -1) let self.tick = get(self, 'tick', -1) + 1
endif if !self.running || self.tick % len(s:jobs) == 0
" To reduce the number of buffer updates let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-')
let self.tick = get(self, 'tick', -1) + 1 let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines)
if self.tick % len(s:jobs) == 0 call s:log(bullet, self.name, result)
call s:log(self.new ? '+' : '*', self.name, self.result)
endif
elseif a:event == 'exit'
let self.running = 0
if a:data != 0
let self.error = 1
endif
call s:reap(self.name)
call s:tick()
endif endif
endfunction endfunction
function! s:job_exit_cb(self, data) abort
let a:self.running = 0
let a:self.error = a:data != 0
call s:reap(a:self.name)
call s:tick()
endfunction
function! s:job_cb(fn, job, ch, data)
if !s:plug_window_exists() " plug window closed
return s:job_abort()
endif
call call(a:fn, [a:job, a:data])
endfunction
function! s:nvim_cb(job_id, data, event) abort
return a:event == 'stdout' ?
\ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) :
\ s:job_cb('s:job_exit_cb', self, 0, a:data)
endfunction
function! s:spawn(name, cmd, opts) function! s:spawn(name, cmd, opts)
let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [], 'result': '', let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
\ 'new': get(a:opts, 'new', 0), \ 'new': get(a:opts, 'new', 0) }
\ 'on_stdout': function('s:job_handler'),
\ 'on_exit' : function('s:job_handler'),
\ }
let s:jobs[a:name] = job let s:jobs[a:name] = job
let argv = add(s:is_win ? ['cmd', '/c'] : ['sh', '-c'],
\ has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd)
if s:nvim if s:nvim
let argv = [ 'sh', '-c', call extend(job, {
\ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) ] \ 'on_stdout': function('s:nvim_cb'),
\ 'on_exit': function('s:nvim_cb'),
\ })
let jid = jobstart(argv, job) let jid = jobstart(argv, job)
if jid > 0 if jid > 0
let job.jobid = jid let job.jobid = jid
else else
let job.running = 0 let job.running = 0
let job.error = 1 let job.error = 1
let job.result = jid < 0 ? 'sh is not executable' : let job.lines = [jid < 0 ? argv[0].' is not executable' :
\ 'Invalid arguments (or job table is full)' \ 'Invalid arguments (or job table is full)']
endif
elseif s:vim8
let jid = job_start(argv, {
\ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]),
\ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]),
\ 'out_mode': 'raw'
\})
if job_status(jid) == 'run'
let job.jobid = jid
else
let job.running = 0
let job.error = 1
let job.lines = ['Failed to start job']
endif endif
else else
let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd] let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]
let job.result = call('s:system', params) let job.lines = s:lines(call('s:system', params))
let job.error = v:shell_error != 0 let job.error = v:shell_error != 0
let job.running = 0 let job.running = 0
endif endif
@@ -1091,7 +1222,9 @@ function! s:reap(name)
endif endif
let s:update.bar .= job.error ? 'x' : '=' let s:update.bar .= job.error ? 'x' : '='
call s:log(job.error ? 'x' : '-', a:name, empty(job.result) ? 'OK' : job.result) let bullet = job.error ? 'x' : '-'
let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines)
call s:log(bullet, a:name, empty(result) ? 'OK' : result)
call s:bar() call s:bar()
call remove(s:jobs, a:name) call remove(s:jobs, a:name)
@@ -1110,23 +1243,31 @@ endfunction
function! s:logpos(name) function! s:logpos(name)
for i in range(4, line('$')) for i in range(4, line('$'))
if getline(i) =~# '^[-+x*] '.a:name.':' if getline(i) =~# '^[-+x*] '.a:name.':'
return i for j in range(i + 1, line('$'))
if getline(j) !~ '^ '
return [i, j - 1]
endif
endfor
return [i, i]
endif endif
endfor endfor
return [0, 0]
endfunction endfunction
function! s:log(bullet, name, lines) function! s:log(bullet, name, lines)
if s:switch_in() if s:switch_in()
let pos = s:logpos(a:name) let [b, e] = s:logpos(a:name)
if pos > 0 if b > 0
execute pos 'd _' silent execute printf('%d,%d d _', b, e)
if pos > winheight('.') if b > winheight('.')
let pos = 4 let b = 4
endif endif
else else
let pos = 4 let b = 4
endif endif
call append(pos - 1, s:format_message(a:bullet, a:name, a:lines)) " FIXME For some reason, nomodifiable is set after :d in vim8
setlocal modifiable
call append(b - 1, s:format_message(a:bullet, a:name, a:lines))
call s:switch_out() call s:switch_out()
endif endif
endfunction endfunction
@@ -1140,12 +1281,12 @@ endfunction
function! s:tick() function! s:tick()
let pull = s:update.pull let pull = s:update.pull
let prog = s:progress_opt(s:nvim) let prog = s:progress_opt(s:nvim || s:vim8)
while 1 " Without TCO, Vim stack is bound to explode while 1 " Without TCO, Vim stack is bound to explode
if empty(s:update.todo) if empty(s:update.todo)
if empty(s:jobs) && !s:update.fin if empty(s:jobs) && !s:update.fin
let s:update.fin = 1
call s:update_finish() call s:update_finish()
let s:update.fin = 1
endif endif
return return
endif endif
@@ -1165,10 +1306,10 @@ while 1 " Without TCO, Vim stack is bound to explode
let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : ''
call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir }) call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir })
else else
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 } let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 }
endif endif
else else
let s:jobs[name] = { 'running': 0, 'result': error, 'error': 1 } let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 }
endif endif
else else
call s:spawn(name, call s:spawn(name,
@@ -1454,10 +1595,12 @@ class Plugin(object):
return result[-1] return result[-1]
def update(self): def update(self):
match = re.compile(r'git::?@') actual_uri = self.repo_uri()
actual_uri = re.sub(match, '', self.repo_uri()) expect_uri = self.args['uri']
expect_uri = re.sub(match, '', self.args['uri']) regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$')
if actual_uri != expect_uri: ma = regex.match(actual_uri)
mb = regex.match(expect_uri)
if ma is None or mb is None or ma.groups() != mb.groups():
msg = ['', msg = ['',
'Invalid URI: {0}'.format(actual_uri), 'Invalid URI: {0}'.format(actual_uri),
'Expected {0}'.format(expect_uri), 'Expected {0}'.format(expect_uri),
@@ -1616,6 +1759,11 @@ function! s:update_ruby()
end end
end end
def compare_git_uri a, b
regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$}
regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1)
end
require 'thread' require 'thread'
require 'fileutils' require 'fileutils'
require 'timeout' require 'timeout'
@@ -1717,9 +1865,8 @@ function! s:update_ruby()
main = Thread.current main = Thread.current
threads = [] threads = []
watcher = Thread.new { watcher = Thread.new {
while VIM::evaluate('getchar(1)') require 'io/console' # >= Ruby 1.9
sleep 0.1 nil until IO.console.getch == 3.chr
end
mtx.synchronize do mtx.synchronize do
running = false running = false
threads.each { |t| t.raise Interrupt } threads.each { |t| t.raise Interrupt }
@@ -1757,7 +1904,7 @@ function! s:update_ruby()
else else
[false, [data.chomp, "PlugClean required."].join($/)] [false, [data.chomp, "PlugClean required."].join($/)]
end end
elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '') elsif !compare_git_uri(current_uri, uri)
[false, ["Invalid URI: #{current_uri}", [false, ["Invalid URI: #{current_uri}",
"Expected: #{uri}", "Expected: #{uri}",
"PlugClean required."].join($/)] "PlugClean required."].join($/)]
@@ -1803,9 +1950,15 @@ function! s:progress_bar(line, bar, total)
endfunction endfunction
function! s:compare_git_uri(a, b) function! s:compare_git_uri(a, b)
let a = substitute(a:a, 'git:\{1,2}@', '', '') " See `git help clone'
let b = substitute(a:b, 'git:\{1,2}@', '', '') " https:// [user@] github.com[:port] / junegunn/vim-plug [.git]
return a ==# b " [git@] github.com[:port] : junegunn/vim-plug [.git]
" file:// / junegunn/vim-plug [/]
" / junegunn/vim-plug [/]
let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$'
let ma = matchlist(a:a, pat)
let mb = matchlist(a:b, pat)
return ma[1:2] ==# mb[1:2]
endfunction endfunction
function! s:format_message(bullet, name, message) function! s:format_message(bullet, name, message)
@@ -1823,10 +1976,7 @@ endfunction
function! s:system(cmd, ...) function! s:system(cmd, ...)
try try
let [sh, shrd] = [&shell, &shellredir] let [sh, shrd] = s:chsh(1)
if !s:is_win
set shell=sh shellredir=>%s\ 2>&1
endif
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
return system(s:is_win ? '('.cmd.')' : cmd) return system(s:is_win ? '('.cmd.')' : cmd)
finally finally
@@ -1948,16 +2098,48 @@ function! s:clean(force)
if empty(todo) if empty(todo)
call append(line('$'), 'Already clean.') call append(line('$'), 'Already clean.')
else else
if a:force || s:ask('Proceed?') let s:clean_count = 0
for dir in todo call append(3, ['Directories to delete:', ''])
call s:rm_rf(dir) redraw!
endfor if a:force || s:ask_no_interrupt('Delete all directories?')
call append(3, ['Removed.', '']) call s:delete([6, line('$')], 1)
else else
call append(3, ['Cancelled.', '']) call setline(4, 'Cancelled.')
nnoremap <silent> <buffer> d :set opfunc=<sid>delete_op<cr>g@
nmap <silent> <buffer> dd d_
xnoremap <silent> <buffer> d :<c-u>call <sid>delete_op(visualmode(), 1)<cr>
echo 'Delete the lines (d{motion}) to delete the corresponding directories'
endif endif
endif endif
4 4
setlocal nomodifiable
endfunction
function! s:delete_op(type, ...)
call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0)
endfunction
function! s:delete(range, force)
let [l1, l2] = a:range
let force = a:force
while l1 <= l2
let line = getline(l1)
if line =~ '^- ' && isdirectory(line[2:])
execute l1
redraw!
let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1)
let force = force || answer > 1
if answer
call s:rm_rf(line[2:])
setlocal modifiable
call setline(l1, '~'.line[1:])
let s:clean_count += 1
call setline(4, printf('Removed %d directories.', s:clean_count))
setlocal nomodifiable
endif
endif
let l1 += 1
endwhile
endfunction endfunction
function! s:upgrade() function! s:upgrade()
@@ -2099,11 +2281,15 @@ function! s:preview_commit()
return return
endif endif
execute 'pedit' sha if exists('g:plug_pwindow') && !s:is_preview_window_open()
wincmd P execute g:plug_pwindow
setlocal filetype=git buftype=nofile nobuflisted modifiable execute 'e' sha
execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha else
normal! gg"_dd execute 'pedit' sha
wincmd P
endif
setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
execute 'silent %!cd' s:shellesc(g:plugs[name].dir) '&& git show --no-color --pretty=medium' sha
setlocal nomodifiable setlocal nomodifiable
nnoremap <silent> <buffer> q :q<cr> nnoremap <silent> <buffer> q :q<cr>
wincmd p wincmd p
@@ -2189,7 +2375,7 @@ function! s:revert()
setlocal modifiable setlocal modifiable
normal! "_dap normal! "_dap
setlocal nomodifiable setlocal nomodifiable
echo 'Reverted.' echo 'Reverted'
endfunction endfunction
function! s:snapshot(force, ...) abort function! s:snapshot(force, ...) abort

View File

@@ -7,19 +7,19 @@ Execute (#112 On-demand loading should not suppress messages from ftplugin):
redir => out redir => out
tabnew a.c tabnew a.c
redir END redir END
Assert stridx(out, 'ftplugin') >= 0 Assert stridx(out, 'ftplugin-c') >= 0
* The same applies to plug#load()) * The same applies to plug#load())
redir => out redir => out
call plug#load('ftplugin-msg') call plug#load('ftplugin-msg')
redir END redir END
Assert stridx(out, 'ftplugin') >= 0 Assert stridx(out, 'ftplugin-c') >= 0
q q
********************************************************************** **********************************************************************
Execute (#114 Should not contain empty path in &rtp): Execute (#114 Should not contain empty path in &rtp):
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
call plug#end() call plug#end()
Log &rtp Log &rtp
@@ -35,7 +35,7 @@ Execute (#130 Proper cleanup of on-demand loading triggers):
" Cleared on command " Cleared on command
call ReloadPlug() call ReloadPlug()
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/vim-emoji', { 'on': ['EmojiCommand', 'EmojiCommand2', '<Plug>(EmojiMapping)'] } Plug 'junegunn/vim-emoji', { 'on': ['EmojiCommand', 'EmojiCommand2', '<Plug>(EmojiMapping)'] }
call plug#end() call plug#end()
PlugInstall | q PlugInstall | q
@@ -52,7 +52,7 @@ Execute (#130 Proper cleanup of on-demand loading triggers):
" Cleared on FileType " Cleared on FileType
call ReloadPlug() call ReloadPlug()
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/vim-emoji', { 'on': ['EmojiCommandExtra', '<Plug>(EmojiMappingExtra)'], 'for': ['emoji'] } Plug 'junegunn/vim-emoji', { 'on': ['EmojiCommandExtra', '<Plug>(EmojiMappingExtra)'], 'for': ['emoji'] }
call plug#end() call plug#end()
@@ -78,13 +78,13 @@ Execute (#131 Syntax error):
********************************************************************** **********************************************************************
Execute (#139-1 Using new remote branch): Execute (#139-1 Using new remote branch):
" Make sure to remove the clone " Make sure to remove the clone
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
call plug#end() call plug#end()
PlugClean! PlugClean!
" Install master branch " Install master branch
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug expand('file:////tmp/new-branch') Plug expand('file:////tmp/vim-plug-test/new-branch')
call plug#end() call plug#end()
PlugUpdate PlugUpdate
@@ -95,14 +95,14 @@ Execute (#139-1 Using new remote branch):
Assert !exists('g:baz'), 'g:baz should not be found' Assert !exists('g:baz'), 'g:baz should not be found'
" Create a new branch on origin " Create a new branch on origin
call system('cd /tmp/new-branch && git checkout -b new &&' call system('cd /tmp/vim-plug-test/new-branch && git checkout -b new &&'
\. 'echo "let g:bar = 1" > plugin/bar.vim && git add plugin/bar.vim &&' \. 'echo "let g:bar = 1" > plugin/bar.vim && git add plugin/bar.vim &&'
\. 'git commit -m second') \. 'git commit -m second')
" We're setting up two plugins so that parallel installer is used " We're setting up two plugins so that parallel installer is used
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
Plug expand('file:////tmp/new-branch'), { 'branch': 'new' } Plug expand('file:////tmp/vim-plug-test/new-branch'), { 'branch': 'new' }
call plug#end() call plug#end()
PlugUpdate PlugUpdate
silent %y silent %y
@@ -125,14 +125,14 @@ Expect:
Execute (#139-2 Using yet another new remote branch): Execute (#139-2 Using yet another new remote branch):
" Create another branch on origin " Create another branch on origin
call system('cd /tmp/new-branch && git checkout master &&' call system('cd /tmp/vim-plug-test/new-branch && git checkout master &&'
\. 'git checkout -b brand-new &&' \. 'git checkout -b brand-new &&'
\. 'echo "let g:baz = 1" > plugin/baz.vim && git add plugin/baz.vim &&' \. 'echo "let g:baz = 1" > plugin/baz.vim && git add plugin/baz.vim &&'
\. 'git commit -m third') \. 'git commit -m third')
" Test Vim installer here " Test Vim installer here
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug expand('file:////tmp/new-branch'), { 'branch': 'brand-new' } Plug expand('file:////tmp/vim-plug-test/new-branch'), { 'branch': 'brand-new' }
call plug#end() call plug#end()
PlugUpdate PlugUpdate
silent %y silent %y
@@ -154,19 +154,19 @@ Expect:
Execute (#139-3 Should fail when not possible to fast-forward): Execute (#139-3 Should fail when not possible to fast-forward):
" Commit on cloned repo " Commit on cloned repo
call system('cd /tmp/plugged/new-branch && git checkout master &&' call system('cd /tmp/vim-plug-test/plugged/new-branch && git checkout master &&'
\. 'touch foobar && git add foobar && git commit -m foobar') \. 'touch foobar && git add foobar && git commit -m foobar')
" Different commit on remote " Different commit on remote
call system('cd /tmp/new-branch && git checkout master &&' call system('cd /tmp/vim-plug-test/new-branch && git checkout master &&'
\. 'touch foobaz && git add foobaz && git commit -m foobaz') \. 'touch foobaz && git add foobaz && git commit -m foobaz')
for multi in [0, 1] for multi in [0, 1]
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
if multi if multi
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
endif endif
Plug expand('file:////tmp/new-branch') Plug expand('file:////tmp/vim-plug-test/new-branch')
call plug#end() call plug#end()
PlugUpdate PlugUpdate
silent %y silent %y
@@ -210,7 +210,7 @@ Execute (#159: shell=/bin/tcsh):
let org = &shell let org = &shell
try try
set shell=/bin/tcsh set shell=/bin/tcsh
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
call plug#end() call plug#end()
@@ -224,7 +224,7 @@ Execute (#159: shell=/bin/tcsh):
********************************************************************** **********************************************************************
Execute (#154: Spaces in &rtp should not be escaped): Execute (#154: Spaces in &rtp should not be escaped):
call plug#begin('/tmp/plug it') call plug#begin('/tmp/vim-plug-test/plug it')
Plug 'seoul256 vim' Plug 'seoul256 vim'
call plug#end() call plug#end()
Log &rtp Log &rtp
@@ -232,7 +232,7 @@ Execute (#154: Spaces in &rtp should not be escaped):
********************************************************************** **********************************************************************
Execute (#184: Duplicate entries in &rtp): Execute (#184: Duplicate entries in &rtp):
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'plugin1' Plug 'plugin1'
\| Plug 'plugin0' \| Plug 'plugin0'
@@ -250,7 +250,7 @@ Execute (#236: Plugin removed from &rtp when .vimrc is reloaded):
silent! delc EasyAlign silent! delc EasyAlign
call ReloadPlug() call ReloadPlug()
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/vim-easy-align', { 'on': 'EasyAlign' } Plug 'junegunn/vim-easy-align', { 'on': 'EasyAlign' }
call plug#end() call plug#end()
PlugInstall | q PlugInstall | q
@@ -259,19 +259,19 @@ Execute (#236: Plugin removed from &rtp when .vimrc is reloaded):
%EasyAlign= %EasyAlign=
Assert &rtp =~ '/vim-easy-align', 'Plugin should be in &rtp' Assert &rtp =~ '/vim-easy-align', 'Plugin should be in &rtp'
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/vim-easy-align', { 'on': 'EasyAlign' } Plug 'junegunn/vim-easy-align', { 'on': 'EasyAlign' }
call plug#end() call plug#end()
Assert &rtp =~ '/vim-easy-align', 'Plugin should still be in &rtp' Assert &rtp =~ '/vim-easy-align', 'Plugin should still be in &rtp'
********************************************************************** **********************************************************************
Execute (#350: Ruby installer failed to unshallow tagged plugin on update): Execute (#350: Ruby installer failed to unshallow tagged plugin on update):
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
call plug#end() call plug#end()
PlugClean! PlugClean!
" Shallow clone. We should have at least 2 plugins to enable parallel installer. " Shallow clone. We should have at least 2 plugins to enable parallel installer.
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/vim-easy-align' Plug 'junegunn/vim-easy-align'
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
call plug#end() call plug#end()
@@ -279,7 +279,7 @@ Execute (#350: Ruby installer failed to unshallow tagged plugin on update):
Assert filereadable(g:plugs['vim-easy-align'].dir.'/.git/shallow') Assert filereadable(g:plugs['vim-easy-align'].dir.'/.git/shallow')
" Now unshallowed " Now unshallowed
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/vim-easy-align', { 'tag': '2.9.0' } Plug 'junegunn/vim-easy-align', { 'tag': '2.9.0' }
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
call plug#end() call plug#end()
@@ -289,16 +289,44 @@ Execute (#350: Ruby installer failed to unshallow tagged plugin on update):
********************************************************************** **********************************************************************
Execute (#474: Load ftdetect files in filetypedetect augroup): Execute (#474: Load ftdetect files in filetypedetect augroup):
call plug#begin('/tmp/plugged') call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/rust.vim', { 'for': 'rust', 'commit': '115d321d383eb96d438466c56cc871fcc1bd0faa' } Plug 'junegunn/rust.vim', { 'for': 'rust', 'commit': '115d321d383eb96d438466c56cc871fcc1bd0faa' }
call plug#end() call plug#end()
PlugInstall! PlugInstall!
q q
tabnew /tmp/any.rs tabnew /tmp/vim-plug-test/any.rs
AssertEqual 'rust', &filetype AssertEqual 'rust', &filetype
Log &filetype Log &filetype
filetype detect filetype detect
AssertEqual 'rust', &filetype AssertEqual 'rust', &filetype
Log &filetype Log &filetype
bd bd
**********************************************************************
Execute (#489 On-demand loading with 'on' option should trigger BufRead autocmd):
call plug#begin('$PLUG_FIXTURES')
Plug 'ftplugin-msg', { 'on': 'XXX' }
call plug#end()
tabnew a.java
redir => out
silent! XXX
redir END
Assert stridx(out, 'ftplugin-java') >= 0
q
**********************************************************************
Execute (Cursor moved to another window during post-update hook):
function! DoSplit(...)
new
call setline(1, 'empty')
endfunction
call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'junegunn/rust.vim', { 'do': function('DoSplit') }
call plug#end()
PlugInstall!
AssertEqual 1, line('$')
AssertEqual 'empty', getline(1)
q!
q

View File

@@ -6,9 +6,12 @@ export BASE="$PWD"
export PLUG_SRC="$PWD/../plug.vim" export PLUG_SRC="$PWD/../plug.vim"
export PLUG_FIXTURES="$PWD/fixtures" export PLUG_FIXTURES="$PWD/fixtures"
mkdir -p "$PLUG_FIXTURES" mkdir -p "$PLUG_FIXTURES"
export TEMP=/tmp/vim-plug-test
rm -rf "$TEMP"
mkdir -p "$TEMP"
cat > /tmp/mini-vimrc << VIMRC cat > $TEMP/mini-vimrc << VIMRC
set rtp+=/tmp/junegunn/vader.vim set rtp+=$TEMP/junegunn/vader.vim
set shell=/bin/bash set shell=/bin/bash
VIMRC VIMRC
@@ -19,7 +22,7 @@ clone() {
} }
clone_repos() ( clone_repos() (
cd /tmp cd $TEMP
mkdir -p junegunn vim-scripts jg mkdir -p junegunn vim-scripts jg
for repo in vader.vim goyo.vim rust.vim seoul256.vim vim-easy-align vim-fnr \ for repo in vader.vim goyo.vim rust.vim seoul256.vim vim-easy-align vim-fnr \
vim-oblique vim-pseudocl vim-redis vim-emoji; do vim-oblique vim-pseudocl vim-redis vim-emoji; do
@@ -77,10 +80,11 @@ DOC
rm -rf "$PLUG_FIXTURES/ftplugin-msg" rm -rf "$PLUG_FIXTURES/ftplugin-msg"
mkdir -p "$PLUG_FIXTURES/ftplugin-msg/ftplugin" mkdir -p "$PLUG_FIXTURES/ftplugin-msg/ftplugin"
echo "echomsg 'ftplugin'" > "$PLUG_FIXTURES/ftplugin-msg/ftplugin/c.vim" echo "echomsg 'ftplugin-c'" > "$PLUG_FIXTURES/ftplugin-msg/ftplugin/c.vim"
echo "echomsg 'ftplugin-java'" > "$PLUG_FIXTURES/ftplugin-msg/ftplugin/java.vim"
rm -rf /tmp/new-branch rm -rf $TEMP/new-branch
cd /tmp cd $TEMP
git init new-branch git init new-branch
cd new-branch cd new-branch
mkdir plugin mkdir plugin
@@ -108,10 +112,10 @@ git --version
VIM=$(select_vim) VIM=$(select_vim)
echo "Selected Vim: $VIM" echo "Selected Vim: $VIM"
if [ "$1" = '!' ]; then if [ "$1" = '!' ]; then
$VIM -Nu /tmp/mini-vimrc -c 'Vader! test.vader' > /dev/null && $VIM -Nu $TEMP/mini-vimrc -c 'Vader! test.vader' > /dev/null &&
prepare && prepare &&
$VIM -Nu /tmp/mini-vimrc -c 'let g:plug_threads = 1 | Vader! test.vader' > /dev/null $VIM -Nu $TEMP/mini-vimrc -c 'let g:plug_threads = 1 | Vader! test.vader' > /dev/null
else else
$VIM -Nu /tmp/mini-vimrc -c 'Vader test.vader' $VIM -Nu $TEMP/mini-vimrc -c 'Vader test.vader'
fi fi

View File

@@ -2,7 +2,7 @@ Execute (Initialize test environment):
Save &rtp, g:plugs, g:plug_home, g:plug_window Save &rtp, g:plugs, g:plug_home, g:plug_window
unlet! g:plugs g:plug_home g:plug_window unlet! g:plugs g:plug_home g:plug_window
let g:plug_url_format = 'file:///tmp/%s' let g:plug_url_format = 'file:///tmp/vim-plug-test/%s'
let g:base_rtp = &rtp let g:base_rtp = &rtp
let g:first_rtp = split(&rtp, ',')[0] let g:first_rtp = split(&rtp, ',')[0]
let g:last_rtp = split(&rtp, ',')[-1] let g:last_rtp = split(&rtp, ',')[-1]
@@ -14,8 +14,15 @@ Execute (Initialize test environment):
" Temporarily patch plug.vim " Temporarily patch plug.vim
call system('cp "$PLUG_SRC" "$PLUG_TMP"') call system('cp "$PLUG_SRC" "$PLUG_TMP"')
call writefile(extend(readfile($PLUG_TMP), let patch =
\ ['function! ResetPlug()', 'let s:loaded = {}', 'endfunction']), $PLUG_TMP) \ ['function! ResetPlug()', 'let s:loaded = {}', 'endfunction',
\ 'function! CompareURI(a, b)', 'return s:compare_git_uri(a:a, a:b)', 'endfunction']
if $ENV != 'vim8'
call add(patch, 'let s:vim8 = 0')
endif
call writefile(extend(readfile($PLUG_TMP), patch), $PLUG_TMP)
set t_Co=256 set t_Co=256
colo default colo default
@@ -69,14 +76,16 @@ Execute (Initialize test environment):
Execute (Print Interpreter Version): Execute (Print Interpreter Version):
redir => out redir => out
if has('ruby') if has('ruby')
silent ruby puts 'Ruby: ' + RUBY_VERSION silent! ruby puts 'Ruby: ' + RUBY_VERSION
elseif has('python') endif
silent python import sys; svi = sys.version_info; print 'Python: {}.{}.{}'.format(svi[0], svi[1], svi[2]) if has('python')
elseif has('python3') silent! python import sys; svi = sys.version_info; print 'Python: {}.{}.{}'.format(svi[0], svi[1], svi[2])
silent python3 import sys; svi = sys.version_info; print('Python: {}.{}.{}'.format(svi[0], svi[1], svi[2])) endif
if has('python3')
silent! python3 import sys; svi = sys.version_info; print('Python: {}.{}.{}'.format(svi[0], svi[1], svi[2]))
endif endif
redir END redir END
Log substitute(out, '\n', '', 'g') Log split(out, '\n')
Include: workflow.vader Include: workflow.vader
Include: regressions.vader Include: regressions.vader

View File

@@ -34,7 +34,7 @@ Execute (Subsequent plug#begin() calls will reuse g:plug_home):
Execute (Test Plug command): Execute (Test Plug command):
^ Git repo with branch (DEPRECATED. USE BRANCH OPTION) ^ Git repo with branch (DEPRECATED. USE BRANCH OPTION)
Plug 'junegunn/seoul256.vim', { 'branch': 'yes-t_co' } Plug 'junegunn/seoul256.vim', { 'branch': 'yes-t_co' }
AssertEqual 'file:///tmp/junegunn/seoul256.vim', g:plugs['seoul256.vim'].uri AssertEqual 'file:///tmp/vim-plug-test/junegunn/seoul256.vim', g:plugs['seoul256.vim'].uri
AssertEqual join([g:temp_plugged, 'seoul256.vim/'], '/'), g:plugs['seoul256.vim'].dir AssertEqual join([g:temp_plugged, 'seoul256.vim/'], '/'), g:plugs['seoul256.vim'].dir
AssertEqual 'yes-t_co', g:plugs['seoul256.vim'].branch AssertEqual 'yes-t_co', g:plugs['seoul256.vim'].branch
@@ -43,7 +43,7 @@ Execute (Test Plug command):
^ Git repo with tag (DEPRECATED. USE TAG OPTION) ^ Git repo with tag (DEPRECATED. USE TAG OPTION)
Plug 'junegunn/goyo.vim', '1.5.2' Plug 'junegunn/goyo.vim', '1.5.2'
AssertEqual 'file:///tmp/junegunn/goyo.vim', g:plugs['goyo.vim'].uri AssertEqual 'file:///tmp/vim-plug-test/junegunn/goyo.vim', g:plugs['goyo.vim'].uri
AssertEqual join([g:temp_plugged, 'goyo.vim/'], '/'), g:plugs['goyo.vim'].dir AssertEqual join([g:temp_plugged, 'goyo.vim/'], '/'), g:plugs['goyo.vim'].dir
AssertEqual '1.5.2', g:plugs['goyo.vim'].tag AssertEqual '1.5.2', g:plugs['goyo.vim'].tag
@@ -51,14 +51,14 @@ Execute (Test Plug command):
AssertEqual '1.5.3', g:plugs['goyo.vim'].tag AssertEqual '1.5.3', g:plugs['goyo.vim'].tag
" Git URI " Git URI
Plug 'file:///tmp/jg/vim-emoji' Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
AssertEqual 'file:///tmp/jg/vim-emoji', g:plugs['vim-emoji'].uri AssertEqual 'file:///tmp/vim-plug-test/jg/vim-emoji', g:plugs['vim-emoji'].uri
AssertEqual 'master', g:plugs['vim-emoji'].branch AssertEqual 'master', g:plugs['vim-emoji'].branch
AssertEqual join([g:temp_plugged, 'vim-emoji/'], '/'), g:plugs['vim-emoji'].dir AssertEqual join([g:temp_plugged, 'vim-emoji/'], '/'), g:plugs['vim-emoji'].dir
" vim-scripts/ " vim-scripts/
Plug 'beauty256' Plug 'beauty256'
AssertEqual 'file:///tmp/vim-scripts/beauty256', g:plugs.beauty256.uri AssertEqual 'file:///tmp/vim-plug-test/vim-scripts/beauty256', g:plugs.beauty256.uri
AssertEqual 'master', g:plugs.beauty256.branch AssertEqual 'master', g:plugs.beauty256.branch
AssertEqual 4, len(g:plugs) AssertEqual 4, len(g:plugs)
@@ -84,7 +84,7 @@ Execute (PlugClean before installation):
Execute (plug#end() updates &rtp): Execute (plug#end() updates &rtp):
" Plug 'junegunn/goyo.vim', { 'tag': '1.5.3' } " Plug 'junegunn/goyo.vim', { 'tag': '1.5.3' }
" Plug 'file:///tmp/jg/vim-emoji' " Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
" Plug 'beauty256' " Plug 'beauty256'
" Plug 'junegunn/seoul256.vim', { 'branch': 'no-t_co', 'rtp': '././' } " Plug 'junegunn/seoul256.vim', { 'branch': 'no-t_co', 'rtp': '././' }
call plug#end() call plug#end()
@@ -159,7 +159,7 @@ Expect:
Execute (Change branch of seoul256.vim): Execute (Change branch of seoul256.vim):
call plug#begin() call plug#begin()
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
Plug 'file:///tmp/jg/vim-emoji' Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
call plug#end() call plug#end()
Execute (PlugStatus): Execute (PlugStatus):
@@ -197,15 +197,15 @@ Expect:
Execute (Change URI of seoul256.vim): Execute (Change URI of seoul256.vim):
call plug#begin() call plug#begin()
Plug 'junegunn.choi/seoul256.vim' Plug 'junegunn.choi/seoul256.vim'
Plug 'file:///tmp/jg/vim-emoji' Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
call plug#end() call plug#end()
Execute (PlugStatus): Execute (PlugStatus):
call PlugStatusSorted() call PlugStatusSorted()
Expect: Expect:
Expected: file:///tmp/junegunn.choi/seoul256.vim Expected: file:///tmp/vim-plug-test/junegunn.choi/seoul256.vim
Invalid URI: file:///tmp/junegunn/seoul256.vim Invalid URI: file:///tmp/vim-plug-test/junegunn/seoul256.vim
PlugClean required. PlugClean required.
- vim-emoji: OK - vim-emoji: OK
Finished. 1 error(s). Finished. 1 error(s).
@@ -215,7 +215,7 @@ Expect:
Execute (Corrected the URI but diverged from master): Execute (Corrected the URI but diverged from master):
call plug#begin() call plug#begin()
Plug 'junegunn/seoul256.vim' Plug 'junegunn/seoul256.vim'
Plug 'file:///tmp/jg/vim-emoji' Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
call plug#end() call plug#end()
for _ in range(3) for _ in range(3)
call system(printf('cd "%s" && git commit --allow-empty -m "dummy"', g:plugs['seoul256.vim'].dir)) call system(printf('cd "%s" && git commit --allow-empty -m "dummy"', g:plugs['seoul256.vim'].dir))
@@ -240,8 +240,8 @@ Expect:
Execute (PlugClean! to remove seoul256.vim): Execute (PlugClean! to remove seoul256.vim):
PlugClean! PlugClean!
" Three removed, emoji left " Three removed, emoji left
AssertEqual 'Removed.', getline(4) AssertEqual 'Removed 3 directories.', getline(4)
AssertExpect '^- ', 3 AssertExpect '^\~ ', 3
AssertExpect 'Diverged', 1 AssertExpect 'Diverged', 1
Assert empty(globpath(&rtp, 'colors/seoul256.vim')) Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert !empty(globpath(&rtp, 'autoload/emoji.vim')) Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
@@ -257,8 +257,8 @@ Execute (PlugStatus):
call PlugStatusSorted() call PlugStatusSorted()
Expect: Expect:
Expected: file:///tmp/junegunn/vim-emoji Expected: file:///tmp/vim-plug-test/junegunn/vim-emoji
Invalid URI: file:///tmp/jg/vim-emoji Invalid URI: file:///tmp/vim-plug-test/jg/vim-emoji
Not found. Try PlugInstall. Not found. Try PlugInstall.
PlugClean required. PlugClean required.
Finished. 2 error(s). Finished. 2 error(s).
@@ -268,8 +268,8 @@ Expect:
Execute (PlugClean! to remove vim-emoji): Execute (PlugClean! to remove vim-emoji):
PlugClean! PlugClean!
AssertExpect '^- ', 1 AssertExpect '^\~ ', 1
AssertEqual 'Removed.', getline(4) AssertEqual 'Removed 1 directories.', getline(4)
Assert empty(globpath(&rtp, 'colors/seoul256.vim')) Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert empty(globpath(&rtp, 'autoload/emoji.vim')) Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
q q
@@ -300,7 +300,7 @@ Execute (PlugDiff - 'No updates.'):
Execute (New commits on remote, PlugUpdate, then PlugDiff): Execute (New commits on remote, PlugUpdate, then PlugDiff):
for repo in ['seoul256.vim', 'vim-emoji'] for repo in ['seoul256.vim', 'vim-emoji']
for _ in range(2) for _ in range(2)
call system(printf('cd /tmp/junegunn/%s && git commit --allow-empty -m "update"', repo)) call system(printf('cd /tmp/vim-plug-test/junegunn/%s && git commit --allow-empty -m "update"', repo))
endfor endfor
endfor endfor
unlet repo unlet repo
@@ -365,6 +365,22 @@ Execute (New commits on remote, PlugUpdate, then PlugDiff):
AssertEqual 1, &previewwindow AssertEqual 1, &previewwindow
pclose pclose
Execute (Test g:plug_pwindow):
let g:plug_pwindow = 'below 5new'
PlugDiff
AssertExpect '^- ', 1
execute "normal ]]jo"
AssertEqual 0, &previewwindow
AssertEqual 1, winnr()
wincmd P
AssertEqual 1, &previewwindow
AssertEqual 2, winnr()
AssertEqual 5, winheight('.')
wincmd p
normal q
unlet g:plug_pwindow
Execute (Reuse Plug window in another tab): Execute (Reuse Plug window in another tab):
let tabnr = tabpagenr() let tabnr = tabpagenr()
PlugDiff PlugDiff
@@ -596,7 +612,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 RmRf(fzf) call RmRf(fzf)
Log system(printf('cp -r "/tmp/fzf" "%s"', fzf)) Log system(printf('cp -r "/tmp/vim-plug-test/fzf" "%s"', fzf))
Execute (PlugUpdate still should not care): Execute (PlugUpdate still should not care):
PlugUpdate PlugUpdate
@@ -769,7 +785,7 @@ Execute (On update):
call plug#end() call plug#end()
" New commits on remote " New commits on remote
call system('cd /tmp/junegunn/vim-pseudocl && git commit --allow-empty -m "update"') call system('cd /tmp/vim-plug-test/junegunn/vim-pseudocl && git commit --allow-empty -m "update"')
silent PlugUpdate silent PlugUpdate
Log getline(1, '$') Log getline(1, '$')
@@ -841,7 +857,12 @@ Execute (PlugUpdate!):
Execute (When submodules are not initialized): Execute (When submodules are not initialized):
call system(printf('cd %s && git submodule deinit subsubmodule', g:plugs['subsubmodule'].dir)) call system(printf('cd %s && git submodule deinit subsubmodule', g:plugs['subsubmodule'].dir))
^ #481 submodule update should use standard shell
let sh = &shell
set sh=/bin/echo
silent PlugUpdate! silent PlugUpdate!
let &shell = sh
unlet sh
q q
AssertEqual ' ', system(printf('cd %s && git submodule status', g:plugs['subsubmodule'].dir))[0], AssertEqual ' ', system(printf('cd %s && git submodule status', g:plugs['subsubmodule'].dir))[0],
\ 'subsubmodule/subsubmodule should be initialized' \ 'subsubmodule/subsubmodule should be initialized'
@@ -856,7 +877,7 @@ Execute (Using Funcref):
Plug 'junegunn/vim-pseudocl', { 'do': function('PlugUpdated') } Plug 'junegunn/vim-pseudocl', { 'do': function('PlugUpdated') }
call plug#end() call plug#end()
call system('cd /tmp/junegunn/vim-easy-align && git commit --allow-empty -m "update"') call system('cd /tmp/vim-plug-test/junegunn/vim-easy-align && git commit --allow-empty -m "update"')
call system('cd '.g:plugs['vim-easy-align'].dir.' && git reset --hard HEAD^') call system('cd '.g:plugs['vim-easy-align'].dir.' && git reset --hard HEAD^')
call RmRf(g:plugs['vim-pseudocl'].dir) call RmRf(g:plugs['vim-pseudocl'].dir)
@@ -916,8 +937,8 @@ Execute (Should not run when failed to update):
call system(printf('cd %s && git remote set-url origin xxx', g:plugs['vim-easy-align'].dir)) call system(printf('cd %s && git remote set-url origin xxx', g:plugs['vim-easy-align'].dir))
" New commits on remote " New commits on remote
call system('cd /tmp/junegunn/vim-easy-align && git commit --allow-empty -m "update"') call system('cd /tmp/vim-plug-test/junegunn/vim-easy-align && git commit --allow-empty -m "update"')
call system('cd /tmp/junegunn/vim-pseudocl && git commit --allow-empty -m "update"') call system('cd /tmp/vim-plug-test/junegunn/vim-pseudocl && git commit --allow-empty -m "update"')
silent PlugUpdate silent PlugUpdate
Log getline(1, '$') Log getline(1, '$')
@@ -928,18 +949,52 @@ Execute (Should not run when failed to update):
Assert filereadable(g:plugs['vim-pseudocl'].dir.'/not-failed'), Assert filereadable(g:plugs['vim-pseudocl'].dir.'/not-failed'),
\ 'vim-pseudocl/not-failed should exist' \ 'vim-pseudocl/not-failed should exist'
Execute (Vim command with : prefix):
call plug#begin()
Plug 'junegunn/vim-pseudocl', { 'do': ':call setline(2, 12345)' }
call plug#end()
PlugInstall!
Log getline(1, '$')
AssertEqual '12345', getline(2)
q
Execute (Vim command with : prefix closing the window):
call plug#begin()
Plug 'junegunn/vim-pseudocl', { 'do': ':close' }
call plug#end()
redir => out
PlugInstall!
redir END
Assert out =~ 'vim-plug was terminated'
Assert out =~ 'of vim-pseudocl'
Execute (Invalid vim command in post-update hook):
call plug#begin()
Plug 'junegunn/vim-pseudocl', { 'do': ':nosuchcommand' }
call plug#end()
PlugInstall!
Log getline(1, '$')
AssertExpect! 'x Post-update hook for vim-pseudocl ... Vim:E492: Not an editor command: nosuchcommand', 1
q
********************************************************************** **********************************************************************
~ Overriding `dir` ~ Overriding `dir`
********************************************************************** **********************************************************************
Execute (Using custom dir): Execute (Using custom dir):
call plug#begin()
Plug 'junegunn/vim-easy-align'
call plug#end()
Assert isdirectory(g:plugs['vim-easy-align'].dir) Assert isdirectory(g:plugs['vim-easy-align'].dir)
call RmRf('/tmp/easy-align') call RmRf('/tmp/vim-plug-test/easy-align')
call plug#begin() call plug#begin()
Plug 'junegunn/vim-easy-align', { 'dir': '/tmp/easy-align' } Plug 'junegunn/vim-easy-align', { 'dir': '/tmp/vim-plug-test/easy-align' }
call plug#end() call plug#end()
AssertEqual '/tmp/easy-align/', g:plugs['vim-easy-align'].dir AssertEqual '/tmp/vim-plug-test/easy-align/', g:plugs['vim-easy-align'].dir
PlugClean! PlugClean!
Assert !isdirectory(g:plugs['vim-easy-align'].dir) Assert !isdirectory(g:plugs['vim-easy-align'].dir)
@@ -1255,11 +1310,11 @@ Execute (PlugClean should not try to remove unmanaged plugins inside g:plug_home
" Remove z1, z2 " Remove z1, z2
PlugClean! PlugClean!
AssertExpect '^- ', 2 AssertExpect '^\~ ', 2
AssertExpect 'Already clean', 0 AssertExpect 'Already clean', 0
PlugClean! PlugClean!
AssertExpect '^- ', 0 AssertExpect '^\~ ', 0
AssertExpect 'Already clean', 1 AssertExpect 'Already clean', 1
q q
@@ -1363,8 +1418,9 @@ Execute (Commit hash support):
call plug#end() call plug#end()
PlugUpdate PlugUpdate
Log getline(1, '$') Log getline(1, '$')
AssertEqual 'x goyo.vim: error: pathspec ''ffffffff'' did not match any file(s) known to git.', getline(5) AssertEqual 'x goyo.vim:', getline(5)
AssertEqual 0, stridx(getline(6), '- vim-emoji: HEAD is now at 9db7fcf...') AssertEqual ' error: pathspec ''ffffffff'' did not match any file(s) known to git.', getline(6)
AssertEqual 0, stridx(getline(7), '- vim-emoji: HEAD is now at 9db7fcf...')
let hash = system(printf('cd %s && git rev-parse HEAD', g:plugs['vim-emoji'].dir))[:-2] let hash = system(printf('cd %s && git rev-parse HEAD', g:plugs['vim-emoji'].dir))[:-2]
AssertEqual '9db7fcfee0d90dafdbcb7a32090c0a9085eb054a', hash AssertEqual '9db7fcfee0d90dafdbcb7a32090c0a9085eb054a', hash
@@ -1419,10 +1475,10 @@ Execute (#371 - 'as' option):
Assert g:plugs.yogo.dir =~# '/yogo/$' Assert g:plugs.yogo.dir =~# '/yogo/$'
call plug#begin() call plug#begin()
Plug 'junegunn/goyo.vim', {'as': 'yogo', 'dir': '/tmp/gogo'} Plug 'junegunn/goyo.vim', {'as': 'yogo', 'dir': '/tmp/vim-plug-test/gogo'}
call plug#end() call plug#end()
AssertEqual ['yogo'], sort(keys(g:plugs)) AssertEqual ['yogo'], sort(keys(g:plugs))
AssertEqual '/tmp/gogo/', g:plugs.yogo.dir AssertEqual '/tmp/vim-plug-test/gogo/', g:plugs.yogo.dir
Execute (#427 - Tag option with wildcard (requires git 1.9.2 or above)): Execute (#427 - Tag option with wildcard (requires git 1.9.2 or above)):
if str2nr(split(split(system('git --version'))[-1], '\.')[0]) < 2 if str2nr(split(split(system('git --version'))[-1], '\.')[0]) < 2
@@ -1437,3 +1493,57 @@ Execute (#427 - Tag option with wildcard (requires git 1.9.2 or above)):
q q
AssertEqual '2.9.7', GitTag('vim-easy-align') AssertEqual '2.9.7', GitTag('vim-easy-align')
endif endif
Execute (#530 - Comparison of compatible git URIs):
" .git suffix
Assert CompareURI('https://github.com/junegunn/vim-plug.git', 'https://github.com/junegunn/vim-plug')
" user@
Assert CompareURI('https://github.com/junegunn/vim-plug.git', 'https://user@github.com/junegunn/vim-plug.git')
" git::@
Assert CompareURI('https://github.com/junegunn/vim-plug.git', 'https://git::@github.com/junegunn/vim-plug.git')
" https and ssh
Assert CompareURI('https://github.com/junegunn/vim-plug.git', 'git@github.com:junegunn/vim-plug.git')
" file://
Assert CompareURI('file:///tmp/vim-plug', '/tmp/vim-plug')
Assert CompareURI('file:///tmp/vim-plug', '/tmp/vim-plug/')
Execute (#530 - Comparison of incompatible git URIs):
" Different hostname
Assert !CompareURI('https://github.com/junegunn/vim-plug.git', 'https://bitbucket.com/junegunn/vim-plug.git')
" Different repository
Assert !CompareURI('https://github.com/junegunn/vim-plug.git', 'https://github.com/junegunn/emacs-plug.git')
" Different port
Assert !CompareURI('https://github.com/junegunn/vim-plug.git', 'https://github.com:12345/junegunn/vim-plug.git')
Execute (#532 - Reuse plug window):
call plug#begin()
Plug 'junegunn/goyo.vim'
call plug#end()
PlugInstall
call system(printf('cd "%s" && git commit --allow-empty -m "dummy"', g:plugs['goyo.vim'].dir))
PlugDiff
AssertEqual 1, winnr()
AssertEqual 2, winnr('$')
" Open preview window
execute "normal ]]jo"
AssertEqual 2, winnr()
AssertEqual 3, winnr('$')
" Move plug window to the right
wincmd L
AssertEqual 3, winnr()
AssertEqual 3, winnr('$')
" Reuse plug window. Preview window is closed.
PlugStatus
AssertEqual 2, winnr()
AssertEqual 2, winnr('$')
q