最近NeoVim放出了0.5.1版本,默认支持Lsp以及Lua脚本运行时。Lsp是我现在非常常用的功能。Vim只依靠插件支持Lsp,很多特性用起来并不顺畅。所以我放弃了Vim,转而使用NeoVim作为主力编辑器。
NeoVim另一个特点是使用Lua做配置,而不是VimScript。Lua语法层面比VimScript要更像一个正常的语言,也很灵活。我花了大概两天时间,把VimScript的配置彻底改成了Lua。这里记录一下我是如何使用Lua组织NeoVim的插件和配置的。
插件管理使用Packer。这是一个Lua编写,利用了NeoVim内置模块功能的插件。主配置文件~/.config/nvim/init.lua
很简单,就是Packer的内容。其余插件都通过require()
,从别的文件中引用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| local fn = vim.fn
local install_path = fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
if fn.empty(fn.glob(install_path)) > 0 then
packer_bootstrap = fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path})
end
require('packer').startup(function(p)
require('editor')(p)
require('telescope')(p)
require('git')(p)
require('treesitter')(p)
require('lsp').init(p)
require('nvim-compe')(p)
require('lang/go')(p)
require('lang/markdown')(p)
require('lang/cider')(p)
-- Automatically set up your configuration after cloning packer.nvim
-- Put this at the end after all plugins
if packer_bootstrap then
require('packer').sync()
end
end)
|
其中require('telescope')(p)
相对简单。文件位置在~/.config/nvim/lua/telescope.lua
。NeoVim所有用于require()
的文件都要放在~/.config/nvim/lua
目录下,并且以此目录为准,使用相对路径做引用。引用时不包括扩展名.lua
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| return function(packer)
packer {
'nvim-telescope/telescope.nvim',
requires = {'nvim-lua/popup.nvim', 'nvim-lua/plenary.nvim'},
config = function()
vim.g.NERDSpaceDelims = 1
local util = require('util')
util.noremap('n', '<C-p>', ':Telescope find_files<CR>')
util.noremap('n', '<leader>fg', ':Telescope live_grep<CR>')
util.noremap('n', '<leader>fb', ':Telescope buffers<CR>')
util.noremap('n', '<leader>fh', ':Telescope help_tags<CR>')
end,
}
end
|
每个文件都会返回一个函数,这个函数会传入一个用于配置的参数packer
。在Packer官方推荐的配置里,这个参数更常被命名为use
。不过拆分到子文件后,再使用use
会比较奇怪,所以这里改为packer
。
调用pack
可以传入一个table。其中第一项必须是插件的名字。这里是nvim-telescope/telescope.nvim
。requires
字段表示载入该插件时还需要依赖哪些插件。config
表示载入该插件后,需要执行哪些配置。这个table还支持其他的字段,具体可以参考Packer官方文档packer.use()
。
比较特别的一个文件是~/.config/nvim/lua/lsp.lua
。因为Lsp还需要对外提供一些其他函数,所以这个文件没有直接返回函数,而是返回了一组函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| local M = {}
function M.init(packer)
packer {
'neovim/nvim-lspconfig',
config = function()
-- blablabla
end,
}
packer "ray-x/lsp_signature.nvim"
end
function M.on_attach(client, bufnr)
-- blablabla
nd
return M
|
一个函数是init
,用来在Packer的startup()
方法里初始化插件。这个函数调用了两次packer
,注册了两个插件。另一个函数on_attach
用于启用Lsp的配置。因为不是所有的文件都有Lsp的支持,比如日志文件就不需要任何Lsp的功能,使用on_attach
可以保证只在打开有Lsp支持的文件时,才执行对应的Lsp配置。
我不打算介绍所有的插件,这里只介绍几个配置比较简单的插件,来展示组织方式。完整的配置文件可以看my_sys。