This configuration provides comprehensive Go support using gopls (the official Go language server), along with formatters, linters, and Go-specific plugins.
Language server
The gopls language server is enabled:
-- From lua/plugins/lsp/init.lua:44
vim . lsp . enable ({
"gopls" , -- Go (you might see 2 processes, one is likely telemetry)
})
You may see two gopls processes running. One is the main server, the other is typically telemetry. Check with pgrep -a gopls.
gopls configuration
Custom configuration is in after/lsp/gopls.lua:
Explicit command
-- From after/lsp/gopls.lua:2
return {
cmd = { "gopls" },
}
This avoids duplicate processes from PATH resolution issues.
Code lenses
Most code lenses are disabled to reduce CPU usage:
-- From after/lsp/gopls.lua:6
codelenses = {
generate = false ,
gc_details = false , -- Very CPU intensive
test = false ,
tidy = false ,
vendor = false , -- Rarely used
regenerate_cgo = false ,
upgrade_dependency = false , -- Triggers on-demand anyway
run_govulncheck = false , -- Very CPU intensive, run manually
}
Code lenses like gc_details and run_govulncheck are CPU-intensive. They’re disabled by default but can be run manually when needed.
Inlay hints
-- From after/lsp/gopls.lua:16
hints = {
assignVariableTypes = true ,
compositeLiteralFields = true ,
compositeLiteralTypes = true ,
constantValues = true ,
functionTypeParameters = true ,
parameterNames = true ,
rangeVariableTypes = true ,
}
Inlay hints show:
Variable types
Composite literal fields and types
Constant values
Function type parameters
Parameter names
Range variable types
Toggle hints with <leader>ih.
Analyses
-- From after/lsp/gopls.lua:25
analyses = {
nilness = true ,
unusedparams = true ,
unusedwrite = true ,
ST1003 = false , -- Disable naming convention checks (Ts -> TS, url -> URL)
undeclaredname = true ,
fillreturns = true ,
nonewvars = true ,
useany = false ,
unreachable = false ,
unusedresult = false ,
simplifyslice = false ,
simplifyrange = false ,
simplifycompositelit = false ,
shadow = false ,
printf = false ,
structtag = true ,
modernize = false ,
stylecheck = false ,
gocritic = false ,
deprecated = false ,
}
Naming convention checks (ST1003) are disabled because they can be noisy (e.g., suggesting url should be URL).
-- From after/lsp/gopls.lua:47
usePlaceholders = false ,
completeUnimported = true ,
staticcheck = false , -- Disable to save CPU/memory (use <leader>ll for linting)
matcher = "Fuzzy" ,
diagnosticsDelay = "1000ms" , -- Increase delay to reduce CPU spikes
symbolMatcher = "fuzzy" ,
Why staticcheck is disabled:
Staticcheck analysis is CPU and memory intensive. Instead, use golangci-lint manually with <leader>ll.
Directory filters
-- From after/lsp/gopls.lua:53
directoryFilters = {
"-.git" ,
"-.vscode" ,
"-.idea" ,
"-.vscode-test" ,
"-node_modules" ,
}
Excludes common directories from workspace scanning.
-- From after/lsp/gopls.lua:61
semanticTokens = true ,
gofumpt = true ,
gopls uses gofumpt for stricter formatting.
Go files use both goimports and gofumpt:
-- From lua/plugins/formatter.lua:71
go = { "goimports" , "gofumpt" }
Both formatters run in sequence:
goimports - Organize and add missing imports
gofumpt - Stricter formatting than standard gofmt
Installation:
go install golang.org/x/tools/cmd/goimports@latest
go install mvdan.cc/gofumpt@latest
Linting
Go linting uses golangci-lint:
-- From lua/plugins/linting.lua:60
go = { "golangcilint" }
Trigger with <leader>ll.
golangci-lint configuration
The linter is configured to find project-specific config files:
-- From lua/plugins/linting.lua:36
function ()
-- Find .golangci.yaml or .golangci.yml in project root
local config_patterns =
{ ".golangci.yaml" , ".golangci.yml" , ".golangci.toml" , ".golangci.json" }
for _ , pattern in ipairs ( config_patterns ) do
local config_file = vim . fs . find ( pattern , {
upward = true ,
path = vim . fn . expand ( "%:p:h" ),
stop = vim . env . HOME ,
})[ 1 ]
if config_file then
return "-c=" .. config_file
end
end
return nil
end
It automatically finds:
.golangci.yaml
.golangci.yml
.golangci.toml
.golangci.json
Installation:
brew install golangci-lint
# or see https://golangci-lint.run/welcome/install/
go.nvim plugin
The go.nvim plugin provides Go-specific features:
-- From lua/plugins/languages/lessgo.lua:2
{
"ray-x/go.nvim" ,
enabled = true ,
dependencies = {
"ray-x/guihua.lua" ,
"nvim-treesitter/nvim-treesitter" ,
"neovim/nvim-lspconfig" ,
"saghen/blink.cmp" ,
},
ft = { "go" , "gomod" },
}
go.nvim configuration
The plugin is configured to work alongside the main LSP setup:
-- From lua/plugins/languages/lessgo.lua:12
require ( "go" ). setup ({
lsp_keymaps = false ,
lsp_codelens = false ,
lsp_on_attach = false ,
lsp_cfg = false , -- Disable go.nvim LSP, using lspconfig instead
lsp_gofumpt = false ,
lsp_inlay_hints = {
enable = false ,
},
})
go.nvim’s LSP features are disabled because we use the main LSP configuration. go.nvim provides additional Go tooling commands.
golangci-lint integration
-- From lua/plugins/languages/lessgo.lua:21
golangci_lint = {
default = "none" , -- Disabled, using nvim-lint instead
flags = {
"--output.json.path=stdout" ,
"--issues-exit-code=0" ,
"--show-stats=false" ,
"--allow-parallel-runners" ,
},
severity = vim . diagnostic . severity . INFO ,
}
Diagnostics
-- From lua/plugins/languages/lessgo.lua:38
diagnostic = false ,
lsp_diag_virtual_text = false ,
lsp_diag_signs = false ,
lsp_diag_update_in_insert = false ,
Diagnostics are handled by tiny-diagnostics plugin.
no-go.nvim plugin
Enhances error handling visualization:
-- From lua/plugins/languages/lessgo.lua:50
{
"snehilshah/no-go.nvim" ,
branch = "no-no-go" ,
enabled = true ,
ft = "go" ,
opts = {
identifiers = { "err" , "error" },
import_virtual_text = {
prefix = " " ,
suffix = " imports " ,
},
reveal_on_cursor = false ,
keys = {
down = "j" ,
up = "k" ,
toggle = "<M-o>" ,
},
},
}
Features:
Conceals if err != nil blocks for cleaner reading
Shows import counts as virtual text
Toggle error block visibility with <M-o>
Common workflows
Running tests
Use go.nvim commands:
:GoTest " Run tests in current file
:GoTestFunc " Run test under cursor
:GoTestFile " Run all tests in file
:GoTestPkg " Run all tests in package
Adding imports
Type the package name
Save the file (goimports runs on save)
Missing imports are automatically added
Filling struct
Place cursor in empty struct literal
Press ga or <leader>ca
Select “Fill struct”
Generating code
Use gopls code actions:
Press ga or <leader>ca
Select from:
“Generate constructor”
“Generate method stubs”
“Add missing imports”
Viewing documentation
Place cursor on symbol
Press K
Shows documentation from comments and standard library.
Keymaps
All standard LSP keymaps work:
Keymap Action KHover documentation <C-k>Signature help gdGo to definition grFind references giGo to implementation gtGo to type definition gaCode action <leader>rnRename symbol <leader>ihToggle inlay hints <leader>fbFormat buffer <leader>llLint with golangci-lint <M-o>Toggle error blocks (no-go.nvim) ]d / [dNext/prev diagnostic
Installation summary
Install gopls
go install golang.org/x/tools/gopls@latest
Install formatters
go install golang.org/x/tools/cmd/goimports@latest
go install mvdan.cc/gofumpt@latest
Install linter
brew install golangci-lint
Verify installation
gopls version
goimports -h
gofumpt --version
golangci-lint --version
Troubleshooting
gopls not starting
Check gopls is installed: gopls version
Run :LspInfoCustom to see client status
Check logs: :LspLog
Look for duplicate processes: pgrep -a gopls
Check CPU usage: Some analyses are disabled in config
Increase diagnostics delay in after/lsp/gopls.lua:51
Consider excluding more directories in directoryFilters
Disable inlay hints: <leader>ih
Imports not organizing
Check goimports is installed: goimports -h
Run :ConformInfo to see formatter status
Manually format: <leader>fb
golangci-lint not working
Check it’s installed: golangci-lint --version
Trigger manually: <leader>ll
Check for config file in project root
Look at linter output in :messages
Next steps
TypeScript TypeScript/JavaScript configuration
Lua Lua language configuration
Formatting Learn more about formatters
Linting Learn more about linters