From a2ce78fa90fe91ba855203cb7e30aa727c85ec31 Mon Sep 17 00:00:00 2001 From: Ching Pei Yang Date: Sat, 28 Jun 2025 15:30:24 +0200 Subject: [PATCH] language/go: migrate to vim.lsp.servers --- modules/plugins/languages/go.nix | 76 ++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/modules/plugins/languages/go.nix b/modules/plugins/languages/go.nix index bab0ff4a..3ecc5d28 100644 --- a/modules/plugins/languages/go.nix +++ b/modules/plugins/languages/go.nix @@ -8,28 +8,53 @@ inherit (lib.options) mkEnableOption mkOption literalMD; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.lists) isList; - inherit (lib.types) bool enum either listOf package str; + inherit (lib.generators) mkLuaInline; + inherit (lib.types) bool enum package listOf; inherit (lib.nvim.types) mkGrammarOption; - inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.dag) entryAfter; + inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.go; - defaultServer = "gopls"; + defaultServers = ["gopls"]; servers = { gopls = { - package = pkgs.gopls; - lspConfig = '' - lspconfig.gopls.setup { - capabilities = capabilities; - on_attach = default_on_attach; - cmd = ${ - if isList cfg.lsp.package - then expToLua cfg.lsp.package - else ''{"${cfg.lsp.package}/bin/gopls", "serve"}'' - }, - } + cmd = [(getExe pkgs.gopls)]; + filetypes = ["go" "gomod" "gowork" "gotmpl"]; + root_dir = mkLuaInline '' + function(bufnr, on_dir) + local fname = vim.api.nvim_buf_get_name(bufnr) + + local function get_root(fname) + if _G.nvf_gopls_mod_cache and fname:sub(1, #_G.nvf_gopls_mod_cache) == _G.nvf_gopls_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') or vim.fs.root(fname, 'go.mod') or vim.fs.root(fname, '.git') + end + + -- see: https://github.com/neovim/nvim-lspconfig/issues/804 + if _G.nvf_gopls_mod_cache then + on_dir(get_root(fname)) + return + end + local cmd = { 'go', 'env', 'GOMODCACHE' } + local ok, err = pcall(vim.system, cmd, { text = true }, function(output) + if output.code == 0 then + if output.stdout then + _G.nvf_gopls_mod_cache = vim.trim(output.stdout) + end + on_dir(get_root(fname)) + else + vim.schedule(function() + vim.notify(('[gopls] cmd failed with code %d: %s\n%s'):format(output.code, cmd, output.stderr)) + end) + end + end) + if not ok then vim.notify(('[gopls] cmd failed: %s\n%s'):format(cmd, err)) end + end ''; }; }; @@ -69,17 +94,10 @@ in { lsp = { enable = mkEnableOption "Go LSP support" // {default = config.vim.lsp.enable;}; - server = mkOption { + servers = mkOption { + type = singleOrListOf (enum (attrNames servers)); + default = defaultServers; description = "Go LSP server to use"; - type = enum (attrNames servers); - default = defaultServer; - }; - - package = mkOption { - description = "Go LSP server package, or the command to run as a list of strings"; - example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]''; - type = either package (listOf str); - default = servers.${cfg.lsp.server}.package; }; }; @@ -134,8 +152,12 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.lspconfig.enable = true; - vim.lsp.lspconfig.sources.go-lsp = servers.${cfg.lsp.server}.lspConfig; + vim.lsp.servers = + mapListToAttrs (name: { + inherit name; + value = servers.${name}; + }) + cfg.lsp.servers; }) (mkIf cfg.format.enable {