aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp.lua
diff options
context:
space:
mode:
authorMichael Lingelbach <m.j.lbach@gmail.com>2021-12-21 10:53:34 -0800
committerGitHub <noreply@github.com>2021-12-21 10:53:34 -0800
commit1b04da52b3ce611e06b7d1c87af4a71c37ad127a (patch)
treebaf0e051b0f31ee99bdef11c48c2fc110a68d939 /runtime/lua/vim/lsp.lua
parent1062ea2cc532b32862346a1972073f1a8dd6d19d (diff)
downloadrneovim-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.lua48
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