DEV Community

Salih Dhaifullah
Salih Dhaifullah

Posted on

Managing LSPs in Neovim: Enable/Disable for the Entire Session

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,
})
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
programmerraja profile image
Boopathi

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.