——————更新日志——————
2022.10.5 更新:简化了plugin
简介
vim
是一个非常强大的文本编辑器,而Neovim
是对原vim
的一个分叉,不过最简单的Neovim
显得太过朴素,只提供了基本的编辑器功能;然而有赖于它提供了强大的插件系统,可以通过各种插件将其由一个简约的文本编辑器转化为强大的代码开发IDE。NvChad
就是一个Neovim
的预配置库,可以使得Neovim
开箱即获得各种强大的功能:
NvChad
是一个用lua
编写的neovim
配置,旨在提供一个具有非常漂亮的用户界面和极快的启动时间的基本配置(在基础硬件上约0.02秒至0.07秒);- 懒加载的机制使得插件不会被默认加载,只有在需要的时候才会被加载,包括特定的命令和vim事件等。这有助于减少启动时间,从而使启动时间比平时快;
NvChad
不是一个框架,它是作为大众的 “基础 “配置使用的。它的目的是提供一个特定的默认插件集。
安装
前提条件
在使用NvChad
之前,要有一些前提依赖:
- 终端
即Neovim
运行的环境,Linux
系统推荐Terminator
,Windows
推荐Windows Terminal
,Mac OS
推荐iTerm2
。 Neovim 0.7.2
及以上
安装教程在这里。- 字体及图标:
一个推荐的编程字体是Fira Code
字体,这里不光安装它,还安装它的一个扩展,即Nerd fonts
(Nerd fonts
本身并不是一种新的字体,而是把常用图标以打补丁的方式打到了常用字体上。)
具体到官网这里进行下载。
对于Linux
字体的安装,步骤为:对于1
2sudo unzip FiraCode.zip -d /usr/share/fonts
sudo fc-cache -fvWindows
版本,注意在下载的文件中选择XXXX Windows Compatible.ttf
。然后在Windows Terminal
的字体中选择FiraCode NF
字体即可。)
为了测试是否成功,可以到这个网址,点击Show All Icons
按钮,选择一个图标,点击右上角的Copy Icon
,然后粘贴到命令行里即可。 - 保证所需的目录干净
对于Linux和MacOS系统,删除~/.local/share/nvim
这个文件夹;对于Windows系统,删除~\AppData\Local\nvim
和~\AppData\Local\nvim-data
。 - 如果要用到
Telescope
的模糊搜索,还要提前安装ripgrep
。具体安装方法可以参考官方文档BurntSushi/ripgrep。
安装
对于Linux/MacOS系统:1
git clone https://github.com/NvChad/NvChad ~/.config/nvim --depth 1 && nvim
对于Windows系统:
(注意:还需提前安装mingw
,以及在环境变量中配置其路径)1
git clone https://github.com/NvChad/NvChad $HOME\AppData\Local\nvim --depth 1 && nvim
升级
NvChad
有一个内置的升级机制,快捷键是<leader> + uu
。
注意,默认配置下<leader>
键是空格键<space>
。
具体地,它在后台会使用git reset --hard
来获取官方git库中的更新,因此在lua/custom
文件夹外的改动都会被丢弃(因此,如果想在NvChad
上自定义配置,需要在lua/custom
文件夹内进行)。
卸载
1 | # linux/macos (unix) |
安装之后
上一步安装好NvChad
后,还可以做一些进阶动作,当然不做也不影响使用。
创建自定义配置
NvChad
的更新不会覆盖lua/custom
目录,因为它被gitignored
了,因此所有的用户修改都必须在这个文件夹中完成。lua/custom/init.lua
在init.lua
主文件的最后被加载,可以在这里添加自定义的命令等。lua/custom/chadrc.lua
用于覆盖lua/core/default_config.lua
并基本上控制整个nvchad
,因此必须采用跟default_config.lua
一样的代码结构。
NvChad
在examples
文件夹中提供了init.lua
和chadrc.lua
,可以将其作为默认初始的自定义配置文件,将其复制到custom
文件夹中。NvChad
提供了一个example_config库,可以将其直接复制到lua
文件夹下,作为起始的自定义配置文件(注意删掉.git
文件夹)。
NvChad
提前预置了很多常用的插件及其配置,但是每个人有不同的喜好,因此通常情况下需要自己配置custom
目录来进一步定制化NvChad
。NvChad/example_config: example custom config 该库已经提供了很好的模板,可以在此基础上进行配置。
那么怎样对自己定制的部分也进行同步呢,就像NvChad
主库那样存储在GitHub
上,需要时直接拉取下来即可。
一个可行的方法是像NvChad/example_config: example custom config 这样,为custom
文件夹单独建立一个仓库,在安装好NvChad
主库后,再将这个库给拉取并合并进去。
但是这里有一个问题:NvChad
库更新是比较频繁的,有时候其API
变动比较剧烈,可能当前的配置需要与特定版本的主库对应才行。如果将custom
和主库分离,就会遇到两者版本不一致的情形。
因此建议通过下面这种方式进行定制化及同步:
(1)对NvChad
主库进行Fork
,如我的这个库qixinbo/NvChad
(2)创建一个custom
分支,该分支相对于main
分支就是添加了custom
目录及其自定义的文件。
(3)同理,本地也会有这两个分支,对自定义部分的改动是发生在custom
分支上。
当NvChad
主库有更新时,
(1)在GitHub
的网页上,通过Sync fork
按钮将NvChad
主库与自己fork
版本的main
分支进行同步
(2)在本地,首先切换分支到main
:1
git checkout main
(3)本地main
与远程main
同步:1
git pull
(4)切换到custom
分支并将main
分支merge
进来:1
2git checkout custom
git merge main
(5)将本地custom
分支推送到远程:1
git push
那么,最终的效果就是,在qixinbo/NvChad 仓库中:
对于main
分支,它始终与NvChad
主库保持同步;
对于custom
分支,它始终比NvChad
主库要多若干个commits
(因为要自定义开发)。
在不同电脑进行配置时,只需要克隆custom
分支即可,这样既能保证NvChad
是最新的,也能自动同步自己的自定义配置。
安装Treesitter解析器
nvim-treesitter
提供了代码高亮、缩进和折叠等功能。nvim-treesitter
在NvChad
中是默认配置安装的,但是其正常运行需要满足以下条件:
- 在环境变量中能找到
tar
和curl
命令(或者git
命令) - 在环境变量中有
C
编译器和libstdc++
在Linux
系统中,使用sudo apt install build-essential
即可安装相应依赖,在Windows
系统中,可查看该详细教程
所以要保证nvim-treesitter
的正常使用,需要提前配置好以上依赖。待treesitter
安装好后,接下来就是安装其针对于不同编程语言的解析器。
安装解析器使用以下命令(以Python
为例):1
:TSInstall python
可以通过:TSModuleInfo
查看安装情况。
安装Node.JS
Node.js
对于后面的LSP
是有用的,比如安装pyright
时需要用到npm
,所以这里也可以事先安装。
安装包在这里。
对于Ubuntu
等Linux
系统,也可以使用包管理器来安装,教程见这里。
以Ubuntu
为例:1
2curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs
mac
系统的话直接用brew
安装即可:1
brew install node
Lua简明教程
1 | print("Hi") |
注释
1 | -- comment |
变量
1 | -- Different types |
条件表达式
1 | -- Number comparisons |
1 | -- Boolean comparison |
组合表达式
1 | local age = 22 |
反转
1 | local x = 18 |
函数
1 | local function print_num(a) |
1 | -- multiple parameters |
作用域
1 | function foo() |
循环
While
1 | local i = 1 |
For
1 | for i = 1, 3 do |
Tables
数组(列表)
1 | local colors = { "red", "green", "blue" } |
字典
1 | local info = { |
嵌套Tables
1 | -- Nested lists |
模块
1 | require("path") |
Neovim中的Lua应用
Neovim中的配置文件和插件都可以使用Lua
进行编写,具体的教程,可以参考该文档。
配置
总览
NvChad
的文件结构如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23├── init.lua
│
├── lua
│ │
│ ├── core
│ │ ├── default_config.lua
│ │ ├── mappings.lua
│ │ ├── options.lua
│ │ ├── packer.lua -- (新版删除了。。bootstrap packer & installs plugins)
│ │ ├── utils.lua -- (core util functions) (i)
│ │ └── init.lua -- (autocmds)
│ │
│ ├── plugins
│ │ ├── init.lua -- (default plugin list)
│ │ └── configs
│ │ ├── cmp.lua
│ │ ├── others.lu -- (list of small configs of plugins)
│ │ └── many more plugin configs
| |
│ ├── custom *
│ │ ├── chadrc.lua -- (overrides default_config)
│ │ ├── init.lua -- (runs after main init.lua file)
│ │ ├── more files, dirs
配置主题
快捷键是:<leader> + th
。
快捷键映射
:Telescope keymaps
默认设置
默认设置在lua/core/default_config.lua
。
选项
在custom/init.lua
中可以进行如下操作:
- 重载默认选项
- 设置
autocmds
和global
全局变量 - 懒加载,具体可以查看packer readme
- 代码片段,比如:
vim.g.luasnippets_path = "your snippets path"
插件
NvChad
在底层使用packer.nvim
,不过它重新定义了一套语法,比如:
packer.nvim
定义插件的方式:1
2
3
4
5
6
7
8
9
10use { "NvChad/nvterm" }, -- without any options
-- with more options
use {
"NvChad/nvterm"
module = "nvterm",
config = function()
require "plugins.configs.nvterm"
end,
},NvChad
定义插件的方式:1
2
3
4
5
6
7
8
9["NvChad/nvterm"] = {}, -- without any options
-- with more options
["NvChad/nvterm"] = {
module = "nvterm",
config = function()
require "plugins.configs.nvterm"
end,
},
安装、卸载和重载插件
以下格式不需要硬记,可以参考NvChad/example_config: example custom config这个库。1
2-- chadrc
M.plugins = require "custom.plugins"
1 | -- custom/plugins/init.lua |
新版NvChad
对插件的编写进一步简化,与旧版有了显著区别。下面的是旧版的插件操作方式,可以不用看了。
旧版的插件安装、重载和卸载
首先创建lua/custom/plugins/init.lua
,按以下格式添加插件:1
2
3
4
5
6
7
8
9
10
11
12
13
14-- custom/plugins/init.lua has to return a table
-- THe plugin name is github user or organization name/reponame
return {
["elkowar/yuck.vim"] = { ft = "yuck" },
["max397574/better-escape.nvim"] = {
event = "InsertEnter",
config = function()
require("better_escape").setup()
end,
},
}
然后在lua/custom/chadrc.lua
中引入该文件(实际写完一次后就不用更改了):1
2
3
4
5-- chadrc.lua
M.plugins = {
user = require "custom.plugins"
}
最后执行:PackerSync
即可。
重载插件的默认配置
当想从一个插件的默认配置选项中改变一个东西,但又不想复制粘贴整个配置时,这个功能就很有用了。
如下:1
2
3
4
5
6
7
8
9
10M.plugins = {
override = {
["nvim-treesitter/nvim-treesitter"] = {
ensure_installed = {
"html",
"css",
},
}
}
}
但以上面这种方式的话,配置一多了就会显得很乱,可以采用如下这种方式:1
2
3
4
5
6
7
8local pluginConfs = require "custom.plugins.configs"
M.plugins = {
override = {
["nvim-treesitter/nvim-treesitter"] = pluginConfs.treesitter,
["kyazdani42/nvim-tree.lua"] = pluginConfs.nvimtree,
},
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39-- custom/plugins/configs.lua file
local M = {}
M.treesitter = {
ensure_installed = {
"lua",
"html",
"css",
},
}
M.nvimtree = {
git = {
enable = true,
},
view = {
side = "right",
width = 20,
},
}
-- you cant directly call a module in chadrc thats related to the default config
-- Thats because most probably that module is lazyloaded
-- In this case its 'cmp', we have lazyloaded it by default
-- So you need to make this override field a function, instead of a table
-- And the function needs to return a table!
M.cmp = function()
local cmp = require 'cmp'
return {
mapping = {
["<C-d>"] = cmp.mapping.scroll_docs(-8),
}
}
end
return M
然后执行:PackerSync
。
修改插件的配置
比如在lua/custom/plugins/init.lua
中是这样定义nvimtree
的:1
2
3
4
5
6
7
8
9
10
11["kyazdani42/nvim-tree.lua"] = {
cmd = { "NvimTreeToggle", "NvimTreeFocus" },
setup = function()
require("core.mappings").nvimtree()
end,
config = function()
require "plugins.configs.nvimtree"
end,
}
现在想修改其中的config
和cmd
配置,那么可以保持该文件不动,在安装它们时再改:1
2
3
4
5
6
7
8
9
10
11
12M.plugins = {
user = {
["kyazdani42/nvim-tree.lua"] = {
cmd = { "abc" },
config = function()
require "custom.plugins.nvimtree"
end,
}
}
-- This will change cmd, config values from default plugin definition
-- So the setup value isnt changed, look close!
删除插件
1 | M.plugins = { |
快捷键映射
C
是Ctrl
<leader>
是<space>
A
是Alt
S
是Shift
- 默认配置在
core/mappings.lua
中定义。
快捷键映射格式
1 | -- opts here is completely optional |
- 映射描述对
Whichkey
是必要的,对于非Whichkey
则不是必需 - 可以使用图标来帮助阅读,不过也不是必选项,而是可选项
- 可以从这里来复制和粘贴图标
- 默认的
opts
的值有:1
2
3
4
5
6
7
8{
buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
silent = true,
noremap = true,
nowait = false,
-- all standard key binding opts are supported
}
增加新的映射
默认配置在core/mappings.lua
中定义,然后可以在custom/mappings.lua
中增加新的映射:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27-- lua/custom/mappings
local M = {}
-- add this table only when you want to disable default keys
M.disabled = {
n = {
["<leader>h"] = "",
["<C-s>"] = ""
}
}
M.abc = {
n = {
["<C-n>"] = {"<cmd> Telescope <CR>", "Open Telescope"}
}
i = {
-- more keys!
}
}
M.xyz = {
-- stuff
}
return M
注意在自己的custom/chadrc.lua
中引入:1
2-- chadrc
M.mappings = require "custom.mappings"
- 上面的
abc
和xyz
是随意取的,为了可读性,可以改成插件名字 - 上面的映射关系是自动加载的,不需要手动加载。
UI插件
NvChad
使用了自己的UI插件。
LSP
以下出在掘金上的这个小册:
想要在 Neovim 中配置代码补全、代码悬停、代码提示等等功能,首先要了解什么是 LSP (Language Server Protocol) 语言服务协议。
在 LSP 出现之前,传统的 IDE 都要为其支持的每个语言实现类似的代码补全、文档提示、跳转到定义等功能,不同的 IDE 做了很多重复的工作,并且兼容性也不是很好。 LSP 的出现将编程工具解耦成了 Language Server 与 Language Client 两部分。定义了编辑器与语言服务器之间交互协议。
Client 专注于显示样式实现, Server 负责提供语言支持,包括常见的自动补全、跳转到定义、查找引用、悬停文档提示等功能。
而这里所说的 Neovim 内置 LSP 就是说 Neovim 内置了一套 Language Client 端的实现,这样就可以连接到和 VSCode 相同的第三方 language servers ,实现高质量的语法补全等功能。
还有一个简单的教程见这里。
为了简化 LSP 的安装和配置,NeoVim 官方专门创建了
nvim-lspconfig
插件来帮助我们。这个插件把所有 LSP 背后的繁琐都封装到其内部,让使用者再也毋需担心出现费了大半天功夫结果仍然无法用起来的事。
搭建内部LSP
1 | -- we are just modifying lspconfig's packer definition table |
1 | -- custom.plugins.lspconfig |
然后执行:PackerCompile
。
外部LSP server
可以使用Mason.nvim
来安装外部LSP Server。
输入命令:Mason
,就能打开它的浮动窗口,来安装、更新、卸载相关的安装包(比如lspservers、linters和formatters等)。
最好是使用配置文件来使用Mason.nvim
,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19["williamboman/mason.nvim"] = {
ensure_installed = {
-- lua stuff
"lua-language-server",
"stylua",
-- web dev
"css-lsp",
"html-lsp",
"typescript-language-server",
"deno",
"emmet-ls",
"json-lsp",
-- shell
"shfmt",
"shellcheck",
},
},
然后执行:MasonInstallAll
(注意该命令是NvChad
的定制命令,不是官方原有命令)。
代码调试DAP
DAP
,即Debug Adapter Protocol
,是neovim
最常用的代码调试工具。
不过当前的NvChad
并没有内置DAP
,据说可能在NvChad 2.0
中会加入。
当前可以参考我的配置,在这里。
使用DAP需要安装一各特定语言的
Debug Adapter。
python的话就是使用
debugpy`。
使用conda安装debugpy
正常安装miniconda
或者ananconda
后,激活某个虚拟环境,然后安装:1
pip install debugpy
然后在custom/plugins/dap/dap-python.lua
中使用nvim-dap-python
的默认配置即可:1
require('dap-python').setup('python')
在venv中debugpy
1 | sudo apt install python3.10-venv |
然后在custom/plugins/dap/dap-python.lua
中将该路径配置进去:1
require('dap-python').setup('path/to/virtualenvs/debugpy/bin/python')