feat(picker): updated Snacks.picker.lsp_config to work with vim.lsp.config

This commit is contained in:
Folke Lemaitre 2025-09-16 09:18:10 +02:00
parent da230e3ca8
commit 292d46f773
No known key found for this signature in database
GPG key ID: 9B52594D560070AB

View file

@ -1,6 +1,8 @@
---@diagnostic disable: await-in-sync
local M = {}
local has_11 = vim.fn.has("nvim-0.11") == 1
---@class snacks.picker.lsp.config.Item: snacks.picker.finder.Item
---@field name string
---@field config? vim.lsp.ClientConfig
@ -13,33 +15,69 @@ local M = {}
---@field cmd? string[]
---@field bin? string
---@class snacks.picker.lsp.config.Config
---@field config vim.lsp.Config
---@field enabled? boolean
---@field docs? string
---@param name string
local function is_enabled(name)
if has_11 then
return vim.lsp.is_enabled(name)
end
local lspconfig = require("lspconfig.configs")
return lspconfig[name] and lspconfig[name].manager ~= nil
end
---@param name string
local function get_config(name)
local modpath = vim.api.nvim_get_runtime_file("lsp/" .. name .. ".lua", false)[1]
local ret = { config = {} } ---@type snacks.picker.lsp.config.Config
local ok, config = pcall(function()
return has_11 and vim.lsp.config[name] or loadfile(modpath)() or {}
end)
ret.config = ok and config or {}
ret.enabled = is_enabled(name)
local lines = modpath and Snacks.picker.util.lines(modpath) or {}
local header = {} ---@type string[]
for _, line in ipairs(lines) do
if line:match("^%s*%-%-") then
if not line:match("@brief") then
header[#header + 1] = line:gsub("^%s*%-%-+%s?", "")
end
elseif not line:match("^%s*$") then
break
end
end
ret.docs = vim.trim(table.concat(header, "\n"))
return ret
end
---@param opts snacks.picker.lsp.config.Config
---@type snacks.picker.finder
function M.find(opts, ctx)
local root = vim.api.nvim_get_runtime_file("lua/lspconfig/configs.lua", false)[1]
if not root then
Snacks.notify.warn("`nvim-lspconfig` not installed?")
local all = vim.api.nvim_get_runtime_file("lsp/*.lua", true)
local available = {} ---@type string[]
for _, f in ipairs(all) do
local name = f:match("([^/\\]+)%.lua$")
if name then
available[#available + 1] = name
end
end
if #all == 0 then
Snacks.notify.warn("No LSP configurations found?")
return {}
end
root = root:gsub("%.lua$", "")
local main_buf = vim.api.nvim_win_get_buf(ctx.picker.main)
local lspconfig = require("lspconfig.configs")
---@param item snacks.picker.lsp.config.Item
local function resolve(item)
---@type boolean, {docs?:{description?:string}, default_config?:vim.lsp.ClientConfig}?
local ok, mod = pcall(function()
if lspconfig[item.name] then
return lspconfig[item.name].config_def
end
return loadfile(root .. "/" .. item.name .. ".lua")()
end)
if not (ok and mod) then
return
end
item.docs = mod.docs and mod.docs.description or ""
item.config = item.config or mod.default_config
item.cmd = item.cmd or lspconfig[item.name] and lspconfig[item.name].cmd
local mod = get_config(item.name)
item.docs = item.docs or mod.docs
item.config = item.config or mod.config
item.cmd = item.cmd or mod.config.cmd
item.enabled = item.enabled or mod.enabled
end
local items = {} ---@type table<string, snacks.picker.lsp.config.Item>
@ -59,17 +97,12 @@ function M.find(opts, ctx)
items[client.name].attached_buf = items[client.name].buffers[main_buf]
end
for f in vim.fs.dir(root) do
local name = f:match("^(.*)%.lua$")
if name then
items[name] = items[name]
or {
name = name,
buffers = {},
enabled = lspconfig[name] and lspconfig[name].manager ~= nil,
}
items[name].resolve = resolve
end
for _, name in ipairs(available) do
items[name] = items[name] or {
name = name,
buffers = {},
}
items[name].resolve = resolve
end
---@param cb async fun(item: snacks.picker.finder.Item)