diff options
author | Michael Lingelbach <m.j.lbach@gmail.com> | 2021-12-21 10:53:34 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-21 10:53:34 -0800 |
commit | 1b04da52b3ce611e06b7d1c87af4a71c37ad127a (patch) | |
tree | baf0e051b0f31ee99bdef11c48c2fc110a68d939 /runtime/lua/vim/lsp.lua | |
parent | 1062ea2cc532b32862346a1972073f1a8dd6d19d (diff) | |
download | rneovim-1b04da52b3ce611e06b7d1c87af4a71c37ad127a.tar.gz rneovim-1b04da52b3ce611e06b7d1c87af4a71c37ad127a.tar.bz2 rneovim-1b04da52b3ce611e06b7d1c87af4a71c37ad127a.zip |
feat(lsp): add buf_detach_client (#16250)
This allows the user to detach an active buffer from the language
client. If no clients remain attached to a buffer, the on_lines callback
is used to cancel nvim_buf_attach.
Diffstat (limited to 'runtime/lua/vim/lsp.lua')
-rw-r--r-- | runtime/lua/vim/lsp.lua | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 25cde843a0..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) @@ -1220,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 |