From d44752dfc277438201e1ae70722b11023b3d76a1 Mon Sep 17 00:00:00 2001 From: Tony Wang Date: Tue, 20 Jan 2026 23:00:50 +0800 Subject: [PATCH] improve get workspace folders only return workspace folders from gopls. It's different when there are other lsp active clients (e.g. copilot) taking precedent, whose workspace folder could be different (e.g. repo root, instead of go.mod) --- lua/go/enum.lua | 1 - lua/go/env.lua | 2 +- lua/go/goget.lua | 2 +- lua/go/gotool.lua | 2 +- lua/go/null_ls.lua | 4 ++-- lua/go/project.lua | 6 +++--- lua/go/utils.lua | 12 +++++++++++- lua/tests/go_gopls_spec.lua | 4 ++-- 8 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lua/go/enum.lua b/lua/go/enum.lua index c1fbe5ad7..8c77e290b 100644 --- a/lua/go/enum.lua +++ b/lua/go/enum.lua @@ -18,7 +18,6 @@ function M.run(args) local new_name = vfn.expand('%:p:r') .. "_enum.go" vim.list_extend(cmd, args) - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() local opts = { update_buffer = true, on_exit = function() diff --git a/lua/go/env.lua b/lua/go/env.lua index aa02d93d9..b95fa4196 100644 --- a/lua/go/env.lua +++ b/lua/go/env.lua @@ -10,7 +10,7 @@ function M.envfile(f) if vfn.filereadable(f) then return f end - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() + local workfolder = util.get_gopls_workspace_folders()[1] or vfn.getcwd() local goenv = workfolder .. sep .. (f or '.env') if vfn.filereadable(goenv) == 1 then diff --git a/lua/go/goget.lua b/lua/go/goget.lua index 5562535da..47fba3b4e 100644 --- a/lua/go/goget.lua +++ b/lua/go/goget.lua @@ -26,7 +26,7 @@ function M.run(args) utils.log(cmd) - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() + local workfolder = utils.get_gopls_workspace_folders()[1] or vfn.getcwd() local modfile = workfolder .. utils.sep() .. 'go.mod' local opts = { update_buffer = true, diff --git a/lua/go/gotool.lua b/lua/go/gotool.lua index 954e45b96..73aeadfe3 100644 --- a/lua/go/gotool.lua +++ b/lua/go/gotool.lua @@ -40,7 +40,7 @@ function M.run(args) vim.list_extend(cmd, args) utils.log(cmd) - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() + local workfolder = utils.get_gopls_workspace_folders()[1] or vfn.getcwd() local modfile = workfolder .. utils.sep() .. 'go.mod' local opts = { update_buffer = true, diff --git a/lua/go/null_ls.lua b/lua/go/null_ls.lua index 1a46c7829..2d1eec562 100644 --- a/lua/go/null_ls.lua +++ b/lua/go/null_ls.lua @@ -197,7 +197,7 @@ return { multiple_files = true, format = 'raw', cwd = h.cache.by_bufnr(function(params) - local ws = vim.lsp.buf.list_workspace_folders() + local ws = utils.get_gopls_workspace_folders() if #ws > 0 then return ws[1] end @@ -353,7 +353,7 @@ return { filetypes = { 'go' }, cwd = h.cache.by_bufnr(function(params) - local ws = vim.lsp.buf.list_workspace_folders() + local ws = utils.get_gopls_workspace_folders() if #ws > 0 then return ws[1] end diff --git a/lua/go/project.lua b/lua/go/project.lua index 1cff04f71..f564cfd2e 100644 --- a/lua/go/project.lua +++ b/lua/go/project.lua @@ -25,7 +25,7 @@ local M = {} local sep = require("go.utils").sep() function M.project_existed() - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() + local workfolder = util.get_gopls_workspace_folders()[1] or vfn.getcwd() local gocfgfd = workfolder .. sep .. ".gonvim" local gocfgbrks = gocfgfd .. sep .. "breakpoints.lua" local gocfg = gocfgfd .. sep .. "init.lua" @@ -36,7 +36,7 @@ function M.project_existed() end function M.setup() - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() + local workfolder = util.get_gopls_workspace_folders()[1] or vfn.getcwd() local gocfgfd = workfolder .. sep .. ".gonvim" local gocfg = gocfgfd .. sep .. "init.lua" @@ -52,7 +52,7 @@ function M.setup() end function M.load_project() - local workfolder = vim.lsp.buf.list_workspace_folders()[1] or vfn.getcwd() + local workfolder = util.get_gopls_workspace_folders()[1] or vfn.getcwd() local gocfg = workfolder .. sep .. ".gonvim" .. sep .. "init.lua" if _GO_NVIM_CFG.disable_per_project_cfg then log("project setup existed but disabled") diff --git a/lua/go/utils.lua b/lua/go/utils.lua index 04bf69f73..298f4229c 100644 --- a/lua/go/utils.lua +++ b/lua/go/utils.lua @@ -529,6 +529,16 @@ function utils.debug(msg) end) end +function utils.get_gopls_workspace_folders() + local workspace_folders = {} + for _, client in pairs(vim.lsp.get_clients({ bufnr = 0, name = 'gopls' })) do + for _, folder in pairs(client.workspace_folders or {}) do + table.insert(workspace_folders, folder.name) + end + end + return workspace_folders +end + function utils.rel_path(folder) -- maybe expand('%:p:h:t') local mod = '%:p' @@ -537,7 +547,7 @@ function utils.rel_path(folder) end local fpath = fn.expand(mod) -- workfolders does not work if user does not setup neovim to follow workspace - local workfolders = vim.lsp.buf.list_workspace_folders() + local workfolders = utils.get_gopls_workspace_folders() local pwd = fn.getcwd() if fn.empty(workfolders) == 0 then diff --git a/lua/tests/go_gopls_spec.lua b/lua/tests/go_gopls_spec.lua index 22a6f4904..a9f24e382 100644 --- a/lua/tests/go_gopls_spec.lua +++ b/lua/tests/go_gopls_spec.lua @@ -1,6 +1,6 @@ local eq = assert.are.same local cur_dir = vim.fn.expand('%:p:h') -local busted = require('plenary/busted') +local utils = require('go.utils') local godir = cur_dir .. '/lua/tests/fixtures' describe('should run gopls related functions', function() @@ -29,7 +29,7 @@ describe('should run gopls related functions', function() end, 100) require('go.format').goimports() local fmt - require('go.utils').log('workspaces:', vim.inspect(vim.lsp.buf.list_workspace_folders())) + require('go.utils').log('workspaces:', vim.inspect(utils.get_gopls_workspace_folders())) vim.wait(4000, function() vim.cmd([[wa]]) fmt = vim.fn.join(vim.fn.readfile(path), '\n')