diff options
Diffstat (limited to 'runtime/lua/vim')
| -rw-r--r-- | runtime/lua/vim/lsp.lua | 54 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/util.lua | 29 | 
2 files changed, 70 insertions, 13 deletions
| diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 2e530ec17a..00839ec181 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -1112,9 +1112,9 @@ local text_document_did_change_handler  do    text_document_did_change_handler = function(_, bufnr, changedtick, firstline, lastline, new_lastline) -    -- Don't do anything if there are no clients attached. +    -- Detach (nvim_buf_attach) via returning True to on_lines if no clients are attached      if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then -      return +      return true      end      util.buf_versions[bufnr] = changedtick      local compute_change_and_notify = changetracking.prepare(bufnr, firstline, lastline, new_lastline) @@ -1156,6 +1156,12 @@ function lsp.buf_attach_client(bufnr, client_id)      client_id = {client_id, 'n'};    }    bufnr = resolve_bufnr(bufnr) +  if not vim.api.nvim_buf_is_loaded(bufnr) then +    local _ = log.warn() and log.warn( +      string.format("buf_attach_client called on unloaded buffer (id: %d): ", bufnr) +    ) +    return false +  end    local buffer_client_ids = all_buffer_active_clients[bufnr]    -- This is our first time attaching to this buffer.    if not buffer_client_ids then @@ -1214,6 +1220,50 @@ function lsp.buf_attach_client(bufnr, client_id)    return true  end +--- Detaches client from the specified buffer. +--- Note: While the server is notified that the text document (buffer) +--- was closed, it is still able to send notifications should it ignore this notification. +--- +---@param bufnr number Buffer handle, or 0 for current +---@param client_id number Client id +function lsp.buf_detach_client(bufnr, client_id) +  validate { +    bufnr     = {bufnr, 'n', true}; +    client_id = {client_id, 'n'}; +  } +  bufnr = resolve_bufnr(bufnr) + +  local client = lsp.get_client_by_id(client_id) +  if not client or not client.attached_buffers[bufnr] then +    vim.notify( +      string.format('Buffer (id: %d) is not attached to client (id: %d). Cannot detach.', client_id, bufnr) +    ) +    return +  end + +  changetracking.reset_buf(client, bufnr) + +  if client.resolved_capabilities.text_document_open_close then +    local uri = vim.uri_from_bufnr(bufnr) +    local params = { textDocument = { uri = uri; } } +    client.notify('textDocument/didClose', params) +  end + +  client.attached_buffers[bufnr] = nil +  util.buf_versions[bufnr] = nil + +  all_buffer_active_clients[bufnr][client_id] = nil +  if #vim.tbl_keys(all_buffer_active_clients[bufnr]) == 0 then +    all_buffer_active_clients[bufnr] = nil +  end + +  local namespace = vim.lsp.diagnostic.get_namespace(client_id) +  vim.diagnostic.reset(namespace, bufnr) + +  vim.notify(string.format('Detached buffer (id: %d) from client (id: %d)', bufnr, client_id)) + +end +  --- Checks if a buffer is attached for a particular client.  ---  ---@param bufnr (number) Buffer handle, or 0 for current diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 68a030d50b..5921eb5bf0 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -97,15 +97,17 @@ end  ---@param encoding string utf-8|utf-16|utf-32|nil defaults to utf-16  ---@return number `encoding` index of `index` in `line`  function M._str_utfindex_enc(line, index, encoding) -  if encoding ~= 'utf-8' then -    local col32, col16 = vim.str_utfindex(line, index) -    if encoding == 'utf-32' then -      return col32 -    else -      return col16 -    end +  if not encoding then encoding = 'utf-16' end +  if encoding == 'utf-8' then +    if index then return index else return #line end +  elseif encoding == 'utf-16' then +    local _, col16 = vim.str_utfindex(line, index) +    return col16 +  elseif encoding == 'utf-32' then +    local col32, _ = vim.str_utfindex(line, index) +    return col32    else -    return index +    error("Invalid encoding: " .. vim.inspect(encoding))    end  end @@ -117,10 +119,15 @@ end  ---@param encoding string utf-8|utf-16|utf-32|nil defaults to utf-16  ---@return number byte (utf-8) index of `encoding` index `index` in `line`  function M._str_byteindex_enc(line, index, encoding) -  if encoding ~= 'utf-8' then -    return vim.str_byteindex(line, index, not encoding or encoding ~= 'utf-32') +  if not encoding then encoding = 'utf-16' end +  if encoding == 'utf-8' then +    if index then return index else return #line end +  elseif encoding == 'utf-16' then +    return vim.str_byteindex(line, index, true) +  elseif encoding == 'utf-32' then +    return vim.str_byteindex(line, index)    else -    return index +    error("Invalid encoding: " .. vim.inspect(encoding))    end  end | 
