aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Fußenegger <mfussenegger@users.noreply.github.com>2024-06-07 11:36:46 +0200
committerGitHub <noreply@github.com>2024-06-07 11:36:46 +0200
commit6e45cd7f0026ee33b8c397b810dcfe5b4678bbd8 (patch)
tree3903f0cca53f9fbd9a47242b011ac69bda14610a
parent6c7677e5d274da7e477518aa29b0faa862e61627 (diff)
downloadrneovim-6e45cd7f0026ee33b8c397b810dcfe5b4678bbd8.tar.gz
rneovim-6e45cd7f0026ee33b8c397b810dcfe5b4678bbd8.tar.bz2
rneovim-6e45cd7f0026ee33b8c397b810dcfe5b4678bbd8.zip
fix(lsp): revert buf_versions deprecation/replacement (#29217)
* Revert "fix(lsp): account for changedtick version gap on modified reset (#29170)" This reverts commit 2e6d295f799c27372e5c0c44727fa613c81717fd. * Revert "refactor(lsp): replace util.buf_versions with changedtick (#28943)" This reverts commit 5c33815448e11b514678f39cecc74e68131d4628.
-rw-r--r--runtime/doc/deprecated.txt3
-rw-r--r--runtime/lua/vim/lsp.lua5
-rw-r--r--runtime/lua/vim/lsp/_changetracking.lua3
-rw-r--r--runtime/lua/vim/lsp/client.lua5
-rw-r--r--runtime/lua/vim/lsp/inlay_hint.lua4
-rw-r--r--runtime/lua/vim/lsp/semantic_tokens.lua6
-rw-r--r--runtime/lua/vim/lsp/util.lua21
-rw-r--r--test/functional/fixtures/fake-lsp-server.lua14
-rw-r--r--test/functional/plugin/lsp/semantic_tokens_spec.lua24
-rw-r--r--test/functional/plugin/lsp_spec.lua51
10 files changed, 69 insertions, 67 deletions
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index 3b3e6afa9e..6c6585d76e 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -22,9 +22,6 @@ API
LUA
- vim.region() Use |getregionpos()| instead.
-LSP
-- *vim.lsp.util.buf_versions* Use |b:changedtick| instead.
-
DIAGNOSTICS
- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count = 1}` instead.
- *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count = -1}` instead.
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 49a24f873c..eb50a0b880 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -484,6 +484,7 @@ local function text_document_did_save_handler(bufnr)
text = lsp._buf_get_full_text(bufnr),
},
})
+ util.buf_versions[bufnr] = 0
end
local save_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'save')
if save_capability then
@@ -519,6 +520,7 @@ local function buf_detach_client(bufnr, client)
end
client.attached_buffers[bufnr] = nil
+ util.buf_versions[bufnr] = nil
local namespace = lsp.diagnostic.get_namespace(client.id)
vim.diagnostic.reset(namespace, bufnr)
@@ -574,11 +576,12 @@ local function buf_attach(bufnr)
})
-- First time, so attach and set up stuff.
api.nvim_buf_attach(bufnr, false, {
- on_lines = function(_, _, _, firstline, lastline, new_lastline)
+ on_lines = function(_, _, changedtick, firstline, lastline, new_lastline)
if #lsp.get_clients({ bufnr = bufnr }) == 0 then
-- detach if there are no clients
return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0
end
+ util.buf_versions[bufnr] = changedtick
changetracking.send_changes(bufnr, firstline, lastline, new_lastline)
end,
diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua
index ce701f0772..b2be53269f 100644
--- a/runtime/lua/vim/lsp/_changetracking.lua
+++ b/runtime/lua/vim/lsp/_changetracking.lua
@@ -1,5 +1,6 @@
local protocol = require('vim.lsp.protocol')
local sync = require('vim.lsp.sync')
+local util = require('vim.lsp.util')
local api = vim.api
local uv = vim.uv
@@ -276,7 +277,7 @@ local function send_changes(bufnr, sync_kind, state, buf_state)
client.notify(protocol.Methods.textDocument_didChange, {
textDocument = {
uri = uri,
- version = vim.b[bufnr].changedtick,
+ version = util.buf_versions[bufnr],
},
contentChanges = changes,
})
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua
index b28fe2f797..327cd19125 100644
--- a/runtime/lua/vim/lsp/client.lua
+++ b/runtime/lua/vim/lsp/client.lua
@@ -673,8 +673,8 @@ function Client:_request(method, params, handler, bufnr)
end
-- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state
changetracking.flush(self, bufnr)
+ local version = lsp.util.buf_versions[bufnr]
bufnr = resolve_bufnr(bufnr)
- local version = vim.b[bufnr].changedtick
log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr)
local success, request_id = self.rpc.request(method, params, function(err, result)
local context = {
@@ -922,13 +922,14 @@ function Client:_text_document_did_open_handler(bufnr)
local params = {
textDocument = {
- version = vim.b[bufnr].changedtick,
+ version = 0,
uri = vim.uri_from_bufnr(bufnr),
languageId = self.get_language_id(bufnr, filetype),
text = lsp._buf_get_full_text(bufnr),
},
}
self.notify(ms.textDocument_didOpen, params)
+ lsp.util.buf_versions[bufnr] = params.textDocument.version
-- Next chance we get, we should re-do the diagnostics
vim.schedule(function()
diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua
index 8fd4ceefd2..2d784816cb 100644
--- a/runtime/lua/vim/lsp/inlay_hint.lua
+++ b/runtime/lua/vim/lsp/inlay_hint.lua
@@ -43,7 +43,7 @@ function M.on_inlayhint(err, result, ctx, _)
return
end
local bufnr = assert(ctx.bufnr)
- if vim.b[bufnr].changedtick ~= ctx.version then
+ if util.buf_versions[bufnr] ~= ctx.version then
return
end
local client_id = ctx.client_id
@@ -324,7 +324,7 @@ api.nvim_set_decoration_provider(namespace, {
return
end
- if bufstate.version ~= vim.b[bufnr].changedtick then
+ if bufstate.version ~= util.buf_versions[bufnr] then
return
end
diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua
index b2a8360aa2..279956658c 100644
--- a/runtime/lua/vim/lsp/semantic_tokens.lua
+++ b/runtime/lua/vim/lsp/semantic_tokens.lua
@@ -116,7 +116,7 @@ local function tokens_to_ranges(data, bufnr, client, request)
if elapsed_ns > yield_interval_ns then
vim.schedule(function()
- coroutine.resume(co, vim.b[bufnr].changedtick)
+ coroutine.resume(co, util.buf_versions[bufnr])
end)
if request.version ~= coroutine.yield() then
-- request became stale since the last time the coroutine ran.
@@ -269,7 +269,7 @@ end
---
---@package
function STHighlighter:send_request()
- local version = vim.b[self.bufnr].changedtick
+ local version = util.buf_versions[self.bufnr]
self:reset_timer()
@@ -412,7 +412,7 @@ end
function STHighlighter:on_win(topline, botline)
for client_id, state in pairs(self.client_state) do
local current_result = state.current_result
- if current_result.version and current_result.version == vim.b[self.bufnr].changedtick then
+ if current_result.version and current_result.version == util.buf_versions[self.bufnr] then
if not current_result.namespace_cleared then
api.nvim_buf_clear_namespace(self.bufnr, state.namespace, 0, -1)
current_result.namespace_cleared = true
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 3215b40d1d..fc027cfcc0 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -502,11 +502,6 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
should_check_version = false
end
- -- changedtick increases on save but server only receives version updates
- -- on line changes (via didChange)
- -- This allows a gap of 1 to account for the servers outdated view
- local version_offset = vim.b[bufnr].modified and 0 or 1
-
-- `VersionedTextDocumentIdentifier`s version may be null
-- https://microsoft.github.io/language-server-protocol/specification#versionedTextDocumentIdentifier
if
@@ -514,7 +509,8 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
and (
text_document.version
and text_document.version > 0
- and vim.b[bufnr].changedtick > (text_document.version + version_offset)
+ and M.buf_versions[bufnr]
+ and M.buf_versions[bufnr] > text_document.version
)
then
print('Buffer ', text_document.uri, ' newer than edits.')
@@ -2206,16 +2202,9 @@ function M._refresh(method, opts)
end
end
----@nodoc
----@deprecated
----@type table<integer,integer>
-M.buf_versions = setmetatable({}, {
- __index = function(_, bufnr)
- vim.deprecate('vim.lsp.util.buf_versions', 'vim.b.changedtick', '0.13')
- return vim.b[bufnr].changedtick
- end,
-})
-
M._get_line_byte_from_position = get_line_byte_from_position
+---@nodoc
+M.buf_versions = {} ---@type table<integer,integer>
+
return M
diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua
index 9aafd38d4f..f806869b40 100644
--- a/test/functional/fixtures/fake-lsp-server.lua
+++ b/test/functional/fixtures/fake-lsp-server.lua
@@ -471,7 +471,7 @@ function tests.basic_check_buffer_open()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n') .. '\n',
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('finish')
@@ -498,7 +498,7 @@ function tests.basic_check_buffer_open_and_change()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n') .. '\n',
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('textDocument/didChange', {
@@ -534,7 +534,7 @@ function tests.basic_check_buffer_open_and_change_noeol()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n'),
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('textDocument/didChange', {
@@ -569,7 +569,7 @@ function tests.basic_check_buffer_open_and_change_multi()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n') .. '\n',
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('textDocument/didChange', {
@@ -614,7 +614,7 @@ function tests.basic_check_buffer_open_and_change_multi_and_close()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n') .. '\n',
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('textDocument/didChange', {
@@ -672,7 +672,7 @@ function tests.basic_check_buffer_open_and_change_incremental()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n') .. '\n',
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('textDocument/didChange', {
@@ -715,7 +715,7 @@ function tests.basic_check_buffer_open_and_change_incremental_editing()
languageId = '',
text = table.concat({ 'testing', '123' }, '\n'),
uri = 'file://',
- version = 2,
+ version = 0,
},
})
expect_notification('textDocument/didChange', {
diff --git a/test/functional/plugin/lsp/semantic_tokens_spec.lua b/test/functional/plugin/lsp/semantic_tokens_spec.lua
index 9babb080e7..7908c5d2e7 100644
--- a/test/functional/plugin/lsp/semantic_tokens_spec.lua
+++ b/test/functional/plugin/lsp/semantic_tokens_spec.lua
@@ -111,7 +111,6 @@ describe('semantic token highlighting', function()
end)
it('buffer is highlighted when attached', function()
- insert(text)
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
@@ -119,6 +118,8 @@ describe('semantic token highlighting', function()
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
+ insert(text)
+
screen:expect {
grid = [[
#include <iostream> |
@@ -140,7 +141,6 @@ describe('semantic token highlighting', function()
end)
it('use LspTokenUpdate and highlight_token', function()
- insert(text)
exec_lua([[
vim.api.nvim_create_autocmd("LspTokenUpdate", {
callback = function(args)
@@ -157,6 +157,8 @@ describe('semantic token highlighting', function()
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
+ insert(text)
+
screen:expect {
grid = [[
#include <iostream> |
@@ -178,17 +180,14 @@ describe('semantic token highlighting', function()
end)
it('buffer is unhighlighted when client is detached', function()
- insert(text)
-
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
- vim.wait(1000, function()
- return #server.messages > 1
- end)
]])
+ insert(text)
+
exec_lua([[
vim.notify = function() end
vim.lsp.buf_detach_client(bufnr, client_id)
@@ -332,13 +331,14 @@ describe('semantic token highlighting', function()
end)
it('buffer is re-highlighted when force refreshed', function()
- insert(text)
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
+ insert(text)
+
screen:expect {
grid = [[
#include <iostream> |
@@ -412,14 +412,13 @@ describe('semantic token highlighting', function()
end)
it('updates highlights with delta request on buffer change', function()
- insert(text)
-
exec_lua([[
bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
]])
+ insert(text)
screen:expect {
grid = [[
#include <iostream> |
@@ -598,7 +597,6 @@ describe('semantic token highlighting', function()
end)
it('does not send delta requests if not supported by server', function()
- insert(text)
exec_lua(
[[
local legend, response, edit_response = ...
@@ -627,6 +625,7 @@ describe('semantic token highlighting', function()
edit_response
)
+ insert(text)
screen:expect {
grid = [[
#include <iostream> |
@@ -1450,7 +1449,6 @@ int main()
},
}) do
it(test.it, function()
- insert(test.text1)
exec_lua(create_server_definition)
exec_lua(
[[
@@ -1487,6 +1485,8 @@ int main()
test.response2
)
+ insert(test.text1)
+
test.expected_screen1()
local highlights = exec_lua([[
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 23f6b733d5..0cf84b50c2 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -255,7 +255,7 @@ describe('LSP', function()
return
end
local expected_handlers = {
- { NIL, {}, { method = 'shutdown', bufnr = 1, client_id = 1, version = 2 } },
+ { NIL, {}, { method = 'shutdown', bufnr = 1, client_id = 1 } },
{ NIL, {}, { method = 'test', client_id = 1 } },
}
test_rpc_server {
@@ -948,11 +948,7 @@ describe('LSP', function()
it('should forward ContentModified to callback', function()
local expected_handlers = {
{ NIL, {}, { method = 'finish', client_id = 1 } },
- {
- { code = -32801 },
- NIL,
- { method = 'error_code_test', bufnr = 1, client_id = 1, version = 2 },
- },
+ { { code = -32801 }, NIL, { method = 'error_code_test', bufnr = 1, client_id = 1 } },
}
local client --- @type vim.lsp.Client
test_rpc_server {
@@ -982,7 +978,7 @@ describe('LSP', function()
it('should track pending requests to the language server', function()
local expected_handlers = {
{ NIL, {}, { method = 'finish', client_id = 1 } },
- { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1, version = 2 } },
+ { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } },
}
local client --- @type vim.lsp.Client
test_rpc_server {
@@ -1049,7 +1045,7 @@ describe('LSP', function()
it('should clear pending and cancel requests on reply', function()
local expected_handlers = {
{ NIL, {}, { method = 'finish', client_id = 1 } },
- { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1, version = 2 } },
+ { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } },
}
local client --- @type vim.lsp.Client
test_rpc_server {
@@ -1088,7 +1084,7 @@ describe('LSP', function()
it('should trigger LspRequest autocmd when requests table changes', function()
local expected_handlers = {
{ NIL, {}, { method = 'finish', client_id = 1 } },
- { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1, version = 2 } },
+ { NIL, {}, { method = 'slow_request', bufnr = 1, client_id = 1 } },
}
local client --- @type vim.lsp.Client
test_rpc_server {
@@ -1368,7 +1364,6 @@ describe('LSP', function()
},
bufnr = 2,
client_id = 1,
- version = 2,
},
},
{ NIL, {}, { method = 'start', client_id = 1 } },
@@ -2122,6 +2117,7 @@ describe('LSP', function()
local args = {...}
local bufnr = select(1, ...)
local text_edit = select(2, ...)
+ vim.lsp.util.buf_versions[bufnr] = 10
vim.lsp.util.apply_text_document_edit(text_edit, nil, 'utf-16')
]],
target_bufnr,
@@ -2133,13 +2129,16 @@ describe('LSP', function()
}, buf_lines(target_bufnr))
end)
it('skips the edit if the version of the edit is behind the local buffer ', function()
- local apply_edit_mocking_current_version = function(edit)
+ local apply_edit_mocking_current_version = function(edit, versionedBuf)
exec_lua(
[[
local args = {...}
+ local versionedBuf = args[2]
+ vim.lsp.util.buf_versions[versionedBuf.bufnr] = versionedBuf.currentVersion
vim.lsp.util.apply_text_document_edit(args[1], nil, 'utf-16')
]],
- edit
+ edit,
+ versionedBuf
)
end
@@ -2151,17 +2150,17 @@ describe('LSP', function()
eq(baseText, buf_lines(target_bufnr))
-- Apply an edit for an old version, should skip
- apply_edit_mocking_current_version(text_document_edit(1))
+ apply_edit_mocking_current_version(
+ text_document_edit(2),
+ { currentVersion = 7, bufnr = target_bufnr }
+ )
eq(baseText, buf_lines(target_bufnr)) -- no change
-- Sanity check that next version to current does apply change
- apply_edit_mocking_current_version(text_document_edit(exec_lua(
- [[
- local bufnr = ...
- return vim.b[bufnr].changedtick
- ]],
- target_bufnr
- )))
+ apply_edit_mocking_current_version(
+ text_document_edit(8),
+ { currentVersion = 7, bufnr = target_bufnr }
+ )
eq({
'First ↥ 🤦 🦄 line of text',
'2nd line of 语text',
@@ -2240,6 +2239,18 @@ describe('LSP', function()
}
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
+
+ local update_changed_tick = function()
+ vim.lsp.util.buf_versions[bufnr] = vim.api.nvim_buf_get_var(bufnr, 'changedtick')
+ end
+
+ update_changed_tick()
+ vim.api.nvim_buf_attach(bufnr, false, {
+ on_changedtick = function()
+ update_changed_tick()
+ end
+ })
+
return {bufnr, vim.api.nvim_buf_get_var(bufnr, 'changedtick')}
]]