mirror of
https://github.com/neovim/neovim
synced 2025-07-17 01:31:48 +00:00
fix(lsp): send textDocument/didChange for each buffer (#16431)
Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net>
This commit is contained in:
committed by
GitHub
parent
102e7e7929
commit
3451121a4e
@ -320,7 +320,8 @@ do
|
|||||||
---
|
---
|
||||||
--- state
|
--- state
|
||||||
--- pending_change?: function that the timer starts to trigger didChange
|
--- pending_change?: function that the timer starts to trigger didChange
|
||||||
--- pending_changes: list of tables with the pending changesets; for incremental_sync only
|
--- pending_changes: table (uri -> list of pending changeset tables));
|
||||||
|
-- Only set if incremental_sync is used
|
||||||
--- use_incremental_sync: bool
|
--- use_incremental_sync: bool
|
||||||
--- buffers?: table (bufnr → lines); for incremental sync only
|
--- buffers?: table (bufnr → lines); for incremental sync only
|
||||||
--- timer?: uv_timer
|
--- timer?: uv_timer
|
||||||
@ -348,12 +349,10 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
function changetracking.reset_buf(client, bufnr)
|
function changetracking.reset_buf(client, bufnr)
|
||||||
|
changetracking.flush(client)
|
||||||
local state = state_by_client[client.id]
|
local state = state_by_client[client.id]
|
||||||
if state then
|
if state and state.buffers then
|
||||||
changetracking._reset_timer(state)
|
state.buffers[bufnr] = nil
|
||||||
if state.buffers then
|
|
||||||
state.buffers[bufnr] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -365,7 +364,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function changetracking.prepare(bufnr, firstline, lastline, new_lastline, changedtick)
|
function changetracking.prepare(bufnr, firstline, lastline, new_lastline)
|
||||||
local incremental_changes = function(client)
|
local incremental_changes = function(client)
|
||||||
local cached_buffers = state_by_client[client.id].buffers
|
local cached_buffers = state_by_client[client.id].buffers
|
||||||
local curr_lines = nvim_buf_get_lines(bufnr, 0, -1, true)
|
local curr_lines = nvim_buf_get_lines(bufnr, 0, -1, true)
|
||||||
@ -392,7 +391,7 @@ do
|
|||||||
client.notify("textDocument/didChange", {
|
client.notify("textDocument/didChange", {
|
||||||
textDocument = {
|
textDocument = {
|
||||||
uri = uri;
|
uri = uri;
|
||||||
version = changedtick;
|
version = util.buf_versions[bufnr];
|
||||||
};
|
};
|
||||||
contentChanges = { changes, }
|
contentChanges = { changes, }
|
||||||
})
|
})
|
||||||
@ -402,27 +401,36 @@ do
|
|||||||
if state.use_incremental_sync then
|
if state.use_incremental_sync then
|
||||||
-- This must be done immediately and cannot be delayed
|
-- This must be done immediately and cannot be delayed
|
||||||
-- The contents would further change and startline/endline may no longer fit
|
-- The contents would further change and startline/endline may no longer fit
|
||||||
table.insert(state.pending_changes, incremental_changes(client))
|
if not state.pending_changes[uri] then
|
||||||
|
state.pending_changes[uri] = {}
|
||||||
|
end
|
||||||
|
table.insert(state.pending_changes[uri], incremental_changes(client))
|
||||||
end
|
end
|
||||||
state.pending_change = function()
|
state.pending_change = function()
|
||||||
state.pending_change = nil
|
state.pending_change = nil
|
||||||
if client.is_stopped() or not vim.api.nvim_buf_is_valid(bufnr) then
|
if client.is_stopped() or not vim.api.nvim_buf_is_valid(bufnr) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local contentChanges
|
|
||||||
if state.use_incremental_sync then
|
if state.use_incremental_sync then
|
||||||
contentChanges = state.pending_changes
|
for change_uri, content_changes in pairs(state.pending_changes) do
|
||||||
|
client.notify("textDocument/didChange", {
|
||||||
|
textDocument = {
|
||||||
|
uri = change_uri;
|
||||||
|
version = util.buf_versions[vim.uri_to_bufnr(change_uri)];
|
||||||
|
};
|
||||||
|
contentChanges = content_changes,
|
||||||
|
})
|
||||||
|
end
|
||||||
state.pending_changes = {}
|
state.pending_changes = {}
|
||||||
else
|
else
|
||||||
contentChanges = { full_changes(), }
|
client.notify("textDocument/didChange", {
|
||||||
|
textDocument = {
|
||||||
|
uri = uri;
|
||||||
|
version = util.buf_versions[bufnr];
|
||||||
|
};
|
||||||
|
contentChanges = { full_changes() },
|
||||||
|
})
|
||||||
end
|
end
|
||||||
client.notify("textDocument/didChange", {
|
|
||||||
textDocument = {
|
|
||||||
uri = uri;
|
|
||||||
version = changedtick;
|
|
||||||
};
|
|
||||||
contentChanges = contentChanges
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
state.timer = vim.loop.new_timer()
|
state.timer = vim.loop.new_timer()
|
||||||
-- Must use schedule_wrap because `full_changes()` calls nvim_buf_get_lines
|
-- Must use schedule_wrap because `full_changes()` calls nvim_buf_get_lines
|
||||||
@ -1103,7 +1111,7 @@ do
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
util.buf_versions[bufnr] = changedtick
|
util.buf_versions[bufnr] = changedtick
|
||||||
local compute_change_and_notify = changetracking.prepare(bufnr, firstline, lastline, new_lastline, changedtick)
|
local compute_change_and_notify = changetracking.prepare(bufnr, firstline, lastline, new_lastline)
|
||||||
for_each_buffer_client(bufnr, compute_change_and_notify)
|
for_each_buffer_client(bufnr, compute_change_and_notify)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1162,6 +1170,7 @@ function lsp.buf_attach_client(bufnr, client_id)
|
|||||||
on_reload = function()
|
on_reload = function()
|
||||||
local params = { textDocument = { uri = uri; } }
|
local params = { textDocument = { uri = uri; } }
|
||||||
for_each_buffer_client(bufnr, function(client, _)
|
for_each_buffer_client(bufnr, function(client, _)
|
||||||
|
changetracking.reset_buf(client, bufnr)
|
||||||
if client.resolved_capabilities.text_document_open_close then
|
if client.resolved_capabilities.text_document_open_close then
|
||||||
client.notify('textDocument/didClose', params)
|
client.notify('textDocument/didClose', params)
|
||||||
end
|
end
|
||||||
@ -1171,10 +1180,10 @@ function lsp.buf_attach_client(bufnr, client_id)
|
|||||||
on_detach = function()
|
on_detach = function()
|
||||||
local params = { textDocument = { uri = uri; } }
|
local params = { textDocument = { uri = uri; } }
|
||||||
for_each_buffer_client(bufnr, function(client, _)
|
for_each_buffer_client(bufnr, function(client, _)
|
||||||
|
changetracking.reset_buf(client, bufnr)
|
||||||
if client.resolved_capabilities.text_document_open_close then
|
if client.resolved_capabilities.text_document_open_close then
|
||||||
client.notify('textDocument/didClose', params)
|
client.notify('textDocument/didClose', params)
|
||||||
end
|
end
|
||||||
changetracking.reset_buf(client, bufnr)
|
|
||||||
end)
|
end)
|
||||||
util.buf_versions[bufnr] = nil
|
util.buf_versions[bufnr] = nil
|
||||||
all_buffer_active_clients[bufnr] = nil
|
all_buffer_active_clients[bufnr] = nil
|
||||||
|
Reference in New Issue
Block a user