Browse Source

lsp: Accept text document edits with version zero

There were a couple of reports of "Buffer X newer than edits" problems.
We first assumed that it is incorrect for a server to send 0 as a
version - and stated that they should send a `null` instead, given that
in the specification the `textDocument` of a `TextDocumentEdit` is a
`OptionalVersionedTextDocumentIdentifier`.

But it turns out that this was a change in 3.16, and in 3.15 and earlier
versions of the specification it was a `VersionedTextDocumentIdentifier`
and language servers didn't have a better option than sending `0` if
they don't keep track of the version numbers.

So this changes the version check to always accept `0` values.

See

- https://github.com/neovim/neovim/issues/12970
- https://github.com/neovim/neovim/issues/14256
- https://github.com/haskell/haskell-language-server/pull/1727
pull/14366/head
Mathias Fussenegger 3 weeks ago
parent
commit
b67f689e4c
  1. 2
      runtime/lua/vim/lsp/util.lua
  2. 13
      test/functional/plugin/lsp_spec.lua

2
runtime/lua/vim/lsp/util.lua

@ -470,6 +470,8 @@ function M.apply_text_document_edit(text_document_edit, index)
-- `VersionedTextDocumentIdentifier`s version may be null
-- https://microsoft.github.io/language-server-protocol/specification#versionedTextDocumentIdentifier
if should_check_version and (text_document.version
and text_document.version ~= vim.NIL
and text_document.version > 0
and M.buf_versions[bufnr]
and M.buf_versions[bufnr] > text_document.version) then
print("Buffer ", text_document.uri, " newer than edits.")

13
test/functional/plugin/lsp_spec.lua

@ -1124,6 +1124,19 @@ describe('LSP', function()
'2nd line of 语text';
}, buf_lines(target_bufnr))
end)
it('always accepts edit with version = 0', function()
exec_lua([[
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)
]], target_bufnr, text_document_edit(0))
eq({
'First ↥ 🤦 🦄 line of text';
'2nd line of 语text';
}, buf_lines(target_bufnr))
end)
it('correctly goes ahead with the edit if the version is vim.NIL', function()
-- we get vim.NIL when we decode json null value.
local json = exec_lua[[

Loading…
Cancel
Save