diff options
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 10 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 94 |
2 files changed, 48 insertions, 56 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 9efab73c2b..099a77099b 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -168,10 +168,12 @@ end function M.apply_text_document_edit(text_document_edit) local text_document = text_document_edit.textDocument local bufnr = vim.uri_to_bufnr(text_document.uri) - -- `VersionedTextDocumentIdentifier`s version may be nil https://microsoft.github.io/language-server-protocol/specification#versionedTextDocumentIdentifier - if text_document.version ~= vim.NIL and M.buf_versions[bufnr] > text_document.version then - print("Buffer ", text_document.uri, " newer than edits.") - return + if text_document.version then + -- `VersionedTextDocumentIdentifier`s version may be null https://microsoft.github.io/language-server-protocol/specification#versionedTextDocumentIdentifier + if text_document.version ~= vim.NIL and M.buf_versions[bufnr] ~= nil and M.buf_versions[bufnr] > text_document.version then + print("Buffer ", text_document.uri, " newer than edits.") + return + end end M.apply_text_edits(text_document_edit.edits, bufnr) end diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index e48d50ff47..62dee7df90 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -835,33 +835,30 @@ describe('LSP', function() describe('apply_text_document_edit', function() local target_bufnr + local text_document_edit = function(editVersion) + return { + edits = { + make_edit(0, 0, 0, 3, "First ↥ 🤦 🦄") + }, + textDocument = { + uri = "file://fake/uri"; + version = editVersion + } + } + end before_each(function() target_bufnr = exec_lua [[ - local bufnr = vim.fn.bufadd("fake/uri") - local lines = {"1st line of text", "2nd line of text"} + local bufnr = vim.uri_to_bufnr("file://fake/uri") + local lines = {"1st line of text", "2nd line of 语text"} vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines) return bufnr ]] end) it('correctly goes ahead with the edit if all is normal', function() - local text_document_edit = { - edits = { - make_edit(0, 0, 0, 3, "First") - }, - textDocument = { - uri = "file://fake/uri"; - version = 5 - } - } - exec_lua([[ - local args = {...} - local target_bufnr = args[2] - vim.lsp.util.buf_versions[target_bufnr] = 4 - vim.lsp.util.apply_text_document_edit(...) - ]], text_document_edit, target_bufnr) + exec_lua('vim.lsp.util.apply_text_document_edit(...)', text_document_edit(5)) eq({ - 'First line of text'; - '2nd line of text'; + '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() @@ -871,45 +868,38 @@ describe('LSP', function() ]] eq(json.b, exec_lua("return vim.NIL")) - local text_document_edit = { - edits = { - make_edit(0, 0, 0, 3, "First") - }, - textDocument = { - uri = "file://fake/uri"; - version = exec_lua("return vim.NIL") - } - } - exec_lua([[ - local args = {...} - local target_bufnr = args[2] - vim.lsp.util.buf_versions[target_bufnr] = vim.NIL - vim.lsp.util.apply_text_document_edit(...) - ]], text_document_edit, target_bufnr) + exec_lua('vim.lsp.util.apply_text_document_edit(...)', text_document_edit(exec_lua("return vim.NIL"))) eq({ - 'First line of text'; - '2nd line of text'; + 'First ↥ 🤦 🦄 line of text'; + '2nd line of 语text'; }, buf_lines(target_bufnr)) end) it('skips the edit if the version of the edit is behind the local buffer ', function() - local text_document_edit = { - edits = { - make_edit(0, 0, 0, 3, "First") - }, - textDocument = { - uri = "file://fake/uri"; - version = 1 - } + 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(...) + ]], edit, versionedBuf) + end + + local baseText = { + '1st line of text'; + '2nd line of 语text'; } - exec_lua([[ - local args = {...} - local target_bufnr = args[2] - vim.lsp.util.buf_versions[target_bufnr] = 2 - vim.lsp.util.apply_text_document_edit(...) - ]], text_document_edit, target_bufnr) + + eq(baseText, buf_lines(target_bufnr)) + + -- Apply an edit for an old version, should skip + 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(8), {currentVersion=7; bufnr=target_bufnr}) eq({ - '1st line of text'; - '2nd line of text'; + 'First ↥ 🤦 🦄 line of text'; + '2nd line of 语text'; }, buf_lines(target_bufnr)) end) end) |