Repository: neovim/neovim
File: runtime/lua/vim/lsp.lua (Lua)

Code before:
    if lsp_enable_autocmd_id then
      api.nvim_del_autocmd(lsp_enable_autocmd_id)
      lsp_enable_autocmd_id = nil
    end
  else
    -- Only ever create autocmd once to reuse computation of config merging.
    lsp_enable_autocmd_id = lsp_enable_autocmd_id
      or api.nvim_create_autocmd('FileType', {
        group = api.nvim_create_augroup('nvim.lsp.enable', {}),
        callback = function(args)
          lsp_enable_callback(args.buf)
        end,
      })
  end

  -- Ensure any pre-existing buffers start/stop their LSP clients.
  if enable ~= false then
    if vim.v.vim_did_enter == 1 and next(lsp._enabled_configs) then
      vim.cmd.doautoall('nvim.lsp.enable FileType')
    end
  else
    for _, nm in ipairs(names) do
      for _, client in ipairs(lsp.get_clients({ name = nm })) do
        client:stop()
      end
    end
  end
end

--- Checks if the given LSP config is enabled (globally, not per-buffer).
---
--- Unlike `vim.lsp.config['…']`, this does not have the side-effect of resolving the config.
---
--- @param name string Config name
--- @return boolean
function lsp.is_enabled(name)
  return lsp._enabled_configs[name] ~= nil
end

--- @class vim.lsp.start.Opts
--- @inlinedoc
---
--- Predicate used to decide if a client should be re-used. Used on all
--- running clients. The default implementation re-uses a client if it has the
--- same name and if the given workspace folders (or root_dir) are all included
--- in the client's workspace folders.
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
---
--- Buffer handle to attach to if starting or re-using a client (0 for current).
--- @field bufnr? integer
---

Review comment (suggestion):
I had some trouble understanding the logic behind the value of `force_timeout`. Could we add a comment like "If `t` is an integer, use that as the timeout. If `t` is nil, use a default timeout of 3000. Else `t` must be false and nvim will exit immediately after sending the shutdown request".

Code after:
    -- If there are no remaining LSPs enabled, remove the enable autocmd.
    if lsp_enable_autocmd_id then
      api.nvim_del_autocmd(lsp_enable_autocmd_id)
      lsp_enable_autocmd_id = nil
    end
  else
    -- Only ever create autocmd once to reuse computation of config merging.
    lsp_enable_autocmd_id = lsp_enable_autocmd_id
      or api.nvim_create_autocmd('FileType', {
        group = api.nvim_create_augroup('nvim.lsp.enable', {}),
        callback = function(args)
          lsp_enable_callback(args.buf)
        end,
      })
  end

  -- Ensure any pre-existing buffers start/stop their LSP clients.
  if enable ~= false then
    if vim.v.vim_did_enter == 1 and next(lsp._enabled_configs) then
      vim.cmd.doautoall('nvim.lsp.enable FileType')
    end
  else
    for _, nm in ipairs(names) do
      for _, client in ipairs(lsp.get_clients({ name = nm })) do
        local t = client.flags.exit_timeout
        local force_timeout = t and tonumber(t) or (t ~= false and 3000 or nil)
        client:stop(force_timeout)
      end
    end
  end
end

--- Checks if the given LSP config is enabled (globally, not per-buffer).
---
--- Unlike `vim.lsp.config['…']`, this does not have the side-effect of resolving the config.
---
--- @param name string Config name
--- @return boolean
function lsp.is_enabled(name)
  return lsp._enabled_configs[name] ~= nil
end

--- @class vim.lsp.start.Opts
--- @inlinedoc
---
--- Predicate used to decide if a client should be re-used. Used on all
--- running clients. The default implementation re-uses a client if it has the
--- same name and if the given workspace folders (or root_dir) are all included
--- in the client's workspace folders.
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
---