diff options
| author | awy <awy@awy.one> | 2025-10-14 18:27:29 +0300 | 
|---|---|---|
| committer | awy <awy@awy.one> | 2025-10-14 18:27:29 +0300 | 
| commit | de009fd679e10d053fdcc10785f91ad5317449ea (patch) | |
| tree | 60918a488b579588596cf4d509fde298dccbf15d /.config/nvim/lsp/gopls.lua | |
| parent | 9ea6cf81adb5d6abc59843de1db45913210f9320 (diff) | |
| download | hyprdots-de009fd679e10d053fdcc10785f91ad5317449ea.tar.gz | |
nvim revamp
Diffstat (limited to '.config/nvim/lsp/gopls.lua')
| -rw-r--r-- | .config/nvim/lsp/gopls.lua | 99 | 
1 files changed, 99 insertions, 0 deletions
diff --git a/.config/nvim/lsp/gopls.lua b/.config/nvim/lsp/gopls.lua new file mode 100644 index 0000000..558f0a9 --- /dev/null +++ b/.config/nvim/lsp/gopls.lua @@ -0,0 +1,99 @@ +---@brief +--- +--- https://github.com/golang/tools/tree/master/gopls +--- +--- Google's lsp server for golang. + +--- @class go_dir_custom_args +--- +--- @field envvar_id string +--- +--- @field custom_subdir string? + +local mod_cache = nil +local std_lib = nil + +---@param custom_args go_dir_custom_args +---@param on_complete fun(dir: string | nil) +local function identify_go_dir(custom_args, on_complete) +  local cmd = { 'go', 'env', custom_args.envvar_id } +  vim.system(cmd, { text = true }, function(output) +    local res = vim.trim(output.stdout or '') +    if output.code == 0 and res ~= '' then +      if custom_args.custom_subdir and custom_args.custom_subdir ~= '' then +        res = res .. custom_args.custom_subdir +      end +      on_complete(res) +    else +      vim.schedule(function() +        vim.notify( +          ('[gopls] identify ' .. custom_args.envvar_id .. ' dir cmd failed with code %d: %s\n%s'):format( +            output.code, +            vim.inspect(cmd), +            output.stderr +          ) +        ) +      end) +      on_complete(nil) +    end +  end) +end + +---@return string? +local function get_std_lib_dir() +  if std_lib and std_lib ~= '' then +    return std_lib +  end + +  identify_go_dir({ envvar_id = 'GOROOT', custom_subdir = '/src' }, function(dir) +    if dir then +      std_lib = dir +    end +  end) +  return std_lib +end + +---@return string? +local function get_mod_cache_dir() +  if mod_cache and mod_cache ~= '' then +    return mod_cache +  end + +  identify_go_dir({ envvar_id = 'GOMODCACHE' }, function(dir) +    if dir then +      mod_cache = dir +    end +  end) +  return mod_cache +end + +---@param fname string +---@return string? +local function get_root_dir(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 +  if std_lib and fname:sub(1, #std_lib) == std_lib 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 + +---@type vim.lsp.Config +return { +  cmd = { 'gopls' }, +  filetypes = { 'go', 'gomod', 'gowork', 'gotmpl' }, +  root_dir = function(bufnr, on_dir) +    local fname = vim.api.nvim_buf_get_name(bufnr) +    get_mod_cache_dir() +    get_std_lib_dir() +    -- see: https://github.com/neovim/nvim-lspconfig/issues/804 +    on_dir(get_root_dir(fname)) +  end, +}  |