Lazy
AtroNvim 的配置完全依赖lazy.nvim插件,对 AstroNvim 的配置同样是通过 lazy 的 opts 表进行的。因此整个配置实际上都是建立在 lazy 这个插件管理器上的。
加载插件
lazy 将要加载的插件以 table 的形式传递给 spec 即可,AstroNvim 默认模版在 lazy_setup 中引入了 lazy 的配置:
require("lazy").setup({
-- plugins config
spec = {
{
-- AstroNvim plugin,Basic Config in opts
"AstroNvim/AstroNvim",
import = "astronvim.plugins",
opts = { -- AstroNvim options must be set here with the `import` key
mapleader = " ",
maplocalleader = ",",
icons_enabled = true,
pin_plugins = nil,
update_notifications = true,
},
},
-- import other plugins
-- other file.lua or other dir/*.lua
{ import = "community" },
{ import = "plugins" },
},
-- lazy.nvim config
install = { colorscheme = { "habamax" } },
checker = { enabled = true },
})
因此安装插件就是编写一个个的 spec 表,而 AstroNvim 也是以插件的形式提供,因此对他的配置也是通过 spec 中的 opts 公开的。
spec
lazy.nvim 对插件的配置都是通过Spec完成的。Spec 本身就是一个 table 其中可用的属性有很多他们被分为几个部分:
Spec Source
Spec Source
即插件源,主要分为网络直接下载和本地目录:
属性 | 类型 | 描述 |
---|---|---|
[1] | string? |
插件网址(只需要路径部分) |
url | string? |
自定义 git url(默认就是 github) |
dir | string? |
本地插件目录(主要是调试用) |
name | string? |
用于本地插件目录的自定义名称 |
Spec Versioning
Spec Versioning
即插件版本控制,主要针对于远程插件
属性 | 类型 | 描述 |
---|---|---|
branch | string? |
仓库的分支 |
tag | string? |
仓库的标签 |
commit | string? |
仓库的提交 |
version | string? or false |
仓库的版本,支持 Semver 定义 |
pin | boolean? |
当为 true 是,此插件不会被更新 |
submodules | boolean? |
如果为 false 不会获取 git 子模块 |
Spec Setup
Spec Setup
即插件配置,这也是最核心的地方
属性 | 类型 | 描述 |
---|---|---|
init | fun(Spec) |
init 函数始终在启动期间执行,主要用于设置 vim.g.* 这样的全局变量来控制插件的行为 |
opts | table or fun(Spec, opts:table) -> opts |
如果是一个 table 将覆盖父配置(未覆盖的依然使用父配置),如果是一个函数,返回的 table 将替换父配置 |
config | fun(Spec, opts: table) or true |
如果 config=true 且设置了 opts,则默认运行 require(MAIN).setup(opts) , 或者是一个配置根据插件推荐方法来设置 |
main | string? |
指定用于 config 中的 main 模块 |
build | fun(Spec) or string or false |
在安装或更新插件时执行的命令 |
这部分是 Spec 最核心的部分。neovim 内置了 lua 引擎,而大多数 lua 插件的配置方式都是:
这也就是 config=true
是的情况。因此我们通常只需要编写 opts 就可以了。当然有些插件也可能不遵循这个规则,此时就需要用到 config=fun
的情况。
Spec Lazy Loading
Lazy Loading 就是懒加载,这也是 Lazy 的强大的地方,从名字也能看出来:
属性 | 类型 | 描述 |
---|---|---|
lazy | boolean? |
当为 true 时,插件仅在需要时加载 |
event | string? or string[] or fun(Spec,envet: string[]) -> string[] |
延迟加载事件 |
cmd | string? or string[] or fun(Spec,cmd: string[]) -> string[] |
延迟加载命令 |
ft | string? or string[] or fun(Spec,cmd: string[]) -> string[] |
在特定 filetype 上延迟加载 |
keys | LazyKeysSpec? or LazyKeysSpec[] or fun(Spec,keys: LazyKeysSpec[]) -> LazyKeysSpec[] |
在特定键位映射上延迟加载 |
lazy=true
启动懒加载,默认会在遇到require(plugin)
时加载插件,也可以指定 cmd、ft、key 来加载。其中比较不好设置的就是 keys,它可以是一个表:
[1]: string
: lhs,即触发按键(必须)[2]: string|func()
: rhs,即要执行的命令(可以为 nil,此时真正的映射必须由 config 函数创建)mode: string|string[]
: 指定模式,默认n
ft: string|string[]
: 特定 filetype 生效的映射desc
: 描述- 其他用于
vim.keymap.set
中可用的属性
-- Example for neo-tree.nvim
{
"nvim-neo-tree/neo-tree.nvim",
keys = {
-- key cmd desc
{ "<leader>ft", "<cmd>Neotree toggle<cr>", desc = "NeoTree" },
},
config = function()
require("neo-tree").setup()
end,
}
Spec Loading
指定插件加载条件:
属性 | 类型 | 描述 |
---|---|---|
dependencies | Spec[] |
插件依赖,注意依赖一定是懒加载的 |
enabled | boolean? or fun() -> boolean |
当为 false 时禁用插件 |
cond | boolean? or fun(Spec) -> boolean |
行为和 enabled 相同,但是当为 false 是不卸载插件(在 vscode 中禁用某些插件很有用) |
priority | number? |
仅仅对 lazy=false 强制加载某些插件时有用,缺省值 50,对于配色方案建议调高 |
Spec Advanced
这里是一些高级设置部分,它主要用于一些 Neovim 发行版中。
属性 | 类型 | 描述 |
---|---|---|
optional | boolean? |
可选,它出现在可能存在多个同一个插件的多个 Spec |
module | false? |
当某处需要此 lua 模块时,不要自动加载该 lua 模块 |
import | string? |
导入给定的 spec 模块 |
opts 以及覆盖原理
opts 是最常用的配置方式,他可以是 table 和 fun 他们之间的区别在于:
- table: 这会和父配置(其他配置)合并或覆盖
- fun -> table: 他会返回新的 table 来作为新的配置
- fun -> nil: 其中需要
opts.map
这样的方式来修改 opts,这种形式大多数和 table 没啥区别,除非需要引用其他库,它更加灵活些
table 这种合并而不是完全替代是在 lazy.nvim V10.23.0
版本修改的,它通过添加了一个 opts_extend
引入的,在之前他是完全替代的,而之前我么修改配置 table 的方式通常都是 fun -> nil
:
-- 旧版本
{
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
-- list like portions of a table cannot be merged naturally and require the user to merge it manually
-- check to make sure the key exists
if not opts.ensure_installed then
opts.ensure_installed = {}
end
vim.list_extend(opts.ensure_installed, {
"lua",
"vim",
-- add more arguments for adding more treesitter parsers
})
end,
}
-- 新版本
{
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = { "lua", "vim" },
highlight = {
enable = true,
},
},
}
插件加载顺序
Lazy 接管了整个 Neovim 的用户插件加载流程,执行顺序:
- 所有插件的 Spec 的
init
配置 - 所有带有
lazy=false
的插件,这也包括/plugin
和/ftdetect
中的脚本文件 - 所有
/after/plugin
中脚本文件
删除
lazy 会用到下面的目录:
# data
$HOME/.local/share/nvim/lazy
# state
$HOME/.local/state/nvim/lazy
# lockfile
$HOME/.config/nvim/lazy-lock.json
多端同步: lockfile
其中 lockfile 比较特殊,在每次更新后会更新该文件,可以将它置于版本控制来同步多台机器确保插件都是相同的版本。
执行 :Lazy restore
会安装 lazy-lock.json 指定版本的插件
推荐配置方式
使用 Lazy 插件管理器,只需要编写 Spec 来配置对应插件即可。而且推荐将不同的插件拆分为多个文件,而不是将所有插件的 Spec 以单表构建。之后可以通过:
-- 只需要引入 plugins 目录
require("lazy").setup("plugins")
-- plugins 目录中的所有 lua 文件都可以直接 return Spec[]
return {
"folke/neodev.nvim",
"folke/which-key.nvim",
{ "folke/neoconf.nvim", cmd = "Neoconf" },
}
编写 Spec 的最佳实践
-- 如果插件必须 setup() 最简单的方式
{ "me/my-plugin", opts = {} }
-- 对于不需要 setup 的纯 lua 库应当延迟加载
{ "nvim-lua/plenary.nvim", lazy = true }
-- 尽可能使用 opts 来配置,而不是 config
{ "folke/todo-comments.nvim", opts = {} } -- good
-- 下面就是不是一个好方式
{
"folke/todo-comments.nvim",
config = function()
require("todo-comments").setup({})
end,
},
Tips
AstroNvim 也提供了一个lazy.nvim 配置指南