Neovim’s built-in LSP functionality provides powerful coding assistance. However, there may be times when you want to disable LSP features entirely for the duration of your session. This guide will show you how to toggle LSPs on and off globally until you close Neovim.
Why Toggle LSPs?
Performance Issues: In larger projects, LSPs can consume resources, leading to slower performance.
Distraction-Free Coding: You may want to focus on code without the assistance of LSP features such as autocompletion or linting.
Testing Changes: Disabling LSPs can help you test specific changes without interference.
Code Implementation
-- Initialize a variable to track if LSPs are enabled or disabled
local lsp_enabled = true
-- Table to store buffers attached to each LSP client
local attached_buffers_by_client = {}
-- Function to toggle LSPs on and off
local function toggle_lsp()
if lsp_enabled then
-- If LSPs are currently enabled, reset the attached buffers table
attached_buffers_by_client = {}
-- Iterate over all LSP clients
for _, client in ipairs(vim.lsp.get_clients()) do
-- Initialize a table for each client's buffers
attached_buffers_by_client[client.id] = {}
-- Check each buffer attached to the client
for buf, active in pairs(client.attached_buffers) do
if active then
-- Store the active buffer in the client's buffer table
table.insert(attached_buffers_by_client[client.id], buf)
-- Detach the client from the active buffer
pcall(vim.lsp.buf_detach_client, buf, client.id)
end
end
end
print("LSPs Disabled")
else
-- If LSPs are currently disabled, reattach buffers to their respective clients
for client_id, buffers in pairs(attached_buffers_by_client) do
for _, buf in ipairs(buffers) do
-- Reattach the client to the previously detached buffer
pcall(vim.lsp.buf_attach_client, buf, client_id)
end
end
print("LSPs Enabled")
end
-- Toggle the state of the lsp_enabled variable
lsp_enabled = not lsp_enabled
end
-- Map the toggle function combination <leader>tl you can use your own keymap here
vim.keymap.set("n", "<leader>tl", toggle_lsp)
-- Create an autocommand that runs on buffer entry or reading
-- If LSPs are disabled, detach active clients from the current buffer
vim.api.nvim_create_autocmd({"BufEnter", "BufRead"}, {
pattern = "*", -- Match all buffers
callback = function()
if not lsp_enabled then
for _, client in ipairs(vim.lsp.get_clients()) do
for buf, active in pairs(client.attached_buffers) do
-- Check if the buffer is active and matches the current buffer
if active and buf == vim.api.nvim_get_current_buf() then
-- Ensure there's a table for the client in the attached_buffers_by_client
if attached_buffers_by_client[client.id] == nil then
attached_buffers_by_client[client.id] = {}
end
-- Store the current buffer in the client's buffer table
table.insert(attached_buffers_by_client[client.id], buf)
-- Detach the client from the current buffer
pcall(vim.lsp.buf_detach_client, buf, client.id)
end
end
end
end
end,
})
Understanding LspStop
While the :LspStop
command can stop LSP clients for the current buffer, it has some limitations. Here’s how it behaves:
Stop Current Buffer: Executing
:LspStop
detaches the LSP client from only the currently active buffer. This means that LSP features will be disabled only for that buffer.Reopening the Buffer: If you close and reopen the buffer, the LSP client automatically restarts and reattaches. This behavior is standard in Neovim, ensuring that once you access a buffer again, the language server is reactivated.
Opening New Buffers: Similarly, if you open a new buffer associated with an LSP client, Neovim will trigger the LSP to start again. Thus, even if you previously stopped LSP for one buffer, any new buffer supported by a language server will reactivate the client.
Top comments (1)
This is a very helpful guide! I'm particularly interested in the
attached_buffers_by_client
table. I've been looking for a way to manage LSPs globally, and this approach seems very efficient. I'm going to try this out in my next project.