83 Commits

Author SHA1 Message Date
Junegunn Choi
b6050d6f03 Allow cloning into an empty directory (#782)
Close #766

We can rely on git to check if the destination directory is empty.
2018-09-12 13:45:38 +09:00
Junegunn Choi
7f8fdd0444 Ignore useless use of on-demand loading (#786) 2018-09-12 13:40:33 +09:00
Samuel D. Leslie
8ed2617ba0 Add support for parallel fetching of Git submodules (#784)
Git v2.8 introduced support for parallel fetching of submodules. This
can result in a substantial performance boost when performing a "git
submodule update" in a repository with many submodules, potentially
further magnified when updating submodules recursively.

This commit introduces a check on the Git version to see if it supports
parallel submodule fetching. If it does, we add the '--jobs=N' argument
to our call to "git submodule update", where N is g:plug_threads or the
vim-plug default of 16.
2018-09-06 14:48:54 +09:00
Árni Dagur
0a255ee62d Clear colorcolumn in vim-plug buffer (#779) 2018-08-08 10:52:00 +09:00
dohq
e0ca037a4f has('win32') is enough for detecting Windows (#765) 2018-06-20 18:18:50 +09:00
Junegunn Choi
f80eed7379 Add <plug>(plug-preview) map (#769)
This allows you to override the default behavior of `o' or `<cr>'
binding in PlugDiff window.

e.g.
    " Move to preview window
    autocmd! FileType vim-plug nmap <buffer> o <plug>(plug-preview)<c-w>P

Close #749
Close #768
2018-06-20 18:09:06 +09:00
WADA Takashi
fef4e434ba Fix Windows batch file format (#755)
`writefile()` always output LF without CR each lines.
But batch file on Windows needs CR and LF, at end of lines.

And if the path of home directory contains non-ASCII
characters like Japanese username (e.g. `C:\Users\太郎`),
batch file without CR can't be executed correctly.
2018-05-12 11:21:17 +09:00
Daniel Hahler
e6a775e0df Fix handling of changed up-to-date msg from Git (#724)
The msg was changed from 'Already up-to-date' to 'Already up to date'.
2018-03-04 13:43:13 +09:00
Junegunn Choi
96375cb7d3 Update README and add vim help file
Close #705
2017-11-27 00:58:29 +09:00
Junegunn Choi
2f4dc4d482 Add link to automatic installation instructions
Close #711
2017-11-27 00:15:46 +09:00
Daniel Hahler
9813d5ead5 Display not-loaded status with all plugins that have a dir (#547) 2017-10-15 18:12:15 +09:00
Junegunn Choi
ddc67fc136 Fix helptags generation for plugins with custom rtp
Close #684
2017-09-25 00:00:03 +09:00
Junegunn Choi
cd44b03db2 Remove extra quotes in PlugDiff output (#680) 2017-09-20 11:28:52 +09:00
Jan Edmund Lazo
4f95bce2f4 Fix PlugDiff for Windows (#681)
Close #680
2017-09-20 11:02:54 +09:00
Jan Edmund Lazo
7f96c98b0a Prepend 'silent' to ':!' to avoid hit-enter prompt (#678)
Close #606

Fix for GVim on Windows.
2017-09-19 13:53:35 +09:00
Jan Edmund Lazo
05c8983d1a Port fzf#shellescape (#676)
Close #635
Close #668
Close #539

Use a temporary batchfile for :!, system(), and jobs and run it in cmd.exe.
This bypasses Vim/Neovim issues in Windows and reduces the need to set more options.
Also, s:shellesc_cmd works in a batchfile only.

Set shellredir for system() in Windows
$SHELL sets the default value of 'shell' (see :h 'shell').
This affects shellredir but cmd.exe requires '>%s 2>&1'.
2017-09-19 10:37:22 +09:00
Junegunn Choi
b93975f794 Fix Travis CI build (dist: trusty) (#670) 2017-09-10 03:38:38 +09:00
Junegunn Choi
88cc9d7868 Create LICENSE 2017-07-10 13:21:14 +09:00
Andrew Pennebaker
cd39fa6133 Hard-wrap installation instructions for Windows (#649)
Long snippets are sometimes difficult to fully select in a Web browser.
Hard wrapping snippets to make them easier to grab.
2017-07-01 00:26:04 +09:00
Junegunn Choi
449b4f1ed6 Disallow using standard Vim plugin directory as plug home
Close #646
2017-06-27 17:44:12 +09:00
Junegunn Choi
802b100415 Extend plug#load to process a list of names instead of varargs
Allows `call plug#load(keys(g:plugs))` for manually loading all plugins
at once. Close #638.
2017-06-06 16:17:31 +09:00
Junegunn Choi
06992bcfb9 Update installation instruction for Neovim on Windows (#634)
Close #633
2017-05-19 03:17:46 +09:00
Junegunn Choi
f7e6a86807 Deprecate implicit vim-scripts expansion
vim-scripts.org is no longer maintained.

Close #625
2017-05-01 21:31:57 +09:00
Daniel Hahler
61ffb61615 Travis: VADER_OUTPUT_FILE=/dev/stderr for neovim (#618) 2017-04-17 02:47:15 +09:00
Daniel Hahler
9dcab48628 Load plugins only once in plug#load (#616)
When loading 'deoplete.nvim' for the 2nd time during InsertEnter
manually, the `s:dobufread` (or `s:lod` itself) prevents it to work
properly - likely because the plugin gets resourced.

Maybe there could be a way to force this (and reload plugins always),
but by default it seems to make sense to skip already loaded plugins.
2017-04-17 02:46:02 +09:00
Andrew Nowak
1d3c88292b Fix invalid diagnosis of PlugStatus with wildcard tags (#619) 2017-04-14 10:13:49 +09:00
Justin M. Keyes
580f0a559c nvim: Enable job-control nvim 0.2+ (#617)
Closes #583
References https://github.com/neovim/neovim/pull/6497
2017-04-12 11:10:09 +09:00
Junegunn Choi
46ae29985d Proper escaping of tag patterns
Close #610
2017-04-04 17:45:37 +09:00
Christian Rondeau
7f4e6cb843 Fix crlf in clones under cygwin (#608)
Close #497
2017-03-13 01:09:25 +09:00
Junegunn Choi
769192d3d0 Append -- to git checkout commands
Checking out a branch or tag may not succeed if there is a path entry
with the same name. This commit appends -- to git checkout commands to
clarify that we're not referring to a file or a directory.

Close #602
2017-02-26 03:35:45 +09:00
Junegunn Choi
e3252aae2c Commit hash in PlugDiff output can be longer than 7 characters
Close #597
2017-02-17 13:33:32 +09:00
Junegunn Choi
f551a71688 Add plugin to &rtp before running post-update hook with : prefix
Close #593
2017-02-11 23:27:52 +09:00
Junegunn Choi
e80a93d5d0 Fix Ruby installer on macOS system Vim
- Do not use io/console
- Interrupting threads crashes Vim, so don't do it

Close #592
Related #537, #538
2017-02-11 11:17:47 +09:00
Junegunn Choi
d1ac3cdd1f Do not use nomodeline when triggering BufRead
Close #587
2017-02-03 13:29:05 +09:00
Nikita Slepogin
359a65230e Fix job_start with spaces in path in Windows (#588)
Close #586 
Close #565
2017-01-31 21:19:48 +09:00
Junegunn Choi
5e6bd469ac Update README 2017-01-30 02:20:36 +09:00
Junegunn Choi
8c1aff151d Update README 2017-01-30 02:19:53 +09:00
Junegunn Choi
d6bda025f1 Fix Vim 8 installer on Windows when path contains spaces
Close #565
2017-01-29 18:23:05 +09:00
Junegunn Choi
5fc9eab788 Add --sync flag to Plug{Install,Update}
Installer is not synchronous when started on VimEnter since
has('vim_starting') returns 0 in that case. We needed a way to make the
installer synchronous.

Related: #574
2017-01-04 02:00:00 +09:00
Junegunn Choi
93ffcb36de Commit preview should work with non-POSIX-compliant &shell
Close #572
2017-01-02 13:06:51 +09:00
Daniel Hahler
d5e9f91c7b Travis CI: sudo: false (#561) 2017-01-01 12:08:09 +09:00
Daniel Hahler
0b1343b582 test/run: shellcheck fixes (#562) 2016-12-30 11:29:00 +09:00
Junegunn Choi
f916aabfbe Update documentation
/cc @accolade
2016-12-19 01:59:24 +09:00
Junegunn Choi
b50f9bb16b More description on plug#end
Related: #379
2016-12-18 12:12:57 +09:00
Junegunn Choi
8180692f81 Update usage examples
vim-plug has no support for dependencies. Remove comment that has been
a source of confusion. #544
2016-12-18 12:06:19 +09:00
Junegunn Choi
a4aac4cf56 Do not check Ruby interface when parallel update is not needed
In case Ruby interface is completely broken that simply running
`:ruby require 'thread'` crashes Vim.

Close #564
2016-12-13 12:26:13 +09:00
Marco Hinz
5bccd9bc98 Neovim: use "dict" when referring to "self" (#566) 2016-12-13 12:25:46 +09:00
Daniel Hahler
1540764563 git_validate: better error with checkout being ahead/diverged (#546) 2016-12-11 21:43:44 +09:00
Daniel Hahler
b9022d9046 test/workflow.vader: minor Assert improvement (#563) 2016-12-11 21:25:33 +09:00
Junegunn Choi
c53ecd3acd Update installation instruction for Neovim
Suggest directories conforming to XDG Base Directory Specification.

Close #559
2016-12-10 18:25:21 +09:00
Junegunn Choi
ca0b726f46 Merge pull request #558 from HiPhish/nospell
Do not check spelling in vim-plug buffers
2016-12-04 01:03:05 +09:00
HiPhish
942f994844 Do not check spelling in vim-plug buffers 2016-12-03 12:30:51 +01:00
Junegunn Choi
6ad18f5fb8 Ignore trailing ! in proxy command name
Close #557
2016-11-26 12:22:55 +09:00
Junegunn Choi
46ddb4af2d Set the default completion type of proxy command to "file"
Though we do not know the completion type of a command until the command
is loaded, setting it to file seems like the best thing we can do.
2016-11-10 12:03:37 +09:00
Junegunn Choi
54683aa2c7 Merge pull request #552 from midchildan/fix-git-version
Fix git version detection
2016-11-04 00:38:09 +09:00
midchildan
8f38888fad Fix git version detection. 2016-11-03 22:38:45 +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
9 changed files with 1093 additions and 214 deletions

View File

@@ -1,4 +1,5 @@
language: ruby
dist: trusty
sudo: false
env:
global:
@@ -6,7 +7,7 @@ env:
- PATH=$DEPS/bin:$PATH
matrix:
include:
- env: ENV=nox
- env: ENV=vim72
rvm: 1.8.7
addons: { apt: { packages: [vim-nox] } }
- env: ENV=python
@@ -15,18 +16,27 @@ matrix:
- env: ENV=python3
rvm: 1.8.7
addons: { apt: { packages: [python3-dev] } }
- env: ENV=ruby
- env: ENV=ruby18
rvm: 1.8.7
- env: ENV=ruby
- env: ENV=ruby20
rvm: 2.0.0
- env: ENV=neovim
- env: ENV=vim8
install: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
if [ "$ENV" == "nox" ]; then
if [ "$ENV" == "vim72" ]; then
mkdir -p ${DEPS}/bin
ln -s /usr/bin/vim.nox ${DEPS}/bin/vim
return
elif [ "$ENV" == "neovim" ]; then
# https://github.com/neovim/bot-ci#nightly-builds
eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) nightly-x64"
mkdir -p ${DEPS}/bin
ln -s $(which nvim) ${DEPS}/bin/vim
export VADER_OUTPUT_FILE=/dev/stderr
return
fi
C_OPTS="--prefix=$DEPS --with-features=huge --disable-gui "
@@ -37,13 +47,14 @@ install: |
python3)
C_OPTS+=--enable-python3interp
;;
ruby)
ruby*)
C_OPTS+=--enable-rubyinterp
;;
esac
git clone --depth 1 https://github.com/vim/vim
cd vim
export PATH=/usr/bin:$PATH
./configure $C_OPTS
make
make install

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Junegunn Choi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -10,7 +10,7 @@ A minimalist Vim plugin manager.
- Easier to setup: Single file. No boilerplate code required.
- Easier to use: Concise, intuitive syntax
- [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
- On-demand loading for [faster startup time][startup-time]
- Can review and rollback updates
@@ -20,13 +20,15 @@ A minimalist Vim plugin manager.
[40/4]: https://raw.githubusercontent.com/junegunn/i/master/vim-plug/40-in-4.gif
[nv]: http://neovim.org/
[startup-time]: http://junegunn.kr/images/vim-startup-time.png
[startup-time]: https://github.com/junegunn/vim-startuptime-benchmark#result
### Installation
[Download plug.vim](https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim)
and put it in the "autoload" directory.
#### Vim
###### Unix
```sh
@@ -34,27 +36,55 @@ curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```
###### Neovim
You can automate the process by putting the command in your Vim configuration
file as suggested [here][auto].
```sh
curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```
[auto]: https://github.com/junegunn/vim-plug/wiki/tips#automatic-installation
###### Windows (PowerShell)
```powershell
md ~\vimfiles\autoload
$uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
(New-Object Net.WebClient).DownloadFile($uri, $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("~\vimfiles\autoload\plug.vim"))
(New-Object Net.WebClient).DownloadFile(
$uri,
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
"~\vimfiles\autoload\plug.vim"
)
)
```
#### Neovim
###### Unix
```sh
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```
###### Windows (PowerShell)
```powershell
md ~\AppData\Local\nvim\autoload
$uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
(New-Object Net.WebClient).DownloadFile(
$uri,
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
"~\AppData\Local\nvim\autoload\plug.vim"
)
)
```
### Getting Help
- See the [requirements] page for debugging information & tested configurations.
- See the [FAQ] for common problems and questions.
- Create an [issue](https://github.com/junegunn/vim-plug/issues/new).
- See [tutorial] page to learn the basics of vim-plug
- See [tips] and [FAQ] pages for common problems and questions
- See [requirements] page for debugging information & tested configurations
- Create an [issue](https://github.com/junegunn/vim-plug/issues/new)
[tutorial]: https://github.com/junegunn/vim-plug/wiki/tutorial
[tips]: https://github.com/junegunn/vim-plug/wiki/tips
[FAQ]: https://github.com/junegunn/vim-plug/wiki/faq
[requirements]: https://github.com/junegunn/vim-plug/wiki/requirements
@@ -65,10 +95,15 @@ Add a vim-plug section to your `~/.vimrc` (or `~/.config/nvim/init.vim` for Neov
1. Begin the section with `call plug#begin()`
1. List the plugins with `Plug` commands
1. `call plug#end()` to update `&runtimepath` and initialize plugin system
- Automatically executes `filetype plugin indent on` and `syntax enable`.
You can revert the settings after the call. e.g. `filetype indent off`, `syntax off`, etc.
#### Example
```vim
" Specify a directory for plugins
" - For Neovim: ~/.local/share/nvim/plugged
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')
" Make sure you use single quotes
@@ -79,7 +114,7 @@ Plug 'junegunn/vim-easy-align'
" Any valid git URL is allowed
Plug 'https://github.com/junegunn/vim-github-dashboard.git'
" Group dependencies, vim-snippets depends on ultisnips
" Multiple Plug commands can be written in a single line using | separators
Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
" On-demand loading
@@ -101,7 +136,7 @@ Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
" Unmanaged plugin (manually installed and updated)
Plug '~/my-prototype-plugin'
" Add plugins to &runtimepath
" Initialize plugin system
call plug#end()
```

376
doc/plug.txt Normal file
View File

@@ -0,0 +1,376 @@
plug.txt plug Last change: November 27 2017
PLUG - TABLE OF CONTENTS *plug* *plug-toc*
==============================================================================
vim-plug
Pros.
Installation
Vim
Unix
Windows (PowerShell)
Neovim
Unix
Windows (PowerShell)
Getting Help
Usage
Example
Commands
Plug options
Global options
Keybindings
Example: A small sensible Vim configuration
On-demand loading of plugins
Post-update hooks
PlugInstall! and PlugUpdate!
Articles
License
VIM-PLUG *vim-plug*
==============================================================================
A minimalist Vim plugin manager.
https://raw.githubusercontent.com/junegunn/i/master/vim-plug/installer.gif
< Pros. >_____________________________________________________________________~
*plug-pros*
- Easier to setup: Single file. No boilerplate code required.
- Easier to use: Concise, intuitive syntax
- {Super-fast}{1} parallel installation/update (with any of `+job`, `+python`,
`+python3`, `+ruby`, or {Neovim}{2})
- Creates shallow clones to minimize disk space usage and download time
- On-demand loading for {faster startup time}{3}
- Can review and rollback updates
- Branch/tag/commit support
- Post-update hooks
- Support for externally managed plugins
{1} https://raw.githubusercontent.com/junegunn/i/master/vim-plug/40-in-4.gif
{2} http://neovim.org/
{3} https://github.com/junegunn/vim-startuptime-benchmark#result
< Installation >______________________________________________________________~
*plug-installation*
{Download plug.vim}{4} and put it in the "autoload" directory.
{4} https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
Vim~
*plug-vim*
>> Unix~
>
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
<
You can automate the process by putting the command in your Vim configuration
file as suggested {here}{5}.
{5} https://github.com/junegunn/vim-plug/wiki/tips#automatic-installation
>> Windows (PowerShell)~
>
md ~\vimfiles\autoload
$uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
(New-Object Net.WebClient).DownloadFile(
$uri,
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
"~\vimfiles\autoload\plug.vim"
)
)
<
Neovim~
*plug-neovim*
>> Unix~
>
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
<
>> Windows (PowerShell)~
>
md ~\AppData\Local\nvim\autoload
$uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
(New-Object Net.WebClient).DownloadFile(
$uri,
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
"~\AppData\Local\nvim\autoload\plug.vim"
)
)
<
< Getting Help >______________________________________________________________~
*plug-getting-help*
- See {tutorial}{6} page to learn the basics of vim-plug
- See {tips}{7} and {FAQ}{8} pages for common problems and questions
- See {requirements}{9} page for debugging information & tested configurations
- Create an {issue}{10}
{6} https://github.com/junegunn/vim-plug/wiki/tutorial
{7} https://github.com/junegunn/vim-plug/wiki/tips
{8} https://github.com/junegunn/vim-plug/wiki/faq
{9} https://github.com/junegunn/vim-plug/wiki/requirements
{10} https://github.com/junegunn/vim-plug/issues/new
< Usage >_____________________________________________________________________~
*plug-usage*
Add a vim-plug section to your `~/.vimrc` (or `~/.config/nvim/init.vim` for
Neovim):
*plug#begin* *plug#end*
1. Begin the section with `callplug#begin()`
2. List the plugins with `Plug` commands
3. `callplug#end()` to update 'runtimepath' and initialize plugin system
- Automatically executes `filetypepluginindenton` and `syntaxenable`.
You can revert the settings after the call. e.g. `filetypeindentoff`,
`syntaxoff`, etc.
Example~
*plug-example*
>
" Specify a directory for plugins
" - For Neovim: ~/.local/share/nvim/plugged
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')
" Make sure you use single quotes
" Shorthand notation; fetches https://github.com/junegunn/vim-easy-align
Plug 'junegunn/vim-easy-align'
" Any valid git URL is allowed
Plug 'https://github.com/junegunn/vim-github-dashboard.git'
" Multiple Plug commands can be written in a single line using | separators
Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
" On-demand loading
Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" Using a non-master branch
Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
" Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
Plug 'fatih/vim-go', { 'tag': '*' }
" Plugin options
Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' }
" Plugin outside ~/.vim/plugged with post-update hook
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
" Unmanaged plugin (manually installed and updated)
Plug '~/my-prototype-plugin'
" Initialize plugin system
call plug#end()
<
*:PlugInstall*
Reload .vimrc and `:PlugInstall` to install plugins.
< Commands >__________________________________________________________________~
*plug-commands*
------------------------------------+-------------------------------------------------------------------
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` | Examine changes from the previous update and the pending changes
`PlugSnapshot[!][outputpath]` | Generate script for restoring the current snapshot of the plugins
------------------------------------+-------------------------------------------------------------------
< Plug options >______________________________________________________________~
*plug-options*
------------------------+-----------------------------------------------
Option | Description ~
------------------------+-----------------------------------------------
`branch` / `tag` / `commit` | Branch/tag/commit of the repository to use
`rtp` | Subdirectory that contains Vim plugin
`dir` | Custom directory for the plugin
`as` | Use different name for the plugin
`do` | Post-update hook (string or funcref)
`on` | On-demand loading: Commands or <Plug>-mappings
`for` | On-demand loading: File types
`frozen` | Do not update unless explicitly specified
------------------------+-----------------------------------------------
< Global options >____________________________________________________________~
*plug-global-options*
*g:plug_threads* *g:plug_timeout* *g:plug_retries* *g:plug_shallow* *g:plug_window*
*g:plug_pwindow* *g:plug_url_format*
--------------------+-----------------------------------+-----------------------------------------------------------------------------------
Flag | Default | Description ~
--------------------+-----------------------------------+-----------------------------------------------------------------------------------
`g:plug_threads` | 16 | Default number of threads to use
`g:plug_timeout` | 60 | Time limit of each task in seconds (Ruby & Python)
`g:plug_retries` | 2 | Number of retries in case of timeout (Ruby & Python)
`g:plug_shallow` | 1 | Use shallow clone
`g:plug_window` | `verticaltopleftnew` | Command to open plug window
`g:plug_pwindow` | `above12new` | 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)
--------------------+-----------------------------------+-----------------------------------------------------------------------------------
< Keybindings >_______________________________________________________________~
*plug-keybindings*
*:PlugStatus* *:PlugDiff*
- `D` - `PlugDiff`
- `S` - `PlugStatus`
- `R` - Retry failed update or installation tasks
- `U` - Update plugins in the selected range
- `q` - Close the window
- `:PlugStatus`
- `L` - Load plugin
- `:PlugDiff`
- `X` - Revert the update
< Example: A small sensible Vim configuration >_______________________________~
*plug-example-a-small-sensible-vim-configuration*
>
call plug#begin()
Plug 'tpope/vim-sensible'
call plug#end()
<
< On-demand loading of plugins >______________________________________________~
*plug-on-demand-loading-of-plugins*
>
" NERD tree will be loaded on the first invocation of NERDTreeToggle command
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' }
" Multiple file types
Plug 'kovisoft/paredit', { 'for': ['clojure', 'scheme'] }
" On-demand loading on both conditions
Plug 'junegunn/vader.vim', { 'on': 'Vader', 'for': 'vader' }
" Code to execute when the plugin is lazily loaded on demand
Plug 'junegunn/goyo.vim', { 'for': 'markdown' }
autocmd! User goyo.vim echom 'Goyo is now loaded!'
<
`for` option is generally not needed as most plugins for specific file types
usually don't have too much code in `plugin` directory. You might want to
examine the output of `vim--startuptime` before applying the option.
< Post-update hooks >_________________________________________________________~
*plug-post-update-hooks*
There are some plugins that require extra steps after installation or update.
In that case, use `do` option to describe the task to be performed.
>
Plug 'Shougo/vimproc.vim', { 'do': 'make' }
Plug 'Valloric/YouCompleteMe', { 'do': './install.py' }
<
If the value starts with `:`, it will be recognized as a Vim command.
*:GoInstallBinaries*
>
Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries' }
<
If you need more control, you can pass a reference to a Vim function that
takes a single argument.
>
function! BuildYCM(info)
" info is a dictionary with 3 fields
" - name: name of the plugin
" - status: 'installed', 'updated', or 'unchanged'
" - force: set on PlugInstall! or PlugUpdate!
if a:info.status == 'installed' || a:info.force
!./install.py
endif
endfunction
Plug 'Valloric/YouCompleteMe', { 'do': function('BuildYCM') }
<
Both forms of post-update hook are executed inside the directory of the plugin
and only run when the repository has changed, but you can force it to run
unconditionally with the bang-versions of the commands: `PlugInstall!` and
`PlugUpdate!`.
Make sure to escape BARs and double-quotes when you write `do` option inline
as they are mistakenly recognized as command separator or the start of the
trailing comment.
>
Plug 'junegunn/fzf', { 'do': 'yes \| ./install' }
<
But you can avoid the escaping if you extract the inline specification using a
variable (or any Vimscript expression) as follows:
*g:fzf_install*
>
let g:fzf_install = 'yes | ./install'
Plug 'junegunn/fzf', { 'do': g:fzf_install }
<
< PlugInstall! and PlugUpdate! >______________________________________________~
*pluginstall-and-plugupdate*
The installer takes the following steps when installing/updating a plugin:
1. `gitclone` or `gitfetch` from its origin
2. Check out branch, tag, or commit and optionally `gitmerge` remote branch
3. If the plugin was updated (or installed for the first time)
1. Update submodules
2. Execute post-update hooks
The commands with `!` suffix ensure that all steps are run unconditionally.
< Articles >__________________________________________________________________~
*plug-articles*
- {Writing my own Vim plugin manager}{11}
- {Vim plugins and startup time}{12}
- ~~{Thoughts on Vim plugin dependency}{13}~~
- Support for Plugfile has been removed since 0.5.0
{11} http://junegunn.kr/2013/09/writing-my-own-vim-plugin-manager
{12} http://junegunn.kr/2014/07/vim-plugins-and-startup-time
{13} http://junegunn.kr/2013/09/thoughts-on-vim-plugin-dependency
< License >___________________________________________________________________~
*plug-license*
MIT
==============================================================================
vim:tw=78:sw=2:ts=2:ft=help:norl:nowrap:

443
plug.vim
View File

@@ -18,7 +18,7 @@
" " Any valid git URL is allowed
" Plug 'https://github.com/junegunn/vim-github-dashboard.git'
"
" " Group dependencies, vim-snippets depends on ultisnips
" " Multiple Plug commands can be written in a single line using | separators
" Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
"
" " On-demand loading
@@ -40,7 +40,7 @@
" " Unmanaged plugin (manually installed and updated)
" Plug '~/my-prototype-plugin'
"
" " Add plugins to &runtimepath
" " Initialize plugin system
" call plug#end()
"
" Then reload .vimrc and :PlugInstall to install plugins.
@@ -61,7 +61,7 @@
" More information: https://github.com/junegunn/vim-plug
"
"
" Copyright (c) 2016 Junegunn Choi
" Copyright (c) 2017 Junegunn Choi
"
" MIT License
"
@@ -96,8 +96,9 @@ let s:plug_src = 'https://github.com/junegunn/vim-plug.git'
let s:plug_tab = get(s:, 'plug_tab', -1)
let s:plug_buf = get(s:, 'plug_buf', -1)
let s:mac_gui = has('gui_macvim') && has('gui_running')
let s:is_win = has('win32') || has('win64')
let s:nvim = has('nvim') && exists('*jobwait') && !s:is_win
let s:is_win = has('win32')
let s:nvim = has('nvim-0.2') || (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:base_spec = { 'branch': 'master', 'frozen': 0 }
let s:TYPE = {
@@ -120,6 +121,9 @@ function! plug#begin(...)
else
return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.')
endif
if fnamemodify(home, ':t') ==# 'plugin' && fnamemodify(home, ':h') ==# s:first_rtp
return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.')
endif
let g:plug_home = home
let g:plugs = {}
@@ -189,6 +193,14 @@ function! s:ask_no_interrupt(...)
endtry
endfunction
function! s:lazy(plug, opt)
return has_key(a:plug, a:opt) &&
\ (empty(s:to_a(a:plug[a:opt])) ||
\ !isdirectory(a:plug.dir) ||
\ len(s:glob(s:rtp(a:plug), 'plugin')) ||
\ len(s:glob(s:rtp(a:plug), 'after/plugin')))
endfunction
function! plug#end()
if !exists('g:plugs')
return s:err('Call plug#begin() first')
@@ -202,13 +214,15 @@ function! plug#end()
endif
let lod = { 'ft': {}, 'map': {}, 'cmd': {} }
if exists('g:did_load_filetypes')
filetype off
endif
for name in g:plugs_order
if !has_key(g:plugs, name)
continue
endif
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) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for')
let s:loaded[name] = 1
continue
endif
@@ -222,6 +236,7 @@ function! plug#end()
endif
call add(s:triggers[name].map, cmd)
elseif cmd =~# '^[A-Z]'
let cmd = substitute(cmd, '!*$', '', '')
if exists(':'.cmd) != 2
call s:assoc(lod.cmd, cmd, name)
endif
@@ -248,7 +263,7 @@ function! plug#end()
for [cmd, names] in items(lod.cmd)
execute printf(
\ 'command! -nargs=* -range -bang %s call s:lod_cmd(%s, "<bang>", <line1>, <line2>, <q-args>, %s)',
\ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "<bang>", <line1>, <line2>, <q-args>, %s)',
\ cmd, string(cmd), string(names))
endfor
@@ -256,8 +271,8 @@ function! plug#end()
for [mode, map_prefix, key_prefix] in
\ [['i', '<C-O>', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
execute printf(
\ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, "%s")<CR>',
\ mode, map, map_prefix, string(map), string(names), key_prefix)
\ '%snoremap <silent> %s %s:<C-U>call <SID>lod_map(%s, %s, %s, "%s")<CR>',
\ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix)
endfor
endfor
@@ -309,7 +324,7 @@ endfunction
function! s:git_version_requirement(...)
if !exists('s:git_version')
let s:git_version = map(split(split(s:system('git --version'))[-1], '\.'), 'str2nr(v:val)')
let s:git_version = map(split(split(s:system('git --version'))[2], '\.'), 'str2nr(v:val)')
endif
return s:version_requirement(s:git_version, a:000)
endfunction
@@ -398,7 +413,7 @@ function! s:reorg_rtp()
let s:middle = get(s:, 'middle', &rtp)
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, ",")'), ',')
\ . ','.s:middle.','
\ . join(map(afters, 'escape(v:val, ",")'), ',')
@@ -422,7 +437,10 @@ function! s:dobufread(names)
let path = s:rtp(g:plugs[name]).'/**'
for dir in ['ftdetect', 'ftplugin']
if len(finddir(dir, path))
return s:doautocmd('BufRead')
if exists('#BufRead')
doautocmd BufRead
endif
return
endif
endfor
endfor
@@ -435,16 +453,21 @@ function! plug#load(...)
if !exists('g:plugs')
return s:err('plug#begin was not called')
endif
let unknowns = filter(copy(a:000), '!has_key(g:plugs, v:val)')
let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000
let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)')
if !empty(unknowns)
let s = len(unknowns) > 1 ? 's' : ''
return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', ')))
end
for name in a:000
let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)')
if !empty(unloaded)
for name in unloaded
call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
endfor
call s:dobufread(a:000)
call s:dobufread(unloaded)
return 1
end
return 0
endfunction
function! s:remove_triggers(name)
@@ -497,7 +520,7 @@ function! s:lod_cmd(cmd, bang, l1, l2, args, names)
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, names, prefix)
function! s:lod_map(map, names, with_prefix, prefix)
call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
call s:dobufread(a:names)
let extra = ''
@@ -508,14 +531,19 @@ function! s:lod_map(map, names, prefix)
endif
let extra .= nr2char(c)
endwhile
if v:count
call feedkeys(v:count, 'n')
endif
call feedkeys('"'.v:register, 'n')
if a:with_prefix
let prefix = v:count ? v:count : ''
let prefix .= '"'.v:register.a:prefix
if mode(1) == 'no'
call feedkeys(v:operator)
if v:operator == 'c'
let prefix = "\<esc>" . prefix
endif
call feedkeys(a:prefix . substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
let prefix .= v:operator
endif
call feedkeys(prefix, 'n')
endif
call feedkeys(substitute(a:map, '^<Plug>', "\<Plug>", '') . extra)
endfunction
function! plug#(repo, ...)
@@ -563,13 +591,12 @@ function! s:infer_properties(name, repo)
let uri = repo
else
if repo !~ '/'
let repo = 'vim-scripts/'. repo
throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo)
endif
let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git')
let uri = printf(fmt, repo)
endif
let dir = s:dirpath( fnamemodify(join([g:plug_home, a:name], '/'), ':p') )
return { 'dir': dir, 'uri': uri }
return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri }
endif
endfunction
@@ -586,7 +613,7 @@ function! plug#helptags()
return s:err('plug#begin was not called')
endif
for spec in values(g:plugs)
let docd = join([spec.dir, 'doc'], '/')
let docd = join([s:rtp(spec), 'doc'], '/')
if isdirectory(docd)
silent! execute 'helptags' s:esc(docd)
endif
@@ -610,10 +637,10 @@ function! s:syntax()
syn match plugTag /(tag: [^)]\+)/
syn match plugInstall /\(^+ \)\@<=[^:]*/
syn match plugUpdate /\(^* \)\@<=[^:]*/
syn match plugCommit /^ \X*[0-9a-f]\{7} .*/ contains=plugRelDate,plugEdge,plugTag
syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag
syn match plugEdge /^ \X\+$/
syn match plugEdge /^ \X*/ contained nextgroup=plugSha
syn match plugSha /[0-9a-f]\{7}/ contained
syn match plugSha /[0-9a-f]\{7,9}/ contained
syn match plugRelDate /([^)]*)$/ contained
syn match plugNotLoaded /(not loaded)$/
syn match plugError /^x.*/
@@ -723,10 +750,14 @@ function! s:prepare(...)
call s:job_abort()
if s:switch_in()
normal q
if b:plug_preview == 1
pc
endif
enew
else
call s:new_window()
endif
call s:new_window()
nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>bd<cr>
if a:0 == 0
call s:finish_bindings()
@@ -739,7 +770,10 @@ function! s:prepare(...)
for k in ['<cr>', 'L', 'o', 'X', 'd', 'dd']
execute 'silent! unmap <buffer>' k
endfor
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell
if exists('+colorcolumn')
setlocal colorcolumn=
endif
setf vim-plug
if exists('g:syntax_on')
call s:syntax()
@@ -759,8 +793,10 @@ function! s:assign_name()
endfunction
function! s:chsh(swap)
let prev = [&shell, &shellredir]
if !s:is_win && a:swap
let prev = [&shell, &shellcmdflag, &shellredir]
if s:is_win
set shell=cmd.exe shellcmdflag=/c shellredir=>%s\ 2>&1
elseif a:swap
set shell=sh shellredir=>%s\ 2>&1
endif
return prev
@@ -768,15 +804,23 @@ endfunction
function! s:bang(cmd, ...)
try
let [sh, shrd] = s:chsh(a:0)
let [sh, shellcmdflag, shrd] = s:chsh(a:0)
" FIXME: Escaping is incomplete. We could use shellescape with eval,
" but it won't work on Windows.
let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
let g:_plug_bang = '!'.escape(cmd, '#!%')
if s:is_win
let batchfile = tempname().'.bat'
call writefile(["@echo off\r", cmd . "\r"], batchfile)
let cmd = batchfile
endif
let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%')
execute "normal! :execute g:_plug_bang\<cr>\<cr>"
finally
unlet g:_plug_bang
let [&shell, &shellredir] = [sh, shrd]
let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
if s:is_win
call delete(batchfile)
endif
endtry
return v:shell_error ? 'Exit status: ' . v:shell_error : ''
endfunction
@@ -805,8 +849,20 @@ function! s:do(pull, force, todo)
let type = type(spec.do)
if type == s:TYPE.string
if spec.do[0] == ':'
if !get(s:loaded, name, 0)
let s:loaded[name] = 1
call s:reorg_rtp()
endif
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
@@ -841,7 +897,7 @@ function! s:checkout(spec)
let output = s:system('git rev-parse HEAD', a:spec.dir)
if !v:shell_error && !s:hash_match(sha, s:lines(output)[0])
let output = s:system(
\ 'git fetch --depth 999999 && git checkout '.s:esc(sha), a:spec.dir)
\ 'git fetch --depth 999999 && git checkout '.s:esc(sha).' --', a:spec.dir)
endif
return output
endfunction
@@ -863,7 +919,7 @@ function! s:finish(pull)
call add(msgs, "Press 'R' to retry.")
endif
if a:pull && len(s:update.new) < len(filter(getline(5, '$'),
\ "v:val =~ '^- ' && stridx(v:val, 'Already up-to-date') < 0"))
\ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'"))
call add(msgs, "Press 'D' to see the updated changes.")
endif
echo join(msgs, ' ')
@@ -899,7 +955,8 @@ function! s:check_ruby()
endfunction
function! s:update_impl(pull, force, args) abort
let args = copy(a:args)
let sync = index(a:args, '--sync') >= 0 || has('vim_starting')
let args = filter(copy(a:args), 'v:val != "--sync"')
let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ?
\ remove(args, -1) : get(g:, 'plug_threads', 16)
@@ -933,8 +990,9 @@ function! s:update_impl(pull, force, args) abort
call s:warn('echom', '[vim-plug] Update Neovim for parallel installer')
endif
let python = (has('python') || has('python3')) && (!s:nvim || has('vim_starting'))
let ruby = has('ruby') && !s:nvim && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && s:check_ruby()
let use_job = s:nvim || s:vim8
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')) && threads > 1 && s:check_ruby()
let s:update = {
\ 'start': reltime(),
@@ -944,7 +1002,7 @@ function! s:update_impl(pull, force, args) abort
\ 'pull': a:pull,
\ 'force': a:force,
\ 'new': {},
\ 'threads': (python || ruby || s:nvim) ? min([len(todo), threads]) : 1,
\ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1,
\ 'bar': '',
\ 'fin': 0
\ }
@@ -957,8 +1015,14 @@ function! s:update_impl(pull, force, args) abort
let s:clone_opt = get(g:, 'plug_shallow', 1) ?
\ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : ''
if has('win32unix')
let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input'
endif
let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : ''
" 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
silent python import platform; print platform.python_version()
redir END
@@ -999,6 +1063,12 @@ function! s:update_impl(pull, force, args) abort
endtry
else
call s:update_vim()
while use_job && sync
sleep 100m
if s:update.fin
break
endif
endwhile
endif
endfunction
@@ -1014,7 +1084,7 @@ function! s:update_finish()
if s:switch_in()
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))'))
let pos = s:logpos(name)
let [pos, _] = s:logpos(name)
if !pos
continue
endif
@@ -1024,7 +1094,7 @@ function! s:update_finish()
elseif has_key(spec, 'tag')
let tag = spec.tag
if tag =~ '\*'
let tags = s:lines(s:system('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir))
let tags = s:lines(s:system('git tag --list '.s:shellesc(tag).' --sort -version:refname 2>&1', spec.dir))
if !v:shell_error && !empty(tags)
let tag = tags[0]
call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
@@ -1032,31 +1102,37 @@ function! s:update_finish()
endif
endif
call s:log4(name, 'Checking out '.tag)
let out = s:system('git checkout -q '.s:esc(tag).' 2>&1', spec.dir)
let out = s:system('git checkout -q '.s:esc(tag).' -- 2>&1', spec.dir)
else
let branch = s:esc(get(spec, 'branch', 'master'))
call s:log4(name, 'Merging origin/'.branch)
let out = s:system('git checkout -q '.branch.' 2>&1'
let out = s:system('git checkout -q '.branch.' -- 2>&1'
\. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir)
endif
if !v:shell_error && filereadable(spec.dir.'/.gitmodules') &&
\ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir))
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'.s:submodule_opt.' 2>&1', spec.dir)
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
call add(s:update.errors, name)
call s:regress_bar()
silent execute pos 'd _'
call append(4, msg) | 4
elseif !empty(out)
call setline(pos, msg)
call setline(pos, msg[0])
endif
redraw
endfor
silent 4 d _
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 setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.')
call s:switch_out('normal! gg')
@@ -1064,12 +1140,16 @@ function! s:update_finish()
endfunction
function! s:job_abort()
if !s:nvim || !exists('s:jobs')
if (!s:nvim && !s:vim8) || !exists('s:jobs')
return
endif
for [name, j] in items(s:jobs)
if s:nvim
silent! call jobstop(j.jobid)
elseif s:vim8
silent! call job_stop(j.jobid)
endif
if j.new
call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir))
endif
@@ -1077,59 +1157,92 @@ function! s:job_abort()
let s:jobs = {}
endfunction
" When a:event == 'stdout', data = list of strings
" When a:event == 'exit', data = returncode
function! s:job_handler(job_id, data, event) abort
if !s:plug_window_exists() " plug window closed
return s:job_abort()
function! s:last_non_empty_line(lines)
let len = len(a:lines)
for idx in range(len)
let line = a:lines[len-idx-1]
if !empty(line)
return line
endif
endfor
return ''
endfunction
if a:event == 'stdout'
let complete = empty(a:data[-1])
let lines = map(filter(a:data, 'len(v:val) > 0'), 'split(v:val, "[\r\n]")[-1]')
function! s:job_out_cb(self, data) abort
let self = a:self
let data = remove(self.lines, -1) . a:data
let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]')
call extend(self.lines, lines)
let self.result = join(self.lines, "\n")
if !complete
call remove(self.lines, -1)
endif
" To reduce the number of buffer updates
let self.tick = get(self, 'tick', -1) + 1
if self.tick % len(s:jobs) == 0
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()
if !self.running || self.tick % len(s:jobs) == 0
let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-')
let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines)
call s:log(bullet, self.name, result)
endif
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) dict 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)
let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [], 'result': '',
\ 'new': get(a:opts, 'new', 0),
\ 'on_stdout': function('s:job_handler'),
\ 'on_exit' : function('s:job_handler'),
\ }
let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
\ 'batchfile': (s:is_win && (s:nvim || s:vim8)) ? tempname().'.bat' : '',
\ 'new': get(a:opts, 'new', 0) }
let s:jobs[a:name] = job
let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd
if !empty(job.batchfile)
call writefile(["@echo off\r", cmd . "\r"], job.batchfile)
let cmd = job.batchfile
endif
let argv = add(s:is_win ? ['cmd', '/c'] : ['sh', '-c'], cmd)
if s:nvim
let argv = [ 'sh', '-c',
\ (has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd) ]
call extend(job, {
\ 'on_stdout': function('s:nvim_cb'),
\ 'on_exit': function('s:nvim_cb'),
\ })
let jid = jobstart(argv, job)
if jid > 0
let job.jobid = jid
else
let job.running = 0
let job.error = 1
let job.result = jid < 0 ? 'sh is not executable' :
\ 'Invalid arguments (or job table is full)'
let job.lines = [jid < 0 ? argv[0].' is not executable' :
\ 'Invalid arguments (or job table is full)']
endif
elseif s:vim8
let jid = job_start(s:is_win ? join(argv, ' ') : 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
else
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', [cmd]))
let job.error = v:shell_error != 0
let job.running = 0
endif
@@ -1144,9 +1257,14 @@ function! s:reap(name)
endif
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()
if has_key(job, 'batchfile') && !empty(job.batchfile)
call delete(job.batchfile)
endif
call remove(s:jobs, a:name)
endfunction
@@ -1163,23 +1281,31 @@ endfunction
function! s:logpos(name)
for i in range(4, line('$'))
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
endfor
return [0, 0]
endfunction
function! s:log(bullet, name, lines)
if s:switch_in()
let pos = s:logpos(a:name)
if pos > 0
silent execute pos 'd _'
if pos > winheight('.')
let pos = 4
let [b, e] = s:logpos(a:name)
if b > 0
silent execute printf('%d,%d d _', b, e)
if b > winheight('.')
let b = 4
endif
else
let pos = 4
let b = 4
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()
endif
endfunction
@@ -1193,19 +1319,19 @@ endfunction
function! s:tick()
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
if empty(s:update.todo)
if empty(s:jobs) && !s:update.fin
let s:update.fin = 1
call s:update_finish()
let s:update.fin = 1
endif
return
endif
let name = keys(s:update.todo)[0]
let spec = remove(s:update.todo, name)
let new = !isdirectory(spec.dir)
let new = empty(globpath(spec.dir, '.git', 1))
call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
redraw
@@ -1218,10 +1344,10 @@ while 1 " Without TCO, Vim stack is bound to explode
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 })
else
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 }
let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 }
endif
else
let s:jobs[name] = { 'running': 0, 'result': error, 'error': 1 }
let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 }
endif
else
call s:spawn(name,
@@ -1507,10 +1633,12 @@ class Plugin(object):
return result[-1]
def update(self):
match = re.compile(r'git::?@')
actual_uri = re.sub(match, '', self.repo_uri())
expect_uri = re.sub(match, '', self.args['uri'])
if actual_uri != expect_uri:
actual_uri = self.repo_uri()
expect_uri = self.args['uri']
regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$')
ma = regex.match(actual_uri)
mb = regex.match(expect_uri)
if ma is None or mb is None or ma.groups() != mb.groups():
msg = ['',
'Invalid URI: {0}'.format(actual_uri),
'Expected {0}'.format(expect_uri),
@@ -1669,6 +1797,11 @@ function! s:update_ruby()
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 'fileutils'
require 'timeout'
@@ -1681,6 +1814,7 @@ function! s:update_ruby()
tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1
nthr = VIM::evaluate('s:update.threads').to_i
maxy = VIM::evaluate('winheight(".")').to_i
vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/
cd = iswin ? 'cd /d' : 'cd'
tot = VIM::evaluate('len(s:update.todo)') || 0
bar = ''
@@ -1770,12 +1904,17 @@ function! s:update_ruby()
main = Thread.current
threads = []
watcher = Thread.new {
if vim7
while VIM::evaluate('getchar(1)')
sleep 0.1
end
else
require 'io/console' # >= Ruby 1.9
nil until IO.console.getch == 3.chr
end
mtx.synchronize do
running = false
threads.each { |t| t.raise Interrupt }
threads.each { |t| t.raise Interrupt } unless vim7
end
threads.each { |t| t.join rescue nil }
main.kill
@@ -1810,7 +1949,7 @@ function! s:update_ruby()
else
[false, [data.chomp, "PlugClean required."].join($/)]
end
elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '')
elsif !compare_git_uri(current_uri, uri)
[false, ["Invalid URI: #{current_uri}",
"Expected: #{uri}",
"PlugClean required."].join($/)]
@@ -1843,8 +1982,19 @@ function! s:update_ruby()
EOF
endfunction
function! s:shellesc_cmd(arg)
let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g')
let escaped = substitute(escaped, '%', '%%', 'g')
let escaped = substitute(escaped, '"', '\\^&', 'g')
let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g')
return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"'
endfunction
function! s:shellesc(arg)
return '"'.escape(a:arg, '"').'"'
if &shell =~# 'cmd.exe$'
return s:shellesc_cmd(a:arg)
endif
return shellescape(a:arg)
endfunction
function! s:glob_dir(path)
@@ -1856,9 +2006,15 @@ function! s:progress_bar(line, bar, total)
endfunction
function! s:compare_git_uri(a, b)
let a = substitute(a:a, 'git:\{1,2}@', '', '')
let b = substitute(a:b, 'git:\{1,2}@', '', '')
return a ==# b
" See `git help clone'
" https:// [user@] github.com[:port] / junegunn/vim-plug [.git]
" [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
function! s:format_message(bullet, name, message)
@@ -1876,11 +2032,19 @@ endfunction
function! s:system(cmd, ...)
try
let [sh, shrd] = s:chsh(1)
let [sh, shellcmdflag, shrd] = s:chsh(1)
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
if s:is_win
let batchfile = tempname().'.bat'
call writefile(["@echo off\r", cmd . "\r"], batchfile)
let cmd = batchfile
endif
return system(s:is_win ? '('.cmd.')' : cmd)
finally
let [&shell, &shellredir] = [sh, shrd]
let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
if s:is_win
call delete(batchfile)
endif
endtry
endfunction
@@ -1915,7 +2079,7 @@ function! s:git_validate(spec, check_branch)
" Check tag
if has_key(a:spec, 'tag')
let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
if a:spec.tag !=# tag
if a:spec.tag !=# tag && a:spec.tag !~ '\*'
let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.',
\ (empty(tag) ? 'N/A' : tag), a:spec.tag)
endif
@@ -1925,10 +2089,21 @@ function! s:git_validate(spec, check_branch)
\ branch, a:spec.branch)
endif
if empty(err)
let commits = len(s:lines(s:system(printf('git rev-list origin/%s..HEAD', a:spec.branch), a:spec.dir)))
if !v:shell_error && commits
let err = join([printf('Diverged from origin/%s by %d commit(s).', a:spec.branch, commits),
\ 'Reinstall after PlugClean.'], "\n")
let [ahead, behind] = split(s:lastline(s:system(printf(
\ 'git rev-list --count --left-right HEAD...origin/%s',
\ a:spec.branch), a:spec.dir)), '\t')
if !v:shell_error && ahead
if behind
" Only mention PlugClean if diverged, otherwise it's likely to be
" pushable (and probably not that messed up).
let err = printf(
\ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n"
\ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind)
else
let err = printf("Ahead of origin/%s by %d commit(s).\n"
\ .'Cannot update until local changes are pushed.',
\ a:spec.branch, ahead)
endif
endif
endif
endif
@@ -2084,15 +2259,16 @@ function! s:status()
let unloaded = 0
let [cnt, total] = [0, len(g:plugs)]
for [name, spec] in items(g:plugs)
let is_dir = isdirectory(spec.dir)
if has_key(spec, 'uri')
if isdirectory(spec.dir)
if is_dir
let [err, _] = s:git_validate(spec, 1)
let [valid, msg] = [empty(err), empty(err) ? 'OK' : err]
else
let [valid, msg] = [0, 'Not found. Try PlugInstall.']
endif
else
if isdirectory(spec.dir)
if is_dir
let [valid, msg] = [1, 'OK']
else
let [valid, msg] = [0, 'Not found.']
@@ -2101,7 +2277,7 @@ function! s:status()
let cnt += 1
let ecnt += !valid
" `s:loaded` entry can be missing if PlugUpgraded
if valid && get(s:loaded, name, -1) == 0
if is_dir && get(s:loaded, name, -1) == 0
let unloaded = 1
let msg .= ' (not loaded)'
endif
@@ -2171,7 +2347,7 @@ function! s:preview_commit()
let b:plug_preview = !s:is_preview_window_open()
endif
let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7}')
let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}')
if empty(sha)
return
endif
@@ -2189,7 +2365,21 @@ function! s:preview_commit()
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
try
let [sh, shellcmdflag, shrd] = s:chsh(1)
let cmd = 'cd '.s:shellesc(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha
if s:is_win
let batchfile = tempname().'.bat'
call writefile(["@echo off\r", cmd . "\r"], batchfile)
let cmd = batchfile
endif
execute 'silent %!' cmd
finally
let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
if s:is_win
call delete(batchfile)
endif
endtry
setlocal nomodifiable
nnoremap <silent> <buffer> q :q<cr>
wincmd p
@@ -2230,7 +2420,7 @@ function! s:diff()
call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
for [k, v] in plugs
let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..'
let diff = s:system_chomp('git log --graph --color=never --pretty=format:"%x01%h%x01%d%x01%s%x01%cr" '.s:shellesc(range), v.dir)
let diff = s:system_chomp('git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 's:shellesc(v:val)')), v.dir)
if !empty(diff)
let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : ''
call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)')))
@@ -2249,8 +2439,13 @@ function! s:diff()
\ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : ''))
if cnts[0] || cnts[1]
nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr>
nnoremap <silent> <buffer> o :silent! call <SID>preview_commit()<cr>
nnoremap <silent> <buffer> <plug>(plug-preview) :silent! call <SID>preview_commit()<cr>
if empty(maparg("\<cr>", 'n'))
nmap <buffer> <cr> <plug>(plug-preview)
endif
if empty(maparg('o', 'n'))
nmap <buffer> o <plug>(plug-preview)
endif
endif
if cnts[0]
nnoremap <silent> <buffer> X :call <SID>revert()<cr>
@@ -2271,7 +2466,7 @@ function! s:revert()
return
endif
call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch), g:plugs[name].dir)
call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch).' --', g:plugs[name].dir)
setlocal modifiable
normal! "_dap
setlocal nomodifiable

View File

@@ -1,5 +1,6 @@
**********************************************************************
Execute (#112 On-demand loading should not suppress messages from ftplugin):
call ResetPlug()
call plug#begin('$PLUG_FIXTURES')
Plug '$PLUG_FIXTURES/ftplugin-msg', { 'for': 'c' }
call plug#end()
@@ -7,13 +8,14 @@ Execute (#112 On-demand loading should not suppress messages from ftplugin):
redir => out
tabnew a.c
redir END
Assert stridx(out, 'ftplugin-c') >= 0
Assert stridx(out, 'ftplugin-c') >= 0, 'Unexpected output (1): '.out
* The same applies to plug#load())
call ResetPlug()
redir => out
call plug#load('ftplugin-msg')
redir END
Assert stridx(out, 'ftplugin-c') >= 0
Assert stridx(out, 'ftplugin-c') >= 0, 'Unexpected output (2): '.out
q
@@ -39,6 +41,7 @@ Execute (#130 Proper cleanup of on-demand loading triggers):
Plug 'junegunn/vim-emoji', { 'on': ['EmojiCommand', 'EmojiCommand2', '<Plug>(EmojiMapping)'] }
call plug#end()
PlugInstall | q
call mkdir(g:plugs['vim-emoji'].dir.'/after/plugin', 'p')
Assert exists(':EmojiCommand'), 'EmojiCommand not defined'
Assert exists(':EmojiCommand2'), 'EmojiCommand2 not defined'
@@ -89,10 +92,11 @@ Execute (#139-1 Using new remote branch):
PlugUpdate
unlet! g:foo g:bar g:baz
call ResetPlug()
call plug#load('new-branch')
Assert exists('g:foo'), 'g:foo should be found'
Assert !exists('g:bar'), 'g:bar should not be found'
Assert !exists('g:baz'), 'g:baz should not be found'
Assert exists('g:foo'), 'g:foo should be found (1)'
Assert !exists('g:bar'), 'g:bar should not be found (1)'
Assert !exists('g:baz'), 'g:baz should not be found (1)'
" Create a new branch on origin
call system('cd /tmp/vim-plug-test/new-branch && git checkout -b new &&'
@@ -110,10 +114,11 @@ Execute (#139-1 Using new remote branch):
Assert @" !~? 'error', 'Should be able to use new remote branch: ' . @"
unlet! g:foo g:bar g:baz
call ResetPlug()
call plug#load('new-branch')
Assert exists('g:foo'), 'g:foo should be found'
Assert exists('g:bar'), 'g:bar should be found'
Assert !exists('g:baz'), 'g:baz should not be found'
Assert exists('g:foo'), 'g:foo should be found (2)'
Assert exists('g:bar'), 'g:bar should be found (2)'
Assert !exists('g:baz'), 'g:baz should not be found (2)'
call PlugStatusSorted()
@@ -140,6 +145,7 @@ Execute (#139-2 Using yet another new remote branch):
Assert @" !~? 'error', 'Should be able to use new remote branch: ' . @"
unlet! g:foo g:bar g:baz
call ResetPlug()
call plug#load('new-branch')
Assert exists('g:foo'), 'g:foo should be found'
Assert !exists('g:bar'), 'g:bar should not be found'
@@ -225,7 +231,7 @@ Execute (#159: shell=/bin/tcsh):
**********************************************************************
Execute (#154: Spaces in &rtp should not be escaped):
call plug#begin('/tmp/vim-plug-test/plug it')
Plug 'seoul256 vim'
Plug 'foo/seoul256 vim'
call plug#end()
Log &rtp
Assert stridx(&rtp, 'plug it/seoul256 vim') >= 0
@@ -233,12 +239,12 @@ Execute (#154: Spaces in &rtp should not be escaped):
**********************************************************************
Execute (#184: Duplicate entries in &rtp):
call plug#begin('/tmp/vim-plug-test/plugged')
Plug 'plugin1'
\| Plug 'plugin0'
Plug 'foo/plugin1'
\| Plug 'foo/plugin0'
Plug 'plugin2'
\| Plug 'plugin0'
\| Plug 'plugin1'
Plug 'foo/plugin2'
\| Plug 'foo/plugin0'
\| Plug 'foo/plugin1'
call plug#end()
Log &rtp
@@ -304,17 +310,19 @@ Execute (#474: Load ftdetect files in filetypedetect augroup):
bd
**********************************************************************
Execute (#489 On-demand loading with 'on' option should trigger BufRead autocmd):
Execute (#489/#587 On-demand loading with 'on' option should trigger BufRead autocmd w/o nomodeline):
call plug#begin('$PLUG_FIXTURES')
Plug 'ftplugin-msg', { 'on': 'XXX' }
Plug 'foo/ftplugin-msg', { 'on': 'XXX' }
call plug#end()
tabnew a.java
call setline(1, '// vim: set filetype=lava:')
redir => out
silent! XXX
redir END
Assert stridx(out, 'ftplugin-java') >= 0
q
AssertEqual 'lava', &filetype
q!
**********************************************************************
Execute (Cursor moved to another window during post-update hook):
@@ -330,3 +338,38 @@ Execute (Cursor moved to another window during post-update hook):
AssertEqual 'empty', getline(1)
q!
q
**********************************************************************
Execute (#593 Add plugin to &rtp before running post-update hook with : prefix):
call ReloadPlug()
call plug#begin()
Plug 'junegunn/vim-pseudocl', { 'on': 'XXX', 'do': ':let g:bar = pseudocl#complete#extract_words(''a b'')' }
call plug#end()
PlugInstall!
AssertEqual ['a', 'b'], g:bar
**********************************************************************
Execute (#602 Confusion with branch name and path name):
call plug#begin()
Plug expand('file:////tmp/vim-plug-test/new-branch'), { 'branch': 'plugin' }
call plug#end()
PlugUpdate
call PlugStatusSorted()
Expect:
- new-branch: OK
Finished. 0 error(s).
[=]
**********************************************************************
Execute (PlugStatus showed error with wildcard tag):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'tag': '*' }
call plug#end()
PlugUpdate
call PlugStatusSorted()
Expect:
- vim-easy-align: OK
Finished. 0 error(s).
[=]

View File

@@ -1,6 +1,10 @@
#!/bin/bash
cd $(dirname "${BASH_SOURCE[0]}")
# Privileged mode, ignores $CDPATH etc.
set -p
set -eu
cd "$(dirname "${BASH_SOURCE[0]}")"
export BASE="$PWD"
export PLUG_SRC="$PWD/../plug.vim"
@@ -16,8 +20,8 @@ set shell=/bin/bash
VIMRC
clone() {
if [ ! -d $2 ]; then
git clone $1 $2
if [ ! -d "$2" ]; then
git clone "$1" "$2"
fi
}
@@ -44,8 +48,8 @@ make_dirs() (
cd "$PLUG_FIXTURES/$1"
mkdir -p autoload colors ftdetect ftplugin indent plugin syntax
for d in *; do
[ -d $d ] || continue
cat > $d/xxx.vim << EOF
[ -d "$d" ] || continue
cat > "$d/xxx.vim" << EOF
" echom expand('<sfile>')
let g:total_order = get(g:, 'total_order', [])
let g:$2 = get(g:, '$2', [])
@@ -73,13 +77,17 @@ DOC
make_dirs yyy/ yyy
make_dirs yyy/after yyy
mkdir -p "$PLUG_FIXTURES/yyy/rtp/doc"
cat > "$PLUG_FIXTURES/yyy/rtp/doc/yyy.txt" << DOC
hello *yyy*
DOC
gitinit yyy
make_dirs z1/ z1
make_dirs z2/ z2
rm -rf "$PLUG_FIXTURES/ftplugin-msg"
mkdir -p "$PLUG_FIXTURES/ftplugin-msg/ftplugin"
mkdir -p "$PLUG_FIXTURES"/ftplugin-msg/{plugin,ftplugin}
echo "echomsg 'ftplugin-c'" > "$PLUG_FIXTURES/ftplugin-msg/ftplugin/c.vim"
echo "echomsg 'ftplugin-java'" > "$PLUG_FIXTURES/ftplugin-msg/ftplugin/java.vim"
@@ -91,13 +99,15 @@ DOC
echo 'let g:foo = 1' > plugin/foo.vim
git add plugin/foo.vim
git commit -m initial
git checkout -b plugin
git checkout master
cd "$BASE"
}
select_vim() {
local vim=/usr/bin/vim
if [ -n "$DEPS" ] && [ -e "${DEPS}/bin/vim" ]; then
if [ -n "${DEPS:-}" ] && [ -e "${DEPS}/bin/vim" ]; then
vim="${DEPS}/bin/vim"
elif [ -e "/usr/local/bin/vim" ]; then
vim=/usr/local/bin/vim
@@ -109,13 +119,12 @@ clone_repos
prepare
git --version
VIM=$(select_vim)
echo "Selected Vim: $VIM"
if [ "$1" = '!' ]; then
$VIM -Nu $TEMP/mini-vimrc -c 'Vader! test.vader' > /dev/null &&
vim=$(select_vim)
echo "Selected Vim: $vim"
if [ "${1:-}" = '!' ]; then
$vim -Nu $TEMP/mini-vimrc -c 'Vader! test.vader' > /dev/null &&
prepare &&
$VIM -Nu $TEMP/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
$VIM -Nu $TEMP/mini-vimrc -c 'Vader test.vader'
$vim -Nu $TEMP/mini-vimrc -c 'Vader test.vader'
fi

View File

@@ -14,8 +14,15 @@ Execute (Initialize test environment):
" Temporarily patch plug.vim
call system('cp "$PLUG_SRC" "$PLUG_TMP"')
call writefile(extend(readfile($PLUG_TMP),
\ ['function! ResetPlug()', 'let s:loaded = {}', 'endfunction']), $PLUG_TMP)
let patch =
\ ['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
colo default
@@ -30,9 +37,10 @@ Execute (Initialize test environment):
g/^$/d
endfunction
function! AssertExpect(bang, pat, cnt)
function! AssertExpect(bang, pat, cnt, ...)
let op = a:bang ? '==#' : '=~#'
AssertEqual a:cnt, len(filter(getline(1, '$'), "v:val ".op." '".a:pat."'"))
let args = [a:cnt, len(filter(getline(1, '$'), "v:val ".op." '".a:pat."'"))] + a:000
call call('vader#assert#equal', args)
endfunction
command! -nargs=+ -bang AssertExpect call AssertExpect('<bang>' == '!', <args>)
@@ -69,14 +77,16 @@ Execute (Initialize test environment):
Execute (Print Interpreter Version):
redir => out
if has('ruby')
silent ruby puts 'Ruby: ' + RUBY_VERSION
elseif has('python')
silent python import sys; svi = sys.version_info; print 'Python: {}.{}.{}'.format(svi[0], svi[1], svi[2])
elseif has('python3')
silent python3 import sys; svi = sys.version_info; print('Python: {}.{}.{}'.format(svi[0], svi[1], svi[2]))
silent! ruby puts 'Ruby: ' + RUBY_VERSION
endif
if has('python')
silent! python 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
redir END
Log substitute(out, '\n', '', 'g')
Log split(out, '\n')
Include: workflow.vader
Include: regressions.vader

View File

@@ -19,6 +19,13 @@ Execute (plug#begin() without path argument with empty &rtp):
let &rtp = save_rtp
unlet save_rtp
Execute (Standard runtime path is not allowed):
redir => out
silent! AssertEqual 0, plug#begin(split(&rtp, ',')[0].'/plugin')
redir END
Log out
Assert stridx(out, 'Invalid plug home') >= 0
Execute (plug#begin(path)):
call plug#begin(g:temp_plugged.'/')
Assert g:plug_home !~ '[/\\]$', 'Trailing / should be stripped from g:plug_home'
@@ -57,12 +64,17 @@ Execute (Test Plug command):
AssertEqual join([g:temp_plugged, 'vim-emoji/'], '/'), g:plugs['vim-emoji'].dir
" vim-scripts/
Plug 'beauty256'
Plug 'vim-scripts/beauty256'
AssertEqual 'file:///tmp/vim-plug-test/vim-scripts/beauty256', g:plugs.beauty256.uri
AssertEqual 'master', g:plugs.beauty256.branch
AssertEqual 4, len(g:plugs)
redir => out
Plug 'beauty256'
redir END
Assert out =~ 'Invalid argument: beauty256'
Execute (Plug command with dictionary option):
Log string(g:plugs)
Plug 'junegunn/seoul256.vim', { 'branch': 'no-t_co', 'rtp': '././' }
@@ -212,7 +224,7 @@ Expect:
[==]
x seoul256.vim:
Execute (Corrected the URI but diverged from master):
Execute (Corrected the URI but ahead of upstream):
call plug#begin()
Plug 'junegunn/seoul256.vim'
Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
@@ -223,8 +235,8 @@ Execute (Corrected the URI but diverged from master):
call PlugStatusSorted()
Expect:
Diverged from origin/master by 3 commit(s).
Reinstall after PlugClean.
Ahead of origin/master by 3 commit(s).
Cannot update until local changes are pushed.
- vim-emoji: OK
Finished. 1 error(s).
[==]
@@ -237,11 +249,44 @@ Expect:
# q
# PGdd
Execute (PlugClean! to remove seoul256.vim):
Execute (PlugClean! keeps seoul256.vim):
PlugClean!
" Three removed, emoji left
AssertEqual 'Removed 3 directories.', getline(4)
AssertExpect '^\~ ', 3
" Two removed, emoji and seoul256 left
AssertEqual 'Removed 2 directories.', getline(4)
AssertExpect '^\~ ', 2
AssertExpect 'Diverged', 0
Assert !empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
q
Execute (Make seoul256 to be diverged):
call plug#begin()
Plug 'junegunn/seoul256.vim'
Plug 'file:///tmp/vim-plug-test/jg/vim-emoji'
call plug#end()
call system(printf(join([
\ 'cd "%s"',
\ 'git fetch --unshallow',
\ 'git reset "@{u}~1"',
\ 'git commit --allow-empty -m "diverged1"',
\ 'git commit --allow-empty -m "diverged2"'], ' && '),
\ g:plugs['seoul256.vim'].dir))
Assert empty(v:shell_error), 'Got shell error: '.v:shell_error
call PlugStatusSorted()
Expect:
Backup local changes and run PlugClean and PlugUpdate to reinstall it.
Diverged from origin/master (2 commit(s) ahead and 1 commit(s) behind!
- vim-emoji: OK
Finished. 1 error(s).
[==]
x seoul256.vim:
Execute (PlugClean! removes seoul256.vim):
PlugClean!
" One removed, emoji left
AssertEqual 'Removed 1 directories.', getline(4)
AssertExpect '^\~ ', 1
AssertExpect 'Diverged', 1
Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert !empty(globpath(&rtp, 'autoload/emoji.vim'))
@@ -270,8 +315,8 @@ Execute (PlugClean! to remove vim-emoji):
PlugClean!
AssertExpect '^\~ ', 1
AssertEqual 'Removed 1 directories.', getline(4)
Assert empty(globpath(&rtp, 'colors/seoul256.vim'))
Assert empty(globpath(&rtp, 'autoload/emoji.vim'))
Assert empty(globpath(&rtp, 'colors/seoul256.vim')), 'seoul256.vim was removed'
Assert empty(globpath(&rtp, 'autoload/emoji.vim')), 'emoji was removed'
q
Execute (PlugUpdate to install both again):
@@ -283,7 +328,7 @@ Execute (PlugUpdate to install both again):
Execute (PlugUpdate only to find out plugins are up-to-date, D key to check):
PlugUpdate
AssertExpect 'Already up-to-date', 2
AssertExpect 'Already up.to.date', 2, 'Expected 2 times "Already up-to-date", but got: '.string(getline(1, '$'))
normal D
AssertEqual '0 plugin(s) updated.', getline(1)
q
@@ -325,8 +370,15 @@ Execute (New commits on remote, PlugUpdate, then PlugDiff):
AssertEqual 1, &previewwindow
AssertEqual 'git', &filetype
" Back to plug window
wincmd p
" Close preview window
pclose
" Open and go to preview window with a custom mapping
nmap <buffer> <c-o> <plug>(plug-preview)<c-w>P
execute "normal \<c-o>"
AssertEqual 1, &previewwindow, 'Should be on preview window'
normal q
AssertEqual 0, &previewwindow, 'Should not be on preview window'
" ]] motion
execute 'normal $]]'
@@ -381,6 +433,27 @@ Execute (Test g:plug_pwindow):
normal q
unlet g:plug_pwindow
Execute (#572 - Commit preview should work with non-POSIX-compliant &shell):
" Invalid shell
let shell = &shell
set shell=shellfish
try
" Preview commit should still work
PlugDiff
execute "normal ]]jo"
wincmd P
Log getline(1, '$')
Assert getline(1) =~ 'commit', 'Preview window is empty'
AssertEqual 'shellfish', &shell
finally
" Restore &shell
let &shell = shell
unlet shell
pclose
q
endtry
Execute (Reuse Plug window in another tab):
let tabnr = tabpagenr()
PlugDiff
@@ -471,7 +544,7 @@ Execute (PlugDiff):
Execute (Trying to execute on-demand commands when plugin is not installed):
call ReloadPlug()
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'on': ['EasyAlign', 'LiveEasyAlign'] }
Plug 'junegunn/vim-easy-align', { 'on': ['EasyAlign', 'LiveEasyAlign!'] }
call plug#end()
Assert exists(':EasyAlign')
@@ -959,6 +1032,27 @@ Execute (Vim command with : prefix):
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`
**********************************************************************
@@ -1043,16 +1137,28 @@ Before:
**********************************************************************
Execute (plug#helptags):
call plug#begin()
Plug '$PLUG_FIXTURES/xxx'
Plug '$PLUG_FIXTURES/yyy', { 'rtp': 'rtp' }
call plug#end()
silent! call delete(expand('$PLUG_FIXTURES/xxx/doc/tags'))
silent! call delete(expand('$PLUG_FIXTURES/yyy/rtp/doc/tags'))
Assert !filereadable(expand('$PLUG_FIXTURES/xxx/doc/tags'))
Assert !filereadable(expand('$PLUG_FIXTURES/yyy/rtp/doc/tags'))
AssertEqual 1, plug#helptags()
Assert filereadable(expand('$PLUG_FIXTURES/xxx/doc/tags'))
Assert filereadable(expand('$PLUG_FIXTURES/yyy/rtp/doc/tags'))
**********************************************************************
~ Manual loading
**********************************************************************
Execute (plug#load - invalid arguments):
call ResetPlug()
call plug#begin()
Plug '$PLUG_FIXTURES/xxx', { 'for': 'xxx' }
Plug '$PLUG_FIXTURES/yyy', { 'for': 'yyy' }
call plug#end()
AssertEqual 0, plug#load()
AssertEqual 0, plug#load('non-existent-plugin')
AssertEqual 0, plug#load('non-existent-plugin', 'another-non-existent-plugin')
@@ -1060,6 +1166,12 @@ Execute (plug#load - invalid arguments):
AssertEqual 0, plug#load('xxx', 'non-existent-plugin')
AssertEqual 0, plug#load('non-existent-plugin', 'xxx')
Execute (plug#load - list argument (#638)):
redir => out
call plug#load(keys(g:plugs))
redir END
AssertEqual '', out
Execute (on: []):
call plug#begin()
Plug 'junegunn/rust.vim', { 'on': [] }
@@ -1154,7 +1266,7 @@ Execute (Using g:plug_url_format):
let g:plug_url_format = 'git@bitbucket.org:%s.git'
Plug 'junegunn/seoul256.vim'
let g:plug_url_format = 'git@bitsocket.org:%s.git'
Plug 'beauty256'
Plug 'vim-scripts/beauty256'
AssertEqual 'git@bitbucket.org:junegunn/seoul256.vim.git', g:plugs['seoul256.vim'].uri
AssertEqual 'git@bitsocket.org:vim-scripts/beauty256.git', g:plugs['beauty256'].uri
let g:plug_url_format = prev_plug_url_format
@@ -1397,8 +1509,9 @@ Execute (Commit hash support):
call plug#end()
PlugUpdate
Log getline(1, '$')
AssertEqual 'x goyo.vim: error: pathspec ''ffffffff'' did not match any file(s) known to git.', getline(5)
AssertEqual 0, stridx(getline(6), '- vim-emoji: HEAD is now at 9db7fcf...')
AssertEqual 'x goyo.vim:', getline(5)
AssertEqual ' fatal: invalid reference: ffffffff', 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]
AssertEqual '9db7fcfee0d90dafdbcb7a32090c0a9085eb054a', hash
@@ -1471,3 +1584,69 @@ Execute (#427 - Tag option with wildcard (requires git 1.9.2 or above)):
q
AssertEqual '2.9.7', GitTag('vim-easy-align')
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(), 'Current window is #1 after PlugDiff (but is '.winnr().')'
AssertEqual 2, winnr('$'), 'Two windows after PlugDiff (but got '.winnr('$').')'
" Open preview window
execute "normal ]]jo"
AssertEqual 2, winnr(), 'Current window is #2 after opening preview (but is '.winnr().')'
AssertEqual 3, winnr('$'), 'Three windows with preview (but got '.winnr('$').')'
" Move plug window to the right
wincmd L
AssertEqual 3, winnr(), 'Current window is #3 after moving window (but is '.winnr().')'
AssertEqual 3, winnr('$'), 'Three windows after moving window (but got '.winnr('$').')'
" Reuse plug window. Preview window is closed.
PlugStatus
AssertEqual 2, winnr(), 'Current window is #2 after PlugStatus (but is '.winnr().')'
AssertEqual 2, winnr('$'), 'Three windows after PlugStatus (but got '.winnr('$').')'
q
Execute (#766 - Allow cloning into an empty directory):
let d = '/tmp/vim-plug-test/goyo-already'
call system('rm -rf ' . d)
call mkdir(d)
call plug#begin()
Plug 'junegunn/goyo.vim', { 'dir': d }
call plug#end()
PlugInstall
AssertExpect! '[=]', 1
q
unlet d