neovimのためのGoの開発環境のセットアップ
概要
neovim で Go の開発環境を構築するために必要な情報、セットアップ方法についてまとめます。
なお macOS 上で確認していますが、適宜自分の環境に置き換えてください。
必要なもの
- 最新の neovim
- neovim のプラグインマネージャー
- 最新の Go
- 最新の gopls
最新の neovim
GitHub リポジトリ
v0.5.0 以上の neovim からビルトインの LSP クライアントが使えます。
私は GitHub から curl で最新のリリースを落としてきて使っています。
$ cd
$ curl -LO https://github.com/neovim/neovim/releases/download/nightly/nvim-macos.tar.gz
$ tar xzf nvim-macos.tar.gz
PATH
環境変数に ~/nvim-macos/bin
を入れておくとよいでしょう。
neovim のプラグインマネージャー
neovim 開発チームが提供している LSP クライアント設定を利用するためにプラグインマネージャーを使います。
私は dein.vim を使っていますが、vim-plug などもあります。
この記事では dein.vim を利用していることを想定します。
最新の Go
v1.15.5 が執筆時の最新バージョンです。
homebrew 経由で利用することが出来ます。
最新の gopls
ドキュメント
v0.6.2 が執筆時の最新のバージョンです。
インストールするには次のコマンドで最新のものをインストールします。
$ go get -u golang.org/x/tools/gopls@latest
手順
- 最新の gopls が動くようにする
- nvim の設定に LSP クライアントの設定を追加する
- 起動して動かしてみる
1. 最新の gopls が動くようにする
最新の gopls がそのプロジェクトで動くようにします。
2. nvim の設定に LSP クライアントの設定を追加する
公式ドキュメントの設定を参考に設定します。
基本の設定
nvim の LSP クライアントの設定は GitHub の neovim/nvim-lspconfig を使います。
このリポジトリを利用するとそれぞれの言語の LSP サーバーの起動設定を簡単に実行できます。
単に gopls を起動するだけなら次の設定を dein.vim に読み込ませる toml ファイルに記述すれば可能です。
[[plugins]]
repo = 'neovim/nvim-lspconfig'
hook_add = '''
lua << EOF
require'lspconfig'.gopls.setup{}
EOF
'''
ですが、これだけでは定義ジャンプも値参照も起動できないため、更に設定を追加していきます。
README にもあるサンプルの設定を元に次のように設定します。
lua << EOF
local nvim_lsp = require('lspconfig')
local on_attach = function(client, bufnr)
local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
-- Mappings.
local opts = { noremap=true, silent=true }
buf_set_keymap('n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts)
buf_set_keymap('n', 'gd', '<Cmd>lua vim.lsp.buf.definition()<CR>', opts)
buf_set_keymap('n', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts)
buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
buf_set_keymap('n', '<space>e', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts)
buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts)
buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts)
buf_set_keymap('n', '<space>q', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts)
-- Set autocommands conditional on server_capabilities
if client.resolved_capabilities.document_highlight then
require('lspconfig').util.nvim_multiline_command [[
:hi LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow
:hi LspReferenceText cterm=bold ctermbg=red guibg=LightYellow
:hi LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow
augroup lsp_document_highlight
autocmd!
autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
augroup END
]]
end
end
nvim_lsp["gopls"].setup { on_attach = on_attach }
EOF
これで変数のリネームや、カーソル位置にある変数のドキュメントを見るなどの機能が利用できるようになりました。
コードフォーマットの設定
Go では書いたコードには gofmt もしくは goimports を実行し、フォーマットすることが求められます。
mattnさんの2020年1月のブログ記事でもあるように以前は LSP クライアントでは goimports を実行できませんでしたが、現在では公式ドキュメントで保存時に goimports を実行する方法が紹介されているます。
この設定をそのまま導入します。
補完の設定
私は deoplete.vim や nvim-lua/completion-nvim などの補完プラグインを使っていません。
そのため neovim が提供している補完機能を使っています。
補完のための設定も公式ドキュメントにあるのでこちらを利用します。
デバッグモードで起動してみる
gopls がうまく動かない場合には gopls をデバッグモードで起動してみましょう。
デバッグモードで動かすためには gopls コマンドに -rpc.trace
と --debug=localhost:6060
をつけて実行します。
-rpc.trace
フラグはより詳細な情報をログに出せるようにします。
--debug
フラグは渡されたアドレスからデバッグのための情報を閲覧できるようにします。
nvim でこれらの設定を有効にするためには neovim/nvim-lspconfig のサーバーの起動コマンドを変更します。
lua << EOF
require('lspconfig').gopls.setup {
cmd = {"gopls", "serve", "-rpc.trace", "--debug=localhost:6060"};
}
EOF
こうして neovim を起動し、 localhost:6060
にアクセスすると、詳細な情報を見ることが出来ます。
3. 起動してみる
ここまでの設定が出来たら実際に起動して、動作しているか遊んでみましょう。
なにか動かない設定があれば、デバッグモードで起動してどこでエラーが出ているのか調べて、 neovim のリポジトリの Issue にバグ報告や回避策がないか調べてみましょう。
最後に
2021/01/16 現在の neovim で gopls を使った開発環境について説明しました。
gopls の利用方法は公式ドキュメントがかなり充実しています。
この記事では説明しなかった daemon モードもドキュメントがあるので、読んでみると今後の gopls の成長について事前にわかるかもしれません。
Discussion