Skip to content

Commit 1a00f1f

Browse files
committed
perf: improve performance of clearing progress messages and dynamic registration
1 parent 2c010a9 commit 1a00f1f

File tree

1 file changed

+27
-26
lines changed

1 file changed

+27
-26
lines changed

lua/astrolsp/init.lua

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ local tbl_isempty = vim.tbl_isempty
1616
M.config = require "astrolsp.config"
1717
--- A table of lsp progress messages that can be used to display LSP progress in a statusline
1818
M.lsp_progress = {}
19+
--- A table of LSP clients that have been attached with AstroLSP
20+
M.attached_clients = {}
1921

20-
local function lsp_event(name)
21-
vim.schedule(function() vim.api.nvim_exec_autocmds("User", { pattern = "AstroLsp" .. name, modeline = false }) end)
22-
end
22+
local function lsp_event(name) vim.api.nvim_exec_autocmds("User", { pattern = "AstroLsp" .. name, modeline = false }) end
2323

2424
---@param cond AstroLSPCondition?
2525
---@param client lsp.Client
@@ -78,11 +78,10 @@ function M.lsp_setup(server)
7878
end
7979
end
8080

81-
--- Helper function that does the actual configuring of the language server configure_environment
82-
--- Useful when dynamically refreshing the environment when capabilities are registered dynamically
83-
---@param client lsp.Client
84-
---@param bufnr integer
85-
local configure_environment = function(client, bufnr)
81+
--- The `on_attach` function used by AstroNvim
82+
---@param client lsp.Client The LSP client details when attaching
83+
---@param bufnr integer The buffer that the LSP client is attaching to
84+
M.on_attach = function(client, bufnr)
8685
if client.supports_method "textDocument/codeLens" and M.config.features.codelens then
8786
vim.lsp.codelens.refresh { bufnr = bufnr }
8887
end
@@ -185,23 +184,10 @@ local configure_environment = function(client, bufnr)
185184
end
186185
end
187186
end
188-
end
189-
190-
--- The `on_attach` function used by AstroNvim
191-
---@param client lsp.Client The LSP client details when attaching
192-
---@param bufnr integer The buffer that the LSP client is attaching to
193-
M.on_attach = function(client, bufnr)
194-
configure_environment(client, bufnr)
195-
196-
for id, _ in pairs(M.lsp_progress) do -- clear lingering progress messages
197-
-- TODO: remove check after dropping support for Neovim v0.9
198-
---@diagnostic disable-next-line: deprecated
199-
if not next((vim.lsp.get_clients or vim.lsp.get_active_clients) { id = tonumber(id:match "^%d+") }) then
200-
M.lsp_progress[id] = nil
201-
end
202-
end
203187

204188
if type(M.config.on_attach) == "function" then M.config.on_attach(client, bufnr) end
189+
190+
if not M.attached_clients[client.id] then M.attached_clients[client.id] = client end
205191
end
206192

207193
--- Get the server configuration for a given language server to be provided to the server's `setup()` call
@@ -265,6 +251,22 @@ function M.setup(opts)
265251
and not (vim.tbl_contains(disabled, client.name) or (type(filter) == "function" and not filter(client)))
266252
end
267253

254+
vim.api.nvim_create_autocmd("LspDetach", {
255+
group = vim.api.nvim_create_augroup("astrolsp_detach", { clear = true }),
256+
desc = "Clear state when language server is detached like LSP progress messages",
257+
callback = function(args)
258+
M.attached_clients[args.data.client_id] = nil
259+
local changed = false
260+
for id, _ in pairs(M.lsp_progress) do -- clear lingering progress messages
261+
if tonumber(id:match "^%d+") == args.data.client_id then
262+
M.lsp_progress[id] = nil
263+
changed = true
264+
end
265+
end
266+
if changed then lsp_event "Progress" end
267+
end,
268+
})
269+
268270
local progress_handler = vim.lsp.handlers["$/progress"]
269271
vim.lsp.handlers["$/progress"] = function(err, res, ctx)
270272
local progress, id = M.lsp_progress, ("%s.%s"):format(ctx.client_id, res.token)
@@ -282,9 +284,8 @@ function M.setup(opts)
282284
local register_capability_handler = vim.lsp.handlers["client/registerCapability"]
283285
vim.lsp.handlers["client/registerCapability"] = function(err, res, ctx)
284286
local ret = register_capability_handler(err, res, ctx)
285-
local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
286-
-- TODO: remove `if` statement when dropping support for Neovim v0.9
287-
if client.supports_method then configure_environment(client, vim.api.nvim_get_current_buf()) end
287+
local attached_client = M.attached_clients[ctx.client_id]
288+
if attached_client then M.on_attach(attached_client, vim.api.nvim_get_current_buf()) end
288289
return ret
289290
end
290291

0 commit comments

Comments
 (0)