Programming Go in Neovim
There are tons of articles on how to programming Go in vim, how to turn vim into IDE. The purpose of this article is to look closer at nvim as an LSP client, especially for Go.
Intro
Nvim introduced nvim-lspconfig
, a collection of common configurations for Neovim’s built-in language server client . From that point nvim
can be lsp client for any server that supports LSP specification.
My primary setup before was vim
with vim-go. After Go Modules were introduced some of the dependencies stopped working. vim-go
depends on a bunch of tools. Support of these tools has relied on the goodwill of community members, and they have been put under a large burden of support at times as the language, toolchain, and environments change. As a result, many tools have ceased to work, have had support problems, or become confusing with forks and replacements, or provided an experience that is not as good as it could be.
Moreover, I want to have the same experience with other languages without wasting time exploring new plugins and tools.
That’s how combination nvim + gopls
appeared on my radar.
Installation
To use the new (still experimental) native LSP client in Neovim, make sure you install the prerelease v0.5.0 version of Neovim (aka “nightly”), the nvim-lspconfig configuration helper plugin, and check the gopls configuration section there.
Migration from Vim-go
Vim-go was my only setup for development Go in vim and my only setup for development in vim at all. That’s why I am so interested to set up a new Go development environment. Minimal configuration:
|
|
Let’s take vim-go tutorial to make a comparision:
|
|
Run, Build, Test, Cover it
For all this action I currently use command line and Go tools and haven’t found analogs in nvim lsp.
To be honest, the only feature I really from the list is test capabilities.
Fix it
Let’s introduce two errors by adding two compile errors:
|
|
Here nvim enters the battlefield. We immediately get error messages from diagnostics without build.
You see available diagnostics and can navigate it back and forth.
|
|
I find diagnostics features easy to use:
- no additional action(build)
- no additional window - errors are shown in the code file
Edit it
Format Let us start with a unformatted file:
|
|
To format it by shortcut you need to have key binding in your lsp config:
|
|
To format it on save file:
|
|
Imports
Let’s print the “gopher” string in all uppercase. For it we’re going to use the strings package. Change the definition to:
|
|
You will see error undeclared name: strings
shown by diagnostics
You need strings
in your imports and there is two ways to solve it: code action triggered manually
Code action:
|
|
and on save
|
|
and
|
|
Snippets
This feature is a bit complicated in configuration. You can configure snippets in a usual way snippets engine(UltiSnips) and snippets itself(honza/vim-snippets).
But LPS support there even more snippets options available. Gopls has a bunch of experimental features and experimental postfix completions is one of them.
Setup requires additional effort. First, you have to set your LSP config in a way that informs LSP server that you have snippet support. So when the server run it knows about your capabilities:
|
|
It will be visible from logs with
|
|
(prerequisites:
|
|
)
logs:
|
|
Check it
Gopls can publish not only errors, but warnings as well. Possible warning depends on analyzers we specify. For example, shadow
analyzer:
|
|
A lot of analyzer are still experiment but I enjoy to use it - it allows you do not postpone to linter execution step
Navigate it
Probably most important feature set for development along with code completion.
Nvim as LSP client supports next type of navigation request:
|
|
Key binding for some of them
|
|
Completion
Completion is available out of the box. We just have to map it to vim omnifunc
to make our Ctrl+x
,Ctrl+o
work:
|
|
Understand it
Documentation lookup nvim supports as LSP client:
|
|
Key binding for some of them
|
|
Refactor it
Rename identifiers From nvim documentaton among LSP requests/notifications defined by default:
|
|
Key binding for it
|
|
Conclusions
After exploring nvim lsp
capabilities I understood how mature the tool vim-go
is. It perfectly covers Go development workflow.
At the same time, nvim as an LSP client looks solid and gopls as server matches it pretty smooth. Despite nvim with lsp support is in a release version and a lot of gopls features are experimental it is already advanced Go development environment and we can expect more in the future.
When it comes to basic setup, nvim requires just one plugin - nvim-lspconfig
and using gopls for it requires just one config line.
|
|