VimからNeovimへの移行とプラグインの棚卸し

2019年ごろにVim/Neovimで開発できる環境を整えてから3年経過しました。
Neovim関連のプラグインが充実しているようで、最近はGitHub copilot XのようなGPT4ベースのツールもNeovimに対応しています。AstroNvimとか、もはやVSCodeと見間違いそうなカッコいい設定ツールも出てきました。
VimとNeovim両方で動くように.vimrcを設定していましたが、そろそろNeovimへ寄せようと思い、プラグインなどの棚卸しを行いました。
プラグインマネージャーの変更
packer.nvimへ移行しました。
READMEを参考に設定後、nvimで下記コマンドを実行することで、設定ファイルに記載したプラグインがインストールされます。
:PackerUpdate
LSP設定用のプラグイン
nvim-lspconfigに移行しました。goplsなどのLanguage Server Protocolを設定することで、コーディング時にVSCodeのような静的解析が可能になります。
vim-lspはLSPの設定を自動化してくれるので、使い勝手はnvim-lspconfigより良かったかもしれません。nvim-lspconfigを採用した理由は、Neovimネイティブの機能であるNvim LSP client用のコンフィグだからです。
関数や変数の定義ジャンプなどの設定はREADMEに書かれていた内容をほぼそのまま利用しました。定義元へジャンプしたいときはgd
、参照先へ飛びたいときはgr
でジャンプできます。omnifuncによる補完はデフォルトのキーバインド<C-x><C-o>
だと使いにくかったので、<C-n>
で補完されるようにしました(「補完用のプラグイン」の項を参照)。
require'lspconfig'.gopls.setup{}
require'lspconfig'.golangci_lint_ls.setup{}
-- Global mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist)
-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
-- Enable completion triggered by <c-x><c-o>
vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
local opts = { buffer = ev.buf }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
vim.keymap.set('n', '<space>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, opts)
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, opts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
vim.keymap.set('n', '<space>f', function()
vim.lsp.buf.format { async = true }
end, opts)
end,
})
フォーマッターとリンター用のプラグイン
aleからnull-ls.nvimに移行しました。非常に動作が軽くなった気がします。
nvim-lspconfigでもLSPに対応しているリンターを設定できるみたいですが、LSPに対応していないリンターやフォーマッター用に使います。
local null_ls = require("null-ls")
-- ------------------------------
-- Autoformat settings.
-- https://github.com/jose-elias-alvarez/null-ls.nvim/wiki/Formatting-on-save
-- https://github.com/jose-elias-alvarez/null-ls.nvim/wiki/Avoiding-LSP-formatting-conflicts
-- ------------------------------
local augroup = vim.api.nvim_create_augroup("LspFormatting", {})
local lsp_formatting = function(bufnr)
vim.lsp.buf.format({
filter = function(client)
return client.name == "null-ls"
end,
bufnr = bufnr,
})
end
-- ------------------------------
-- null_ls setup.
-- ------------------------------
null_ls.setup({
sources = {
null_ls.builtins.formatting.shfmt,
null_ls.builtins.formatting.stylua,
null_ls.builtins.diagnostics.eslint,
-- null_ls.builtins.completion.spell,
-- null_ls.builtins.diagnostics.golangci_lint,
null_ls.builtins.formatting.goimports,
null_ls.builtins.diagnostics.markdownlint_cli2,
null_ls.builtins.formatting.markdownlint,
},
on_attach = function(client, bufnr)
if client.supports_method("textDocument/formatting") then
vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr })
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup,
buffer = bufnr,
callback = function()
lsp_formatting(bufnr)
end,
})
end
end,
})
補完用のプラグイン
変数や関数、メソッドの入力時に自動で補完するためのプラグインnvim-cmpに移行しました。以前はasyncomplete.vimを利用していました(vim-lspを開発したエンジニアが公開しているプラグインです)。
nvim-cmpの利用に際し下記の依存ツールが必要だったので、合わせて導入しました。
- vim-vsnip: スニペット用プラグイン
- cmp-nvim-lsp: nvim-cmpでLSPを利用できるようにするためのプラグイン
以下、luaの設定内容。
omnifunkを<C-n>
と<C-p>
で実行できるようにしました。それ以外はREADMEに記載されている内容と同じです。
local cmp = require'cmp'
cmp.setup({
snippet = {
-- REQUIRED - you must specify a snippet engine
expand = function(args)
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
end,
},
window = {
-- completion = cmp.config.window.bordered(),
-- documentation = cmp.config.window.bordered(),
},
mapping = cmp.mapping.preset.insert({
["<C-p>"] = cmp.mapping.select_prev_item(),
["<C-n>"] = cmp.mapping.select_next_item(),
['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
}, {
{ name = 'buffer' },
})
})
その他
下記のプラグインは引き続き利用することにしました。
- lambdalisue/fern.vim: ファイルマネージャー
- Morhetz/gruvbox: カラースキーマ
- nathanaelkane/vim-indent-guides: インデントを見やすくする
- airblade/vim-gitgutter:
git diff
がわかるようにする - vim-airline/vim-airline: 見た目を整える
- vim-airline/vim-airline-themes: 見た目を整える
- sebdah/vim-delve: Goのデバッガ支援
まとめ
nvim-dapなど気になるプラグインはまだあるのですが、取り急ぎ業務でも問題なく使える状態にアップデートしました。
今はGoのコーディングとMarkdownに特化した設定ですが、少しずつ他の言語の開発も行えるように整えていきたいです。
コメントを残す
comments powered by Disqus