mirror of
https://github.com/LazyVim/LazyVim.git
synced 2025-12-25 12:14:19 +01:00
feat(lsp): refactor lsp code to use Snacks.util.lsp.on
This commit is contained in:
@@ -85,9 +85,9 @@ return {
|
||||
copilot_cmp.setup(opts)
|
||||
-- attach cmp source whenever copilot attaches
|
||||
-- fixes lazy-loading issues with the copilot cmp source
|
||||
LazyVim.lsp.on_attach(function()
|
||||
Snacks.util.lsp.on({ name = "copilot" }, function()
|
||||
copilot_cmp._on_insert_enter({})
|
||||
end, "copilot")
|
||||
end)
|
||||
end,
|
||||
specs = {
|
||||
{
|
||||
|
||||
@@ -7,10 +7,8 @@ return {
|
||||
lazy = true,
|
||||
init = function()
|
||||
vim.g.navic_silence = true
|
||||
LazyVim.lsp.on_attach(function(client, buffer)
|
||||
if client:supports_method("textDocument/documentSymbol") then
|
||||
require("nvim-navic").attach(client, buffer)
|
||||
end
|
||||
Snacks.util.lsp.on({ method = "textDocument/documentSymbol" }, function(buffer, client)
|
||||
require("nvim-navic").attach(client, buffer)
|
||||
end)
|
||||
end,
|
||||
opts = function()
|
||||
|
||||
@@ -35,10 +35,10 @@ return {
|
||||
},
|
||||
setup = {
|
||||
angularls = function()
|
||||
LazyVim.lsp.on_attach(function(client)
|
||||
Snacks.util.lsp.on({ name = "angularls" }, function(_, client)
|
||||
--HACK: disable angular renaming capability due to duplicate rename popping up
|
||||
client.server_capabilities.renameProvider = false
|
||||
end, "angularls")
|
||||
end)
|
||||
end,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -55,7 +55,7 @@ return {
|
||||
gopls = function(_, opts)
|
||||
-- workaround for gopls not supporting semanticTokensProvider
|
||||
-- https://github.com/golang/go/issues/54531#issuecomment-1464982242
|
||||
LazyVim.lsp.on_attach(function(client, _)
|
||||
Snacks.util.lsp.on({ name = "gopls" }, function(_, client)
|
||||
if not client.server_capabilities.semanticTokensProvider then
|
||||
local semantic = client.config.capabilities.textDocument.semanticTokens
|
||||
client.server_capabilities.semanticTokensProvider = {
|
||||
@@ -67,7 +67,7 @@ return {
|
||||
range = true,
|
||||
}
|
||||
end
|
||||
end, "gopls")
|
||||
end)
|
||||
-- end workaround
|
||||
end,
|
||||
},
|
||||
|
||||
@@ -58,10 +58,10 @@ return {
|
||||
},
|
||||
setup = {
|
||||
[ruff] = function()
|
||||
LazyVim.lsp.on_attach(function(client, _)
|
||||
Snacks.util.lsp.on({ name = ruff }, function(_, client)
|
||||
-- Disable hover in favor of Pyright
|
||||
client.server_capabilities.hoverProvider = false
|
||||
end, ruff)
|
||||
end)
|
||||
end,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -154,7 +154,7 @@ return {
|
||||
resolve("vtsls")
|
||||
end
|
||||
|
||||
LazyVim.lsp.on_attach(function(client, buffer)
|
||||
Snacks.util.lsp.on({ name = "vtsls" }, function(buffer, client)
|
||||
client.commands["_typescript.moveToFileRefactoring"] = function(command, ctx)
|
||||
---@type string, string, lsp.Range
|
||||
local action, uri, range = unpack(command.arguments)
|
||||
@@ -203,7 +203,7 @@ return {
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end, "vtsls")
|
||||
end)
|
||||
-- copy typescript settings to javascript
|
||||
opts.settings.javascript =
|
||||
vim.tbl_deep_extend("force", {}, opts.settings.typescript, opts.settings.javascript or {})
|
||||
|
||||
@@ -125,16 +125,15 @@ return {
|
||||
LazyVim.format.register(LazyVim.lsp.formatter())
|
||||
|
||||
-- setup keymaps
|
||||
LazyVim.lsp.on_attach(function(client, buffer)
|
||||
require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer)
|
||||
end)
|
||||
|
||||
LazyVim.lsp.setup()
|
||||
LazyVim.lsp.on_dynamic_capability(require("lazyvim.plugins.lsp.keymaps").on_attach)
|
||||
for server, server_opts in pairs(opts.servers) do
|
||||
if type(server_opts) == "table" and server_opts.keys then
|
||||
require("lazyvim.plugins.lsp.keymaps").set({ name = server ~= "*" and server or nil }, server_opts.keys)
|
||||
end
|
||||
end
|
||||
|
||||
-- inlay hints
|
||||
if opts.inlay_hints.enabled then
|
||||
LazyVim.lsp.on_supports_method("textDocument/inlayHint", function(client, buffer)
|
||||
Snacks.util.lsp.on({ method = "textDocument/inlayHint" }, function(buffer)
|
||||
if
|
||||
vim.api.nvim_buf_is_valid(buffer)
|
||||
and vim.bo[buffer].buftype == ""
|
||||
@@ -147,7 +146,7 @@ return {
|
||||
|
||||
-- folds
|
||||
if opts.folds.enabled then
|
||||
LazyVim.lsp.on_supports_method("textDocument/foldingRange", function(client, buffer)
|
||||
Snacks.util.lsp.on({ method = "textDocument/foldingRange" }, function()
|
||||
if LazyVim.set_default("foldmethod", "expr") then
|
||||
LazyVim.set_default("foldexpr", "v:lua.vim.lsp.foldexpr()")
|
||||
end
|
||||
@@ -156,7 +155,7 @@ return {
|
||||
|
||||
-- code lens
|
||||
if opts.codelens.enabled and vim.lsp.codelens then
|
||||
LazyVim.lsp.on_supports_method("textDocument/codeLens", function(client, buffer)
|
||||
Snacks.util.lsp.on({ method = "textDocument/codeLens" }, function(buffer)
|
||||
vim.lsp.codelens.refresh()
|
||||
vim.api.nvim_create_autocmd({ "BufEnter", "CursorHold", "InsertLeave" }, {
|
||||
buffer = buffer,
|
||||
|
||||
@@ -6,6 +6,22 @@ M.moved = {
|
||||
rename_file = { "Snacks.rename.rename_file" },
|
||||
on_rename = { "Snacks.rename.on_rename_file" },
|
||||
words = { "Snacks.words" },
|
||||
on_supports_method = {
|
||||
"Snacks.util.lsp.on",
|
||||
fn = function(method, cb)
|
||||
return Snacks.util.lsp.on({ method = method }, function(buffer, client)
|
||||
cb(client, buffer)
|
||||
end)
|
||||
end,
|
||||
},
|
||||
on_attach = {
|
||||
"Snacks.util.lsp.on",
|
||||
fn = function(cb, name)
|
||||
return Snacks.util.lsp.on({ name = name }, function(buffer, client)
|
||||
cb(client, buffer)
|
||||
end)
|
||||
end,
|
||||
},
|
||||
},
|
||||
terminal = {
|
||||
open = { "Snacks.terminal" },
|
||||
|
||||
@@ -1,103 +1,6 @@
|
||||
---@class lazyvim.util.lsp
|
||||
local M = {}
|
||||
|
||||
---@param on_attach fun(client:vim.lsp.Client, buffer)
|
||||
---@param name? string
|
||||
function M.on_attach(on_attach, name)
|
||||
return vim.api.nvim_create_autocmd("LspAttach", {
|
||||
callback = function(args)
|
||||
local buffer = args.buf ---@type number
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
if client and (not name or client.name == name) then
|
||||
return on_attach(client, buffer)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@type table<string, table<vim.lsp.Client, table<number, boolean>>>
|
||||
M._supports_method = {}
|
||||
|
||||
function M.setup()
|
||||
local register_capability = vim.lsp.handlers["client/registerCapability"]
|
||||
vim.lsp.handlers["client/registerCapability"] = function(err, res, ctx)
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
local ret = register_capability(err, res, ctx)
|
||||
local client = vim.lsp.get_client_by_id(ctx.client_id)
|
||||
if client then
|
||||
for buffer in pairs(client.attached_buffers) do
|
||||
vim.api.nvim_exec_autocmds("User", {
|
||||
pattern = "LspDynamicCapability",
|
||||
data = { client_id = client.id, buffer = buffer },
|
||||
})
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
M.on_attach(M._check_methods)
|
||||
M.on_dynamic_capability(M._check_methods)
|
||||
end
|
||||
|
||||
---@param client vim.lsp.Client
|
||||
function M._check_methods(client, buffer)
|
||||
-- don't trigger on invalid buffers
|
||||
if not vim.api.nvim_buf_is_valid(buffer) then
|
||||
return
|
||||
end
|
||||
-- don't trigger on non-listed buffers
|
||||
if not vim.bo[buffer].buflisted then
|
||||
return
|
||||
end
|
||||
-- don't trigger on nofile buffers
|
||||
if vim.bo[buffer].buftype == "nofile" then
|
||||
return
|
||||
end
|
||||
for method, clients in pairs(M._supports_method) do
|
||||
clients[client] = clients[client] or {}
|
||||
if not clients[client][buffer] then
|
||||
if client.supports_method and client:supports_method(method, buffer) then
|
||||
clients[client][buffer] = true
|
||||
vim.api.nvim_exec_autocmds("User", {
|
||||
pattern = "LspSupportsMethod",
|
||||
data = { client_id = client.id, buffer = buffer, method = method },
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param fn fun(client:vim.lsp.Client, buffer):boolean?
|
||||
---@param opts? {group?: integer}
|
||||
function M.on_dynamic_capability(fn, opts)
|
||||
return vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "LspDynamicCapability",
|
||||
group = opts and opts.group or nil,
|
||||
callback = function(args)
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
local buffer = args.data.buffer ---@type number
|
||||
if client then
|
||||
return fn(client, buffer)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param method string
|
||||
---@param fn fun(client:vim.lsp.Client, buffer)
|
||||
function M.on_supports_method(method, fn)
|
||||
M._supports_method[method] = M._supports_method[method] or setmetatable({}, { __mode = "k" })
|
||||
return vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "LspSupportsMethod",
|
||||
callback = function(args)
|
||||
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||
local buffer = args.data.buffer ---@type number
|
||||
if client and method == args.data.method then
|
||||
return fn(client, buffer)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param opts? LazyFormatter| {filter?: (string|vim.lsp.get_clients.Filter)}
|
||||
function M.formatter(opts)
|
||||
opts = opts or {}
|
||||
|
||||
Reference in New Issue
Block a user