From e24630d7c33bfc4f10ad557917c46ebf8c498d85 Mon Sep 17 00:00:00 2001 From: Snoweuph Date: Sun, 12 Apr 2026 14:48:18 +0200 Subject: [PATCH] lsp/presets/gopls: init --- modules/plugins/lsp/presets/default.nix | 1 + modules/plugins/lsp/presets/gopls.nix | 59 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 modules/plugins/lsp/presets/gopls.nix diff --git a/modules/plugins/lsp/presets/default.nix b/modules/plugins/lsp/presets/default.nix index 8910bb43..1d09184d 100644 --- a/modules/plugins/lsp/presets/default.nix +++ b/modules/plugins/lsp/presets/default.nix @@ -7,6 +7,7 @@ ./bash-language-server.nix ./deno.nix ./emmet-ls.nix + ./gopls.nix ./harper.nix ./helm-ls.nix ./intelephense.nix diff --git a/modules/plugins/lsp/presets/gopls.nix b/modules/plugins/lsp/presets/gopls.nix new file mode 100644 index 00000000..3a95738f --- /dev/null +++ b/modules/plugins/lsp/presets/gopls.nix @@ -0,0 +1,59 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib.meta) getExe; + inherit (lib.modules) mkIf; + inherit (lib.options) mkEnableOption; + inherit (lib.generators) mkLuaInline; + + cfg = config.vim.lsp.presets.gopls; +in { + options.vim.lsp.presets.gopls = { + enable = mkEnableOption "the official Go Language Server"; + }; + + config = mkIf cfg.enable { + vim.lsp.servers.gopls = { + enable = true; + cmd = [(getExe pkgs.gopls)]; + 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 + ''; + }; + }; +}