前言
vim-plug 是一个非常优秀的 Vim 插件管理器,但是随着安装的插件越来越多,逐渐发现即使使用 vim-plug,首次启动速度仍然很慢。
究其原因,虽然 vim-plug 本身提供了优秀的延迟加载机制,但是可用于延迟加载的选项相对较少,另一方面,vim-plug 对插件的延迟加载与配置无法进行统一,很多时候,我们想对插件进行延迟加载,但是插件配置项如果调用了插件功能,则加载的时候就会报错(因为插件此时还未加载)...
针对上述问题,dein.vim 都给出了更优秀的解决方案。
注:vim-plug 是一款非常优秀的插件管理器,具备优秀的插件管理性能,同时操作及其简单,且具备优秀的 UI 显示,通常情况下,建议使用 vim-plug。
但是如果当使用 vim-plug 后,启动速度仍然很慢,那就可以考虑下 dein.vim
注:dein 本身只提供函数接口进行操作,没有提供命令与 UI 显示,对于用户相对不友好。
不过 Github 上面已经有人对其进行了再一次封装:
- dein-command.vim:为 dein 封装了一些命令
- dein-ui.vim:为 dein 提供了类似 vim-plug 的 UI 界面
可以结合以上两个插件,简化 dein 使用。
优点
- 启动快
- 支持异步安装
- 支持本地插件
- 支持多种 VCS(包括 git)
- 支持缓存
- 支持
merge特性,有效减少runtimepath层级
...
安装
- 对于 Unix/Linux/Mac:
curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
# 安装路径我们选择:~/.vim/dein
sh ./installer.sh ~/.vim/dein
- 对于 Windows:
Invoke-WebRequest https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.ps1 -OutFile installer.ps1
# Allow to run third-party script
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# 安装路径我们选择:~/.vim/dein
./installer.ps1 ~/.vim/dein
dein 基本使用
- 最简配置:基本结构如下:
if &compatible
set nocompatible
endif
let s:dein_path = '~/.vim/dein'
" Add the dein installation directory into runtimepath
let &runtimepath = &runtimepath.','.s:dein_path.'/repos/github.com/Shougo/dein.vim'
if dein#load_state(s:dein_path)
call dein#begin(s:dein_path)
call dein#add(s:dein_path.'/repos/github.com/Shougo/dein.vim')
" install third-party plugins
" call dein#add('tpope/vim-surround')
call dein#end()
call dein#save_state()
endif
filetype plugin indent on
syntax enable
-
插件安装:插件基本安装方法如下:
- 在
dein#begin()和dein#end()之间使用dein#add({plugin})声明要安装的插件:
call dein#begin(s:dein_path) " install third-party plugins call dein#add('tpope/vim-surround') call dein#end()- 重新打开 Vim 或者手动重新加载配置
:so %后,使用如下命令安装插件:
:call dein#install()注:由于 dein 没有 UI 显示下载进度,需等待一段时间,等下载完成后,底部提示栏会有显示通知。
也可以直接到<dein_path>/repos/查看插件是否已安装完成。- 关闭 Vim,再重新打开,就可以使用已安装的插件功能了。
- 在
-
插件卸载:dein.vim 并未直接提供插件卸载功能,因此其插件卸载相对麻烦,步骤如下:
- 取消插件添加配置:将要卸载的插件进行注释:
call dein#begin(s:dein_path) " uninstall vim-surround " call dein#add('tpope/vim-surround') call dein#end()清除缓存:关闭再重新打开 Vim,执行
:call dein#recache_runtimepath()。
注:由于 dein 采用了merge功能,其会将所有插件的plugin/目录下的内容都缓存到同一个目录(具体为<dein_path>/.cache/init.vim/.dein/plugin)中,因此虽然我们上一步配置文件取消了添加插件,但由于缓存未删除,导致本次启动仍然会加载相应插件,故还需手动进行缓存清除操作。关闭再重新打开 Vim,就可以发现插件功能已禁止(可选)
删除插件:以上操作只是停用了插件,插件仍然存在于本地电脑,如果想进行删除,还需调用如下命令:
:call map(dein#check_clean(), "delete(v:val, 'rf')")此时就可以看到 dein 目录下的
repo下的相应插件被删除了,缓存文件夹.cache下的.dein/plugin相关的插件缓存也被删除了。 -
失能插件:不删除插件,只是不进行加载,步骤如下:
- 将配置文件中的
dein#add改为dein#disable,如下所示:
call dein#begin(s:dein_path) call dein#add('tpope/vim-surround') " disable 添加到 add 后面 call dein#disable('vim-surround') call dein#end()关闭 Vim,再重新打开,执行
:call dein#recache_runtimepath()关闭 Vim,再重新打开,就可以看到插件功能禁止了。
- 将配置文件中的
注:以上任何操作如果失败,一律进行如下操作,确保不受 dein 缓存机制影响:
- 重新打开 Vim,执行
:call dein#clear_state(),清除状态文件,强制 dein 重新加载配置。 - 退出后重新打开 Vim,执行
:call dein#recache_runtimepath(),清除旧缓存 - 退出 Vim,再重新打开,执行剩余操作
一些有用操作/设置
在对 dein 进行详细介绍前,先了解下其提供的一些比较有用的操作/设置,方便理解与使用。
- 手动安装插件:依次输入以下命令:
" 开始块,安装路径可以自由更改
:call dein#begin('~/.cache/dein')
" 添加插件安装声明
:call dein#add('~/.vim/plugB')
" 配置块结束,安装自动开始
:call dein#end()
- 手动加载插件:
dein#source([{plugins}])
:call dein#source('vim-surround')
注:dein#source会直接加载插件,无论插件是否配置了懒加载。
-
检测插件是否已安装:
dein#check_install({plugins})- 返回
0:表示插件已安装,可以正常使用 - 返回
-1:表示是无效插件 - 返回其他:表示插件未安装
:call dein#check_install('vim-surround') - 返回
-
检测插件是否已加载:
dein#is_sourced({plugin-name})- 返回
0:表示插件未加载 - 返回其他:表示插件存在且已加载
:call dein#is_sourced('vim-surround')注:由于 dein 存在懒加载,因此存在插件已安装(
dein#check_install)但未加载(dein#is_sourced)的情形。 - 返回
-
检测插件是否被禁用:
dein#tap({plugin-name})- 返回
0:表示插件不存在,或者被禁用 - 返回其他:表示插件存在,且可以使用(懒加载插件在未加载前也是属于可以使用状态)
:call dein#tap('vim-surround') - 返回
插件懒加载:
call dein#add('junegunn/fzf', {
\'lzay': 1, " 非0 表示启用懒加载
\ 'if': s:has_exec('fzf'), " 条件满足时才加载(判断类型`String`/`Number`)
\ 'on_if': 'winnr("$") > 1', " 条件满足时才加载(判断类型`String`)
\ 'on_cmd': 'FZF', " 存在 FZF 命令时才加载
\ 'on_func': 'fzf#run', " 调用了函数 fzf#run 时才进行加载
\ 'on_event': ['VimEnter', 'BufRead'] " 事件发生时才加载
\ 'on_ft': 'python' " 文件类型匹配时才加载
\ 'on_map': { 'n' : ['<C-n>', '<C-p>'], 'x' : '<C-n>'}} " 匹配特定模式下的按键映射时才加载
\ 'on_path': '.editorconfig', " 路径匹配时才加载
\ 'on_source': ['vim-surround'] " 插件 vim-surround 加载时才加载
\ })
注:懒加载时lazy可忽略,dein 会自动根据其他选项自动判断是否启用懒加载。
检测未使用的插件目录(可以清除):
dein#check_clean()获取插件配置:
dein#get([{plugin-name}])
:echo dein#get('vim-surround')
函数
以下是 dein.vim 内置的函数简介:
-
dein#add({repo}[, {options}]):初始化/添加插件。{repo}:表示插件 URI 或者插件本地路径。{options}:对插件进行额外选项配置,具体选项请参考下文:选项(OPTIONS)
注:
dein#add必须在dein#begin()块中使用。 -
dein#begin({base-path}, [{vimrcs}]):初始化 dein.vim,开启插件配置块。{base-path}:表示插件下载安装路径{vimrcs}:额外配置选项或者 TOML 配置文件。默认值为$MYVIMRC
注:不能在
has('vim_starting')块中调用dein#begin()
注:dein#begin()会自动设置:filetype off -
dein#build([{plugins}]):编译插件{plugins}注:当使用类似
dein#add('autozimu/LanguageClient-neovim', {'build': 'bash install.sh'})配置插件时,指定了build选项,则可通过调用:call dein#build()对插件进行重新编译安装,即执行bash install.sh。
-
dein#call_hook({hook-name}):调用钩子函数{hook-name}。注:如果
{hook-name}设置为source,那么 dein 就会触发已加载的插件的hook_source钩子函数。 -
dein#check_install({plugins}):查看插件是否已安装。- 对于已安装的插件
{plugins},该函数返回0。 - 对于未安装的插件
{plugins},该函数返回 非0 数值。 - 对于无效插件,该函数返回 -1。
- 如果
{plugins}忽略不写,则对所有插件进行检测。
" 已安装,则返回 0 :echo dein#check_install('vim-surround') - 对于已安装的插件
-
dein#check_lazy_plugins():检测无意义的懒加载插件。插件如果没有
plugin/目录,那么对这类插件进行懒加载是没有意义的。 dein#check_update([{plugins}]):异步检测插件是否可更新。dein#check_clean():返回未使用的插件。可以结合其他命令手动进行删除。-
dein#clear_state():手动清除状态文件。注:状态文件的路径为:
<dein_path>/state_vim.vim -
dein#config({plugin-name}, {options})/dein#config({options}):修改插件配置选项。如果忽略
{plugin-name},那么配置选项作用于全局变量g:dein#name指定的值。
如果{plugin-name}是列表,那么一套相同的配置项就可以作用于多个插件。
如果{plugin-name}已经加载,或者是无效状态,那么忽略该配置选项{options}。call dein#add('Shougo/deoplete.nvim') call dein#config('deoplete.nvim', { \ 'lazy' : 1, 'on_i' : 1, \ })注:
dein#config()必须在dein#begin()和dein#end()块中调用。 -
dein#direct_install({repo}[, {options}]):下载插件,并直接进行加载(source),即不会加载配置块(dein#begin()/dein#end())选项。" 直接加载插件 deoplete.vim call dein#direct_install('Shougo/deoplete.nvim')注:
dein#direct_install直接下载的插件配置文件存放于dein#get_direct_plugins_path(),我们可以手动加载更改该文件配置。 -
dein#disable({plugins}):失能/禁止加载插件。注:
dein#disable()函数必须在相关插件加载之前进行使用。因为 Vim 默认机制在加载插件后,无法直接失能/禁止。call dein#add('skywind3000/asyncrun.vim') call dein#disable('asyncrun.vim') dein#each({command}[, {plugins}]):为每个插件{plugins}执行{command}命令。-
dein#end():dein 配置块结束位置。注:如果使能了
g:dein#auto_recache,那么dein#end()会自动执行dein#recache_runtimepath(),重新加载缓存。
注:在dein#end()执行后,runtimepath会被更改。 -
dein#get([{plugin-name}]):获取插件{plugin-name}配置选项。:echo dein#get('asyncrun.vim')注:如果未指定
{plugin-name},则返回所有插件信息。 dein#get_direct_plugins_path():获取直接下载安装插件脚本路径。dein#get_log():获取插件安装日志信息。dein#get_progress():获取当前更新进程信息。dein#get_updates_log():打印插件更新日志。-
dein#install([{plugins}]):异步安装插件。-
{plugins}:指定插件名称。如果该参数未设置,则默认安装所有插件。
-
-
dein#is_sourced({plugin-name}):查询插件加载状态。返回任意非 0 值表示插件存在且已加载(source)。注:更多相关信息,可参考:
:h dein#source()、:h dein#tap()。 -
dein#load_dict({dict}, [{options}]):从字典{dict}中加载插件配置选项。-
{dict}:key为插件 URI,value为dein-options构成的字典。比如:
call dein#load_dict({ \ 'Shougo/denite.nvim': {}, \ 'Shougo/deoplete.nvim': {'name': 'deoplete'} \ }) -
-
dein#load_rollback({rollbackfile}[, {plugins}]):以{rollbackfile}文件回滚插件。注:这是一个危险命令。
-
dein#load_state({base-path}):从缓存脚本文件中加载 dein 状态信息。-
{base-path}:为插件下载存放路径。
如果该函数返回 1,则表示缓存脚本过期,或者无效,或者不存在。
if dein#load_state(path) call dein#begin(path) " My plugins here: " ... call dein#end() call dein#save_state() endif注:dein 的状态缓存脚本存放路径为:
dein#util#_get_runtime_path() . '/state_' . fnamemodify(v:progname, ':r') . '.vim',也即:<dein_path>/.cache/init.vim/.dein/state_nvim.vim(注:实践中发现,状态文件存储路径为:<dein_path>/state_nvim.vim)
注:dein#load_state()函数必须在dein#begin()前进行调用,因为它会清除 dein 的所有配置。
注:dein#load_state()会完全覆盖runtimepath,因此在动态更改runtimepath后,千万不要调用该函数,否则前面的设置就无效了。
注:当 dein 的状态信息已被加载时,会自动跳过该块内容。 -
dein#load_toml({filename}, [{options}]):从{filename}文件中以 TOML 格式加载插件配置。-
dein#local({directory}, [{options}, [{names}]]):添加{directory}的子目录到runtimepath。{names}:为子目录的名称。如果指定了{names},那么 dein 就只会加载这些子目录(子目录可使用通配符匹配)。" Load plugin from "~/.vim/bundle". call dein#local("~/.vim/bundle") " Load plugin1 and plugin2 from "~/.vim/bundle". call dein#local("~/.vim/bundle", {}, \ ['plugin1', 'plugin2', 'vim-*', '*.vim']) -
dein#update([{plugins}]):安装/更新插件。注:
dein#update()在 Vim 8.0+ 和 Neovim 中,会以异步方式执行。 dein#plugins2toml({plugins}):获取插件{plugins}TOML 格式的配置信息。dein#reinstall({plugins}):重新安装插件。-
dein#remote_plugins():加载尚未加载的远程插件remote-plugin,并执行命令:UpdateRemotePlugins。注:
dein#remote_plugins()只在 Neovim 中可用。 -
dein#rollback({date}[, {plugins}]):回滚到最接近{date}指定日期的插件版本。-
{data}:如果设置为"",则回滚到插件最新版本。
注:
dein#rollback()是一个危险命令。 -
-
dein#recache_runtimepath():重新加载 dein 的runtimepath缓存目录,并执行:helptags。该命令会在安装完成后自动调用。注:dein 中使用了一种称为
merge特性的功能,简单来讲,就是 dein 会自动将所有插件plugin/目录都融合merge到一个缓存目录中,目的就是为了减少runtimepath的层级,通常的插件管理器都是将插件的路径添加到runtimepath中,这样runtimepath就会变得很大,插件搜索与加载就会变慢,而 dein 采用merge特性,将所有插件都融合到一个目录中,以后无论安装多少插件,都只需在该目录下进行查找即可,提升了插件加载效率。 dein#save_rollback({rollbackfile}[, {plugins}]):保存插件回滚信息到文件{rollbackfile}中。-
dein#save_state():保存 dein 状态到缓存脚本中。注:
dein#save_state()必须在dein#end()后面被调用。
注:dein#save_state()会完整保存当前runtimepath,因此在调用后不能再动态更改runtimepath。 -
dein#set_hook({plugins}, {hook-name}, {hook}):为插件设置钩子函数{hook},钩子函数名称为{hook-name}。-
{plugins}:如果未指定,则表示为所有插件设置钩子函数。
注:
dein#set_hook()可以在dein#begin()/dein#end()块后调用。
注:dein#set_hook()如果设置在dein#load_state()/dein#save_state()块中的时候,如果钩子函数是函数类型Funcref,那么就不起作用。call dein#add('Shougo/neosnippet.vim', {'lazy': 1}) function! Foo() abort endfunction " Does not work for dein#load_state()/dein#save_state() block call dein#set_hook('neosnippet.vim', 'hook_source', function('Foo')) " Does work for dein#load_state()/dein#save_state() block call dein#set_hook('neosnippet.vim', 'hook_source', 'echomsg "foo"') -
-
dein#source([{plugins}]):加载(:source)插件。-
{plugins}:如果未指定,则会加载所有插件。
-
-
dein#tap({plugin-name}):如果插件存在且没有被禁止,则返回非 0 数值。注:
dein#tap()会初始化全局变量g:dein#name和:dein#plugin。
变量
-
g:dein#auto_recache:是否自动调用dein#recache_runtimepath()更新缓存。-
1:开启自动更新缓存。 -
0:则关闭自动更新缓存(默认值)
注:该选项会重新加载
$MYVIMRC -
-
g:dein#cache_directory:设置缓存目录。其默认缓存目录为:
dein#begin()指定的路径。 -
g:dein#download_command:默认下载命令。其默认值为:
curl --silent --location --output,
或者为:wget -q -O
或者使用 PowerShell。 -
g:dein#enable_name_conversion:使能命名转换。-
1:如果值为1,且配置时未指定插件名,则使用dein-options-normalized_name作为插件名称。 -
0:禁止命名转换(默认值)。
" 使能命名转换 let g:dein#enable_name_conversion = 1 if dein#load_state(s:dein_path) call dein#begin(s:dein_path) " 将 asyncrun.vim 名称设置为 asyncrun call dein#add('skywind3000/asyncrun.vim',{'normalized_name' :'asyncrun'}) call dein#end() call dein#save_state() endif上述代码将插件名为
asyncrun.vim修改为asyncrun,现在使用asyncrun可以成功访问插件,使用asyncrun.vim访问会失效。 -
-
g:dein#enable_notification:开启通知功能。-
1:表示开启通知功能。 -
0:表示失能通知功能(默认值)。
注:该选项涉及外部命令调用,因此在不同的平台上,需要有相应的命令存在,具体为:
-
Windows:存在
Snarl或Snarl_CMD命令 -
Mac:存在
terminal-notifier或osascript命令 -
Linux:存在
notify-send命令。
-
-
g:dein#install_max_processes:设置 dein 最大进程数。其默认值为 8,即最大开启进程数为 8。
注:如果该值小于等于 1,则表示关闭多进程。
-
g:dein#install_process_timeout:插件安装/更新超时时间,单位为秒。其默认值为:120(即超时时间为 120 秒)
-
g:dein#install_progress_type:安装进度条输出样式。其值有如下几个选项:
-
'none':不进行输出 -
'echo':echo区中显示(默认值) -
'tabline':tabline中显示 -
title:标题栏中显示(该选项只在 Neovim 中生效)
注:如果需要在状态栏
statusline中进行展示,需要结合dein#get_progress()函数。 -
-
g:dein#install_message_type:安装消息输出类型。其值有如下两个选项:
-
'none':不输出安装信息 -
'echo':echo区域显示安装信息
-
-
g:dein#install_log_filename:安装日志文件。该值默认为
"",表示失能日志记录。 -
g:dein#name:当前插件名称。注:
g:dein#name只能在dein#tap()块中使用。
注:g:dein#name已被标记为废弃状态deprecated -
g:dein#notification_icon:设置通知图标路径。该值默认为
""。 -
g:dein#notification_time:通知显示时长,单位为秒。该选项默认值为:
2,表示默认显示时间为 2 秒。注:该选项只支持 Linux 和 Windows 平台。
-
g:dein#plugin:当前插件。注:
g:dein#plugin可用在dein#tap()和dein-hooks块中。 -
g:dein#types#git#clone_depth:git clone默认历史深度(default history depth)。其默认值为 0。
如果该值设置为 1,则 dein 会采用浅拷贝功能。
更多信息,请参考:dein-options-type__depth -
g:dein#types#git#command_path:git命令路径。其默认值为:
git -
g:dein#types#git#default_protocol:git默认使用协议。其有两种类型可选:
https、ssh
其默认值为:https -
g:dein#types#git#pull_command:git pull命令。其默认值为:
"pull --ff --ff-only"
选项(OPTIONS)
以下是 dein 提供的选项列表简介:dein-options:
-
augroup:插件对于VimEnter和GUIEnter事件的自动命令组名称。类型:
String -
build:指定编译脚本。类型:
String注:
build指定的命令最终由system()函数执行。
注:build会在插件根目录执行命令,如果想使用cd命令,必须结合使用sh -c命令:" 在 vimproc.vim 目录下执行 make call dein#add('Shougo/vimproc.vim', {'build': 'make'}) " 在 command-t 目录下执行:sh -c "cd ruby/command-t && ruby extconf.rb && make" call dein#add('wincent/command-t', { \ 'build':'sh -c "cd ruby/command-t && ruby extconf.rb && make"' \ }) -
depends:指定插件依赖的其他插件。类型:
String、Listcall dein#add('tpope/vim-surround', { \'on_map': {'n' : ['cs', 'ds', 'ys'], 'x' : 'S'}, \'depends' : 'vim-repeat' \})注:
depends列表指定的依赖 不会 自动进行安装。
注:对于非懒加载插件,depends指定的依赖插件加载顺序无法确保有序。 -
frozen:如果设置为1,则表示禁止该插件自动更新。类型:
Number -
ftplugin:这个应该是指定插件类型路径(不是很确定)。类型:
Dictionary,其中:- 当
key为_时,在加载完所有ftplugin后,会执行该操作。 - 当
key为{filetype}时,就只会加载ftplugin目录中的{filetype}插件。
- 当
-
if:添加条件判断。类型:
Number、String,其中: -
lazy:设置插件懒加载。类型:
Number,其中:注:对于没有
plugin/目录的插件,不要设置懒加载,因为这是没有意义的。可以通过dein#check_lazy_plugins()找到无意义的懒加载插件。 -
merged:启用merged特性。类型:
Number,其中:- 如果设置为
0,则表示禁止merged特性,这样当前插件的plugin/目录就不会被融合进缓存目录中,这对于插件文件存在冲突的情形下是一个很好的解决方案。
- 如果设置为
-
name:指定插件名称。类型:
String注:如果未指定
name选项,则 dein 会默认将插件名称设置为插件仓库尾部名称,即:skywind3000/asyncrun.vim的名称为asyncrun.vim。
注:插件名称必须全局唯一,如果存在两个或以上相同的插件名称,则后面的会覆盖前面,此时使用name选项自己指定名称就可以很好地解决这个冲突。 -
normalized_name:设置插件标准名称。类型:
String注:如果未指定
normalized_name选项,则默认使用插件名称主体部分作为其标准化名称,如下所示:name : normalized name denite.nvim denite dein.vim dein vim-quickrun quickrun -
on_cmd:如果执行了指定的命令,dein 就会加载该插件dein#source()。类型:
String、Listcall dein#add('tpope/vim-fugitive', {'on_cmd' : 'Gstatus'})上述代码中,当我们在 Vim 中执行
Gstatus时,dein 就会加载vim-fugitive插件。 -
on_event:当指定的事件发生时,dein 就会加载该插件dein#source()。类型:
String、Listcall dein#add('RomainEndelin/vim-projectionist', { \ 'on_event': ['VimEnter', 'BufRead'], \ 'on_if': 'findfile(".projections.json", a:event == "VimEnter" ? ";" : ".;") != ""' \ }) -
on_func:当指定的函数被调用时,dein 就会加载该插件dein#source()。类型:
Stringcall dein#add('junegunn/fzf', { \ 'if': s:has_exec('fzf'), \ 'on_cmd': 'FZF', " 存在 FZF 命令时才加载 \ 'on_func': 'fzf#run', " 调用了函数 fzf#run 时才进行加载 \ }) -
on_ft:打开指定的文件类型时,才加载插件。类型:
String、Listcall dein#add('bps/vim-textobj-python', { 'on_ft' : 'python' }) call dein#add('tmhedberg/matchit', { 'on_ft' : 'html' }) -
on_if:当满足条件时,dein 就会加载该插件dein#source()。类型:
String注:
on_if选项的默认会在事件BufRead,BufNewFile,VimEnter和FileType发生时进行判断。
如果存在dein-options-on_event事件,则在dein-options-on_event事件中进行判断,比如:call dein#add('blueyed/vim-diminactive', \ {'on_event': 'WinEnter', 'on_if': 'winnr("$") > 1'})上述代码中,
on_if会在事件WinEnter发生时进行判断。 -
on_map:当指定模式下,发生指定的按键映射时,加载该插件。类型:
Dictionary、List、String,其中:- 当值为
Dictionary类型时,key为模式{mode}指定,其余条目为按键映射:{mapping}或[{mapping1},{mapping2},...],比如:
call dein#add('terryma/vim-multiple-cursors', { 'on_map' : { 'n' : ['<C-n>', '<C-p>'], 'x' : '<C-n>'}})- 当值为
List类型时,则其条目设置格式为:{mapping}或[{mode}, {mapping1}, [{mapping2}, ...]],比如:
call dein#add('dhruvasagar/vim-table-mode', {'on_map' : '<LocalLeader>t' }) call dein#add('terryma/vim-multiple-cursors', { 'on_map' : ['<C-n>', '<C-p>']})注:当未指定模式
{mode}时,则默认为nx。
注:on_map选项支持<Plug>按键映射,如果映射只指定了<Plug>,那么实质上映射的是<Plug>(normalized_name,比如:" It is same as "'mappings': '<Plug>(anzu' call dein#add('osyo-manga/vim-anzu', {'on_map': '<Plug>'}) - 当值为
-
on_path:当编辑指定路径的文件时,加载相应插件dein#source()。类型:
String、List,其中:- 如果值为
.*,则表示编辑任何文件时,都加载插件。 - 其他情况,则只有缓冲区名称匹配
on_path指定的字符串时,才进行加载。
call dein#add('editorconfig/editorconfig-vim', { \ 'if': has('pythonx'), \ 'on_event': 'InsertEnter', \ 'on_path': '.editorconfig', \ })注:
on_path选项对于文件夹浏览类型的插件很有用。 - 如果值为
-
on_source:指定插件依赖关系,表示在指定的插件加载后,会加载当前插件。类型:
String、List注:插件必须设置了懒加载选项。
" ~/.vim/plugA/plugin/a.vim echom 'a.vim loaded!!' command! -nargs=0 CmdA :echom 'this is command a' echom 'a.vim done!!' " ~/.vim/plugB/plugin/b.vim echom 'b.vim loaded!!' command! -nargs=0 CmdB :echom 'this is command b' echom 'b.vim done!!' " ~/.config/nvim/init.vim call dein#add('~/.vim/plugA', { \ 'on_source': ['plugB'], \ 'on_cmd': ['CmdA'], \ 'lazy': 1}) call dein#add('~/.vim/plugB', { \ 'on_cmd': ['CmdB'], \ 'lazy':1 })上述代码中,当触发加载
plugB后,会加载plugA。注:官方文档写的是:
on_source (List) or (String) Load the plugin before the listed plugins are loaded. Note: The plugins must be lazy loaded plugins.在
on_source指定的插件加载之前,先加载当前插件。
对应我们上面的例子,应该是当加载plugB之前,先加载plugA。
但是我本地运行显示的结果是:- 执行
:CmdB,触发加载PlugB,然后再触发加载plugA。 - 执行
:CmdA,只触发加载plugA,plugB不会被加载。
因此,我认为官方文档此处存在错误描述。
注:可通过
:scriptnames查看已加载的插件(有序) - 执行
-
path:指定插件下载路径。类型:
String -
rev:指定插件版本/标签号。类型:
String,其中:-
*:如果选项type为git,则表示使用最新的released标签版本 - 支持通配符选择,比如:
0.* - 如果
type为raw,那么rev必须是一个哈希值。
call dein#add('Shougo/deol.nvim', { 'rev': 'a1b5108fd5' }) -
-
rtp:将指定目录添加到runtimepath。类型:
String注:当一个仓库中的子目录包含 Vim 插件时,可以通过设置
rtp选项将该目录添加到runtimepath中,从而使能插件:" 选择仓库 rstacruz/sparkup 的 vim 目录作为插件添加 call dein#add('rstacruz/sparkup', {'rtp': 'vim'})注:如果
rtp为空字符串"",那么 dein 不会将其路径添加到runtimepath。 -
script_type:指定脚本类型。类型:
String注:对于没有按照 Vim 官方文档规定的目录组织结构的插件,可以通过
script_type手动设置脚本类型,比如"indent","plugin","ftplugin"...call dein#add( \ 'https://raw.githubusercontent.com/Shougo/' \ . 'shougo-s-github/master/vim/colors/candy.vim', \ {'script_type' : 'colors'}) call dein#add( \ 'https://github.com/bronzehedwick/impactjs-colorscheme', \ {'script_type' : 'colors'}) -
timeout:安装/更新插件的超时时间(单位:秒)。类型:
Number注:如果忽略该选项,那么超时时间由
g:dein#install_process_timeout控制。 -
trusted:以管理员权限(sudo)加载插件。类型:
Number,其中:注:dein.vim 默认在
sudo会话下,不会对插件进行加载,这是为了增加安全性,否则插件在sudo模式下可以进行任何操作。
但是如果一定需要在sudo会话下加载插件,则为插件添加trusted选项即可。比如,coc.nvim如果没有加载的话,会一直弹出烦人的错误信息(晕),那么最好为其添加trusted选项,避免在sudo会话时一直弹窗:
call dein#add('neoclide/coc.nvim', {'merged':0, 'rev': 'release', 'trusted': 1})
注:sudo模式启动后,dein.vim 的状态会变更,导致下一次非sudo会话时,普通插件无法触发加载,此时手动调用call dein#clear_state(),然后重启 Vim 即可。
-
type:指定仓库类型。类型:
String,其值有如下几个可选:-
none:无仓库 -
raw:原始插件文本(必须指定script_type) -
git:Git 仓库
注:如果忽略该选项,dein 会自动根据
{repository}类型设置该选项 -
-
type__depth:git clone下载历史深度。类型:
Number,其中:- 如果忽略该选项,则使用
g:dein#types#git#clone_depth - 如果该值大于
0,则使用浅拷贝,这会加快下载速度。
注:浅拷贝在克隆某些仓库时可能存在问题,具体请参考:
https://github.com/Shougo/neobundle.vim/issues/81https://github.com/Homebrew/homebrew/issues/12024
注:建议不使用浅拷贝机制,反正时间不会增加多少。
- 如果忽略该选项,则使用
钩子函数(HOOKS)
dein 提供了一些钩子函数,对于插件的初始化操作很有用。
注:函数类型的钩子函数( Function hooks)不会被缓存,必须手动初始化。
注:对于非懒加载插件,钩子函数的加载顺序无法保证有序。
注:钩子函数的字符串表达式以命令行模式(Ex commands)进行执行。
注:钩子函数中涉及多个操作时,使用换行符进行分割。
以下是 dein 提供的钩子函数简介:
-
hook_add:当解析完dein#add()行后,触发该钩子函数。类型:
String、Functioncal dein#add("~/.vim/plugA", { \'hook_add': "echom 'hook_add invoked!!'" \})上述代码为本地插件
plugA设置了一个hook_add钩子,当 dein 解析到call dein#add("~/.vim/plugA")语句后,会先调用钩子函数hoot_add,然后再加载插件plugA。当钩子函数涉及多个操作时,使用换行符进行分割,如下所示:
call dein#add('kana/vim-niceblock', { \ 'hook_add': join(['xmap I <Plug>(niceblock-I)', 'xmap A <Plug>(niceblock-A)'], "\n") \ }) call dein#add('godlygeek/csapprox', { \ 'hook_add': " \ let g:CSApprox_konsole = 1\n \ let g:CSApprox_attr_map = \ { 'bold' : 'bold', 'italic' : '', 'sp' : '' }\n \ "})注:不能在钩子函数
hook_add中调用插件内定义的函数,因此此时插件还未加载。 -
hook_done_update:当所有插件都更新完毕后,触发该钩子函数。类型:
String、Function -
hook_post_source:当插件加载(:source)完成后,触发该钩子函数。类型:
String、Functioncal dein#add("~/.vim/plugA", { \'lazy': 1, \'on_cmd': ['CmdA'], \'hook_post_source': "echom 'hook_post_source invoked!!'" \})注:本人实验过后,发现
hook_post_source只在懒加载插件上才会被回调,如果要想让插件每次加载(无论是懒加载还是直接加载)时,都能触发hook_post_source,则可以VimEnter事件手动触发:autocmd VimEnter * call dein#call_hook('post_source') -
hook_post_update:当插件更新完成后,触发该钩子函数。类型:
String、Function -
hook_source:在加载(:source)插件前,触发该钩子函数。类型:
String、Function注:
hoot_source与hook_post_source一致,只能作用于栏加载插件,如果要想让插件每次加载(无论是懒加载还是直接加载)时,都能触发hook_source,则必须手动进行触发:call dein#begin() ... call dein#end() call dein#call_hook('source')注:
hook_source不能跟hoo_post_source一样,结合VimEnter使用,因为插件直接加载发生在VimEnter事件之前,如果hook_source和VimEnter结合,实际上是等到插件加载完成后,才会触发hook_source,此时该钩子的作用就与hook_post_source一样了。