diff options
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 7 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 22 |
2 files changed, 16 insertions, 13 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index b33f6ccf69..3215b40d1d 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -502,6 +502,11 @@ 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 @@ -509,7 +514,7 @@ 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 + and vim.b[bufnr].changedtick > (text_document.version + version_offset) ) then print('Buffer ', text_document.uri, ' newer than edits.') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 85891e59b5..23f6b733d5 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -2133,15 +2133,13 @@ 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, versionedBuf) + local apply_edit_mocking_current_version = function(edit) exec_lua( [[ local args = {...} - local versionedBuf = args[2] vim.lsp.util.apply_text_document_edit(args[1], nil, 'utf-16') ]], - edit, - versionedBuf + edit ) end @@ -2153,17 +2151,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(2), - { currentVersion = 7, bufnr = target_bufnr } - ) + apply_edit_mocking_current_version(text_document_edit(1)) 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 } - ) + apply_edit_mocking_current_version(text_document_edit(exec_lua( + [[ + local bufnr = ... + return vim.b[bufnr].changedtick + ]], + target_bufnr + ))) eq({ 'First ↥ 🤦 🦄 line of text', '2nd line of 语text', |