-- https://github.com/golang/tools/tree/master/gopls local mod_cache = nil ---@param fname string ---@return string? local function get_root(fname) if mod_cache and fname:sub(1, #mod_cache) == mod_cache then local clients = vim.lsp.get_clients({ name = 'gopls' }) if #clients > 0 then return clients[#clients].config.root_dir end end return vim.fs.root(fname, { 'go.work', 'go.mod', '.git' }) end return { cmd = { 'gopls' }, filetypes = { 'go', 'gomod', 'gowork', 'gotmpl' }, root_dir = function(bufnr, on_dir) local fname = vim.api.nvim_buf_get_name(bufnr) -- see: https://github.com/neovim/nvim-lspconfig/issues/804 if mod_cache then on_dir(get_root(fname)) return end local cmd = { 'go', 'env', 'GOMODCACHE' } vim.system(cmd, { text = true }, function(output) if output.code == 0 then if output.stdout then mod_cache = vim.trim(output.stdout) end on_dir(get_root(fname)) else vim.notify(('[gopls] cmd failed with code %d: %s\n%s'):format(output.code, cmd, output.stderr)) end end) end, settings = { gopls = { gofumpt = true, codelenses = { gc_details = false, generate = true, regenerate_cgo = true, run_govulncheck = true, test = true, tidy = true, upgrade_dependency = true, vendor = true, }, hints = { assignVariableTypes = false, compositeLiteralFields = false, compositeLiteralTypes = true, constantValues = true, functionTypeParameters = false, parameterNames = false, rangeVariableTypes = true, }, analyses = { fieldalignment = true, nilness = true, unusedparams = true, unusedwrite = true, useany = true, }, usePlaceholders = false, completeUnimported = true, staticcheck = true, directoryFilters = { '-.git', '-.vscode', '-.idea', '-.vscode-test', '-node_modules' }, semanticTokens = true, }, }, on_attach = function(client) -- workaround for gopls not supporting semanticTokensProvider -- https://github.com/golang/go/issues/54531#issuecomment-1464982242 if not client.server_capabilities.semanticTokensProvider then local semantic = client.config.capabilities.textDocument.semanticTokens client.server_capabilities.semanticTokensProvider = { full = true, legend = { tokenTypes = semantic.tokenTypes, tokenModifiers = semantic.tokenModifiers, }, range = true, } end -- end workaround end, }