[nvim] update minpac
This commit is contained in:
parent
fe7f4bf07f
commit
112992ebec
@ -1,4 +1,3 @@
|
||||
dist: trusty
|
||||
language: generic
|
||||
sudo: false
|
||||
|
||||
@ -15,12 +14,16 @@ env:
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: focal
|
||||
env: VIM=vim VIMPROG=$OPT/bin/$VIM
|
||||
- os: linux
|
||||
dist: focal
|
||||
env: VIM=nvim VIMPROG=$VIM
|
||||
- os: osx
|
||||
osx_image: xcode12
|
||||
env: VIM=vim PACKAGE=vim VIMPROG=$VIM
|
||||
- os: osx
|
||||
osx_image: xcode12
|
||||
env: VIM=nvim PACKAGE=neovim VIMPROG=$VIM
|
||||
|
||||
|
||||
@ -38,10 +38,16 @@ Plugins installed under `pack/*/start/` are automatically added to the `'runtime
|
||||
|
||||
### Windows
|
||||
|
||||
Vim:
|
||||
|
||||
```cmd
|
||||
cd /d %USERPROFILE%
|
||||
git clone https://github.com/k-takata/minpac.git ^
|
||||
vimfiles\pack\minpac\opt\minpac
|
||||
git clone https://github.com/k-takata/minpac.git %USERPROFILE%\vimfiles\pack\minpac\opt\minpac
|
||||
```
|
||||
|
||||
Neovim:
|
||||
|
||||
```cmd
|
||||
git clone https://github.com/k-takata/minpac.git %LOCALAPPDATA%\nvim\pack\minpac\opt\minpac
|
||||
```
|
||||
|
||||
### Linux, macOS
|
||||
@ -49,15 +55,13 @@ git clone https://github.com/k-takata/minpac.git ^
|
||||
Vim:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/k-takata/minpac.git \
|
||||
~/.vim/pack/minpac/opt/minpac
|
||||
git clone https://github.com/k-takata/minpac.git ~/.vim/pack/minpac/opt/minpac
|
||||
```
|
||||
|
||||
Neovim (use `$XDG_CONFIG_HOME` in place of `~/.config` if set on your system):
|
||||
|
||||
```sh
|
||||
git clone https://github.com/k-takata/minpac.git \
|
||||
~/.config/nvim/pack/minpac/opt/minpac
|
||||
git clone https://github.com/k-takata/minpac.git ~/.config/nvim/pack/minpac/opt/minpac
|
||||
```
|
||||
|
||||
### Sample .vimrc
|
||||
@ -65,6 +69,15 @@ git clone https://github.com/k-takata/minpac.git \
|
||||
#### Basic sample
|
||||
|
||||
```vim
|
||||
" Normally this if-block is not needed, because `:set nocp` is done
|
||||
" automatically when .vimrc is found. However, this might be useful
|
||||
" when you execute `vim -u .vimrc` from the command line.
|
||||
if &compatible
|
||||
" `:set nocp` has many side effects. Therefore this should be done
|
||||
" only when 'compatible' is set.
|
||||
set nocompatible
|
||||
endif
|
||||
|
||||
packadd minpac
|
||||
|
||||
call minpac#init()
|
||||
@ -80,6 +93,8 @@ call minpac#add('vim-jp/syntax-vim-ex')
|
||||
"packloadall
|
||||
```
|
||||
|
||||
Minpac itself requires 'compatible' to be unset. However, the `if &compatible`-block is optional.
|
||||
|
||||
#### Customizing 'packpath'
|
||||
|
||||
If you want to use `.vim` directory instead of `vimfiles` even on Windows,
|
||||
@ -101,7 +116,7 @@ You can write a .vimrc which can be also used even if minpac is not installed.
|
||||
" Try to load minpac.
|
||||
packadd minpac
|
||||
|
||||
if !exists('*minpac#init')
|
||||
if !exists('g:loaded_minpac')
|
||||
" minpac is not available.
|
||||
|
||||
" Settings for plugin-less environment.
|
||||
@ -124,49 +139,9 @@ endif
|
||||
|
||||
#### Load minpac on demand
|
||||
|
||||
Very interestingly, minpac doesn't need to be loaded every time. Unlike other plugin managers, it is needed only when updating, installing or cleaning the plugins. This is because minpac itself doesn't handle the runtime path.
|
||||
Very interestingly, minpac doesn't need to be loaded every time when you execute Vim. Unlike other plugin managers, it is needed only when updating, installing or cleaning the plugins. This is because minpac itself doesn't handle the runtime path.
|
||||
|
||||
You can define a user command to load minpac, reload .vimrc to register the information of plugins, then call `minpac#update()`, `minpac#clean()` or `minpac#status()`.
|
||||
|
||||
```vim
|
||||
" For a paranoia.
|
||||
" Normally `:set nocp` is not needed, because it is done automatically
|
||||
" when .vimrc is found.
|
||||
if &compatible
|
||||
" `:set nocp` has many side effects. Therefore this should be done
|
||||
" only when 'compatible' is set.
|
||||
set nocompatible
|
||||
endif
|
||||
|
||||
if exists('*minpac#init')
|
||||
" minpac is loaded.
|
||||
call minpac#init()
|
||||
call minpac#add('k-takata/minpac', {'type': 'opt'})
|
||||
|
||||
" Additional plugins here.
|
||||
call minpac#add('vim-jp/syntax-vim-ex')
|
||||
...
|
||||
endif
|
||||
|
||||
" Plugin settings here.
|
||||
...
|
||||
|
||||
" Define user commands for updating/cleaning the plugins.
|
||||
" Each of them loads minpac, reloads .vimrc to register the
|
||||
" information of plugins, then performs the task.
|
||||
command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update('', {'do': 'call minpac#status()'})
|
||||
command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean()
|
||||
command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status()
|
||||
```
|
||||
|
||||
Note that your .vimrc must be reloadable to use this. E.g.:
|
||||
|
||||
* `:set nocompatible` should not be executed twice to avoid side effects.
|
||||
* `:function!` should be used to define a user function.
|
||||
* `:command!` should be used to define a user command.
|
||||
* `:augroup!` should be used properly to avoid the same autogroups are defined twice.
|
||||
|
||||
Another way is defining a function to load minpac and register the information of plugins.
|
||||
You can define user commands to load minpac, register the information of plugins, then call `minpac#update()`, `minpac#clean()` or `minpac#status()`.
|
||||
|
||||
```vim
|
||||
function! PackInit() abort
|
||||
@ -187,13 +162,25 @@ endfunction
|
||||
" Define user commands for updating/cleaning the plugins.
|
||||
" Each of them calls PackInit() to load minpac and register
|
||||
" the information of plugins, then performs the task.
|
||||
command! PackUpdate call PackInit() | call minpac#update('', {'do': 'call minpac#status()'})
|
||||
command! PackUpdate call PackInit() | call minpac#update()
|
||||
command! PackClean call PackInit() | call minpac#clean()
|
||||
command! PackStatus call PackInit() | call minpac#status()
|
||||
command! PackStatus packadd minpac | call minpac#status()
|
||||
```
|
||||
|
||||
This doesn't reload .vimrc, so the .vimrc doesn't need to be reloadable.
|
||||
However, if you make it reloadable, you can apply the changes to the .vimrc immediately by executing `:so $MYVIMRC | PackUpdate`.
|
||||
If you make your .vimrc reloadable, you can reflect the setting of the .vimrc immediately after you edit it by executing `:so $MYVIMRC | PackUpdate`. Or you can define the commands like this:
|
||||
|
||||
```vim
|
||||
command! PackUpdate source $MYVIMRC | call PackInit() | call minpac#update()
|
||||
command! PackClean source $MYVIMRC | call PackInit() | call minpac#clean()
|
||||
command! PackStatus packadd minpac | call minpac#status()
|
||||
```
|
||||
|
||||
To make your .vimrc reloadable:
|
||||
|
||||
* `:set nocompatible` should not be executed twice to avoid side effects.
|
||||
* `:function!` should be used to define a user function.
|
||||
* `:command!` should be used to define a user command.
|
||||
* `:augroup!` should be used properly to avoid the same autogroups are defined twice.
|
||||
|
||||
|
||||
Sometimes, you may want to open a shell at the directory where a plugin is installed. The following example defines a command to open a terminal window at the directory of a specified plugin. (Requires Vim 8.0.902 or later.)
|
||||
@ -242,6 +229,8 @@ call minpac#clean()
|
||||
call minpac#status()
|
||||
```
|
||||
|
||||
Or define commands by yourself as described in the previous section.
|
||||
|
||||
|
||||
### Functions
|
||||
|
||||
@ -259,7 +248,10 @@ Initialize minpac.
|
||||
| `'depth'` | Default clone depth. Default: 1 |
|
||||
| `'jobs'` | Maximum job numbers. If <= 0, unlimited. Default: 8 |
|
||||
| `'verbose'` | Verbosity level (0 to 4).<br/>0: Show only important messages.<br/>1: Show the result of each plugin.<br/>2: Show error messages from external commands.<br/>3: Show start/end messages for each plugin.<br/>4: Show debug messages.<br/>Default: 2 |
|
||||
| `'status_open'` | Default setting for the open option of `minpac#status()`. Default: `'vertical'` |
|
||||
| `'confirm'` | Show interactive confirmation prompts, such as in `minpac#clean()`.<br/>Default: TRUE |
|
||||
| `'progress_open'` | Specify how to show the progress of `minpac#update()`.<br/>`'none'`: Do not open the progress window. (Compatible with minpac v2.0.x or earlier.)<br/>`'horizontal'`: Open the progress window by splitting horizontally.<br/>`'vertical'`: Open the progress window by splitting vertically.<br/>`'tab'`: Open the progress window in a new tab.<br/>Default: `'horizontal'` |
|
||||
| `'status_open'` | Default setting for the open option of `minpac#status()`. Default: `'horizontal'` |
|
||||
| `'status_auto'` | Specify whether the status window will open automatically after `minpac#update()` is finished.<br/>TRUE: Open the status window automatically, when one or more plugins are updated or installed.<br/>FALSE: Do not open the status window automatically.<br/>Default: FALSE |
|
||||
|
||||
All plugins will be installed under the following directories:
|
||||
|
||||
@ -284,11 +276,13 @@ Note: Unlike Vundle, a short form without `<github-account>/` is not supported.
|
||||
|------------|-------------|
|
||||
| `'name'` | Unique name of the plugin (`plugin_name`). Also used as a local directory name. Default: derived from the repository name. |
|
||||
| `'type'` | Type of the plugin. `'start'` or `'opt'`. Default: `'start'` |
|
||||
| `'frozen'` | If 1, the plugin will not be updated automatically. Default: 0 |
|
||||
| `'frozen'` | If TRUE, the plugin will not be updated automatically. Default: FALSE |
|
||||
| `'depth'` | If >= 1, it is used as a depth to be cloned. Only effective when install the plugin newly. Default: 1 or specified value by `minpac#init()`. |
|
||||
| `'branch'` | Used as a branch name to be cloned. Only effective when install the plugin newly. Default: empty |
|
||||
| `'rev'` | Commit ID, branch name or tag name to be checked out. If this is specified, `'depth'` will be ignored. Default: empty |
|
||||
| `'do'` | Post-update hook. See [Post-update hooks](#post-update-hooks). Default: empty |
|
||||
| `'subdir'` | Subdirectory that contains Vim plugin. Default: empty |
|
||||
| `'pullmethod'` | Specify how to update the plugin.<br/>Empty: Update with `--ff-only` option.<br/>`'autostash'`: Update with `--rebase --autostash` options.<br/>Default: empty |
|
||||
|
||||
The `'branch'` and `'rev'` options are slightly different.
|
||||
The `'branch'` option is used only when the plugin is newly installed. It clones the plugin by `git clone <URL> --depth=<DEPTH> -b <BRANCH>`. This is faster at the installation, but it can be slow if you want to change the branch (by the `'rev'` option) later. This cannot specify a commit ID.
|
||||
@ -297,6 +291,14 @@ So, if you want to change the branch frequently or want to specify a commit ID,
|
||||
|
||||
If you include `*` in `'rev'`, minpac tries to checkout the latest tag name which matches the `'rev'`.
|
||||
|
||||
When `'subdir'` is specified, the plugin will be installed as usual (e.g. in `pack/minpac/start/pluginname`), however, another directory is created and a symlink (or a junction on Windows) will be created in it. E.g.:
|
||||
|
||||
```
|
||||
ln -s pack/minpac/start/pluginname/subdir pack/minpac-sub/start/pluginname
|
||||
```
|
||||
|
||||
This way, Vim can load the plugin from its subdirectory.
|
||||
|
||||
|
||||
#### minpac#update([{name}[, {config}]])
|
||||
|
||||
@ -323,12 +325,12 @@ Note: This resets the 'more' option temporarily to avoid jobs being interrupted.
|
||||
|
||||
Remove all plugins which are not registered, or remove the specified plugin.
|
||||
|
||||
`{name}` is a name of a plugin. It can be a unique plugin name (`plugin_name`) or a plugin name with wildcards (`*` and `?` are supported).
|
||||
`{name}` is a name of a plugin. It can be a unique plugin name (`plugin_name`) or a plugin name with wildcards (`*` and `?` are supported). It can also be a list of plugin names.
|
||||
|
||||
If `{name}` is omitted, all plugins under the `minpac` directory will be checked. If unregistered plugins are found, they are listed and a prompt is shown. If you type `y`, they will be removed.
|
||||
|
||||
If `{name}` is specified, matched plugins are listed (even they are registered with `minpac#add()`) and a prompt is shown. If you type `y`, they will be removed.
|
||||
`{name}` can also be a list of plugin names.
|
||||
When called, matched plugins are listed (even they are registered with `minpac#add()`) and a prompt is shown. If you type `y`, they will be removed.
|
||||
`{name}` can also be a list of plugin names. If the `'confirm'` option is not |TRUE|, the prompt will not be shown.
|
||||
|
||||
#### minpac#getpluginfo({name})
|
||||
|
||||
@ -342,7 +344,8 @@ A dictionary with following items will be returned:
|
||||
| `'name'` | Name of the plugin. |
|
||||
| `'url'` | URL of the plugin repository. |
|
||||
| `'dir'` | Local directory of the plugin. |
|
||||
| `'frozen'` | If 1, the plugin is frozen. |
|
||||
| `'subdir'` | Subdirectory that contains Vim plugin. |
|
||||
| `'frozen'` | If TRUE, the plugin is frozen. |
|
||||
| `'type'` | Type of the plugin. |
|
||||
| `'depth'` | Depth to be cloned. |
|
||||
| `'branch'` | Branch name to be cloned. |
|
||||
@ -367,7 +370,7 @@ If `"NONE"` is specified, package directories are listed instead of plugin direc
|
||||
|
||||
`{plugname}` specifies a plugin name. Wildcards can be used. If omitted or an empty string is specified, `"*"` is used.
|
||||
|
||||
If `{nameonly}` is 1, plugin (or package) names are listed instead of the direcotries. Default is 0.
|
||||
If `{nameonly}` is TRUE, plugin (or package) names are listed instead of the direcotries. Default is FALSE.
|
||||
|
||||
E.g.:
|
||||
|
||||
@ -398,7 +401,7 @@ Otherwise, shows the status of the plugin and commits of last update (if any).
|
||||
|
||||
| option | description |
|
||||
|----------|-------------|
|
||||
| `'open'` | Specify how to open the status window.<br/>`'vertical'`: Open in vertical split.<br/>`'horizontal'`: Open in horizontal split.<br/>`'tab'`: Open in a new tab.<br/>Default: `'vertical'` or specified value by `minpac#init()`. |
|
||||
| `'open'` | Specify how to open the status window.<br/>`'vertical'`: Open in vertical split.<br/>`'horizontal'`: Open in horizontal split.<br/>`'tab'`: Open in a new tab.<br/>Default: `'horizontal'` or specified value by `minpac#init()`. |
|
||||
|
||||
### Hooks
|
||||
|
||||
@ -467,6 +470,13 @@ call minpac#update('', {'do': 'quit'})
|
||||
|
||||
### Mappings
|
||||
|
||||
List of mappings available only in progress window.
|
||||
|
||||
| mapping | description |
|
||||
|---------|-------------|
|
||||
|`s` | Open the status window. |
|
||||
|`q` | Exit the progress window. |
|
||||
|
||||
List of mappings available only in status window.
|
||||
|
||||
| mapping | description |
|
||||
|
||||
@ -3,7 +3,7 @@ version: '1.0.{build}'
|
||||
shallow_clone: true
|
||||
|
||||
environment:
|
||||
VIMPROG: '%APPVEYOR_BUILD_FOLDER%\vim-kaoriya-win64\gvim.exe'
|
||||
VIMPROG: '%APPVEYOR_BUILD_FOLDER%\vim-kt-win64\gvim.exe'
|
||||
AUTH_TOKEN: # for GitHub
|
||||
secure: wdTzzL05DoG4BZIgqlc3y/Ff50ZOTjfaqMazhdMLcXmxYYbmeCsI9PN01TJCQMaw
|
||||
API_TOKEN: # for AppVeyor
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
" ---------------------------------------------------------------------
|
||||
" minpac: A minimal package manager for Vim 8 (and Neovim)
|
||||
"
|
||||
" Maintainer: Ken Takata
|
||||
" Last Change: 2020-08-22
|
||||
" License: VIM License
|
||||
" URL: https://github.com/k-takata/minpac
|
||||
" ---------------------------------------------------------------------
|
||||
|
||||
" Get a list of package/plugin directories.
|
||||
function! minpac#getpackages(...)
|
||||
return call("minpac#impl#getpackages", a:000)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:ensure_initialization() abort
|
||||
if !exists('g:minpac#opt')
|
||||
echohl WarningMsg
|
||||
echom 'Minpac has not been initialized. Use the default values.'
|
||||
echohl None
|
||||
call minpac#init()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Initialize minpac.
|
||||
function! minpac#init(...) abort
|
||||
let l:opt = extend(copy(get(a:000, 0, {})),
|
||||
\ {'dir': '', 'package_name': 'minpac', 'git': 'git', 'depth': 1,
|
||||
\ 'jobs': 8, 'verbose': 2, 'confirm': v:true,
|
||||
\ 'progress_open': 'horizontal', 'status_open': 'horizontal',
|
||||
\ 'status_auto': v:false}, 'keep')
|
||||
|
||||
let g:minpac#opt = l:opt
|
||||
let g:minpac#pluglist = {}
|
||||
|
||||
let l:packdir = l:opt.dir
|
||||
if l:packdir ==# ''
|
||||
" If 'dir' is not specified, the first directory of 'packpath' is used.
|
||||
let l:packdir = split(&packpath, ',')[0]
|
||||
endif
|
||||
|
||||
let l:opt.minpac_dir = l:packdir . '/pack/' . l:opt.package_name
|
||||
let l:opt.minpac_start_dir = l:opt.minpac_dir . '/start'
|
||||
let l:opt.minpac_opt_dir = l:opt.minpac_dir . '/opt'
|
||||
|
||||
" directories for 'subdir'
|
||||
let l:opt.minpac_dir_sub = l:packdir . '/pack/' . l:opt.package_name . '-sub'
|
||||
let l:opt.minpac_start_dir_sub = l:opt.minpac_dir_sub . '/start'
|
||||
let l:opt.minpac_opt_dir_sub = l:opt.minpac_dir_sub . '/opt'
|
||||
|
||||
if !isdirectory(l:packdir)
|
||||
echoerr 'Pack directory not available: ' . l:packdir
|
||||
return
|
||||
endif
|
||||
if !isdirectory(l:opt.minpac_start_dir)
|
||||
call mkdir(l:opt.minpac_start_dir, 'p')
|
||||
endif
|
||||
if !isdirectory(l:opt.minpac_opt_dir)
|
||||
call mkdir(l:opt.minpac_opt_dir, 'p')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" Register the specified plugin.
|
||||
function! minpac#add(plugname, ...) abort
|
||||
call s:ensure_initialization()
|
||||
let l:opt = extend(copy(get(a:000, 0, {})),
|
||||
\ {'name': '', 'type': 'start', 'depth': g:minpac#opt.depth,
|
||||
\ 'frozen': v:false, 'branch': '', 'rev': '', 'do': '', 'subdir': '',
|
||||
\ 'pullmethod': ''
|
||||
\ }, 'keep')
|
||||
|
||||
" URL
|
||||
if a:plugname =~? '^[-._0-9a-z]\+\/[-._0-9a-z]\+$'
|
||||
let l:opt.url = 'https://github.com/' . a:plugname . '.git'
|
||||
else
|
||||
let l:opt.url = a:plugname
|
||||
endif
|
||||
|
||||
" Name of the plugin
|
||||
if l:opt.name ==# ''
|
||||
let l:opt.name = matchstr(l:opt.url, '[/\\]\zs[^/\\]\+$')
|
||||
let l:opt.name = substitute(l:opt.name, '\C\.git$', '', '')
|
||||
endif
|
||||
if l:opt.name ==# ''
|
||||
echoerr 'Cannot extract the plugin name. (' . a:plugname . ')'
|
||||
return
|
||||
endif
|
||||
|
||||
" Loading type / Local directory
|
||||
if l:opt.type ==# 'start'
|
||||
let l:opt.dir = g:minpac#opt.minpac_start_dir . '/' . l:opt.name
|
||||
elseif l:opt.type ==# 'opt'
|
||||
let l:opt.dir = g:minpac#opt.minpac_opt_dir . '/' . l:opt.name
|
||||
else
|
||||
echoerr a:plugname . ": Wrong type (must be 'start' or 'opt'): " . l:opt.type
|
||||
return
|
||||
endif
|
||||
|
||||
" Check pullmethod
|
||||
if l:opt.pullmethod !=# '' && l:opt.pullmethod !=# 'autostash'
|
||||
echoerr a:plugname . ": Wrong pullmethod (must be empty or 'autostash'): " . l:opt.pullmethod
|
||||
return
|
||||
endif
|
||||
|
||||
" Initialize the status
|
||||
let l:opt.stat = {'errcode': 0, 'lines': [], 'prev_rev': '', 'installed': -1}
|
||||
|
||||
" Add to pluglist
|
||||
let g:minpac#pluglist[l:opt.name] = l:opt
|
||||
endfunction
|
||||
|
||||
|
||||
" Update all or specified plugin(s).
|
||||
function! minpac#update(...)
|
||||
call s:ensure_initialization()
|
||||
return call("minpac#impl#update", a:000)
|
||||
endfunction
|
||||
|
||||
|
||||
" Remove plugins that are not registered.
|
||||
function! minpac#clean(...)
|
||||
call s:ensure_initialization()
|
||||
return call("minpac#impl#clean", a:000)
|
||||
endfunction
|
||||
|
||||
function! minpac#status(...)
|
||||
call s:ensure_initialization()
|
||||
let l:opt = extend(copy(get(a:000, 0, {})),
|
||||
\ {'open': g:minpac#opt.status_open}, 'keep')
|
||||
return minpac#status#get(l:opt)
|
||||
endfunction
|
||||
|
||||
|
||||
" Get information of specified plugin. Mainly for debugging.
|
||||
function! minpac#getpluginfo(name)
|
||||
call s:ensure_initialization()
|
||||
return g:minpac#pluglist[a:name]
|
||||
endfunction
|
||||
|
||||
|
||||
" Get a list of plugin information. Mainly for debugging.
|
||||
function! minpac#getpluglist()
|
||||
return g:minpac#pluglist
|
||||
endfunction
|
||||
|
||||
" vim: set ts=8 sw=2 et:
|
||||
@ -0,0 +1,75 @@
|
||||
" ---------------------------------------------------------------------
|
||||
" minpac: A minimal package manager for Vim 8 (and Neovim)
|
||||
"
|
||||
" Maintainer: Ken Takata
|
||||
" Last Change: 2020-02-01
|
||||
" License: VIM License
|
||||
" URL: https://github.com/k-takata/minpac
|
||||
" ---------------------------------------------------------------------
|
||||
|
||||
function! s:isabsolute(dir) abort
|
||||
return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)')
|
||||
endfunction
|
||||
|
||||
function! s:get_gitdir(dir) abort
|
||||
let l:gitdir = a:dir . '/.git'
|
||||
if isdirectory(l:gitdir)
|
||||
return l:gitdir
|
||||
endif
|
||||
try
|
||||
let l:line = readfile(l:gitdir)[0]
|
||||
if l:line =~# '^gitdir: '
|
||||
let l:gitdir = l:line[8:]
|
||||
if !s:isabsolute(l:gitdir)
|
||||
let l:gitdir = a:dir . '/' . l:gitdir
|
||||
endif
|
||||
if isdirectory(l:gitdir)
|
||||
return l:gitdir
|
||||
endif
|
||||
endif
|
||||
catch
|
||||
endtry
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! minpac#git#get_revision(dir) abort
|
||||
let l:gitdir = s:get_gitdir(a:dir)
|
||||
if l:gitdir ==# ''
|
||||
return v:null
|
||||
endif
|
||||
try
|
||||
let l:line = readfile(l:gitdir . '/HEAD')[0]
|
||||
if l:line =~# '^ref: '
|
||||
let l:ref = l:line[5:]
|
||||
if filereadable(l:gitdir . '/' . l:ref)
|
||||
return readfile(l:gitdir . '/' . l:ref)[0]
|
||||
endif
|
||||
for l:line in readfile(l:gitdir . '/packed-refs')
|
||||
if l:line =~# ' ' . l:ref
|
||||
return substitute(l:line, '^\([0-9a-f]*\) ', '\1', '')
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return l:line
|
||||
catch
|
||||
endtry
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
function! minpac#git#get_branch(dir) abort
|
||||
let l:gitdir = s:get_gitdir(a:dir)
|
||||
if l:gitdir ==# ''
|
||||
return v:null
|
||||
endif
|
||||
try
|
||||
let l:line = readfile(l:gitdir . '/HEAD')[0]
|
||||
if l:line =~# '^ref: refs/heads/'
|
||||
return l:line[16:]
|
||||
endif
|
||||
return ''
|
||||
catch
|
||||
return v:null
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" vim: set ts=8 sw=2 et:
|
||||
@ -2,7 +2,7 @@
|
||||
" minpac: A minimal package manager for Vim 8 (and Neovim)
|
||||
"
|
||||
" Maintainer: Ken Takata
|
||||
" Last Change: 2018-09-01
|
||||
" Last Change: 2020-08-22
|
||||
" License: VIM License
|
||||
" URL: https://github.com/k-takata/minpac
|
||||
" ---------------------------------------------------------------------
|
||||
@ -15,7 +15,7 @@ function! minpac#impl#getpackages(...) abort
|
||||
let l:packname = get(a:000, 0, '')
|
||||
let l:packtype = get(a:000, 1, '')
|
||||
let l:plugname = get(a:000, 2, '')
|
||||
let l:nameonly = get(a:000, 3, 0)
|
||||
let l:nameonly = get(a:000, 3, v:false)
|
||||
|
||||
if l:packname ==# '' | let l:packname = '*' | endif
|
||||
if l:packtype ==# '' | let l:packtype = '*' | endif
|
||||
@ -35,25 +35,42 @@ function! minpac#impl#getpackages(...) abort
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:echo_verbose(level, msg) abort
|
||||
function! s:echox_verbose(level, echocmd, type, msg) abort
|
||||
if g:minpac#opt.verbose >= a:level
|
||||
echo a:msg
|
||||
if g:minpac#opt.progress_open ==# 'none'
|
||||
if a:type ==# 'warning'
|
||||
echohl WarningMsg
|
||||
elseif a:type ==# 'error'
|
||||
echohl ErrorMsg
|
||||
endif
|
||||
exec a:echocmd . " '" . substitute(a:msg, "'", "''", "g") . "'"
|
||||
echohl None
|
||||
else
|
||||
call minpac#progress#add_msg(a:type, a:msg)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:echom_verbose(level, msg) abort
|
||||
if g:minpac#opt.verbose >= a:level
|
||||
echom a:msg
|
||||
endif
|
||||
function! s:echo_verbose(level, type, msg) abort
|
||||
call s:echox_verbose(a:level, 'echo', a:type, a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:echom_verbose(level, type, msg) abort
|
||||
call s:echox_verbose(a:level, 'echom', a:type, a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:echoerr_verbose(level, msg) abort
|
||||
call s:echox_verbose(a:level, 'echoerr', 'error', a:msg)
|
||||
endfunction
|
||||
|
||||
|
||||
if has('win32')
|
||||
function! s:quote_cmds(cmds) abort
|
||||
" If space is found, surround the argument with "".
|
||||
" If space (or brace) is found, surround the argument with "".
|
||||
" Assuming double quotations are not used elsewhere.
|
||||
" (Brace needs to be quoted for msys2/git.)
|
||||
return join(map(a:cmds,
|
||||
\ {-> (v:val =~# ' ') ? '"' . v:val . '"' : v:val}), ' ')
|
||||
\ {-> (v:val =~# '[ {]') ? '"' . v:val . '"' : v:val}), ' ')
|
||||
endfunction
|
||||
else
|
||||
function! s:quote_cmds(cmds) abort
|
||||
@ -67,7 +84,7 @@ function! minpac#impl#system(cmds) abort
|
||||
let l:out = []
|
||||
let l:ret = -1
|
||||
let l:quote_cmds = s:quote_cmds(a:cmds)
|
||||
call s:echom_verbose(4, 'system: cmds=' . string(l:quote_cmds))
|
||||
call s:echom_verbose(4, '', 'system: cmds=' . string(l:quote_cmds))
|
||||
let l:job = minpac#job#start(l:quote_cmds,
|
||||
\ {'on_stdout': {id, mes, ev -> extend(l:out, mes)}})
|
||||
if l:job > 0
|
||||
@ -84,7 +101,7 @@ function! s:exec_plugin_cmd(name, cmd, mes) abort
|
||||
let l:dir = l:pluginfo.dir
|
||||
let l:res = minpac#impl#system([g:minpac#opt.git, '-C', l:dir] + a:cmd)
|
||||
if l:res[0] == 0 && len(l:res[1]) > 0
|
||||
call s:echom_verbose(4, a:mes . ': ' . l:res[1][0])
|
||||
call s:echom_verbose(4, '', a:mes . ': ' . l:res[1][0])
|
||||
return l:res[1][0]
|
||||
else
|
||||
" Error
|
||||
@ -94,6 +111,11 @@ endfunction
|
||||
|
||||
" Get the revision of the specified plugin.
|
||||
function! minpac#impl#get_plugin_revision(name) abort
|
||||
let l:rev = minpac#git#get_revision(g:minpac#pluglist[a:name].dir)
|
||||
if l:rev != v:null
|
||||
call s:echom_verbose(4, '', 'revision: ' . l:rev)
|
||||
return l:rev
|
||||
endif
|
||||
return s:exec_plugin_cmd(a:name, ['rev-parse', 'HEAD'], 'revision')
|
||||
endfunction
|
||||
|
||||
@ -109,6 +131,11 @@ endfunction
|
||||
|
||||
" Get the branch name of the specified plugin.
|
||||
function! s:get_plugin_branch(name) abort
|
||||
let l:branch = minpac#git#get_branch(g:minpac#pluglist[a:name].dir)
|
||||
if l:branch != v:null
|
||||
call s:echom_verbose(4, '', 'branch: ' . l:branch)
|
||||
return l:branch
|
||||
endif
|
||||
return s:exec_plugin_cmd(a:name, ['symbolic-ref', '--short', 'HEAD'], 'branch')
|
||||
endfunction
|
||||
|
||||
@ -125,16 +152,29 @@ function! s:decrement_job_count() abort
|
||||
endif
|
||||
|
||||
" Show the status.
|
||||
if s:error_plugins != 0
|
||||
echohl WarningMsg
|
||||
echom 'Error plugins: ' . s:error_plugins
|
||||
echohl None
|
||||
if s:error_plugins + s:updated_plugins + s:installed_plugins > 0
|
||||
if g:minpac#opt.progress_open !=# 'none'
|
||||
call s:echom_verbose(1, '', '') " empty line
|
||||
endif
|
||||
endif
|
||||
if s:error_plugins > 0
|
||||
call s:echom_verbose(1, 'warning', 'Error plugins: ' . s:error_plugins)
|
||||
else
|
||||
let l:mes = 'All plugins are up to date.'
|
||||
if s:updated_plugins > 0 || s:installed_plugins > 0
|
||||
if s:updated_plugins + s:installed_plugins > 0
|
||||
let l:mes .= ' (Updated: ' . s:updated_plugins . ', Newly installed: ' . s:installed_plugins . ')'
|
||||
endif
|
||||
echom l:mes
|
||||
call s:echom_verbose(1, '', l:mes)
|
||||
endif
|
||||
if g:minpac#opt.progress_open !=# 'none'
|
||||
call s:echom_verbose(1, '', '(Type "q" to close this window. Type "s" to open the status window.)')
|
||||
endif
|
||||
|
||||
" Open the status window.
|
||||
if s:updated_plugins + s:installed_plugins > 0
|
||||
if g:minpac#opt.status_auto
|
||||
call minpac#status()
|
||||
endif
|
||||
endif
|
||||
|
||||
" Restore the pager.
|
||||
@ -177,10 +217,8 @@ function! s:invoke_hook(hooktype, args, hook) abort
|
||||
execute a:hook
|
||||
endif
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echom v:throwpoint
|
||||
echom v:exception
|
||||
echohl None
|
||||
call s:echom_verbose(1, 'error', v:throwpoint)
|
||||
call s:echom_verbose(1, 'error', v:exception)
|
||||
finally
|
||||
if a:hooktype ==# 'post-update'
|
||||
noautocmd call s:chdir(l:pwd)
|
||||
@ -211,6 +249,41 @@ function! s:add_rtp(dir) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
if has('win32')
|
||||
function! s:create_link(target, link) abort
|
||||
if isdirectory(a:target)
|
||||
call delete(a:target)
|
||||
endif
|
||||
call minpac#impl#system(['cmd.exe', '/c', 'mklink', '/J',
|
||||
\ substitute(a:link, '/', '\', 'g'),
|
||||
\ substitute(a:target, '/', '\', 'g')])
|
||||
endfunction
|
||||
else
|
||||
function! s:create_link(target, link) abort
|
||||
call minpac#impl#system(['ln', '-sf', a:target, a:link])
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:handle_subdir(pluginfo) abort
|
||||
if a:pluginfo.type ==# 'start'
|
||||
let l:workdir = g:minpac#opt.minpac_start_dir_sub
|
||||
else
|
||||
let l:workdir = g:minpac#opt.minpac_opt_dir_sub
|
||||
endif
|
||||
if !isdirectory(l:workdir)
|
||||
call mkdir(l:workdir, 'p')
|
||||
endif
|
||||
noautocmd let l:pwd = s:chdir(l:workdir)
|
||||
try
|
||||
if !isdirectory(a:pluginfo.name)
|
||||
call s:create_link(a:pluginfo.dir . '/' . a:pluginfo.subdir,
|
||||
\ a:pluginfo.name)
|
||||
endif
|
||||
finally
|
||||
noautocmd call s:chdir(l:pwd)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:job_exit_cb(id, errcode, event) dict abort
|
||||
call filter(s:joblist, {-> v:val != a:id})
|
||||
|
||||
@ -243,16 +316,14 @@ function! s:job_exit_cb(id, errcode, event) dict abort
|
||||
let l:rev = s:get_plugin_latest_tag(self.name, l:rev)
|
||||
if l:rev ==# ''
|
||||
let s:error_plugins += 1
|
||||
echohl ErrorMsg
|
||||
call s:echom_verbose(1, 'Error while updating "' . self.name . '". No tags found.')
|
||||
echohl None
|
||||
call s:echom_verbose(1, 'error', 'Error while updating "' . self.name . '". No tags found.')
|
||||
call s:decrement_job_count()
|
||||
return
|
||||
endif
|
||||
endif
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'checkout',
|
||||
\ l:rev, '--']
|
||||
call s:echom_verbose(3, 'Checking out the revison: ' . self.name
|
||||
call s:echom_verbose(3, '', 'Checking out the revison: ' . self.name
|
||||
\ . ': ' . l:rev)
|
||||
call s:start_job(l:cmd, self.name, self.seq + 1)
|
||||
return
|
||||
@ -261,7 +332,7 @@ function! s:job_exit_cb(id, errcode, event) dict abort
|
||||
" Checked out the branch. Update to the upstream.
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'merge', '--quiet',
|
||||
\ '--ff-only', '@{u}']
|
||||
call s:echom_verbose(3, 'Update to the upstream: ' . self.name)
|
||||
call s:echom_verbose(3, '', 'Update to the upstream: ' . self.name)
|
||||
call s:start_job(l:cmd, self.name, self.seq + 1)
|
||||
return
|
||||
endif
|
||||
@ -272,7 +343,7 @@ function! s:job_exit_cb(id, errcode, event) dict abort
|
||||
" Update git submodule.
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'submodule', '--quiet',
|
||||
\ 'update', '--init', '--recursive']
|
||||
call s:echom_verbose(3, 'Updating submodules: ' . self.name)
|
||||
call s:echom_verbose(3, '', 'Updating submodules: ' . self.name)
|
||||
call s:start_job(l:cmd, self.name, self.seq + 1)
|
||||
return
|
||||
endif
|
||||
@ -280,6 +351,10 @@ function! s:job_exit_cb(id, errcode, event) dict abort
|
||||
|
||||
call s:generate_helptags(l:dir)
|
||||
|
||||
if l:pluginfo.subdir !=# ''
|
||||
call s:handle_subdir(l:pluginfo)
|
||||
endif
|
||||
|
||||
if has('nvim') && isdirectory(l:dir . '/rplugin')
|
||||
" Required for :UpdateRemotePlugins.
|
||||
call s:add_rtp(l:dir)
|
||||
@ -294,29 +369,26 @@ function! s:job_exit_cb(id, errcode, event) dict abort
|
||||
if l:pluginfo.stat.installed
|
||||
if l:updated
|
||||
let s:updated_plugins += 1
|
||||
call s:echom_verbose(1, 'Updated: ' . self.name)
|
||||
call s:echom_verbose(1, '', 'Updated: ' . self.name)
|
||||
else
|
||||
call s:echom_verbose(3, 'Already up-to-date: ' . self.name)
|
||||
call s:echom_verbose(3, '', 'Already up-to-date: ' . self.name)
|
||||
endif
|
||||
else
|
||||
let s:installed_plugins += 1
|
||||
call s:echom_verbose(1, 'Installed: ' . self.name)
|
||||
call s:echom_verbose(1, '', 'Installed: ' . self.name)
|
||||
endif
|
||||
let l:err = 0
|
||||
endif
|
||||
endif
|
||||
if l:err
|
||||
let s:error_plugins += 1
|
||||
echohl ErrorMsg
|
||||
call s:echom_verbose(1, 'Error while updating "' . self.name . '". Error code: ' . a:errcode)
|
||||
echohl None
|
||||
call s:echom_verbose(1, 'error', 'Error while updating "' . self.name . '". Error code: ' . a:errcode)
|
||||
endif
|
||||
|
||||
call s:decrement_job_count()
|
||||
endfunction
|
||||
|
||||
function! s:job_err_cb(id, message, event) dict abort
|
||||
echohl WarningMsg
|
||||
let l:mes = copy(a:message)
|
||||
if len(l:mes) > 0 && l:mes[-1] ==# ''
|
||||
" Remove the last empty line. It is redundant.
|
||||
@ -325,9 +397,8 @@ function! s:job_err_cb(id, message, event) dict abort
|
||||
for l:line in l:mes
|
||||
let l:line = substitute(l:line, "\t", ' ', 'g')
|
||||
call add(g:minpac#pluglist[self.name].stat.lines, l:line)
|
||||
call s:echom_verbose(2, self.name . ': ' . l:line)
|
||||
call s:echom_verbose(2, 'warning', self.name . ': ' . l:line)
|
||||
endfor
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
function! s:start_job(cmds, name, seq) abort
|
||||
@ -341,7 +412,7 @@ function! s:start_job(cmds, name, seq) abort
|
||||
endif
|
||||
|
||||
let l:quote_cmds = s:quote_cmds(a:cmds)
|
||||
call s:echom_verbose(4, 'start_job: cmds=' . string(l:quote_cmds))
|
||||
call s:echom_verbose(4, '', 'start_job: cmds=' . string(l:quote_cmds))
|
||||
let l:job = minpac#job#start(l:quote_cmds, {
|
||||
\ 'on_stderr': function('s:job_err_cb'),
|
||||
\ 'on_exit': function('s:job_exit_cb'),
|
||||
@ -350,9 +421,7 @@ function! s:start_job(cmds, name, seq) abort
|
||||
if l:job > 0
|
||||
" It worked!
|
||||
else
|
||||
echohl ErrorMsg
|
||||
echom 'Fail to execute: ' . a:cmds[0]
|
||||
echohl None
|
||||
call s:echom_verbose(1, 'error', 'Fail to execute: ' . a:cmds[0])
|
||||
call s:decrement_job_count()
|
||||
return 1
|
||||
endif
|
||||
@ -401,10 +470,43 @@ function! s:check_plugin_status(name) abort
|
||||
return 2
|
||||
endfunction
|
||||
|
||||
" Check whether the type was changed. If it was changed, rename the directory.
|
||||
function! s:prepare_plugin_dir(pluginfo) abort
|
||||
let l:dir = a:pluginfo.dir
|
||||
if !isdirectory(l:dir)
|
||||
if a:pluginfo.type ==# 'start'
|
||||
let l:dirtmp = substitute(l:dir, '/start/\ze[^/]\+$', '/opt/', '')
|
||||
else
|
||||
let l:dirtmp = substitute(l:dir, '/opt/\ze[^/]\+$', '/start/', '')
|
||||
endif
|
||||
if isdirectory(l:dirtmp)
|
||||
" The type was changed (start <-> opt).
|
||||
call rename(l:dirtmp, l:dir)
|
||||
endif
|
||||
endif
|
||||
|
||||
" Check subdir.
|
||||
if a:pluginfo.subdir !=# ''
|
||||
let l:name = a:pluginfo.name
|
||||
if a:pluginfo.type ==# 'start'
|
||||
let l:subdir = g:minpac#opt.minpac_start_dir_sub . '/' . l:name
|
||||
let l:otherdir = g:minpac#opt.minpac_opt_dir_sub . '/' . l:name
|
||||
else
|
||||
let l:subdir = g:minpac#opt.minpac_opt_dir_sub . '/' . l:name
|
||||
let l:otherdir = g:minpac#opt.minpac_start_dir_sub . '/' . l:name
|
||||
endif
|
||||
if isdirectory(l:otherdir) && !isdirectory(l:subdir)
|
||||
" The type was changed (start <-> opt).
|
||||
call delete(l:otherdir)
|
||||
call s:handle_subdir(a:pluginfo)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Update a single plugin.
|
||||
function! s:update_single_plugin(name, force) abort
|
||||
if !has_key(g:minpac#pluglist, a:name)
|
||||
echoerr 'Plugin not registered: ' . a:name
|
||||
call s:echoerr_verbose(1, 'Plugin not registered: ' . a:name)
|
||||
call s:decrement_job_count()
|
||||
return 1
|
||||
endif
|
||||
@ -417,41 +519,11 @@ function! s:update_single_plugin(name, force) abort
|
||||
let l:pluginfo.stat.prev_rev = ''
|
||||
let l:pluginfo.stat.submod = 0
|
||||
|
||||
if !isdirectory(l:dir)
|
||||
if g:minpac#pluglist[a:name].type ==# 'start'
|
||||
let l:dirtmp = substitute(l:dir, '/start/\ze[^/]\+$', '/opt/', '')
|
||||
else
|
||||
let l:dirtmp = substitute(l:dir, '/opt/\ze[^/]\+$', '/start/', '')
|
||||
endif
|
||||
|
||||
if !isdirectory(l:dirtmp)
|
||||
let l:pluginfo.stat.installed = 0
|
||||
if l:pluginfo.rev ==# ''
|
||||
let l:pluginfo.stat.upd_method = 1
|
||||
else
|
||||
let l:pluginfo.stat.upd_method = 2
|
||||
endif
|
||||
call s:echo_verbose(3, 'Cloning ' . a:name)
|
||||
|
||||
let l:cmd = [g:minpac#opt.git, 'clone', '--quiet', l:url, l:dir, '--no-single-branch']
|
||||
if l:pluginfo.depth > 0 && l:pluginfo.rev ==# ''
|
||||
let l:cmd += ['--depth=' . l:pluginfo.depth]
|
||||
endif
|
||||
if l:pluginfo.branch !=# ''
|
||||
let l:cmd += ['--branch=' . l:pluginfo.branch]
|
||||
endif
|
||||
else
|
||||
" The type was changed (start <-> opt).
|
||||
call rename(l:dirtmp, l:dir)
|
||||
call s:prepare_plugin_dir(l:pluginfo)
|
||||
if isdirectory(l:dir)
|
||||
let l:pluginfo.stat.installed = 1
|
||||
endif
|
||||
else
|
||||
let l:pluginfo.stat.installed = 1
|
||||
endif
|
||||
|
||||
if l:pluginfo.stat.installed == 1
|
||||
if l:pluginfo.frozen && !a:force
|
||||
call s:echom_verbose(3, 'Skipped: ' . a:name)
|
||||
call s:echom_verbose(3, '', 'Skipped: ' . a:name)
|
||||
call s:decrement_job_count()
|
||||
return 0
|
||||
endif
|
||||
@ -460,24 +532,54 @@ function! s:update_single_plugin(name, force) abort
|
||||
let l:pluginfo.stat.upd_method = l:ret
|
||||
if l:ret == 0
|
||||
" No need to update.
|
||||
call s:echom_verbose(3, 'Already up-to-date: ' . a:name)
|
||||
call s:echom_verbose(3, '', 'Already up-to-date: ' . a:name)
|
||||
call s:decrement_job_count()
|
||||
return 0
|
||||
elseif l:ret == 1
|
||||
" Same branch. Update by pull.
|
||||
call s:echo_verbose(3, 'Updating (pull): ' . a:name)
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'pull', '--quiet', '--ff-only', '--rebase=false']
|
||||
call s:echo_verbose(3, '', 'Updating (pull): ' . a:name)
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'pull', '--quiet']
|
||||
if l:pluginfo.pullmethod ==# 'autostash'
|
||||
let l:cmd += ['--rebase', '--autostash']
|
||||
else
|
||||
let l:cmd += ['--ff-only', '--rebase=false']
|
||||
endif
|
||||
elseif l:ret == 2
|
||||
" Different branch. Update by fetch & checkout.
|
||||
call s:echo_verbose(3, 'Updating (fetch): ' . a:name)
|
||||
call s:echo_verbose(3, '', 'Updating (fetch): ' . a:name)
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'fetch', '--depth', '999999']
|
||||
endif
|
||||
else
|
||||
let l:pluginfo.stat.installed = 0
|
||||
if l:pluginfo.rev ==# ''
|
||||
let l:pluginfo.stat.upd_method = 1
|
||||
else
|
||||
let l:pluginfo.stat.upd_method = 2
|
||||
endif
|
||||
call s:echo_verbose(3, '', 'Cloning ' . a:name)
|
||||
|
||||
let l:cmd = [g:minpac#opt.git, 'clone', '--quiet', l:url, l:dir, '--no-single-branch']
|
||||
if l:pluginfo.depth > 0 && l:pluginfo.rev ==# ''
|
||||
let l:cmd += ['--depth=' . l:pluginfo.depth]
|
||||
endif
|
||||
if l:pluginfo.branch !=# ''
|
||||
let l:cmd += ['--branch=' . l:pluginfo.branch]
|
||||
endif
|
||||
endif
|
||||
return s:start_job(l:cmd, a:name, 0)
|
||||
endfunction
|
||||
|
||||
function! s:start_update(names, force, id) abort
|
||||
for l:name in a:names
|
||||
call s:update_single_plugin(l:name, a:force)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Update all or specified plugin(s).
|
||||
function! minpac#impl#update(...) abort
|
||||
if g:minpac#opt.progress_open !=# 'none'
|
||||
call minpac#progress#open(['## minpac update progress ##', ''])
|
||||
endif
|
||||
let l:opt = extend(copy(get(a:000, 1, {})),
|
||||
\ {'do': ''}, 'keep')
|
||||
|
||||
@ -491,12 +593,12 @@ function! minpac#impl#update(...) abort
|
||||
let l:names = a:1
|
||||
let l:force = 1
|
||||
else
|
||||
echoerr 'Wrong parameter type. Must be a String or a List of Strings.'
|
||||
call s:echoerr_verbose(1, 'Wrong parameter type. Must be a String or a List of Strings.')
|
||||
return
|
||||
endif
|
||||
|
||||
if s:remain_jobs > 0
|
||||
echom 'Previous update has not been finished.'
|
||||
call s:echom_verbose(1, '', 'Previous update has not been finished.')
|
||||
return
|
||||
endif
|
||||
let s:remain_jobs = len(l:names)
|
||||
@ -505,15 +607,15 @@ function! minpac#impl#update(...) abort
|
||||
let s:installed_plugins = 0
|
||||
let s:finish_update_hook = l:opt.do
|
||||
|
||||
if g:minpac#opt.progress_open ==# 'none'
|
||||
" Disable the pager temporarily to avoid jobs being interrupted.
|
||||
if !exists('s:save_more')
|
||||
let s:save_more = &more
|
||||
endif
|
||||
set nomore
|
||||
endif
|
||||
|
||||
for l:name in l:names
|
||||
let ret = s:update_single_plugin(l:name, l:force)
|
||||
endfor
|
||||
call timer_start(1, function('s:start_update', [l:names, l:force]))
|
||||
endfunction
|
||||
|
||||
|
||||
@ -524,9 +626,9 @@ function! s:match_plugin(dir, packname, plugnames) abort
|
||||
let l:plugname = substitute(l:plugname, '\*', '.*', 'g')
|
||||
let l:plugname = substitute(l:plugname, '?', '.', 'g')
|
||||
if l:plugname =~# '/'
|
||||
let l:pat = '/pack/' . a:packname . '/' . l:plugname . '$'
|
||||
let l:pat = '/pack/' . a:packname . '\%(-sub\)\?' . '/' . l:plugname . '$'
|
||||
else
|
||||
let l:pat = '/pack/' . a:packname . '/\%(start\|opt\)/' . l:plugname . '$'
|
||||
let l:pat = '/pack/' . a:packname . '\%(-sub\)\?' . '/\%(start\|opt\)/' . l:plugname . '$'
|
||||
endif
|
||||
if has('win32')
|
||||
let l:pat = substitute(l:pat, '/', '[/\\\\]', 'g')
|
||||
@ -541,6 +643,7 @@ endfunction
|
||||
" Remove plugins that are not registered.
|
||||
function! minpac#impl#clean(...) abort
|
||||
let l:plugin_dirs = minpac#getpackages(g:minpac#opt.package_name)
|
||||
\ + minpac#getpackages(g:minpac#opt.package_name . '-sub')
|
||||
|
||||
if a:0 > 0
|
||||
" Going to remove only specified plugins.
|
||||
@ -574,7 +677,8 @@ function! minpac#impl#clean(...) abort
|
||||
endfor
|
||||
|
||||
let l:dir = (len(l:to_remove) > 1) ? 'directories' : 'directory'
|
||||
if input('Removing the above ' . l:dir . '. [y/N]? ') =~? '^y'
|
||||
|
||||
if !g:minpac#opt.confirm || input('Removing the above ' . l:dir . '. [y/N]? ') =~? '^y'
|
||||
echo "\n"
|
||||
let err = 0
|
||||
for l:item in l:to_remove
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
" ---------------------------------------------------------------------
|
||||
" minpac: A minimal package manager for Vim 8 (and Neovim)
|
||||
"
|
||||
" Maintainer: Ken Takata
|
||||
" Last Change: 2020-01-28
|
||||
" License: VIM License
|
||||
" URL: https://github.com/k-takata/minpac
|
||||
" ---------------------------------------------------------------------
|
||||
|
||||
let s:winid = 0
|
||||
let s:bufnr = 0
|
||||
|
||||
" Add a message to the minpac progress window
|
||||
function! minpac#progress#add_msg(type, msg) abort
|
||||
" Goes to the minpac progress window.
|
||||
if !win_gotoid(s:winid)
|
||||
echom 'warning: minpac progress window not found.'
|
||||
return
|
||||
endif
|
||||
setlocal modifiable
|
||||
let l:markers = {'': ' ', 'warning': 'W:', 'error': 'E:'}
|
||||
call append(line('$') - 1, l:markers[a:type] . ' ' . a:msg)
|
||||
setlocal nomodifiable
|
||||
endfunction
|
||||
|
||||
" Open the minpac progress window
|
||||
function! minpac#progress#open(msg) abort
|
||||
let l:bufname = '[minpac progress]'
|
||||
if s:bufnr != 0
|
||||
exec "silent! bwipe" s:bufnr
|
||||
endif
|
||||
if g:minpac#opt.progress_open ==# 'vertical'
|
||||
vertical topleft new
|
||||
elseif g:minpac#opt.progress_open ==# 'horizontal'
|
||||
topleft new
|
||||
elseif g:minpac#opt.progress_open ==# 'tab'
|
||||
tabnew
|
||||
endif
|
||||
let s:winid = win_getid()
|
||||
call append(0, a:msg)
|
||||
|
||||
setf minpacprgs
|
||||
call s:syntax()
|
||||
call s:mappings()
|
||||
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nomodifiable nospell
|
||||
silent file `=l:bufname`
|
||||
let s:bufnr = bufnr('')
|
||||
endfunction
|
||||
|
||||
function! s:syntax() abort
|
||||
syntax clear
|
||||
syn match minpacPrgsTitle /^## .* ##/
|
||||
syn match minpacPrgsError /^E: .*/
|
||||
syn match minpacPrgsWarning /^W: .*/
|
||||
syn match minpacPrgsInstalled /^ Installed:/
|
||||
syn match minpacPrgsUpdated /^ Updated:/
|
||||
syn match minpacPrgsUptodate /^ Already up-to-date:/
|
||||
syn region minpacPrgsString start='"' end='"'
|
||||
|
||||
hi def link minpacPrgsTitle Title
|
||||
hi def link minpacPrgsError ErrorMsg
|
||||
hi def link minpacPrgsWarning WarningMsg
|
||||
hi def link minpacPrgsInstalled Constant
|
||||
hi def link minpacPrgsUpdated Special
|
||||
hi def link minpacPrgsUptodate Comment
|
||||
hi def link minpacPrgsString String
|
||||
endfunction
|
||||
|
||||
function! s:mappings() abort
|
||||
nnoremap <silent><buffer> q :q<CR>
|
||||
nnoremap <silent><buffer> s :call minpac#status()<CR>
|
||||
endfunction
|
||||
|
||||
" vim: set ts=8 sw=2 et:
|
||||
@ -3,14 +3,20 @@
|
||||
"
|
||||
" Maintainer: Ken Takata
|
||||
" Created By: Kristijan Husak
|
||||
" Last Change: 2018-09-01
|
||||
" Last Change: 2020-01-28
|
||||
" License: VIM License
|
||||
" URL: https://github.com/k-takata/minpac
|
||||
" ---------------------------------------------------------------------
|
||||
|
||||
let s:results = []
|
||||
let s:bufnr = 0
|
||||
let s:git_sign = -1 " Support --no-show-signature option.
|
||||
|
||||
function! minpac#status#get(opt) abort
|
||||
let l:bufname = '[minpac status]'
|
||||
if s:bufnr != 0
|
||||
exec "silent! bwipe" s:bufnr
|
||||
endif
|
||||
let l:is_update_ran = minpac#impl#is_update_ran()
|
||||
let l:update_count = 0
|
||||
let l:install_count = 0
|
||||
@ -24,9 +30,18 @@ function! minpac#status#get(opt) abort
|
||||
if !isdirectory(l:dir)
|
||||
let l:plugin.status = 'Not installed'
|
||||
else
|
||||
let l:commits = minpac#impl#system([g:minpac#opt.git, '-C', l:dir, 'log',
|
||||
\ '--color=never', '--pretty=format:%h <<<<%D>>>> %s (%cr)', '--no-show-signature', 'HEAD...HEAD@{1}'
|
||||
\ ])
|
||||
let l:cmd = [g:minpac#opt.git, '-C', l:dir, 'log',
|
||||
\ '--color=never', '--pretty=format:%h <<<<%D>>>> %s (%cr)', 'HEAD...HEAD@{1}'
|
||||
\ ]
|
||||
let l:commits = minpac#impl#system(l:cmd + (s:git_sign ? ['--no-show-signature'] : []))
|
||||
if s:git_sign == -1
|
||||
if l:commits[0] == 128
|
||||
let s:git_sign = v:false
|
||||
let l:commits = minpac#impl#system(l:cmd)
|
||||
else
|
||||
let s:git_sign = v:true
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:plugin.lines = filter(l:commits[1], {-> v:val !=# ''})
|
||||
call map(l:plugin.lines,
|
||||
@ -95,6 +110,8 @@ function! minpac#status#get(opt) abort
|
||||
call s:syntax()
|
||||
call s:mappings()
|
||||
setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline nomodifiable nospell
|
||||
silent file `=l:bufname`
|
||||
let s:bufnr = bufnr('')
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
*minpac.txt* A minimal package manager for Vim 8 (and Neovim)
|
||||
|
||||
Version: 2.0
|
||||
Version: 3.0.0
|
||||
Author: Ken Takata
|
||||
License: The Vim License
|
||||
URL: https://github.com/k-takata/minpac
|
||||
@ -56,10 +56,16 @@ before that. Therefore, minpac should be installed under "opt" directory, and
|
||||
should be loaded using `packadd minpac`.
|
||||
|
||||
Windows ~
|
||||
|
||||
Vim:
|
||||
>
|
||||
cd /d %USERPROFILE%
|
||||
git clone https://github.com/k-takata/minpac.git ^
|
||||
vimfiles\pack\minpac\opt\minpac
|
||||
%USERPROFILE%\vimfiles\pack\minpac\opt\minpac
|
||||
<
|
||||
Neovim:
|
||||
>
|
||||
git clone https://github.com/k-takata/minpac.git ^
|
||||
%LOCALAPPDATA%\nvim\pack\minpac\opt\minpac
|
||||
<
|
||||
|
||||
Linux, macOS ~
|
||||
@ -79,6 +85,15 @@ Sample .vimrc ~
|
||||
|
||||
Basic sample
|
||||
>
|
||||
" Normally this if-block is not needed, because `:set nocp` is done
|
||||
" automatically when .vimrc is found. However, this might be useful
|
||||
" when you execute `vim -u .vimrc` from the command line.
|
||||
if &compatible
|
||||
" `:set nocp` has many side effects. Therefore this should be done
|
||||
" only when 'compatible' is set.
|
||||
set nocompatible
|
||||
endif
|
||||
|
||||
packadd minpac
|
||||
|
||||
call minpac#init()
|
||||
@ -94,6 +109,9 @@ Basic sample
|
||||
" Load the plugins right now. (optional)
|
||||
"packloadall
|
||||
<
|
||||
Minpac itself requires 'compatible' to be unset. However, the
|
||||
`if &compatible`-block is optional.
|
||||
|
||||
Customizing 'packpath'
|
||||
|
||||
If you want to use ".vim" directory instead of "vimfiles" even on Windows,
|
||||
@ -113,7 +131,7 @@ Advanced sample
|
||||
" Try to load minpac.
|
||||
packadd minpac
|
||||
|
||||
if !exists('*minpac#init')
|
||||
if !exists('g:loaded_minpac')
|
||||
" minpac is not available.
|
||||
|
||||
" Settings for plugin-less environment.
|
||||
@ -135,55 +153,14 @@ Advanced sample
|
||||
<
|
||||
Load minpac on demand
|
||||
|
||||
Very interestingly, minpac doesn't need to be loaded every time. Unlike
|
||||
other plugin managers, it is needed only when updating, installing or
|
||||
cleaning the plugins. This is because minpac itself doesn't handle the
|
||||
runtime path.
|
||||
|
||||
You can define a user command to load minpac, reload .vimrc to register the
|
||||
information of plugins, then call |minpac#update()|, |minpac#clean()| or
|
||||
|minpac#status()|. >
|
||||
|
||||
" For a paranoia.
|
||||
" Normally `:set nocp` is not needed, because it is done automatically
|
||||
" when .vimrc is found.
|
||||
if &compatible
|
||||
" `:set nocp` has many side effects. Therefore this should be done
|
||||
" only when 'compatible' is set.
|
||||
set nocompatible
|
||||
endif
|
||||
|
||||
if exists('*minpac#init')
|
||||
" minpac is loaded.
|
||||
call minpac#init()
|
||||
call minpac#add('k-takata/minpac', {'type': 'opt'})
|
||||
|
||||
" Additional plugins here.
|
||||
call minpac#add('vim-jp/syntax-vim-ex')
|
||||
...
|
||||
endif
|
||||
|
||||
" Plugin settings here.
|
||||
...
|
||||
|
||||
" Define user commands for updating/cleaning the plugins.
|
||||
" Each of them loads minpac, reloads .vimrc to register the
|
||||
" information of plugins, then performs the task.
|
||||
command! PackUpdate packadd minpac | source $MYVIMRC | call minpac#update('', {'do': 'call minpac#status()'})
|
||||
command! PackClean packadd minpac | source $MYVIMRC | call minpac#clean()
|
||||
command! PackStatus packadd minpac | source $MYVIMRC | call minpac#status()
|
||||
<
|
||||
Note that your .vimrc must be reloadable to use this. E.g.:
|
||||
|
||||
* `:set nocompatible` should not be executed twice to avoid side effects.
|
||||
* `:function!` should be used to define a user function.
|
||||
* `:command!` should be used to define a user command.
|
||||
* `:augroup!` should be used properly to avoid the same autogroups are
|
||||
defined twice.
|
||||
|
||||
Another way is defining a function to load minpac and register the
|
||||
information of plugins. >
|
||||
Very interestingly, minpac doesn't need to be loaded every time when you
|
||||
execute Vim. Unlike other plugin managers, it is needed only when updating,
|
||||
installing or cleaning the plugins. This is because minpac itself doesn't
|
||||
handle the runtime path.
|
||||
|
||||
You can define user commands to load minpac, register the information of
|
||||
plugins, then call |minpac#update()|, |minpac#clean()| or |minpac#status()|.
|
||||
>
|
||||
function! PackInit() abort
|
||||
packadd minpac
|
||||
|
||||
@ -202,13 +179,25 @@ Load minpac on demand
|
||||
" Define user commands for updating/cleaning the plugins.
|
||||
" Each of them calls PackInit() to load minpac and register
|
||||
" the information of plugins, then performs the task.
|
||||
command! PackUpdate call PackInit() | call minpac#update('', {'do': 'call minpac#status()'})
|
||||
command! PackUpdate call PackInit() | call minpac#update()
|
||||
command! PackClean call PackInit() | call minpac#clean()
|
||||
command! PackStatus call PackInit() | call minpac#status()
|
||||
command! PackStatus packadd minpac | call minpac#status()
|
||||
<
|
||||
This doesn't reload .vimrc, so the .vimrc doesn't need to be reloadable.
|
||||
However, if you make it reloadable, you can apply the changes to the .vimrc
|
||||
immediately by executing `:so $MYVIMRC | PackUpdate` .
|
||||
If you make your .vimrc reloadable, you can reflect the setting of the
|
||||
.vimrc immediately after you edit it by executing
|
||||
`:so $MYVIMRC | PackUpdate`. Or you can define the commands like this: >
|
||||
|
||||
command! PackUpdate source $MYVIMRC | call PackInit() | call minpac#update()
|
||||
command! PackClean source $MYVIMRC | call PackInit() | call minpac#clean()
|
||||
command! PackStatus packadd minpac | call minpac#status()
|
||||
<
|
||||
To make your .vimrc reloadable:
|
||||
|
||||
* `:set nocompatible` should not be executed twice to avoid side effects.
|
||||
* `:function!` should be used to define a user function.
|
||||
* `:command!` should be used to define a user command.
|
||||
* `:augroup!` should be used properly to avoid the same autogroups are
|
||||
defined twice.
|
||||
|
||||
|
||||
Sometimes, you may want to open a shell at the directory where a plugin is
|
||||
@ -255,6 +244,8 @@ functions. E.g.: >
|
||||
" To see plugins status:
|
||||
call minpac#status()
|
||||
<
|
||||
Or define commands by yourself as described in the previous section.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
FUNCTIONS *minpac-functions*
|
||||
@ -279,9 +270,31 @@ minpac#init([{config}]) *minpac#init()*
|
||||
3: Show start/end messages for each plugin.
|
||||
4: Show debug messages.
|
||||
Default: 2
|
||||
confirm Show interactive confirmation prompts, such as
|
||||
in |minpac#clean()|.
|
||||
Default: |TRUE|
|
||||
progress_open Specify how to show the progress of
|
||||
|minpac#update()|.
|
||||
"none": Do not open the progress window.
|
||||
(Compatible with minpac v2.0.x or earlier.)
|
||||
"horizontal": Open the progress window by
|
||||
splitting horizontally.
|
||||
"vertical": Open the progress window by
|
||||
splitting vertically.
|
||||
"tab": Open the progress window in a new tab.
|
||||
Default: "horizontal"
|
||||
status_open Default setting for the open option of
|
||||
|minpac#status()|.
|
||||
Default: "vertical"
|
||||
Default: "horizontal"
|
||||
status_auto Specify whether the status window will open
|
||||
automatically after |minpac#update()| is
|
||||
finished.
|
||||
|TRUE|: Open the status window automatically,
|
||||
when one or more plugins are updated or
|
||||
installed.
|
||||
|FALSE|: Do not open the status window
|
||||
automatically.
|
||||
Default: |FALSE|
|
||||
|
||||
All plugins will be installed under the following directories:
|
||||
|
||||
@ -312,8 +325,8 @@ minpac#add({url}[, {config}]) *minpac#add()*
|
||||
Default: derived from the repository name.
|
||||
type Type of the plugin. "start" or "opt".
|
||||
Default: "start"
|
||||
frozen If 1, the plugin will not be updated
|
||||
automatically. Default: 0
|
||||
frozen If |TRUE|, the plugin will not be updated
|
||||
automatically. Default: |FALSE|
|
||||
depth If >= 1, it is used as a depth to be cloned.
|
||||
Only effective when install the plugin newly.
|
||||
Default: 1 or specified value by
|
||||
@ -328,6 +341,13 @@ minpac#add({url}[, {config}]) *minpac#add()*
|
||||
do Post-update hook.
|
||||
See |minpac-post-update-hooks|.
|
||||
Default: empty
|
||||
subdir Subdirectory that contains Vim plugin.
|
||||
Default: empty
|
||||
pullmethod Specify how to update the plugin.
|
||||
Empty: Update with `--ff-only` option.
|
||||
"autostash": Update with `--rebase --autostash`
|
||||
options.
|
||||
Default: empty
|
||||
|
||||
The "branch" and "rev" options are slightly different.
|
||||
The "branch" option is used only when the plugin is newly installed.
|
||||
@ -347,6 +367,16 @@ minpac#add({url}[, {config}]) *minpac#add()*
|
||||
If you include "*" in "rev", minpac tries to checkout the latest tag
|
||||
name which matches the "rev".
|
||||
|
||||
When "subdir"" is specified, the plugin will be installed as usual
|
||||
(e.g. in `pack/minpac/start/pluginname`), however, another directory
|
||||
is created and a symlink (or a junction on Windows) will be created in
|
||||
it. E.g.: >
|
||||
|
||||
ln -s pack/minpac/start/pluginname/subdir \
|
||||
pack/minpac-sub/start/pluginname
|
||||
|
||||
< This way, Vim can load the plugin from its subdirectory.
|
||||
|
||||
|
||||
minpac#update([{name}[, {config}]]) *minpac#update()*
|
||||
Install or update all plugins or the specified plugin.
|
||||
@ -380,15 +410,16 @@ minpac#clean([{name}]) *minpac#clean()*
|
||||
|
||||
{name} is a name of a plugin. It can be a unique plugin name
|
||||
(|minpac-plugin_name|) or a plugin name with wildcards ("*" and "?"
|
||||
are supported).
|
||||
are supported). It can also be a list of plugin names.
|
||||
|
||||
If {name} is omitted, all plugins under the minpac directory will be
|
||||
checked. If unregistered plugins are found, they are listed and a
|
||||
prompt is shown. If you type "y", they will be removed.
|
||||
|
||||
If {name} is specified, matched plugins are listed (even they are
|
||||
registered with |minpac#add()|) and a prompt is shown. If you type
|
||||
"y", they will be removed. {name} can also be a list of plugin names.
|
||||
When called, matched plugins are listed (even they are registered with
|
||||
|minpac#add()|) and a prompt is shown. If you type "y", they will be
|
||||
removed. If the "confirm" option is not |TRUE|, the prompt will not
|
||||
be shown.
|
||||
|
||||
|
||||
minpac#getpluginfo({name}) *minpac#getpluginfo()*
|
||||
@ -401,7 +432,8 @@ minpac#getpluginfo({name}) *minpac#getpluginfo()*
|
||||
name Name of the plugin.
|
||||
url URL of the plugin repository.
|
||||
dir Local directory of the plugin.
|
||||
frozen If 1, the plugin is frozen.
|
||||
subdir Subdirectory that contains Vim plugin.
|
||||
frozen If |TRUE|, the plugin is frozen.
|
||||
type Type of the plugin.
|
||||
depth Depth to be cloned.
|
||||
branch Branch name to be cloned.
|
||||
@ -431,8 +463,8 @@ minpac#getpackages([{packname}[, {packtype}[, {plugname}[, {nameonly}]]]])
|
||||
{plugname} specifies a plugin name. Wildcards can be used. If omitted
|
||||
or an empty string is specified, "*" is used.
|
||||
|
||||
If {nameonly} is 1, plugin (or package) names are listed instead of
|
||||
the direcotries. Default is 0.
|
||||
If {nameonly} is |TRUE|, plugin (or package) names are listed instead
|
||||
of the direcotries. Default is |FALSE|.
|
||||
|
||||
E.g.: >
|
||||
|
||||
@ -462,7 +494,7 @@ minpac#status([{config}]) *minpac#status()*
|
||||
"vertical": Open in vertical split.
|
||||
"horizontal": Open in horizontal split.
|
||||
"tab": Open in a new tab.
|
||||
Default: "vertical" or specified value by
|
||||
Default: "horizontal" or specified value by
|
||||
|minpac#init()|.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@ -543,18 +575,27 @@ E.g.: >
|
||||
------------------------------------------------------------------------------
|
||||
MAPPINGS *minpac-mappings*
|
||||
|
||||
List of mappings available only in progress window.
|
||||
|
||||
*minpac-progress-s*
|
||||
s Open the status window.
|
||||
|
||||
*minpac-progress-q*
|
||||
q Exit the progress window.
|
||||
|
||||
|
||||
List of mappings available only in status window.
|
||||
|
||||
*minpac-<CR>*
|
||||
*minpac-status-<CR>*
|
||||
<CR> Preview the commit under the cursor.
|
||||
|
||||
*minpac-CTRL-j*
|
||||
*minpac-status-CTRL-j*
|
||||
<C-j> Jump to next package in list.
|
||||
|
||||
*minpac-CTRL-k*
|
||||
*minpac-status-CTRL-k*
|
||||
<C-k> Jump to previous package in list.
|
||||
|
||||
*minpac-q*
|
||||
*minpac-status-q*
|
||||
q Exit the status window.
|
||||
(Also works for commit preview window)
|
||||
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
minpac#add() minpac.txt /*minpac#add()*
|
||||
minpac#clean() minpac.txt /*minpac#clean()*
|
||||
minpac#getpackages() minpac.txt /*minpac#getpackages()*
|
||||
minpac#getpluginfo() minpac.txt /*minpac#getpluginfo()*
|
||||
minpac#getpluglist() minpac.txt /*minpac#getpluglist()*
|
||||
minpac#init() minpac.txt /*minpac#init()*
|
||||
minpac#status() minpac.txt /*minpac#status()*
|
||||
minpac#update() minpac.txt /*minpac#update()*
|
||||
minpac-<CR> minpac.txt /*minpac-<CR>*
|
||||
minpac-CTRL-j minpac.txt /*minpac-CTRL-j*
|
||||
minpac-CTRL-k minpac.txt /*minpac-CTRL-k*
|
||||
minpac-commands minpac.txt /*minpac-commands*
|
||||
minpac-concept minpac.txt /*minpac-concept*
|
||||
minpac-contents minpac.txt /*minpac-contents*
|
||||
minpac-finish-update-hooks minpac.txt /*minpac-finish-update-hooks*
|
||||
minpac-functions minpac.txt /*minpac-functions*
|
||||
minpac-hooks minpac.txt /*minpac-hooks*
|
||||
minpac-installation minpac.txt /*minpac-installation*
|
||||
minpac-mappings minpac.txt /*minpac-mappings*
|
||||
minpac-overview minpac.txt /*minpac-overview*
|
||||
minpac-plugin_name minpac.txt /*minpac-plugin_name*
|
||||
minpac-post-update-hooks minpac.txt /*minpac-post-update-hooks*
|
||||
minpac-q minpac.txt /*minpac-q*
|
||||
minpac-requirements minpac.txt /*minpac-requirements*
|
||||
minpac-usage minpac.txt /*minpac-usage*
|
||||
minpac.txt minpac.txt /*minpac.txt*
|
||||
@ -2,7 +2,7 @@
|
||||
" minpac: A minimal package manager for Vim 8 (and Neovim)
|
||||
"
|
||||
" Maintainer: Ken Takata
|
||||
" Last Change: 2018-09-01
|
||||
" Last Change: 2020-08-22
|
||||
" License: VIM License
|
||||
" URL: https://github.com/k-takata/minpac
|
||||
" ---------------------------------------------------------------------
|
||||
@ -11,125 +11,3 @@ if exists('g:loaded_minpac')
|
||||
finish
|
||||
endif
|
||||
let g:loaded_minpac = 1
|
||||
|
||||
|
||||
" Get a list of package/plugin directories.
|
||||
function! minpac#getpackages(...)
|
||||
return call("minpac#impl#getpackages", a:000)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:ensure_initialization() abort
|
||||
if !exists('g:minpac#opt')
|
||||
echohl WarningMsg
|
||||
echom 'Minpac has not been initialized. Use the default values.'
|
||||
echohl None
|
||||
call minpac#init()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Initialize minpac.
|
||||
function! minpac#init(...) abort
|
||||
let l:opt = extend(copy(get(a:000, 0, {})),
|
||||
\ {'dir': '', 'package_name': 'minpac', 'git': 'git', 'depth': 1, 'jobs': 8, 'verbose': 2, 'status_open': 'vertical'}, 'keep')
|
||||
|
||||
let g:minpac#opt = l:opt
|
||||
let g:minpac#pluglist = {}
|
||||
|
||||
let l:packdir = l:opt.dir
|
||||
if l:packdir ==# ''
|
||||
" If 'dir' is not specified, the first directory of 'packpath' is used.
|
||||
let l:packdir = split(&packpath, ',')[0]
|
||||
endif
|
||||
let l:opt.minpac_dir = l:packdir . '/pack/' . l:opt.package_name
|
||||
let l:opt.minpac_start_dir = l:opt.minpac_dir . '/start'
|
||||
let l:opt.minpac_opt_dir = l:opt.minpac_dir . '/opt'
|
||||
if !isdirectory(l:packdir)
|
||||
echoerr 'Pack directory not available: ' . l:packdir
|
||||
return
|
||||
endif
|
||||
if !isdirectory(l:opt.minpac_start_dir)
|
||||
call mkdir(l:opt.minpac_start_dir, 'p')
|
||||
endif
|
||||
if !isdirectory(l:opt.minpac_opt_dir)
|
||||
call mkdir(l:opt.minpac_opt_dir, 'p')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" Register the specified plugin.
|
||||
function! minpac#add(plugname, ...) abort
|
||||
call s:ensure_initialization()
|
||||
let l:opt = extend(copy(get(a:000, 0, {})),
|
||||
\ {'name': '', 'type': 'start', 'depth': g:minpac#opt.depth,
|
||||
\ 'frozen': 0, 'branch': '', 'rev': '', 'do': ''}, 'keep')
|
||||
|
||||
" URL
|
||||
if a:plugname =~? '^[-._0-9a-z]\+\/[-._0-9a-z]\+$'
|
||||
let l:opt.url = 'https://github.com/' . a:plugname . '.git'
|
||||
else
|
||||
let l:opt.url = a:plugname
|
||||
endif
|
||||
|
||||
" Name of the plugin
|
||||
if l:opt.name ==# ''
|
||||
let l:opt.name = matchstr(l:opt.url, '[/\\]\zs[^/\\]\+$')
|
||||
let l:opt.name = substitute(l:opt.name, '\C\.git$', '', '')
|
||||
endif
|
||||
if l:opt.name ==# ''
|
||||
echoerr 'Cannot extract the plugin name. (' . a:plugname . ')'
|
||||
return
|
||||
endif
|
||||
|
||||
" Loading type / Local directory
|
||||
if l:opt.type ==# 'start'
|
||||
let l:opt.dir = g:minpac#opt.minpac_start_dir . '/' . l:opt.name
|
||||
elseif l:opt.type ==# 'opt'
|
||||
let l:opt.dir = g:minpac#opt.minpac_opt_dir . '/' . l:opt.name
|
||||
else
|
||||
echoerr "Wrong type (must be 'start' or 'opt'): " . l:opt.type
|
||||
return
|
||||
endif
|
||||
|
||||
" Initialize the status
|
||||
let l:opt.stat = {'errcode': 0, 'lines': [], 'prev_rev': '', 'installed': -1}
|
||||
|
||||
" Add to pluglist
|
||||
let g:minpac#pluglist[l:opt.name] = l:opt
|
||||
endfunction
|
||||
|
||||
|
||||
" Update all or specified plugin(s).
|
||||
function! minpac#update(...)
|
||||
call s:ensure_initialization()
|
||||
return call("minpac#impl#update", a:000)
|
||||
endfunction
|
||||
|
||||
|
||||
" Remove plugins that are not registered.
|
||||
function! minpac#clean(...)
|
||||
call s:ensure_initialization()
|
||||
return call("minpac#impl#clean", a:000)
|
||||
endfunction
|
||||
|
||||
function! minpac#status(...)
|
||||
call s:ensure_initialization()
|
||||
let l:opt = extend(copy(get(a:000, 0, {})),
|
||||
\ {'open': g:minpac#opt.status_open}, 'keep')
|
||||
return minpac#status#get(l:opt)
|
||||
endfunction
|
||||
|
||||
|
||||
" Get information of specified plugin. Mainly for debugging.
|
||||
function! minpac#getpluginfo(name)
|
||||
call s:ensure_initialization()
|
||||
return g:minpac#pluglist[a:name]
|
||||
endfunction
|
||||
|
||||
|
||||
" Get a list of plugin information. Mainly for debugging.
|
||||
function! minpac#getpluglist()
|
||||
return g:minpac#pluglist
|
||||
endfunction
|
||||
|
||||
" vim: set ts=8 sw=2 et:
|
||||
|
||||
@ -7,8 +7,12 @@
|
||||
NO_PLUGINS = --noplugin # --not-a-term
|
||||
NO_INITS = -U NONE $(NO_PLUGINS)
|
||||
|
||||
# Tests using runtest.vim.
|
||||
# Individual tests.
|
||||
NEW_TESTS = \
|
||||
test_minpac
|
||||
|
||||
# Test targets that use runtest.vim.
|
||||
NEW_TESTS_RES = \
|
||||
test_minpac.res
|
||||
|
||||
# vim: ts=8 sw=8 sts=8
|
||||
|
||||
@ -10,14 +10,24 @@ VIMPROG = vim
|
||||
|
||||
.SUFFIXES: .res .vim
|
||||
|
||||
all: newtests report
|
||||
all: nolog newtests report
|
||||
|
||||
report:
|
||||
@echo ""
|
||||
@echo.
|
||||
@echo Test results:
|
||||
@if exist test.log ( type test.log & echo TEST FAILURE & exit /b 1 ) \
|
||||
else ( echo ALL DONE )
|
||||
|
||||
# Execute an individual new style test, e.g.:
|
||||
# nmake -f Make_dos.mak test_largefile
|
||||
$(NEW_TESTS):
|
||||
-if exist $@.res del $@.res
|
||||
-if exist test.log del test.log
|
||||
-if exist messages del messages
|
||||
@$(MAKE) -nologo -f Make_win.mak $@.res VIMPROG=$(VIMPROG)
|
||||
@type messages
|
||||
@if exist test.log exit 1
|
||||
|
||||
clean:
|
||||
-del *.res
|
||||
-if exist test.log del test.log
|
||||
@ -33,7 +43,10 @@ nolog:
|
||||
# to write and a lot easier to read and debug.
|
||||
# Limitation: Only works with the +eval feature.
|
||||
|
||||
newtests: $(NEW_TESTS)
|
||||
newtests: newtestssilent
|
||||
@if exist messages type messages
|
||||
|
||||
newtestssilent: $(NEW_TESTS_RES)
|
||||
|
||||
.vim.res:
|
||||
@echo "$(VIMPROG)" > vimcmd
|
||||
|
||||
@ -4,14 +4,18 @@
|
||||
|
||||
VIMPROG = vim
|
||||
|
||||
# Comment out this line to see the verbose output of tests.
|
||||
#
|
||||
# Catches SwapExists to avoid hanging at the ATTENTION prompt.
|
||||
REDIR_TEST_TO_NULL = --cmd 'au SwapExists * let v:swapchoice = "e"' > /dev/null
|
||||
|
||||
# The list of tests is common to all systems.
|
||||
# This defines NEW_TESTS.
|
||||
include Make_all.mak
|
||||
|
||||
.SUFFIXES: .res .vim
|
||||
|
||||
#all: newtests report
|
||||
all: newtestssilent report
|
||||
all: nolog newtests report
|
||||
|
||||
report:
|
||||
@echo
|
||||
@ -21,9 +25,20 @@ report:
|
||||
else echo ALL DONE; \
|
||||
fi"
|
||||
|
||||
# Execute an individual new style test, e.g.:
|
||||
# make test_largefile
|
||||
$(NEW_TESTS):
|
||||
rm -f $@.res test.log messages
|
||||
@MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $@.res VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE)
|
||||
@cat messages
|
||||
@if test -f test.log; then \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
-rm -rf *.res test.log messages
|
||||
-rm -rf pack
|
||||
|
||||
nolog:
|
||||
-rm -f test.log messages
|
||||
|
||||
@ -34,14 +49,15 @@ nolog:
|
||||
RUN_VIMTEST = $(VIMPROG) -u NONE
|
||||
|
||||
newtests: newtestssilent
|
||||
@/bin/sh -c "if test -f messages && grep -q 'SKIPPED\|FAILED' messages; then cat messages && if test -f test.log; then cat test.log; fi ; fi"
|
||||
@if test -f messages; then cat messages; fi
|
||||
|
||||
newtestssilent: $(NEW_TESTS)
|
||||
newtestssilent: $(NEW_TESTS_RES)
|
||||
|
||||
|
||||
.vim.res:
|
||||
@echo "$(RUN_VIMTEST)" > vimcmd
|
||||
$(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim
|
||||
@echo "$(VIMPROG)" > vimcmd
|
||||
@echo "$(RUN_VIMTEST)" >> vimcmd
|
||||
$(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL)
|
||||
@rm vimcmd
|
||||
|
||||
# vim: ts=8 sw=8 sts=8
|
||||
|
||||
@ -3,10 +3,26 @@
|
||||
" Errors are appended to the test.log file.
|
||||
"
|
||||
" To execute only specific test functions, add a second argument. It will be
|
||||
" matched against the names of the Test_ funtion. E.g.:
|
||||
" matched against the names of the Test_ function. E.g.:
|
||||
" ../vim -u NONE -S runtest.vim test_channel.vim open_delay
|
||||
" The output can be found in the "messages" file.
|
||||
"
|
||||
" If the environment variable $TEST_FILTER is set then only test functions
|
||||
" matching this pattern are executed. E.g. for sh/bash:
|
||||
" export TEST_FILTER=Test_channel
|
||||
" For csh:
|
||||
" setenv TEST_FILTER Test_channel
|
||||
"
|
||||
" While working on a test you can make $TEST_NO_RETRY non-empty to not retry:
|
||||
" export TEST_NO_RETRY=yes
|
||||
"
|
||||
" To ignore failure for tests that are known to fail in a certain environment,
|
||||
" set $TEST_MAY_FAIL to a comma separated list of function names. E.g. for
|
||||
" sh/bash:
|
||||
" export TEST_MAY_FAIL=Test_channel_one,Test_channel_other
|
||||
" The failure report will then not be included in the test.log file and
|
||||
" "make test" will not fail.
|
||||
"
|
||||
" The test script may contain anything, only functions that start with
|
||||
" "Test_" are special. These will be invoked and should contain assert
|
||||
" functions. See test_assert.vim for an example.
|
||||
@ -30,16 +46,32 @@
|
||||
|
||||
|
||||
" Without the +eval feature we can't run these tests, bail out.
|
||||
so small.vim
|
||||
silent! while 0
|
||||
qa!
|
||||
silent! endwhile
|
||||
|
||||
" In the GUI we can always change the screen size.
|
||||
if has('gui_running')
|
||||
set columns=80 lines=25
|
||||
endif
|
||||
|
||||
" Check that the screen size is at least 24 x 80 characters.
|
||||
if &lines < 24 || &columns < 80
|
||||
let error = 'Screen size too small! Tests require at least 24 lines with 80 characters'
|
||||
let error = 'Screen size too small! Tests require at least 24 lines with 80 characters, got ' .. &lines .. ' lines with ' .. &columns .. ' characters'
|
||||
echoerr error
|
||||
split test.log
|
||||
$put =error
|
||||
w
|
||||
cquit
|
||||
write
|
||||
split messages
|
||||
call append(line('$'), '')
|
||||
call append(line('$'), 'From ' . expand('%') . ':')
|
||||
call append(line('$'), error)
|
||||
write
|
||||
qa!
|
||||
endif
|
||||
|
||||
if has('reltime')
|
||||
let s:start_time = reltime()
|
||||
endif
|
||||
|
||||
" Common with all tests on all systems.
|
||||
@ -49,13 +81,31 @@ source setup.vim
|
||||
" This also enables use of line continuation.
|
||||
set nocp viminfo+=nviminfo
|
||||
|
||||
" Use utf-8 or latin1 by default, instead of whatever the system default
|
||||
" happens to be. Individual tests can overrule this at the top of the file.
|
||||
if has('multi_byte')
|
||||
" Use utf-8 by default, instead of whatever the system default happens to be.
|
||||
" Individual tests can overrule this at the top of the file and use
|
||||
" g:orig_encoding if needed.
|
||||
let g:orig_encoding = &encoding
|
||||
set encoding=utf-8
|
||||
else
|
||||
set encoding=latin1
|
||||
|
||||
" REDIR_TEST_TO_NULL has a very permissive SwapExists autocommand which is for
|
||||
" the test_name.vim file itself. Replace it here with a more restrictive one,
|
||||
" so we still catch mistakes.
|
||||
let s:test_script_fname = expand('%')
|
||||
au! SwapExists * call HandleSwapExists()
|
||||
func HandleSwapExists()
|
||||
if exists('g:ignoreSwapExists')
|
||||
return
|
||||
endif
|
||||
" Ignore finding a swap file for the test script (the user might be
|
||||
" editing it and do ":make test_name") and the output file.
|
||||
" Report finding another swap file and chose 'q' to avoid getting stuck.
|
||||
if expand('<afile>') == 'messages' || expand('<afile>') =~ s:test_script_fname
|
||||
let v:swapchoice = 'e'
|
||||
else
|
||||
call assert_report('Unexpected swap file: ' .. v:swapname)
|
||||
let v:swapchoice = 'q'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Avoid stopping at the "hit enter" prompt
|
||||
set nomore
|
||||
@ -63,11 +113,29 @@ set nomore
|
||||
" Output all messages in English.
|
||||
lang mess C
|
||||
|
||||
" suppress menu translation
|
||||
if has('gui_running') && exists('did_install_default_menus')
|
||||
source $VIMRUNTIME/delmenu.vim
|
||||
set langmenu=none
|
||||
source $VIMRUNTIME/menu.vim
|
||||
endif
|
||||
|
||||
" Always use forward slashes.
|
||||
set shellslash
|
||||
|
||||
let s:srcdir = expand('%:p:h:h')
|
||||
|
||||
if has('win32')
|
||||
" avoid prompt that is long or contains a line break
|
||||
let $PROMPT = '$P$G'
|
||||
" On MS-Windows t_md and t_me are Vim specific escape sequences.
|
||||
let s:t_bold = "\x1b[1m"
|
||||
let s:t_normal = "\x1b[m"
|
||||
else
|
||||
let s:t_bold = &t_md
|
||||
let s:t_normal = &t_me
|
||||
endif
|
||||
|
||||
" Prepare for calling test_garbagecollect_now().
|
||||
let v:testing = 1
|
||||
|
||||
@ -88,6 +156,9 @@ endfunc
|
||||
|
||||
func RunTheTest(test)
|
||||
echo 'Executing ' . a:test
|
||||
if has('reltime')
|
||||
let func_start = reltime()
|
||||
endif
|
||||
|
||||
" Avoid stopping at the "hit enter" prompt
|
||||
set nomore
|
||||
@ -117,17 +188,13 @@ func RunTheTest(test)
|
||||
endtry
|
||||
endif
|
||||
|
||||
call add(s:messages, 'Executing ' . a:test)
|
||||
let s:done += 1
|
||||
|
||||
if a:test =~ 'Test_nocatch_'
|
||||
" Function handles errors itself. This avoids skipping commands after the
|
||||
" error.
|
||||
exe 'call ' . a:test
|
||||
else
|
||||
try
|
||||
let s:test = a:test
|
||||
au VimLeavePre * call EarlyExit(s:test)
|
||||
au VimLeavePre * call EarlyExit(g:testfunc)
|
||||
exe 'call ' . a:test
|
||||
au! VimLeavePre
|
||||
catch /^\cskipped/
|
||||
@ -138,6 +205,10 @@ func RunTheTest(test)
|
||||
endtry
|
||||
endif
|
||||
|
||||
" In case 'insertmode' was set and something went wrong, make sure it is
|
||||
" reset to avoid trouble with anything else.
|
||||
set noinsertmode
|
||||
|
||||
if exists("*TearDown")
|
||||
try
|
||||
call TearDown()
|
||||
@ -146,8 +217,15 @@ func RunTheTest(test)
|
||||
endtry
|
||||
endif
|
||||
|
||||
" Clear any autocommands
|
||||
" Clear any autocommands and put back the catch-all for SwapExists.
|
||||
au!
|
||||
au SwapExists * call HandleSwapExists()
|
||||
|
||||
" Check for and close any stray popup windows.
|
||||
if has('popupwin')
|
||||
call assert_equal([], popup_list())
|
||||
call popup_clear(1)
|
||||
endif
|
||||
|
||||
" Close any extra tab pages and windows and make the current one not modified.
|
||||
while tabpagenr('$') > 1
|
||||
@ -168,13 +246,34 @@ func RunTheTest(test)
|
||||
endwhile
|
||||
|
||||
exe 'cd ' . save_cwd
|
||||
|
||||
let message = 'Executed ' . a:test
|
||||
if has('reltime')
|
||||
let message ..= repeat(' ', 50 - len(message))
|
||||
let time = reltime(func_start)
|
||||
if has('float') && reltimefloat(time) > 0.1
|
||||
let message = s:t_bold .. message
|
||||
endif
|
||||
let message ..= ' in ' .. reltimestr(time) .. ' seconds'
|
||||
if has('float') && reltimefloat(time) > 0.1
|
||||
let message ..= s:t_normal
|
||||
endif
|
||||
endif
|
||||
call add(s:messages, message)
|
||||
let s:done += 1
|
||||
endfunc
|
||||
|
||||
func AfterTheTest()
|
||||
func AfterTheTest(func_name)
|
||||
if len(v:errors) > 0
|
||||
if match(s:may_fail_list, '^' .. a:func_name) >= 0
|
||||
let s:fail_expected += 1
|
||||
call add(s:errors_expected, 'Found errors in ' . g:testfunc . ':')
|
||||
call extend(s:errors_expected, v:errors)
|
||||
else
|
||||
let s:fail += 1
|
||||
call add(s:errors, 'Found errors in ' . s:test . ':')
|
||||
call add(s:errors, 'Found errors in ' . g:testfunc . ':')
|
||||
call extend(s:errors, v:errors)
|
||||
endif
|
||||
let v:errors = []
|
||||
endif
|
||||
endfunc
|
||||
@ -190,7 +289,7 @@ endfunc
|
||||
|
||||
" This function can be called by a test if it wants to abort testing.
|
||||
func FinishTesting()
|
||||
call AfterTheTest()
|
||||
call AfterTheTest('')
|
||||
|
||||
" Don't write viminfo on exit.
|
||||
set viminfo=
|
||||
@ -198,7 +297,7 @@ func FinishTesting()
|
||||
" Clean up files created by setup.vim
|
||||
call delete('XfakeHOME', 'rf')
|
||||
|
||||
if s:fail == 0
|
||||
if s:fail == 0 && s:fail_expected == 0
|
||||
" Success, create the .res file so that make knows it's done.
|
||||
exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
|
||||
write
|
||||
@ -214,10 +313,22 @@ func FinishTesting()
|
||||
endif
|
||||
|
||||
if s:done == 0
|
||||
let message = 'NO tests executed'
|
||||
if s:filtered > 0
|
||||
let message = "NO tests match $TEST_FILTER: '" .. $TEST_FILTER .. "'"
|
||||
else
|
||||
let message = 'NO tests executed'
|
||||
endif
|
||||
else
|
||||
if s:filtered > 0
|
||||
call add(s:messages, "Filtered " .. s:filtered .. " tests with $TEST_FILTER")
|
||||
endif
|
||||
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
|
||||
endif
|
||||
if s:done > 0 && has('reltime')
|
||||
let message = s:t_bold .. message .. repeat(' ', 40 - len(message))
|
||||
let message ..= ' in ' .. reltimestr(reltime(s:start_time)) .. ' seconds'
|
||||
let message ..= s:t_normal
|
||||
endif
|
||||
echo message
|
||||
call add(s:messages, message)
|
||||
if s:fail > 0
|
||||
@ -226,6 +337,12 @@ func FinishTesting()
|
||||
call add(s:messages, message)
|
||||
call extend(s:messages, s:errors)
|
||||
endif
|
||||
if s:fail_expected > 0
|
||||
let message = s:fail_expected . ' FAILED (matching $TEST_MAY_FAIL):'
|
||||
echo message
|
||||
call add(s:messages, message)
|
||||
call extend(s:messages, s:errors_expected)
|
||||
endif
|
||||
|
||||
" Add SKIPPED messages
|
||||
call extend(s:messages, s:skipped)
|
||||
@ -245,15 +362,20 @@ endfunc
|
||||
let g:testname = expand('%')
|
||||
let s:done = 0
|
||||
let s:fail = 0
|
||||
let s:fail_expected = 0
|
||||
let s:errors = []
|
||||
let s:errors_expected = []
|
||||
let s:messages = []
|
||||
let s:skipped = []
|
||||
if expand('%') =~ 'test_vimscript.vim'
|
||||
" this test has intentional s:errors, don't use try/catch.
|
||||
" this test has intentional errors, don't use try/catch.
|
||||
source %
|
||||
else
|
||||
try
|
||||
source %
|
||||
catch /^\cskipped/
|
||||
call add(s:messages, ' Skipped')
|
||||
call add(s:skipped, 'SKIPPED ' . expand('%') . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
|
||||
catch
|
||||
let s:fail += 1
|
||||
call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
|
||||
@ -261,49 +383,90 @@ else
|
||||
endif
|
||||
|
||||
" Names of flaky tests.
|
||||
let s:flaky = [
|
||||
let s:flaky_tests = [
|
||||
\ ]
|
||||
|
||||
" Locate Test_ functions and execute them.
|
||||
redir @q
|
||||
silent function /^Test_
|
||||
redir END
|
||||
let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
|
||||
let s:tests = split(substitute(@q, '\(function\|def\) \(\k*()\)', '\2', 'g'))
|
||||
|
||||
" If there is an extra argument filter the function names against it.
|
||||
if argc() > 1
|
||||
let s:tests = filter(s:tests, 'v:val =~ argv(1)')
|
||||
endif
|
||||
|
||||
" If the environment variable $TEST_FILTER is set then filter the function
|
||||
" names against it.
|
||||
let s:filtered = 0
|
||||
if $TEST_FILTER != ''
|
||||
let s:filtered = len(s:tests)
|
||||
let s:tests = filter(s:tests, 'v:val =~ $TEST_FILTER')
|
||||
let s:filtered -= len(s:tests)
|
||||
endif
|
||||
|
||||
let s:may_fail_list = []
|
||||
if $TEST_MAY_FAIL != ''
|
||||
" Split the list at commas and add () to make it match g:testfunc.
|
||||
let s:may_fail_list = split($TEST_MAY_FAIL, ',')->map({i, v -> v .. '()'})
|
||||
endif
|
||||
|
||||
" Execute the tests in alphabetical order.
|
||||
for s:test in sort(s:tests)
|
||||
for g:testfunc in sort(s:tests)
|
||||
" Silence, please!
|
||||
silent! set belloff=all
|
||||
let prev_error = ''
|
||||
let total_errors = []
|
||||
let g:run_nr = 1
|
||||
|
||||
call RunTheTest(s:test)
|
||||
" A test can set g:test_is_flaky to retry running the test.
|
||||
let g:test_is_flaky = 0
|
||||
|
||||
if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
|
||||
call add(s:messages, 'Found errors in ' . s:test . ':')
|
||||
call RunTheTest(g:testfunc)
|
||||
|
||||
" Repeat a flaky test. Give up when:
|
||||
" - $TEST_NO_RETRY is not empty
|
||||
" - it fails again with the same message
|
||||
" - it fails five times (with a different message)
|
||||
if len(v:errors) > 0
|
||||
\ && $TEST_NO_RETRY == ''
|
||||
\ && (index(s:flaky_tests, g:testfunc) >= 0
|
||||
\ || g:test_is_flaky)
|
||||
while 1
|
||||
call add(s:messages, 'Found errors in ' . g:testfunc . ':')
|
||||
call extend(s:messages, v:errors)
|
||||
call add(s:messages, 'Flaky test failed, running it again')
|
||||
let first_run = v:errors
|
||||
|
||||
" Flakiness is often caused by the system being very busy. Sleep a couple
|
||||
" of seconds to have a higher chance of succeeding the second time.
|
||||
call add(total_errors, 'Run ' . g:run_nr . ':')
|
||||
call extend(total_errors, v:errors)
|
||||
|
||||
if g:run_nr == 5 || prev_error == v:errors[0]
|
||||
call add(total_errors, 'Flaky test failed too often, giving up')
|
||||
let v:errors = total_errors
|
||||
break
|
||||
endif
|
||||
|
||||
call add(s:messages, 'Flaky test failed, running it again')
|
||||
|
||||
" Flakiness is often caused by the system being very busy. Sleep a
|
||||
" couple of seconds to have a higher chance of succeeding the second
|
||||
" time.
|
||||
sleep 2
|
||||
|
||||
let prev_error = v:errors[0]
|
||||
let v:errors = []
|
||||
call RunTheTest(s:test)
|
||||
if len(v:errors) > 0
|
||||
let second_run = v:errors
|
||||
let v:errors = ['First run:']
|
||||
call extend(v:errors, first_run)
|
||||
call add(v:errors, 'Second run:')
|
||||
call extend(v:errors, second_run)
|
||||
let g:run_nr += 1
|
||||
|
||||
call RunTheTest(g:testfunc)
|
||||
|
||||
if len(v:errors) == 0
|
||||
" Test passed on rerun.
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
|
||||
call AfterTheTest()
|
||||
call AfterTheTest(g:testfunc)
|
||||
endfor
|
||||
|
||||
call FinishTesting()
|
||||
|
||||
@ -21,20 +21,24 @@ func Test_minpac_init()
|
||||
call assert_equal(1, g:minpac#opt.depth)
|
||||
call assert_equal(8, g:minpac#opt.jobs)
|
||||
call assert_equal(2, g:minpac#opt.verbose)
|
||||
call assert_equal('vertical', g:minpac#opt.status_open)
|
||||
call assert_equal('horizontal', g:minpac#opt.progress_open)
|
||||
call assert_equal('horizontal', g:minpac#opt.status_open)
|
||||
call assert_equal(v:false, g:minpac#opt.status_auto)
|
||||
call assert_equal({}, minpac#getpluglist())
|
||||
|
||||
let g:minpac#pluglist.foo = 'bar'
|
||||
|
||||
" Change settings
|
||||
call minpac#init({'package_name': 'm', 'git': 'foo', 'depth': 10, 'jobs': 2, 'verbose': 1, 'status_open': 'horizontal'})
|
||||
call minpac#init({'package_name': 'm', 'git': 'foo', 'depth': 10, 'jobs': 2, 'verbose': 1, 'progress_open': 'tab', 'status_open': 'vertical', 'status_auto': v:true})
|
||||
call assert_true(isdirectory('pack/m/start'))
|
||||
call assert_true(isdirectory('pack/m/opt'))
|
||||
call assert_equal('foo', g:minpac#opt.git)
|
||||
call assert_equal(10, g:minpac#opt.depth)
|
||||
call assert_equal(2, g:minpac#opt.jobs)
|
||||
call assert_equal(1, g:minpac#opt.verbose)
|
||||
call assert_equal('horizontal', g:minpac#opt.status_open)
|
||||
call assert_equal('tab', g:minpac#opt.progress_open)
|
||||
call assert_equal('vertical', g:minpac#opt.status_open)
|
||||
call assert_equal(v:true, g:minpac#opt.status_auto)
|
||||
call assert_equal({}, minpac#getpluglist())
|
||||
|
||||
call delete('pack', 'rf')
|
||||
@ -51,24 +55,28 @@ func Test_minpac_add()
|
||||
let p = minpac#getpluginfo('minpac')
|
||||
call assert_equal('https://github.com/k-takata/minpac.git', p.url)
|
||||
call assert_match('/pack/minpac/start/minpac$', p.dir)
|
||||
call assert_equal(0, p.frozen)
|
||||
call assert_equal(v:false, p.frozen)
|
||||
call assert_equal('start', p.type)
|
||||
call assert_equal('', p.branch)
|
||||
call assert_equal(1, p.depth)
|
||||
call assert_equal('', p.do)
|
||||
call assert_equal('', p.rev)
|
||||
call assert_equal('', p.subdir)
|
||||
call assert_equal('', p.pullmethod)
|
||||
|
||||
" With configuration
|
||||
call minpac#add('k-takata/minpac', {'type': 'opt', 'frozen': 1, 'branch': 'master', 'depth': 10, 'rev': 'abcdef'})
|
||||
call minpac#add('k-takata/minpac', {'type': 'opt', 'frozen': v:true, 'branch': 'master', 'depth': 10, 'rev': 'abcdef', 'subdir': 'dir', 'pullmethod': 'autostash'})
|
||||
let p = minpac#getpluginfo('minpac')
|
||||
call assert_equal('https://github.com/k-takata/minpac.git', p.url)
|
||||
call assert_match('/pack/minpac/opt/minpac$', p.dir)
|
||||
call assert_equal(1, p.frozen)
|
||||
call assert_equal(v:true, p.frozen)
|
||||
call assert_equal('opt', p.type)
|
||||
call assert_equal('master', p.branch)
|
||||
call assert_equal(10, p.depth)
|
||||
call assert_equal('', p.do)
|
||||
call assert_equal('abcdef', p.rev)
|
||||
call assert_equal('dir', p.subdir)
|
||||
call assert_equal('autostash', p.pullmethod)
|
||||
|
||||
" SSH URL
|
||||
call minpac#add('git@github.com:k-takata/minpac.git', {'name': 'm'})
|
||||
@ -189,7 +197,7 @@ func Test_minpac_update()
|
||||
let g:finish_update = 0
|
||||
call minpac#update('', {'do': 'let g:finish_update = 1'})
|
||||
while g:finish_update == 0
|
||||
sleep 1
|
||||
sleep 100m
|
||||
endwhile
|
||||
call assert_equal(1, g:post_update)
|
||||
call assert_true(isdirectory('pack/minpac/opt/minpac'))
|
||||
@ -211,7 +219,7 @@ func Test_minpac_update()
|
||||
\ l:finish_update
|
||||
\ ]}})
|
||||
while l:finish_update == 0
|
||||
sleep 1
|
||||
sleep 100m
|
||||
endwhile
|
||||
call assert_equal(1, l:post_update)
|
||||
call assert_true(isdirectory('pack/minpac/start/hg-vim'))
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
set CACHED=yes
|
||||
set DL=yes
|
||||
py tools\dl-kaoriya-vim.py -c > release-info.txt
|
||||
py tools\dl-vim-kt.py -c > release-info.txt
|
||||
if ERRORLEVEL 1 (
|
||||
rem Maybe this is a PR build and reaches the limit rate of GitHub API.
|
||||
set DL=no
|
||||
@ -15,7 +15,7 @@ if ERRORLEVEL 1 (
|
||||
)
|
||||
if "%DL%"=="yes" (
|
||||
echo Download the latest Vim.
|
||||
py tools\dl-kaoriya-vim.py --arch win64 --filename vim.zip --force --noprogress
|
||||
py tools\dl-vim-kt.py --arch win64 --filename vim.zip --force --noprogress
|
||||
if not ERRORLEVEL 1 (
|
||||
move /y vim.zip downloads > nul
|
||||
copy /y release-info.txt downloads > nul
|
||||
@ -29,4 +29,3 @@ if "%DL%"=="yes" (
|
||||
echo Use cached version of Vim.
|
||||
)
|
||||
7z x downloads\vim.zip > nul
|
||||
move vim??-kaoriya-win64 vim-kaoriya-win64 > nul
|
||||
136
private_dot_config/nvim/pack/minpac/opt/minpac/tools/dl-vim-kt.py
Executable file
136
private_dot_config/nvim/pack/minpac/opt/minpac/tools/dl-vim-kt.py
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Download the latest vim-kt from the GitHub releases
|
||||
|
||||
import argparse
|
||||
import calendar
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import urllib.request, urllib.error
|
||||
|
||||
# Repository Name
|
||||
repo_name = 'k-takata/vim-kt'
|
||||
gh_releases_url = 'https://api.github.com/repos/' + repo_name + '/releases'
|
||||
|
||||
# Asset name checker
|
||||
def does_skip_asset(asset):
|
||||
return asset['name'].find('pdb') >= 0 or asset['name'].find('zip') >= 0
|
||||
|
||||
# Arguments properties
|
||||
arg_desc = 'Download the latest vim-kt from the GitHub releases'
|
||||
arg_archs = ['all', 'win32', 'win64']
|
||||
arg_default_arch = 'all'
|
||||
arg_allow_prerelease = False
|
||||
|
||||
|
||||
# Parse arguments
|
||||
def parse_args():
|
||||
global parser
|
||||
parser = argparse.ArgumentParser(description=arg_desc)
|
||||
parser.add_argument('-c', '--check', action='store_true',
|
||||
help='only check the information of the latest release')
|
||||
parser.add_argument('--noprogress', action='store_true',
|
||||
help="Don't show the progress")
|
||||
parser.add_argument('-f', '--force', action='store_true',
|
||||
help='overwrite the download file')
|
||||
parser.add_argument('-n', '--filename', type=str, action='store',
|
||||
help='filename to save')
|
||||
parser.add_argument('-p', '--prerelease', action='store_true',
|
||||
default=arg_allow_prerelease,
|
||||
help='Allow downloading prerelease')
|
||||
parser.add_argument('-a', '--arch', type=str, action='store',
|
||||
choices=arg_archs, default=arg_default_arch,
|
||||
help='architecture to download')
|
||||
parser.add_argument('--auth', type=str, action='store',
|
||||
default=os.getenv('AUTH_TOKEN'),
|
||||
metavar="TOKEN", help='GitHub API token (Environment variable AUTH_TOKEN can be also used.)')
|
||||
return parser.parse_args()
|
||||
|
||||
# Get information of GitHub release
|
||||
# see: https://developer.github.com/v3/repos/releases/
|
||||
def get_rel_info(url, auth):
|
||||
if auth:
|
||||
# Unauthenticated requests are limited up to 60 requests per hour.
|
||||
# Authenticated requests are allowed up to 5,000 requests per hour.
|
||||
# See: https://developer.github.com/v3/#rate-limiting
|
||||
request = urllib.request.Request(url)
|
||||
request.add_header("Authorization", "token " + auth)
|
||||
else:
|
||||
request = url
|
||||
try:
|
||||
response = urllib.request.urlopen(request)
|
||||
except urllib.error.HTTPError as err:
|
||||
print('GitHub release not found. (%s)' % err.reason, file=sys.stderr)
|
||||
exit(1)
|
||||
return json.load(io.StringIO(str(response.read(), 'utf-8')))
|
||||
|
||||
# Show progress
|
||||
def reporthook(count, blocksize, totalsize):
|
||||
size = count * blocksize
|
||||
if totalsize <= 0:
|
||||
print("\r{:,}".format(size))
|
||||
else:
|
||||
size = min(size, totalsize)
|
||||
print("\r{:,} / {:,} ({:.1%})".format(size, totalsize, size / totalsize), end='')
|
||||
|
||||
# Download the files
|
||||
def download(args, rel_info):
|
||||
for asset in rel_info['assets']:
|
||||
if args.filename:
|
||||
name = args.filename
|
||||
else:
|
||||
name = asset['name']
|
||||
if does_skip_asset(asset):
|
||||
continue
|
||||
if args.arch != 'all' and asset['name'].find(args.arch) < 0:
|
||||
continue
|
||||
if os.path.isfile(name) and not args.force:
|
||||
print('File exists:', name)
|
||||
continue
|
||||
print('Downloading from:', asset['browser_download_url'])
|
||||
print('Downloading to:', name)
|
||||
if args.noprogress:
|
||||
hook = None
|
||||
else:
|
||||
hook = reporthook
|
||||
urllib.request.urlretrieve(asset['browser_download_url'], name, hook)
|
||||
# Set timestamp
|
||||
asset_time = time.strptime(asset['updated_at'], '%Y-%m-%dT%H:%M:%SZ')
|
||||
os.utime(name, times=(time.time(), calendar.timegm(asset_time)))
|
||||
if not args.noprogress:
|
||||
print()
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
if args.filename and args.arch == 'all':
|
||||
parser.error('-a must be specified when you specify -n.')
|
||||
|
||||
if args.prerelease:
|
||||
rels_info = get_rel_info(gh_releases_url, args.auth)
|
||||
for rel in rels_info:
|
||||
if rel['draft']:
|
||||
continue
|
||||
gh_release_url = rel['url']
|
||||
break
|
||||
else:
|
||||
print('GitHub release not found.', file=sys.stderr)
|
||||
exit(1)
|
||||
else:
|
||||
gh_release_url = gh_releases_url + '/latest'
|
||||
|
||||
rel_info = get_rel_info(gh_release_url, args.auth)
|
||||
print('Last release:', rel_info['name'])
|
||||
print('Created at:', rel_info['created_at'])
|
||||
|
||||
if args.check:
|
||||
exit(0)
|
||||
|
||||
download(args, rel_info)
|
||||
exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,102 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Download the latest KaoriYa Vim from the GitHub release
|
||||
|
||||
import argparse
|
||||
import calendar
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import urllib.request, urllib.error
|
||||
|
||||
# Repository Name
|
||||
repo_name = 'koron/vim-kaoriya'
|
||||
gh_release_url = 'https://api.github.com/repos/' + repo_name + '/releases/latest'
|
||||
|
||||
# Asset name checker
|
||||
def does_skip_asset(asset):
|
||||
return asset['name'].find('pdb') >= 0
|
||||
|
||||
# Arguments properties
|
||||
arg_desc = 'Download the latest KaoriYa Vim from the GitHub release'
|
||||
arg_archs = ['all', 'win32', 'win64']
|
||||
arg_default_arch = 'all'
|
||||
|
||||
# Parse arguments
|
||||
parser = argparse.ArgumentParser(description=arg_desc)
|
||||
parser.add_argument('-c', '--check', action='store_true',
|
||||
help='only check the information of the latest release')
|
||||
parser.add_argument('-p', '--noprogress', action='store_true',
|
||||
help="Don't show the progress")
|
||||
parser.add_argument('-f', '--force', action='store_true',
|
||||
help='overwrite the download file')
|
||||
parser.add_argument('-n', '--filename', type=str, action='store',
|
||||
help='filename to save')
|
||||
parser.add_argument('-a', '--arch', type=str, action='store',
|
||||
choices=arg_archs, default=arg_default_arch,
|
||||
help='architecture to download')
|
||||
parser.add_argument('--auth', type=str, action='store',
|
||||
default=os.getenv('AUTH_TOKEN'),
|
||||
metavar="TOKEN", help='GitHub API token (Environment variable AUTH_TOKEN can be also used.)')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.filename and args.arch == 'all':
|
||||
parser.error('-a must be specified when you specify -n.')
|
||||
|
||||
# Get information of GitHub release
|
||||
# see: https://developer.github.com/v3/repos/releases/
|
||||
if args.auth:
|
||||
# Unauthenticated requests are limited up to 60 requests per hour.
|
||||
# Authenticated requests are allowed up to 5,000 requests per hour.
|
||||
# See: https://developer.github.com/v3/#rate-limiting
|
||||
request = urllib.request.Request(gh_release_url)
|
||||
request.add_header("Authorization", "token " + args.auth)
|
||||
else:
|
||||
request = gh_release_url
|
||||
try:
|
||||
response = urllib.request.urlopen(request)
|
||||
except urllib.error.HTTPError as err:
|
||||
print('GitHub release not found. (%s)' % err.reason, file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
rel_info = json.load(io.StringIO(str(response.read(), 'utf-8')))
|
||||
print('Last release:', rel_info['name'])
|
||||
print('Created at:', rel_info['created_at'])
|
||||
|
||||
if args.check:
|
||||
exit(0)
|
||||
|
||||
def reporthook(count, blocksize, totalsize):
|
||||
if args.noprogress:
|
||||
return
|
||||
size = count * blocksize
|
||||
if totalsize <= 0:
|
||||
print("\r{:,}".format(size))
|
||||
else:
|
||||
size = min(size, totalsize)
|
||||
print("\r{:,} / {:,} ({:.1%})".format(size, totalsize, size / totalsize), end='')
|
||||
|
||||
# Download the files
|
||||
for asset in rel_info['assets']:
|
||||
if args.filename:
|
||||
name = args.filename
|
||||
else:
|
||||
name = asset['name']
|
||||
if does_skip_asset(asset):
|
||||
continue
|
||||
if args.arch != 'all' and asset['name'].find(args.arch) < 0:
|
||||
continue
|
||||
if os.path.isfile(name) and not args.force:
|
||||
print('File exists:', name)
|
||||
continue
|
||||
print('Downloading from:', asset['browser_download_url'])
|
||||
print('Downloading to:', name)
|
||||
urllib.request.urlretrieve(asset['browser_download_url'], name, reporthook)
|
||||
# Set timestamp
|
||||
asset_time = time.strptime(asset['updated_at'], '%Y-%m-%dT%H:%M:%SZ')
|
||||
os.utime(name, times=(time.time(), calendar.timegm(asset_time)))
|
||||
print()
|
||||
|
||||
exit(0)
|
||||
Loading…
x
Reference in New Issue
Block a user