前言
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
、List
call 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
、List
call dein#add('tpope/vim-fugitive', {'on_cmd' : 'Gstatus'})
上述代码中,当我们在 Vim 中执行
Gstatus
时,dein 就会加载vim-fugitive
插件。 -
on_event
:当指定的事件发生时,dein 就会加载该插件dein#source()
。类型:
String
、List
call dein#add('RomainEndelin/vim-projectionist', { \ 'on_event': ['VimEnter', 'BufRead'], \ 'on_if': 'findfile(".projections.json", a:event == "VimEnter" ? ";" : ".;") != ""' \ })
-
on_func
:当指定的函数被调用时,dein 就会加载该插件dein#source()
。类型:
String
call dein#add('junegunn/fzf', { \ 'if': s:has_exec('fzf'), \ 'on_cmd': 'FZF', " 存在 FZF 命令时才加载 \ 'on_func': 'fzf#run', " 调用了函数 fzf#run 时才进行加载 \ })
-
on_ft
:打开指定的文件类型时,才加载插件。类型:
String
、List
call 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/81
https://github.com/Homebrew/homebrew/issues/12024
注:建议不使用浅拷贝机制,反正时间不会增加多少。
- 如果忽略该选项,则使用
钩子函数(HOOKS)
dein 提供了一些钩子函数,对于插件的初始化操作很有用。
注:函数类型的钩子函数( Function hooks)不会被缓存,必须手动初始化。
注:对于非懒加载插件,钩子函数的加载顺序无法保证有序。
注:钩子函数的字符串表达式以命令行模式(Ex commands)进行执行。
注:钩子函数中涉及多个操作时,使用换行符进行分割。
以下是 dein 提供的钩子函数简介:
-
hook_add
:当解析完dein#add()
行后,触发该钩子函数。类型:
String
、Function
cal 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
、Function
cal 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
一样了。
网友评论