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

Code before:
    end
  end
  return clients
end

---@deprecated
function lsp.get_active_clients(filter)
  vim.deprecate('vim.lsp.get_active_clients()', 'vim.lsp.get_clients()', '0.12')
  return lsp.get_clients(filter)
end

api.nvim_create_autocmd('VimLeavePre', {
  desc = 'vim.lsp: exit handler',
  callback = function()
    local active_clients = lsp.get_clients()
    log.info('exit_handler', active_clients)

    local max_timeout = 0
    for _, client in pairs(active_clients) do
      client:stop(client.exit_timeout)
      if type(client.exit_timeout) == 'integer' then
        max_timeout = math.max(max_timeout, client.exit_timeout)
      end
    end

    vim.wait(max_timeout + 1, function()
      return vim.iter(active_clients):all(function(client)
        return client._shutdown_timer == nil
      end)
    end)
  end,
})

---@nodoc
--- Sends an async request for all active clients attached to the
--- buffer.
---
---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (vim.lsp.protocol.Method.ClientToServer.Request) LSP method name
---@param params? table|(fun(client: vim.lsp.Client, bufnr: integer): table?) Parameters to send to the server
---@param handler? lsp.Handler See |lsp-handler|
---       If nil, follows resolution strategy defined in |lsp-handler-configuration|
---@param on_unsupported? fun()
---       The function to call when the buffer has no clients that support the given method.
---       Defaults to an `ERROR` level notification.
---@return table<integer, integer> client_request_ids Map of client-id:request-id pairs
---for all successful requests.
---@return function _cancel_all_requests Function which can be used to
---cancel all the requests. You could instead
---iterate all clients and call their `cancel_request()` methods.
function lsp.buf_request(bufnr, method, params, handler, on_unsupported)

Review comment (suggestion):
It is probably worth showing a message here.

```suggestion
    if max_timeout > 10 then
      vim.api.nvim_echo(...)
    end
    vim.wait(max_timeout + 1, function()
```

Code after:
      client:stop(client.exit_timeout)
    end
    if max_timeout > 10 then
      api.nvim_echo({
        {
          string.format('Waiting %ss for lsp exit (Press Ctrl-C to force exit)', max_timeout / 1e3),
          'WarningMsg',
        },
      }, true, {})
    end

    vim.wait(max_timeout, function()
      return vim.iter(active_clients):all(function(client)
        return client.rpc.is_closing()
      end)
    end)
  end,
})

---@nodoc
--- Sends an async request for all active clients attached to the
--- buffer.
---
---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (vim.lsp.protocol.Method.ClientToServer.Request) LSP method name
---@param params? table|(fun(client: vim.lsp.Client, bufnr: integer): table?) Parameters to send to the server
---@param handler? lsp.Handler See |lsp-handler|
---       If nil, follows resolution strategy defined in |lsp-handler-configuration|
---@param on_unsupported? fun()
---       The function to call when the buffer has no clients that support the given method.
---       Defaults to an `ERROR` level notification.
---@return table<integer, integer> client_request_ids Map of client-id:request-id pairs
---for all successful requests.
---@return function _cancel_all_requests Function which can be used to
---cancel all the requests. You could instead
---iterate all clients and call their `cancel_request()` methods.
function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
  validate('bufnr', bufnr, 'number', true)
  validate('method', method, 'string')
  validate('handler', handler, 'function', true)
  validate('on_unsupported', on_unsupported, 'function', true)

  bufnr = vim._resolve_bufnr(bufnr)
  local method_supported = false
  local clients = lsp.get_clients({ bufnr = bufnr })
  local client_request_ids = {} --- @type table<integer,integer>
  for _, client in ipairs(clients) do
    if client:supports_method(method, bufnr) then
      method_supported = true

      local cparams = type(params) == 'function' and params(client, bufnr) or params --[[@as table?]]