LSP クライアントの設定 (nvim-lspconfig)
Go の LSP サーバー gopls をインストールする。
$ go install golang.org/x/tools/gopls@latest
$ gopls version
golang.org/x/tools/gopls v0.16.2
Neovim に LSP クライアントが built-in されているので nvim-lspconfig にある gopls の設定を渡すだけではたらく。
保存時にフォーマットがかかるようにする。
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.go",
callback = function()
local params = vim.lsp.util.make_range_params()
params.context = {only = {"source.organizeImports"}}
-- buf_request_sync defaults to a 1000ms timeout. Depending on your
-- machine and codebase, you may want longer. Add an additional
-- argument after params if you find that you have to write the file
-- twice for changes to be saved.
-- E.g., vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 3000)
local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params)
for cid, res in pairs(result or {}) do
for _, r in pairs(res.result or {}) do
if r.edit then
local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or "utf-16"
vim.lsp.util.apply_workspace_edit(r.edit, enc)
end
end
end
vim.lsp.buf.format({async = false})
end
})
定義ジャンプなどの keymap を設定する。C-o で戻って C-i で進む。
vim.keymap.set('n', 'K', vim.lsp.buf.hover, { desc = 'Show hover' })
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { desc = 'Go to definition' })
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, { desc = 'Go to implementation'})
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts, { desc = 'Show references' })
補完 (nvim-cmp)
LSP 単体でも C-x C-o で補完できるが、nvim-cmp を用いると自動で補完され godocs が併せて表示される。また、パスなど他のソースによる補完も効く。
Neovim のプラグインマネージャー lazy.nvim をインストールしてプラグインを入れる - sambaiz-net
{
{
'hrsh7th/nvim-cmp',
config = function()
local cmp = require('cmp')
cmp.setup({
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = 'nvim_lsp' },
{ name = 'buffer' },
{ name = 'path' },
},
mapping = cmp.mapping.preset.insert({
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
}),
})
end
},
{
'hrsh7th/cmp-nvim-lsp',
dependencies = {
'neovim/nvim-lspconfig',
},
config = function()
local lspconfig = require("lspconfig")
local capabilities = require('cmp_nvim_lsp').default_capabilities()
lspconfig.gopls.setup({
capabilities = capabilities,
})
end
},
{
'hrsh7th/cmp-buffer',
},
{
'hrsh7th/cmp-path',
},
{
'hrsh7th/cmp-cmdline',
}
}
syntax highlight (nvim-treesitter)
コードをパースして syntax tree を作る tree-sitter を使うための nvim-treesitter を入れると、syntax highlight が完全になる。
{
'nvim-treesitter/nvim-treesitter', tag = 'v0.9.3',
config = function()
require('nvim-treesitter.configs').setup({
ensure_installed = { 'go', 'lua', 'typescript', 'javascript', 'json', 'yaml', 'html', 'css', 'bash', 'python', 'markdown', 'scala' },
highlight = {
enable = true,
},
})
end
}
テストの実行とカバレッジの可視化 (neotest, nvim-coverage)
neotest と Go の runner neotest-go をインストールしてテストを実行できるようにする。
{
'nvim-neotest/neotest', tag = 'v5.6.1',
dependencies = {
'nvim-neotest/nvim-nio',
'nvim-lua/plenary.nvim',
'antoinemadec/FixCursorHold.nvim',
'nvim-treesitter/nvim-treesitter',
'nvim-neotest/neotest-go',
},
config = function()
require('neotest').setup({
adapters = {
require('neotest-go')({
args = { '-coverprofile=coverage.out' },
})
},
})
end,
}
vim.keymap.set('n', '<Leader>tt', ':lua require("neotest").run.run()<CR>', { desc = 'Run test' })
標準のターミナルではステータスのアイコンが文字化けしたが WezTerm では表示された。
出力した coverage profiles を nvim-coverage で可視化できる。
{
'andythigpen/nvim-coverage',
dependencies = {
'nvim-lua/plenary.nvim',
},
config = function()
require('coverage').setup({
lang = {
go = {
coverage_file = vim.fn.getcwd() .. '/coverage.out',
}
}
})
end,
}
:Coverage で表示されるバーの色でテスト済かどうかが分かる。