As a Go developer who spends most of the day in the terminal, I’ve invested time in crafting a Neovim setup that rivals full-featured IDEs. Here’s how I configured Neovim for serious Go development.
LSP Integration
The foundation of my setup is gopls, the official Go language server. I use nvim-lspconfig for easy configuration:
require('lspconfig').gopls.setup({
settings = {
gopls = {
analyses = {
unusedparams = true,
shadow = true,
},
staticcheck = true,
gofumpt = true,
},
},
})
This setup gives me:
- Code completion
- Signature help
- Go-to-definition
- Find references
- Diagnostics (including
staticcheckintegration)
Code Completion
For completion, I use nvim-cmp with several sources:
luasnipfor snippetsnvim_lspfor LSP completionsbufferfor text from other bufferspathfor file paths
Testing Integration
I created a custom plugin called nvim-dbee for database management, but for Go tests, I rely on vim-test with a custom wrapper:
let test#go#gotest#executable = 'go test -v -count=1'
Running tests is as simple as :TestFile or :TestNearest.
Debugging
Debugging Go in Neovim is surprisingly smooth with nvim-dap and delve:
require('dap-go').setup()
Set breakpoints with DapToggleBreakpoint, start debugging with DapContinue, and step through code with DapStepOver.
Key Mappings
My most-used mappings:
nnoremap <leader>gd :lua vim.lsp.buf.definition()<CR>
nnoremap <leader>gr :lua vim.lsp.buf.references()<CR>
nnoremap <leader>ca :lua vim.lsp.buf.code_action()<CR>
nnoremap <leader>rn :lua vim.lsp.buf.rename()<CR>
nnoremap <leader>tf :TestFile<CR>
Why This Works for Me
This setup keeps me in the terminal while providing all the features I need. The learning curve was worth it—my workflow is faster and more efficient than it ever was with VS Code or GoLand.
The key is starting simple: LSP first, then add completion, testing, and debugging incrementally. Don’t try to replicate an IDE feature-for-feature on day one.