neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

client.lua (51712B)


      1 local uv = vim.uv
      2 local api = vim.api
      3 local lsp = vim.lsp
      4 local log = lsp.log
      5 local changetracking = lsp._changetracking
      6 local validate = vim.validate
      7 
      8 --- Tracks all clients initialized.
      9 ---@type table<integer,vim.lsp.Client>
     10 local all_clients = {}
     11 
     12 --- @alias vim.lsp.client.on_init_cb fun(client: vim.lsp.Client, init_result: lsp.InitializeResult)
     13 --- @alias vim.lsp.client.on_attach_cb fun(client: vim.lsp.Client, bufnr: integer)
     14 --- @alias vim.lsp.client.on_exit_cb fun(code: integer, signal: integer, client_id: integer)
     15 --- @alias vim.lsp.client.before_init_cb fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig)
     16 
     17 --- @class vim.lsp.Client.Flags
     18 --- @inlinedoc
     19 ---
     20 --- Allow using incremental sync for buffer edits
     21 --- (default: `true`)
     22 --- @field allow_incremental_sync? boolean
     23 ---
     24 --- Debounce `didChange` notifications to the server by the given number in milliseconds.
     25 --- (default: `150`)
     26 --- @field debounce_text_changes? integer
     27 
     28 --- @class vim.lsp.ClientConfig
     29 ---
     30 --- Callback which can modify parameters before they are sent to the server. Invoked before LSP
     31 --- "initialize" phase (after `cmd` is invoked), where `params` is the parameters being sent to the
     32 --- server and `config` is the config passed to |vim.lsp.start()|.
     33 --- @field before_init? fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig)
     34 ---
     35 --- Map overriding the default capabilities defined by |vim.lsp.protocol.make_client_capabilities()|,
     36 --- passed to the language server on initialization. Hint: use make_client_capabilities() and modify
     37 --- its result.
     38 --- - Note: To send an empty dictionary use |vim.empty_dict()|, else it will be encoded as an
     39 ---   array.
     40 --- @field capabilities? lsp.ClientCapabilities
     41 ---
     42 --- Command `string[]` that launches the language server (treated as in |jobstart()|, must be
     43 --- absolute or on `$PATH`, shell constructs like "~" are not expanded), or function that creates an
     44 --- RPC client. Function receives a `dispatchers` table and the resolved `config`, and must return
     45 --- a table with member functions `request`, `notify`, `is_closing` and `terminate`.
     46 --- See |vim.lsp.rpc.request()|, |vim.lsp.rpc.notify()|.
     47 --- For TCP there is a builtin RPC client factory: |vim.lsp.rpc.connect()|
     48 --- @field cmd string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers, config: vim.lsp.ClientConfig): vim.lsp.rpc.PublicClient
     49 ---
     50 --- Directory to launch the `cmd` process. Not related to `root_dir`.
     51 --- (default: cwd)
     52 --- @field cmd_cwd? string
     53 ---
     54 --- Environment variables passed to the LSP process on spawn. Non-string values are coerced to
     55 --- string.
     56 --- Example:
     57 --- ```lua
     58 --- { PORT = 8080; HOST = '0.0.0.0'; }
     59 --- ```
     60 --- @field cmd_env? table
     61 ---
     62 --- Map of client-defined commands overriding the global |vim.lsp.commands|.
     63 --- @field commands? table<string,fun(command: lsp.Command, ctx: table)>
     64 ---
     65 --- Daemonize the server process so that it runs in a separate process group from Nvim.
     66 --- Nvim will shutdown the process on exit, but if Nvim fails to exit cleanly this could leave
     67 --- behind orphaned server processes.
     68 --- (default: `true`)
     69 --- @field detached? boolean
     70 ---
     71 --- Milliseconds to wait for server to exit cleanly after sending the "shutdown" request before
     72 --- sending kill -15. If set to false, waits indefinitely. If set to true, nvim will kill the
     73 --- server immediately.
     74 --- (default: `false`)
     75 --- @field exit_timeout? integer|boolean
     76 ---
     77 --- Experimental client flags:
     78 --- @field flags? vim.lsp.Client.Flags
     79 ---
     80 --- Language ID as string. Defaults to the buffer filetype.
     81 --- @field get_language_id? fun(bufnr: integer, filetype: string): string
     82 ---
     83 --- Map of LSP method names to |lsp-handler|s.
     84 --- @field handlers? table<string,function>
     85 ---
     86 --- Values to pass in the initialization request as `initializationOptions`. See `initialize` in
     87 --- the LSP spec.
     88 --- @field init_options? lsp.LSPObject
     89 ---
     90 --- Name in logs and user messages.
     91 --- (default: client-id)
     92 --- @field name? string
     93 ---
     94 --- Called "position encoding" in LSP spec. The encoding that the LSP server expects, used for
     95 --- communication. Not validated. Can be modified in `on_init` before text is sent to the server.
     96 --- @field offset_encoding? 'utf-8'|'utf-16'|'utf-32'
     97 ---
     98 --- Callback invoked when client attaches to a buffer.
     99 --- @field on_attach? elem_or_list<fun(client: vim.lsp.Client, bufnr: integer)>
    100 ---
    101 --- Callback invoked when the client operation throws an error. `code` is a number describing the error.
    102 --- Other arguments may be passed depending on the error kind.  See `vim.lsp.rpc.client_errors`
    103 --- for possible errors. Use `vim.lsp.rpc.client_errors[code]` to get human-friendly name.
    104 --- @field on_error? fun(code: integer, err: string)
    105 ---
    106 --- Callback invoked on client exit.
    107 ---   - code: exit code of the process
    108 ---   - signal: number describing the signal used to terminate (if any)
    109 ---   - client_id: client handle
    110 --- @field on_exit? elem_or_list<fun(code: integer, signal: integer, client_id: integer)>
    111 ---
    112 --- Callback invoked after LSP "initialize", where `result` is a table of `capabilities` and
    113 --- anything else the server may send. For example, clangd sends `init_result.offsetEncoding` if
    114 --- `capabilities.offsetEncoding` was sent to it. You can only modify the `client.offset_encoding`
    115 --- here before any notifications are sent.
    116 --- @field on_init? elem_or_list<fun(client: vim.lsp.Client, init_result: lsp.InitializeResult)>
    117 ---
    118 --- Directory where the LSP server will base its workspaceFolders, rootUri, and rootPath on initialization.
    119 --- @field root_dir? string
    120 ---
    121 --- Map of language server-specific settings, decided by the client. Sent to the LS if requested via
    122 --- `workspace/configuration`. Keys are case-sensitive.
    123 --- @field settings? lsp.LSPObject
    124 ---
    125 --- Passed directly to the language server in the initialize request. Invalid/empty values will
    126 --- (default: "off")
    127 --- @field trace? 'off'|'messages'|'verbose'
    128 ---
    129 --- List of workspace folders passed to the language server. For backwards compatibility rootUri and
    130 --- rootPath are derived from the first workspace folder in this list. Can be `null` if the client
    131 --- supports workspace folders but none are configured. See `workspaceFolders` in LSP spec.
    132 --- @field workspace_folders? lsp.WorkspaceFolder[]
    133 ---
    134 --- Server requires a workspace (no "single file" support). Note: Without
    135 --- a workspace, cross-file features (navigation, hover) may or may not work depending on the
    136 --- language server, even if the server doesn't require a workspace.
    137 --- (default: `false`)
    138 --- @field workspace_required? boolean
    139 
    140 --- @class vim.lsp.Client.Progress: vim.Ringbuf<{token: integer|string, value: any}>
    141 --- @field pending table<lsp.ProgressToken,lsp.LSPAny>
    142 
    143 --- @class vim.lsp.Client
    144 ---
    145 --- @field attached_buffers table<integer,true>
    146 ---
    147 --- Capabilities provided by the client (editor or tool), at startup.
    148 --- @field capabilities lsp.ClientCapabilities
    149 ---
    150 --- Client commands. See [vim.lsp.ClientConfig].
    151 --- @field commands table<string,fun(command: lsp.Command, ctx: table)>
    152 ---
    153 --- Copy of the config passed to |vim.lsp.start()|.
    154 --- @field config vim.lsp.ClientConfig
    155 ---
    156 --- Capabilities provided at runtime (after startup).
    157 --- @field dynamic_capabilities lsp.DynamicCapabilities
    158 ---
    159 --- Milliseconds to wait for server to exit cleanly after sending the "shutdown" request before
    160 --- sending kill -15. If set to false, waits indefinitely. If set to true, nvim will kill the
    161 --- server immediately.
    162 --- (default: `false`)
    163 --- @field exit_timeout integer|boolean
    164 ---
    165 --- Experimental client flags:
    166 --- @field flags vim.lsp.Client.Flags
    167 ---
    168 --- See [vim.lsp.ClientConfig].
    169 --- @field get_language_id fun(bufnr: integer, filetype: string): string
    170 ---
    171 --- See [vim.lsp.ClientConfig].
    172 --- @field handlers table<string,lsp.Handler>
    173 ---
    174 --- The id allocated to the client.
    175 --- @field id integer
    176 ---
    177 --- @field initialized true?
    178 ---
    179 --- See [vim.lsp.ClientConfig].
    180 --- @field name string
    181 ---
    182 --- See [vim.lsp.ClientConfig].
    183 --- @field offset_encoding 'utf-8'|'utf-16'|'utf-32'
    184 ---
    185 --- A ring buffer (|vim.ringbuf()|) containing progress messages
    186 --- sent by the server.
    187 --- @field progress vim.lsp.Client.Progress
    188 ---
    189 --- The current pending requests in flight to the server. Entries are key-value
    190 --- pairs with the key being the request id while the value is a table with
    191 --- `type`, `bufnr`, and `method` key-value pairs. `type` is either "pending"
    192 --- for an active request, or "cancel" for a cancel request. It will be
    193 --- "complete" ephemerally while executing |LspRequest| autocmds when replies
    194 --- are received from the server.
    195 --- @field requests table<integer,{ type: string, bufnr: integer, method: string}?>
    196 ---
    197 --- See [vim.lsp.ClientConfig].
    198 --- @field root_dir string?
    199 ---
    200 --- RPC client object, for low level interaction with the client.
    201 --- See |vim.lsp.rpc.start()|.
    202 --- @field rpc vim.lsp.rpc.PublicClient
    203 ---
    204 --- Response from the server sent on `initialize` describing the server's capabilities.
    205 --- @field server_capabilities lsp.ServerCapabilities?
    206 ---
    207 --- Response from the server sent on `initialize` describing server information (e.g. version).
    208 --- @field server_info lsp.ServerInfo?
    209 ---
    210 --- See [vim.lsp.ClientConfig].
    211 --- @field settings lsp.LSPObject
    212 ---
    213 --- See [vim.lsp.ClientConfig].
    214 --- @field workspace_folders lsp.WorkspaceFolder[]?
    215 ---
    216 --- @field _enabled_capabilities table<vim.lsp.capability.Name, boolean?>
    217 ---
    218 --- Whether on-type formatting is enabled for this client.
    219 --- @field _otf_enabled boolean?
    220 ---
    221 --- Timer for stop() with timeout.
    222 --- @field private _shutdown_timer uv.uv_timer_t?
    223 ---
    224 --- Track this so that we can escalate automatically if we've already tried a
    225 --- graceful shutdown
    226 --- @field private _graceful_shutdown_failed true?
    227 ---
    228 --- The initial trace setting. If omitted trace is disabled ("off").
    229 --- trace = "off" | "messages" | "verbose";
    230 --- @field private _trace 'off'|'messages'|'verbose'
    231 ---
    232 --- @field private registrations table<string,lsp.Registration[]>
    233 --- @field private _log_prefix string
    234 --- @field private _before_init_cb? vim.lsp.client.before_init_cb
    235 --- @field private _on_attach_cbs vim.lsp.client.on_attach_cb[]
    236 --- @field private _on_init_cbs vim.lsp.client.on_init_cb[]
    237 --- @field private _on_exit_cbs vim.lsp.client.on_exit_cb[]
    238 --- @field private _on_error_cb? fun(code: integer, err: string)
    239 local Client = {}
    240 Client.__index = Client
    241 
    242 --- @param obj table<string,any>
    243 --- @param cls table<string,function>
    244 --- @param name string
    245 local function method_wrapper(obj, cls, name)
    246  local meth = assert(cls[name])
    247  obj[name] = function(...)
    248    local arg = select(1, ...)
    249    if arg and getmetatable(arg) == cls then
    250      -- First argument is self, call meth directly
    251      return meth(...)
    252    end
    253    vim.deprecate('client.' .. name, 'client:' .. name, '0.13')
    254    -- First argument is not self, insert it
    255    return meth(obj, ...)
    256  end
    257 end
    258 
    259 local client_index = 0
    260 
    261 --- Checks whether a given path is a directory.
    262 --- @param filename (string) path to check
    263 --- @return boolean # true if {filename} exists and is a directory, false otherwise
    264 local function is_dir(filename)
    265  validate('filename', filename, 'string')
    266  local stat = uv.fs_stat(filename)
    267  return stat and stat.type == 'directory' or false
    268 end
    269 
    270 local valid_encodings = {
    271  ['utf-8'] = 'utf-8',
    272  ['utf-16'] = 'utf-16',
    273  ['utf-32'] = 'utf-32',
    274  ['utf8'] = 'utf-8',
    275  ['utf16'] = 'utf-16',
    276  ['utf32'] = 'utf-32',
    277 }
    278 
    279 --- Normalizes {encoding} to valid LSP encoding names.
    280 --- @param encoding string? Encoding to normalize
    281 --- @return string # normalized encoding name
    282 local function validate_encoding(encoding)
    283  validate('encoding', encoding, 'string', true)
    284  if not encoding then
    285    return valid_encodings.utf16
    286  end
    287  return valid_encodings[encoding:lower()]
    288    or error(
    289      string.format(
    290        "Invalid position encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'",
    291        encoding
    292      )
    293    )
    294 end
    295 
    296 --- Augments a validator function with support for optional (nil) values.
    297 --- @param fn (fun(v): boolean) The original validator function; should return a
    298 --- bool.
    299 --- @return fun(v): boolean # The augmented function. Also returns true if {v} is
    300 --- `nil`.
    301 local function optional_validator(fn)
    302  return function(v)
    303    return v == nil or fn(v)
    304  end
    305 end
    306 
    307 --- By default, get_language_id just returns the exact filetype it is passed.
    308 --- It is possible to pass in something that will calculate a different filetype,
    309 --- to be sent by the client.
    310 --- @param _bufnr integer
    311 --- @param filetype string
    312 local function default_get_language_id(_bufnr, filetype)
    313  return filetype
    314 end
    315 
    316 --- Validates a client configuration as given to |vim.lsp.start()|.
    317 --- @param config vim.lsp.ClientConfig
    318 local function validate_config(config)
    319  validate('config', config, 'table')
    320  validate('handlers', config.handlers, 'table', true)
    321  validate('capabilities', config.capabilities, 'table', true)
    322  validate('cmd_cwd', config.cmd_cwd, optional_validator(is_dir), 'directory')
    323  validate('cmd_env', config.cmd_env, 'table', true)
    324  validate('detached', config.detached, 'boolean', true)
    325  validate('exit_timeout', config.exit_timeout, { 'number', 'boolean' }, true)
    326  validate('name', config.name, 'string', true)
    327  validate('on_error', config.on_error, 'function', true)
    328  validate('on_exit', config.on_exit, { 'function', 'table' }, true)
    329  validate('on_init', config.on_init, { 'function', 'table' }, true)
    330  validate('on_attach', config.on_attach, { 'function', 'table' }, true)
    331  validate('settings', config.settings, 'table', true)
    332  validate('commands', config.commands, 'table', true)
    333  validate('before_init', config.before_init, { 'function', 'table' }, true)
    334  validate('offset_encoding', config.offset_encoding, 'string', true)
    335  validate('flags', config.flags, 'table', true)
    336  validate('get_language_id', config.get_language_id, 'function', true)
    337 
    338  assert(
    339    (
    340      not config.flags
    341      or not config.flags.debounce_text_changes
    342      or type(config.flags.debounce_text_changes) == 'number'
    343    ),
    344    'flags.debounce_text_changes must be a number with the debounce time in milliseconds'
    345  )
    346 end
    347 
    348 --- @param trace string
    349 --- @return 'off'|'messages'|'verbose'
    350 local function get_trace(trace)
    351  local valid_traces = {
    352    off = 'off',
    353    messages = 'messages',
    354    verbose = 'verbose',
    355  }
    356  return trace and valid_traces[trace] or 'off'
    357 end
    358 
    359 --- @param id integer
    360 --- @param config vim.lsp.ClientConfig
    361 --- @return string
    362 local function get_name(id, config)
    363  local name = config.name
    364  if name then
    365    return name
    366  end
    367 
    368  if type(config.cmd) == 'table' and config.cmd[1] then
    369    return assert(vim.fs.basename(config.cmd[1]))
    370  end
    371 
    372  return tostring(id)
    373 end
    374 
    375 --- @nodoc
    376 --- @param config vim.lsp.ClientConfig
    377 --- @return vim.lsp.Client?
    378 function Client.create(config)
    379  validate_config(config)
    380 
    381  client_index = client_index + 1
    382  local id = client_index
    383  local name = get_name(id, config)
    384 
    385  --- @class vim.lsp.Client
    386  local self = {
    387    id = id,
    388    config = config,
    389    handlers = config.handlers or {},
    390    offset_encoding = validate_encoding(config.offset_encoding),
    391    name = name,
    392    _log_prefix = string.format('LSP[%s]', name),
    393    requests = {},
    394    attached_buffers = {},
    395    server_capabilities = {},
    396    registrations = {},
    397    commands = config.commands or {},
    398    settings = config.settings or {},
    399    flags = config.flags or {},
    400    exit_timeout = config.exit_timeout or false,
    401    get_language_id = config.get_language_id or default_get_language_id,
    402    capabilities = config.capabilities,
    403    workspace_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir),
    404    root_dir = config.root_dir,
    405    _is_stopping = false,
    406    _before_init_cb = config.before_init,
    407    _on_init_cbs = vim._ensure_list(config.on_init),
    408    _on_exit_cbs = vim._ensure_list(config.on_exit),
    409    _on_attach_cbs = vim._ensure_list(config.on_attach),
    410    _on_error_cb = config.on_error,
    411    _trace = get_trace(config.trace),
    412 
    413    --- Contains $/progress report messages.
    414    --- They have the format {token: integer|string, value: any}
    415    --- For "work done progress", value will be one of:
    416    --- - lsp.WorkDoneProgressBegin,
    417    --- - lsp.WorkDoneProgressReport (extended with title from Begin)
    418    --- - lsp.WorkDoneProgressEnd    (extended with title from Begin)
    419    progress = vim.ringbuf(50) --[[@as vim.lsp.Client.Progress]],
    420 
    421    --- @deprecated use client.progress instead
    422    messages = { name = name, messages = {}, progress = {}, status = {} },
    423  }
    424 
    425  self.capabilities =
    426    vim.tbl_deep_extend('force', lsp.protocol.make_client_capabilities(), self.capabilities or {})
    427 
    428  --- @class lsp.DynamicCapabilities
    429  --- @nodoc
    430  self.dynamic_capabilities = {
    431    capabilities = self.registrations,
    432    client_id = id,
    433    register = function(_, registrations)
    434      return self:_register_dynamic(registrations)
    435    end,
    436    unregister = function(_, unregistrations)
    437      return self:_unregister_dynamic(unregistrations)
    438    end,
    439    get = function(_, method, opts)
    440      return self:_get_registrations(method, opts and opts.bufnr)
    441    end,
    442    supports_registration = function(_, method)
    443      return self:_supports_registration(method)
    444    end,
    445    supports = function(_, method, opts)
    446      return self:_get_registrations(method, opts and opts.bufnr) ~= nil
    447    end,
    448  }
    449 
    450  ---@type table <vim.lsp.capability.Name, boolean?>
    451  self._enabled_capabilities = {}
    452 
    453  --- @type table<string|integer, string> title of unfinished progress sequences by token
    454  self.progress.pending = {}
    455 
    456  --- @type vim.lsp.rpc.Dispatchers
    457  local dispatchers = {
    458    notification = function(...)
    459      self:_notification(...)
    460    end,
    461    server_request = function(...)
    462      return self:_server_request(...)
    463    end,
    464    on_error = function(...)
    465      self:_on_error(...)
    466    end,
    467    on_exit = function(...)
    468      self:_on_exit(...)
    469    end,
    470  }
    471 
    472  -- Start the RPC client.
    473  local config_cmd = config.cmd
    474  if type(config_cmd) == 'function' then
    475    self.rpc = config_cmd(dispatchers, config)
    476  else
    477    self.rpc = lsp.rpc.start(config_cmd, dispatchers, {
    478      cwd = config.cmd_cwd,
    479      env = config.cmd_env,
    480      detached = config.detached,
    481    })
    482  end
    483 
    484  setmetatable(self, Client)
    485 
    486  method_wrapper(self, Client, 'request')
    487  method_wrapper(self, Client, 'request_sync')
    488  method_wrapper(self, Client, 'notify')
    489  method_wrapper(self, Client, 'cancel_request')
    490  method_wrapper(self, Client, 'stop')
    491  method_wrapper(self, Client, 'is_stopped')
    492  method_wrapper(self, Client, 'on_attach')
    493  method_wrapper(self, Client, 'supports_method')
    494 
    495  return self
    496 end
    497 
    498 --- @private
    499 --- @param cbs function[]
    500 --- @param error_id integer
    501 --- @param ... any
    502 function Client:_run_callbacks(cbs, error_id, ...)
    503  for _, cb in pairs(cbs) do
    504    --- @type boolean, string?
    505    local status, err = pcall(cb, ...)
    506    if not status then
    507      self:write_error(error_id, err)
    508    end
    509  end
    510 end
    511 
    512 --- @nodoc
    513 function Client:initialize()
    514  -- Register all initialized clients.
    515  all_clients[self.id] = self
    516 
    517  local config = self.config
    518 
    519  local root_uri --- @type string?
    520  local root_path --- @type string?
    521  if self.workspace_folders then
    522    root_uri = self.workspace_folders[1].uri
    523    root_path = vim.uri_to_fname(root_uri)
    524  end
    525 
    526  -- HACK: Capability modules must be loaded
    527  require('vim.lsp.semantic_tokens')
    528  require('vim.lsp._folding_range')
    529  require('vim.lsp.inline_completion')
    530 
    531  local init_params = {
    532    -- The process Id of the parent process that started the server. Is null if
    533    -- the process has not been started by another process.  If the parent
    534    -- process is not alive then the server should exit (see exit notification)
    535    -- its process.
    536    processId = uv.os_getpid(),
    537    -- Information about the client
    538    -- since 3.15.0
    539    clientInfo = {
    540      name = 'Neovim',
    541      version = tostring(vim.version()),
    542    },
    543    -- The rootPath of the workspace. Is null if no folder is open.
    544    --
    545    -- @deprecated in favour of rootUri.
    546    rootPath = root_path or vim.NIL,
    547    -- The rootUri of the workspace. Is null if no folder is open. If both
    548    -- `rootPath` and `rootUri` are set `rootUri` wins.
    549    rootUri = root_uri or vim.NIL,
    550    workspaceFolders = self.workspace_folders or vim.NIL,
    551    -- User provided initialization options.
    552    initializationOptions = config.init_options,
    553    capabilities = self.capabilities,
    554    trace = self._trace,
    555    workDoneToken = '1',
    556  }
    557 
    558  self:_run_callbacks(
    559    { self._before_init_cb },
    560    lsp.client_errors.BEFORE_INIT_CALLBACK_ERROR,
    561    init_params,
    562    config
    563  )
    564 
    565  log.trace(self._log_prefix, 'init_params', init_params)
    566 
    567  local rpc = self.rpc
    568 
    569  rpc.request('initialize', init_params, function(init_err, result)
    570    assert(not init_err, tostring(init_err))
    571    assert(result, 'server sent empty result')
    572    rpc.notify('initialized', vim.empty_dict())
    573    self.initialized = true
    574 
    575    -- These are the cleaned up capabilities we use for dynamically deciding
    576    -- when to send certain events to clients.
    577    self.server_capabilities =
    578      assert(result.capabilities, "initialize result doesn't contain capabilities")
    579    self.server_capabilities = assert(lsp.protocol.resolve_capabilities(self.server_capabilities))
    580 
    581    self:_process_static_registrations()
    582 
    583    if self.server_capabilities.positionEncoding then
    584      self.offset_encoding = self.server_capabilities.positionEncoding
    585    end
    586 
    587    self.server_info = result.serverInfo
    588 
    589    if next(self.settings) then
    590      self:notify('workspace/didChangeConfiguration', { settings = self.settings })
    591    end
    592 
    593    -- If server is being restarted, make sure to re-attach to any previously attached buffers.
    594    -- Save which buffers before on_init in case new buffers are attached.
    595    local reattach_bufs = vim.deepcopy(self.attached_buffers)
    596 
    597    self:_run_callbacks(self._on_init_cbs, lsp.client_errors.ON_INIT_CALLBACK_ERROR, self, result)
    598 
    599    for buf in pairs(reattach_bufs) do
    600      -- The buffer may have been detached in the on_init callback.
    601      if self.attached_buffers[buf] then
    602        self:on_attach(buf)
    603      end
    604    end
    605 
    606    log.info(
    607      self._log_prefix,
    608      'server_capabilities',
    609      { server_capabilities = self.server_capabilities }
    610    )
    611  end)
    612 end
    613 
    614 --- @private
    615 function Client:_process_static_registrations()
    616  local static_registrations = {} ---@type lsp.Registration[]
    617 
    618  for method in pairs(lsp.protocol._method_supports_static_registration) do
    619    local capability = lsp.protocol._request_name_to_server_capability[method]
    620    if
    621      vim.tbl_get(self.server_capabilities, capability[1], 'id')
    622      and self:_supports_registration(method)
    623    then
    624      local cap = vim.tbl_get(self.server_capabilities, capability[1])
    625      static_registrations[#static_registrations + 1] = {
    626        id = cap.id,
    627        method = method,
    628        registerOptions = cap or {},
    629      }
    630    end
    631  end
    632 
    633  if next(static_registrations) then
    634    self:_register_dynamic(static_registrations)
    635  end
    636 end
    637 
    638 --- @private
    639 --- Returns the handler associated with an LSP method.
    640 --- Returns the default handler if the user hasn't set a custom one.
    641 ---
    642 --- @param method (vim.lsp.protocol.Method) LSP method name
    643 --- @return lsp.Handler? handler for the given method, if defined, or the default from |vim.lsp.handlers|
    644 function Client:_resolve_handler(method)
    645  return self.handlers[method] or lsp.handlers[method]
    646 end
    647 
    648 --- @private
    649 --- @param id integer
    650 --- @param req_type 'pending'|'complete'|'cancel'
    651 --- @param bufnr? integer (only required for req_type='pending')
    652 --- @param method? vim.lsp.protocol.Method (only required for req_type='pending')
    653 function Client:_process_request(id, req_type, bufnr, method)
    654  local pending = req_type == 'pending'
    655 
    656  validate('id', id, 'number')
    657  if pending then
    658    validate('bufnr', bufnr, 'number')
    659    validate('method', method, 'string')
    660  end
    661 
    662  local cur_request = self.requests[id]
    663 
    664  if pending and cur_request then
    665    log.error(
    666      self._log_prefix,
    667      ('Cannot create request with id %d as one already exists'):format(id)
    668    )
    669    return
    670  elseif not pending and not cur_request then
    671    log.error(
    672      self._log_prefix,
    673      ('Cannot find request with id %d whilst attempting to %s'):format(id, req_type)
    674    )
    675    return
    676  end
    677 
    678  if cur_request then
    679    bufnr = cur_request.bufnr
    680    method = cur_request.method
    681  end
    682 
    683  assert(bufnr and method)
    684 
    685  local request = { type = req_type, bufnr = bufnr, method = method }
    686 
    687  -- Clear 'complete' requests
    688  -- Note 'pending' and 'cancelled' requests are cleared when the server sends a response
    689  -- which is processed via the notify_reply_callback argument to rpc.request.
    690  self.requests[id] = req_type ~= 'complete' and request or nil
    691 
    692  api.nvim_exec_autocmds('LspRequest', {
    693    buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
    694    modeline = false,
    695    data = { client_id = self.id, request_id = id, request = request },
    696  })
    697 end
    698 
    699 --- Sends a request to the server.
    700 ---
    701 --- This is a thin wrapper around {client.rpc.request} with some additional
    702 --- checks for capabilities and handler availability.
    703 ---
    704 --- @param method vim.lsp.protocol.Method.ClientToServer.Request LSP method name.
    705 --- @param params? table LSP request params.
    706 --- @param handler? lsp.Handler Response |lsp-handler| for this method.
    707 --- @param bufnr? integer (default: 0) Buffer handle, or 0 for current.
    708 --- @return boolean status indicates whether the request was successful.
    709 ---     If it is `false`, then it will always be `false` (the client has shutdown).
    710 --- @return integer? request_id Can be used with |Client:cancel_request()|.
    711 ---                             `nil` is request failed.
    712 --- to cancel the-request.
    713 --- @see |vim.lsp.buf_request_all()|
    714 function Client:request(method, params, handler, bufnr)
    715  if not handler then
    716    handler = assert(
    717      self:_resolve_handler(method),
    718      string.format('not found: %q request handler for client %q.', method, self.name)
    719    )
    720  end
    721  -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state
    722  changetracking.flush(self, bufnr)
    723  bufnr = vim._resolve_bufnr(bufnr)
    724  local version = lsp.util.buf_versions[bufnr]
    725  log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr)
    726 
    727  -- Detect if request resolved synchronously (only possible with in-process servers).
    728  local already_responded = false
    729  local request_registered = false
    730 
    731  -- NOTE: rpc.request might call an in-process (Lua) server, thus may be synchronous.
    732  local success, request_id = self.rpc.request(method, params, function(err, result, request_id)
    733    handler(err, result, {
    734      method = method,
    735      client_id = self.id,
    736      request_id = request_id,
    737      bufnr = bufnr,
    738      params = params,
    739      version = version,
    740    })
    741  end, function(request_id)
    742    -- Called when the server sends a response to the request (including cancelled acknowledgment).
    743    if request_registered then
    744      self:_process_request(request_id, 'complete')
    745    end
    746    already_responded = true
    747  end)
    748 
    749  if success and request_id and not already_responded then
    750    self:_process_request(request_id, 'pending', bufnr, method)
    751    request_registered = true
    752  end
    753 
    754  return success, request_id
    755 end
    756 
    757 -- TODO(lewis6991): duplicated from lsp.lua
    758 local wait_result_reason = { [-1] = 'timeout', [-2] = 'interrupted', [-3] = 'error' }
    759 
    760 --- Concatenates and writes a list of strings to the Vim error buffer.
    761 ---
    762 --- @param ... string List to write to the buffer
    763 local function err_message(...)
    764  local chunks = { { table.concat(vim.iter({ ... }):flatten():totable()) } }
    765  if vim.in_fast_event() then
    766    vim.schedule(function()
    767      api.nvim_echo(chunks, true, { err = true })
    768      api.nvim_command('redraw')
    769    end)
    770  else
    771    api.nvim_echo(chunks, true, { err = true })
    772    api.nvim_command('redraw')
    773  end
    774 end
    775 
    776 --- Sends a request to the server and synchronously waits for the response.
    777 ---
    778 --- This is a wrapper around |Client:request()|
    779 ---
    780 --- @param method vim.lsp.protocol.Method.ClientToServer.Request LSP method name.
    781 --- @param params table LSP request params.
    782 --- @param timeout_ms integer? Maximum time in milliseconds to wait for
    783 ---                                a result. Defaults to 1000
    784 --- @param bufnr? integer (default: 0) Buffer handle, or 0 for current.
    785 --- @return {err: lsp.ResponseError?, result:any}? `result` and `err` from the |lsp-handler|.
    786 ---                 `nil` is the request was unsuccessful
    787 --- @return string? err On timeout, cancel or error, where `err` is a
    788 ---                 string describing the failure reason.
    789 --- @see |vim.lsp.buf_request_sync()|
    790 function Client:request_sync(method, params, timeout_ms, bufnr)
    791  local request_result = nil
    792  local function _sync_handler(err, result)
    793    request_result = { err = err, result = result }
    794  end
    795 
    796  local success, request_id = self:request(method, params, _sync_handler, bufnr)
    797  if not success then
    798    return nil
    799  end
    800 
    801  local wait_result, reason = vim.wait(timeout_ms or 1000, function()
    802    return request_result ~= nil
    803  end, 10)
    804 
    805  if not wait_result then
    806    if request_id then
    807      self:cancel_request(request_id)
    808    end
    809    return nil, wait_result_reason[reason]
    810  end
    811  return request_result
    812 end
    813 
    814 --- Sends a notification to an LSP server.
    815 ---
    816 --- @param method vim.lsp.protocol.Method.ClientToServer.Notification LSP method name.
    817 --- @param params table? LSP request params.
    818 --- @return boolean status indicating if the notification was successful.
    819 ---                        If it is false, then the client has shutdown.
    820 function Client:notify(method, params)
    821  if method ~= 'textDocument/didChange' then
    822    changetracking.flush(self)
    823  end
    824 
    825  local client_active = self.rpc.notify(method, params)
    826 
    827  if client_active then
    828    vim.schedule(function()
    829      api.nvim_exec_autocmds('LspNotify', {
    830        modeline = false,
    831        data = {
    832          client_id = self.id,
    833          method = method,
    834          params = params,
    835        },
    836      })
    837    end)
    838  end
    839 
    840  return client_active
    841 end
    842 
    843 --- Cancels a request with a given request id.
    844 ---
    845 --- @param id integer id of request to cancel
    846 --- @return boolean status indicating if the notification was successful.
    847 --- @see |Client:notify()|
    848 function Client:cancel_request(id)
    849  self:_process_request(id, 'cancel')
    850  return self.rpc.notify('$/cancelRequest', { id = id })
    851 end
    852 
    853 --- Stops a client, optionally with force after a timeout.
    854 ---
    855 --- By default, it will request the server to shutdown, then force a shutdown
    856 --- if the server has not exited after `self.exit_timeout` milliseconds. If
    857 --- you request to stop a client which has previously been requested to
    858 --- shutdown, it will automatically escalate and force shutdown immediately,
    859 --- regardless of the value of `force` (or `self.exit_timeout` if `nil`).
    860 ---
    861 --- Note: Forcing shutdown while a server is busy writing out project or index
    862 --- files can lead to file corruption.
    863 ---
    864 --- @param force? integer|boolean Time in milliseconds to wait before forcing
    865 ---                               a shutdown. If false, only request the
    866 ---                               server to shutdown, but don't force it. If
    867 ---                               true, force a shutdown immediately.
    868 ---                               (default: `self.exit_timeout`)
    869 function Client:stop(force)
    870  validate('force', force, { 'number', 'boolean' }, true)
    871 
    872  if force == nil then
    873    force = self.exit_timeout
    874  end
    875 
    876  local rpc = self.rpc
    877  if rpc.is_closing() then
    878    return
    879  end
    880 
    881  self._is_stopping = true
    882 
    883  lsp._watchfiles.cancel(self.id)
    884 
    885  if force == true or not self.initialized or self._graceful_shutdown_failed then
    886    rpc.terminate()
    887    return
    888  end
    889 
    890  if type(force) == 'number' then
    891    self._shutdown_timer = vim.defer_fn(function()
    892      self._shutdown_timer = nil
    893      self:stop(true)
    894    end, force)
    895  end
    896 
    897  -- Sending a signal after a process has exited is acceptable.
    898  rpc.request('shutdown', nil, function(err, _, _)
    899    if err == nil then
    900      rpc.notify('exit')
    901    else
    902      -- If there was an error in the shutdown request, then terminate to be safe.
    903      rpc.terminate()
    904      self._graceful_shutdown_failed = true
    905    end
    906  end)
    907 end
    908 
    909 --- Stops a client, then starts a new client with the same config and attached
    910 --- buffers.
    911 ---
    912 --- @param force? integer|boolean See [Client:stop()] for details.
    913 ---                               (default: `self.exit_timeout`)
    914 function Client:_restart(force)
    915  validate('force', force, { 'number', 'boolean' }, true)
    916 
    917  self._handle_restart = function()
    918    --- @type integer[]
    919    local attached_buffers = vim.tbl_keys(self.attached_buffers)
    920 
    921    vim.schedule(function()
    922      local new_client_id = lsp.start(self.config, { attach = false })
    923      if new_client_id then
    924        for _, buffer in ipairs(attached_buffers) do
    925          lsp.buf_attach_client(buffer, new_client_id)
    926        end
    927      end
    928    end)
    929  end
    930 
    931  self:stop(force)
    932 end
    933 
    934 --- Get options for a method that is registered dynamically.
    935 --- @param method vim.lsp.protocol.Method | vim.lsp.protocol.Method.Registration
    936 function Client:_supports_registration(method)
    937  if lsp.protocol._methods_with_no_registration_options[method] then
    938    return true
    939  end
    940  local provider = self:_registration_provider(method)
    941  local capability_path = lsp.protocol._provider_to_client_registration[provider]
    942  local capability = vim.tbl_get(self.capabilities, unpack(capability_path))
    943  return type(capability) == 'table' and capability.dynamicRegistration
    944 end
    945 
    946 --- Get provider for a method to be registered dynamically.
    947 --- @param method vim.lsp.protocol.Method | vim.lsp.protocol.Method.Registration
    948 function Client:_registration_provider(method)
    949  local capability_path = lsp.protocol._request_name_to_server_capability[method]
    950  return capability_path and capability_path[1]
    951 end
    952 
    953 --- @private
    954 --- @param registrations lsp.Registration[]
    955 function Client:_register_dynamic(registrations)
    956  -- remove duplicates
    957  self:_unregister_dynamic(registrations)
    958  for _, reg in ipairs(registrations) do
    959    local provider = self:_registration_provider(reg.method)
    960    if not self.registrations[provider] then
    961      self.registrations[provider] = {}
    962    end
    963    table.insert(self.registrations[provider], reg)
    964  end
    965 end
    966 
    967 --- @param registrations lsp.Registration[]
    968 function Client:_register(registrations)
    969  self:_register_dynamic(registrations)
    970 
    971  local unsupported = {} --- @type string[]
    972 
    973  for _, reg in ipairs(registrations) do
    974    local method = reg.method
    975    if method == 'workspace/didChangeWatchedFiles' then
    976      lsp._watchfiles.register(reg, self.id)
    977    elseif not self:_supports_registration(method) then
    978      unsupported[#unsupported + 1] = method
    979    end
    980  end
    981 
    982  if #unsupported > 0 then
    983    local warning_tpl = 'The language server %s triggers a registerCapability '
    984      .. 'handler for %s despite dynamicRegistration set to false. '
    985      .. 'Report upstream, this warning is harmless'
    986    log.warn(string.format(warning_tpl, self.name, table.concat(unsupported, ', ')))
    987  end
    988 end
    989 
    990 --- @private
    991 --- @param unregistrations lsp.Unregistration[]
    992 function Client:_unregister_dynamic(unregistrations)
    993  for _, unreg in ipairs(unregistrations) do
    994    local provider = self:_registration_provider(unreg.method)
    995    local sreg = self.registrations[provider]
    996    -- Unegister dynamic capability
    997    for i, reg in ipairs(sreg or {}) do
    998      if reg.id == unreg.id then
    999        table.remove(sreg, i)
   1000        break
   1001      end
   1002    end
   1003  end
   1004 end
   1005 
   1006 --- @param unregistrations lsp.Unregistration[]
   1007 function Client:_unregister(unregistrations)
   1008  self:_unregister_dynamic(unregistrations)
   1009  for _, unreg in ipairs(unregistrations) do
   1010    if unreg.method == 'workspace/didChangeWatchedFiles' then
   1011      lsp._watchfiles.unregister(unreg, self.id)
   1012    end
   1013  end
   1014 end
   1015 
   1016 --- @private
   1017 function Client:_get_language_id(bufnr)
   1018  return self.get_language_id(bufnr, vim.bo[bufnr].filetype)
   1019 end
   1020 
   1021 --- @param provider string
   1022 --- @param bufnr? integer
   1023 --- @return lsp.Registration[]?
   1024 function Client:_get_registrations(provider, bufnr)
   1025  bufnr = vim._resolve_bufnr(bufnr)
   1026  local matched_regs = {} --- @type lsp.Registration[]
   1027  for _, reg in ipairs(self.registrations[provider] or {}) do
   1028    local regoptions = reg.registerOptions --[[@as {documentSelector:lsp.DocumentSelector|lsp.null}]]
   1029    if
   1030      not regoptions
   1031      or regoptions == vim.NIL
   1032      or not regoptions.documentSelector
   1033      or regoptions.documentSelector == vim.NIL
   1034    then
   1035      matched_regs[#matched_regs + 1] = reg
   1036    else
   1037      local language = self:_get_language_id(bufnr)
   1038      local uri = vim.uri_from_bufnr(bufnr)
   1039      local fname = vim.uri_to_fname(uri)
   1040      for _, filter in ipairs(regoptions.documentSelector) do
   1041        local flang, fscheme, fpat = filter.language, filter.scheme, filter.pattern
   1042        if
   1043          not (flang and language ~= flang)
   1044          and not (fscheme and not vim.startswith(uri, fscheme .. ':'))
   1045          and not (type(fpat) == 'string' and not vim.glob.to_lpeg(fpat):match(fname))
   1046        then
   1047          matched_regs[#matched_regs + 1] = reg
   1048        end
   1049      end
   1050    end
   1051  end
   1052  return #matched_regs > 0 and matched_regs or nil
   1053 end
   1054 
   1055 --- Checks whether a client is stopped.
   1056 ---
   1057 --- @return boolean # true if client is stopped or in the process of being
   1058 --- stopped; false otherwise
   1059 function Client:is_stopped()
   1060  return self.rpc.is_closing() or self._is_stopping
   1061 end
   1062 
   1063 --- Execute a lsp command, either via client command function (if available)
   1064 --- or via workspace/executeCommand (if supported by the server)
   1065 ---
   1066 --- @param command lsp.Command
   1067 --- @param context? {bufnr?: integer}
   1068 --- @param handler? lsp.Handler only called if a server command
   1069 function Client:exec_cmd(command, context, handler)
   1070  context = vim.deepcopy(context or {}, true) --[[@as lsp.HandlerContext]]
   1071  context.bufnr = vim._resolve_bufnr(context.bufnr)
   1072  context.client_id = self.id
   1073  local cmdname = command.command
   1074  local fn = self.commands[cmdname] or lsp.commands[cmdname]
   1075  if fn then
   1076    fn(command, context)
   1077    return
   1078  end
   1079 
   1080  local command_provider = self.server_capabilities.executeCommandProvider
   1081  local commands = type(command_provider) == 'table' and command_provider.commands or {}
   1082 
   1083  if not vim.list_contains(commands, cmdname) then
   1084    vim.notify_once(
   1085      string.format(
   1086        'Language server `%s` does not support command `%s`. This command may require a client extension.',
   1087        self.name,
   1088        cmdname
   1089      ),
   1090      vim.log.levels.WARN
   1091    )
   1092    return
   1093  end
   1094  -- Not using command directly to exclude extra properties,
   1095  -- see https://github.com/python-lsp/python-lsp-server/issues/146
   1096  --- @type lsp.ExecuteCommandParams
   1097  local params = {
   1098    command = cmdname,
   1099    arguments = command.arguments,
   1100  }
   1101  self:request('workspace/executeCommand', params, handler, context.bufnr)
   1102 end
   1103 
   1104 --- Default handler for the 'textDocument/didOpen' LSP notification.
   1105 ---
   1106 --- @param bufnr integer Number of the buffer, or 0 for current
   1107 function Client:_text_document_did_open_handler(bufnr)
   1108  changetracking.init(self, bufnr)
   1109  if not self:supports_method('textDocument/didOpen') then
   1110    return
   1111  end
   1112  if not api.nvim_buf_is_loaded(bufnr) then
   1113    return
   1114  end
   1115 
   1116  self:notify('textDocument/didOpen', {
   1117    textDocument = {
   1118      version = lsp.util.buf_versions[bufnr],
   1119      uri = vim.uri_from_bufnr(bufnr),
   1120      languageId = self:_get_language_id(bufnr),
   1121      text = lsp._buf_get_full_text(bufnr),
   1122    },
   1123  })
   1124 
   1125  -- Next chance we get, we should re-do the diagnostics
   1126  vim.schedule(function()
   1127    -- Protect against a race where the buffer disappears
   1128    -- between `did_open_handler` and the scheduled function firing.
   1129    if api.nvim_buf_is_valid(bufnr) then
   1130      local namespace = lsp.diagnostic.get_namespace(self.id)
   1131      vim.diagnostic.show(namespace, bufnr)
   1132    end
   1133  end)
   1134 end
   1135 
   1136 --- Runs the on_attach function from the client's config if it was defined.
   1137 --- Useful for buffer-local setup.
   1138 --- @param bufnr integer Buffer number
   1139 function Client:on_attach(bufnr)
   1140  self:_text_document_did_open_handler(bufnr)
   1141 
   1142  lsp._set_defaults(self, bufnr)
   1143  -- `enable(true)` cannot be called from `_set_defaults` for features with dynamic registration,
   1144  -- because it overrides the state every time `client/registerCapability` is received.
   1145  -- To allow disabling it once in `LspAttach`, we enable it once here instead.
   1146  lsp.document_color.enable(true, bufnr)
   1147 
   1148  api.nvim_exec_autocmds('LspAttach', {
   1149    buffer = bufnr,
   1150    modeline = false,
   1151    data = { client_id = self.id },
   1152  })
   1153 
   1154  self:_run_callbacks(self._on_attach_cbs, lsp.client_errors.ON_ATTACH_ERROR, self, bufnr)
   1155  -- schedule the initialization of capabilities to give the above
   1156  -- on_attach and LspAttach callbacks the ability to schedule wrap the
   1157  -- opt-out (such as deleting the semanticTokensProvider from capabilities)
   1158  vim.schedule(function()
   1159    if not vim.api.nvim_buf_is_valid(bufnr) then
   1160      return
   1161    end
   1162    for _, Capability in pairs(lsp._capability.all) do
   1163      if
   1164        self:supports_method(Capability.method)
   1165        and lsp._capability.is_enabled(Capability.name, {
   1166          bufnr = bufnr,
   1167          client_id = self.id,
   1168        })
   1169      then
   1170        local capability = Capability.active[bufnr] or Capability:new(bufnr)
   1171        capability:on_attach(self.id)
   1172      end
   1173    end
   1174  end)
   1175 
   1176  self.attached_buffers[bufnr] = true
   1177 end
   1178 
   1179 --- @private
   1180 --- Logs the given error to the LSP log and to the error buffer.
   1181 --- @param code integer Error code
   1182 --- @param err any Error arguments
   1183 function Client:write_error(code, err)
   1184  local client_error = lsp.client_errors[code] --- @type string|integer
   1185  log.error(self._log_prefix, 'on_error', { code = client_error, err = err })
   1186  err_message(self._log_prefix, ': Error ', client_error, ': ', vim.inspect(err))
   1187 end
   1188 
   1189 --- Checks if a client supports a given method.
   1190 --- Always returns true for unknown off-spec methods.
   1191 ---
   1192 --- Note: Some language server capabilities can be file specific.
   1193 --- @param method vim.lsp.protocol.Method.ClientToServer | vim.lsp.protocol.Method.Registration
   1194 --- @param bufnr? integer
   1195 --- @return boolean
   1196 function Client:supports_method(method, bufnr)
   1197  -- Deprecated form
   1198  if type(bufnr) == 'table' then
   1199    --- @diagnostic disable-next-line:no-unknown
   1200    bufnr = bufnr.bufnr
   1201  end
   1202  local required_capability = lsp.protocol._request_name_to_server_capability[method]
   1203  if required_capability and vim.tbl_get(self.server_capabilities, unpack(required_capability)) then
   1204    return true
   1205  end
   1206 
   1207  local provider = self:_registration_provider(method)
   1208  local regs = self:_get_registrations(provider, bufnr)
   1209  if lsp.protocol._method_supports_dynamic_registration[method] and not regs then
   1210    return false
   1211  end
   1212  if regs then
   1213    for _, reg in ipairs(regs or {}) do
   1214      if required_capability and #required_capability > 1 then
   1215        if vim.tbl_get(reg, 'registerOptions', unpack(required_capability, 2)) then
   1216          return self:_supports_registration(reg.method)
   1217        end
   1218        if lsp.protocol._methods_with_no_registration_options[method] then
   1219          return true
   1220        end
   1221      else
   1222        return self:_supports_registration(reg.method)
   1223      end
   1224    end
   1225    return false
   1226  end
   1227 
   1228  -- if we don't know about the method, assume that the client supports it.
   1229  -- This needs to be at the end, so that dynamic_capabilities are checked first
   1230  return required_capability == nil
   1231 end
   1232 
   1233 --- Retrieves all capability values for a given LSP method, handling both static and dynamic registrations.
   1234 --- This function abstracts over differences between capabilities declared in `server_capabilities`
   1235 --- and those registered dynamically at runtime, returning all matching capability values.
   1236 --- It also handles cases where the registration method differs from the calling method by abstracting to the Provider.
   1237 --- For example, `workspace/diagnostic` uses capabilities registered under `textDocument/diagnostic`.
   1238 --- This is useful for features like diagnostics and formatting, where servers may register multiple providers
   1239 --- with different options (such as specific filetypes or document selectors).
   1240 --- @param method vim.lsp.protocol.Method.ClientToServer | vim.lsp.protocol.Method.Registration LSP method name
   1241 --- @param ... any Additional keys to index into the capability
   1242 --- @return lsp.LSPAny[] # The capability value if it exists, empty table if not found
   1243 function Client:_provider_value_get(method, ...)
   1244  local matched_regs = {} --- @type any[]
   1245  local provider = self:_registration_provider(method)
   1246  local dynamic_regs = self:_get_registrations(provider)
   1247  if not provider then
   1248    return matched_regs
   1249  elseif not dynamic_regs then
   1250    -- First check static capabilities
   1251    local static_reg = vim.tbl_get(self.server_capabilities, provider)
   1252    if static_reg then
   1253      matched_regs[1] = vim.tbl_get(static_reg, ...) or vim.NIL
   1254    end
   1255  else
   1256    local required_capability = lsp.protocol._request_name_to_server_capability[method]
   1257    for _, reg in ipairs(dynamic_regs) do
   1258      if vim.tbl_get(reg, 'registerOptions', unpack(required_capability, 2)) then
   1259        matched_regs[#matched_regs + 1] = vim.tbl_get(reg, 'registerOptions', ...) or vim.NIL
   1260      end
   1261    end
   1262  end
   1263 
   1264  return matched_regs
   1265 end
   1266 
   1267 --- @private
   1268 --- Handles a notification sent by an LSP server by invoking the
   1269 --- corresponding handler.
   1270 ---
   1271 --- @param method vim.lsp.protocol.Method.ServerToClient.Notification LSP method name
   1272 --- @param params table The parameters for that method.
   1273 function Client:_notification(method, params)
   1274  log.trace('notification', method, params)
   1275  local handler = self:_resolve_handler(method)
   1276  if handler then
   1277    -- Method name is provided here for convenience.
   1278    handler(nil, params, { method = method, client_id = self.id })
   1279  end
   1280 end
   1281 
   1282 --- @private
   1283 --- Handles a request from an LSP server by invoking the corresponding handler.
   1284 ---
   1285 --- @param method (vim.lsp.protocol.Method.ServerToClient) LSP method name
   1286 --- @param params (table) The parameters for that method
   1287 --- @return any result
   1288 --- @return lsp.ResponseError? error code and message set in case an exception happens during the request.
   1289 function Client:_server_request(method, params)
   1290  log.trace('server_request', method, params)
   1291  local handler = self:_resolve_handler(method)
   1292  if handler then
   1293    log.trace('server_request: found handler for', method)
   1294    return handler(nil, params, { method = method, client_id = self.id })
   1295  end
   1296  log.warn('server_request: no handler found for', method)
   1297  return nil, lsp.rpc_response_error(lsp.protocol.ErrorCodes.MethodNotFound)
   1298 end
   1299 
   1300 --- @private
   1301 --- Invoked when the client operation throws an error.
   1302 ---
   1303 --- @param code integer Error code
   1304 --- @param err any Other arguments may be passed depending on the error kind
   1305 --- @see vim.lsp.rpc.client_errors for possible errors. Use
   1306 --- `vim.lsp.rpc.client_errors[code]` to get a human-friendly name.
   1307 function Client:_on_error(code, err)
   1308  self:write_error(code, err)
   1309  if self._on_error_cb then
   1310    --- @type boolean, string
   1311    local status, usererr = pcall(self._on_error_cb, code, err)
   1312    if not status then
   1313      log.error(self._log_prefix, 'user on_error failed', { err = usererr })
   1314      err_message(self._log_prefix, ' user on_error failed: ', tostring(usererr))
   1315    end
   1316  end
   1317 end
   1318 
   1319 ---@param bufnr integer resolved buffer
   1320 function Client:_on_detach(bufnr)
   1321  if self.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
   1322    api.nvim_exec_autocmds('LspDetach', {
   1323      buffer = bufnr,
   1324      modeline = false,
   1325      data = { client_id = self.id },
   1326    })
   1327  end
   1328 
   1329  for _, Capability in pairs(lsp._capability.all) do
   1330    if
   1331      self:supports_method(Capability.method)
   1332      and lsp._capability.is_enabled(Capability.name, {
   1333        bufnr = bufnr,
   1334        client_id = self.id,
   1335      })
   1336    then
   1337      local capability = Capability.active[bufnr]
   1338      if capability then
   1339        capability:on_detach(self.id)
   1340        if next(capability.client_state) == nil then
   1341          capability:destroy()
   1342        end
   1343      end
   1344    end
   1345  end
   1346 
   1347  changetracking.reset_buf(self, bufnr)
   1348 
   1349  if self:supports_method('textDocument/didClose') then
   1350    local uri = vim.uri_from_bufnr(bufnr)
   1351    local params = { textDocument = { uri = uri } }
   1352    self:notify('textDocument/didClose', params)
   1353  end
   1354 
   1355  self.attached_buffers[bufnr] = nil
   1356 
   1357  local namespace = lsp.diagnostic.get_namespace(self.id)
   1358  vim.diagnostic.reset(namespace, bufnr)
   1359 end
   1360 
   1361 --- Reset defaults set by `set_defaults`.
   1362 --- Must only be called if the last client attached to a buffer exits.
   1363 local function reset_defaults(bufnr)
   1364  if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
   1365    vim.bo[bufnr].tagfunc = nil
   1366  end
   1367  if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
   1368    vim.bo[bufnr].omnifunc = nil
   1369  end
   1370  if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
   1371    vim.bo[bufnr].formatexpr = nil
   1372  end
   1373  vim._with({ buf = bufnr }, function()
   1374    local keymap = vim.fn.maparg('K', 'n', false, true)
   1375    if keymap and keymap.callback == lsp.buf.hover and keymap.buffer == 1 then
   1376      vim.keymap.del('n', 'K', { buffer = bufnr })
   1377    end
   1378  end)
   1379 end
   1380 
   1381 --- @private
   1382 --- Invoked on client exit.
   1383 ---
   1384 --- @param code integer) exit code of the process
   1385 --- @param signal integer the signal used to terminate (if any)
   1386 function Client:_on_exit(code, signal)
   1387  if self._shutdown_timer and not self._shutdown_timer:is_closing() then
   1388    self._shutdown_timer:close()
   1389    self._shutdown_timer = nil
   1390  end
   1391 
   1392  vim.schedule(function()
   1393    for bufnr in pairs(self.attached_buffers) do
   1394      self:_on_detach(bufnr)
   1395      if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
   1396        reset_defaults(bufnr)
   1397      end
   1398    end
   1399 
   1400    -- Schedule the deletion of the client object
   1401    -- so that it exists in the execution of autocommands
   1402    vim.schedule(function()
   1403      all_clients[self.id] = nil
   1404 
   1405      -- Client can be absent if executable starts, but initialize fails
   1406      -- init/attach won't have happened
   1407      if self then
   1408        changetracking.reset(self)
   1409      end
   1410      if code ~= 0 or (signal ~= 0 and signal ~= 15) then
   1411        local msg = string.format(
   1412          'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
   1413          self and self.name or 'unknown',
   1414          code,
   1415          signal,
   1416          log.get_filename()
   1417        )
   1418        vim.notify(msg, vim.log.levels.WARN)
   1419      end
   1420    end)
   1421  end)
   1422 
   1423  if self._handle_restart ~= nil then
   1424    self._handle_restart()
   1425    self._handle_restart = nil
   1426  end
   1427 
   1428  self:_run_callbacks(
   1429    self._on_exit_cbs,
   1430    lsp.client_errors.ON_EXIT_CALLBACK_ERROR,
   1431    code,
   1432    signal,
   1433    self.id
   1434  )
   1435 end
   1436 
   1437 --- Add a directory to the workspace folders.
   1438 --- @param dir string?
   1439 function Client:_add_workspace_folder(dir)
   1440  for _, folder in pairs(self.workspace_folders or {}) do
   1441    if folder.name == dir then
   1442      print(dir, 'is already part of this workspace')
   1443      return
   1444    end
   1445  end
   1446 
   1447  local wf = assert(lsp._get_workspace_folders(dir))
   1448 
   1449  self:notify('workspace/didChangeWorkspaceFolders', {
   1450    event = { added = wf, removed = {} },
   1451  })
   1452 
   1453  if not self.workspace_folders then
   1454    self.workspace_folders = {}
   1455  end
   1456  vim.list_extend(self.workspace_folders, wf)
   1457 end
   1458 
   1459 --- Remove a directory to the workspace folders.
   1460 --- @param dir string?
   1461 function Client:_remove_workspace_folder(dir)
   1462  local wf = assert(lsp._get_workspace_folders(dir))
   1463 
   1464  self:notify('workspace/didChangeWorkspaceFolders', {
   1465    event = { added = {}, removed = wf },
   1466  })
   1467 
   1468  for idx, folder in pairs(self.workspace_folders) do
   1469    if folder.name == dir then
   1470      table.remove(self.workspace_folders, idx)
   1471      break
   1472    end
   1473  end
   1474 end
   1475 
   1476 -- Export for internal use only.
   1477 Client._all = all_clients
   1478 
   1479 return Client