aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp/sync.lua13
-rw-r--r--test/functional/plugin/lsp/incremental_sync_spec.lua44
2 files changed, 53 insertions, 4 deletions
diff --git a/runtime/lua/vim/lsp/sync.lua b/runtime/lua/vim/lsp/sync.lua
index 936579e003..bdfe8d51b8 100644
--- a/runtime/lua/vim/lsp/sync.lua
+++ b/runtime/lua/vim/lsp/sync.lua
@@ -212,7 +212,8 @@ end
---@param lastline integer
---@param new_lastline integer
---@param offset_encoding string
----@return vim.lsp.sync.Range, vim.lsp.sync.Range
+---@return vim.lsp.sync.Range prev_end_range
+---@return vim.lsp.sync.Range curr_end_range
local function compute_end_range(
prev_lines,
curr_lines,
@@ -222,6 +223,16 @@ local function compute_end_range(
new_lastline,
offset_encoding
)
+ -- A special case for the following `firstline == new_lastline` case where lines are deleted.
+ -- Even if the buffer has become empty, nvim behaves as if it has an empty line with eol.
+ if #curr_lines == 1 and curr_lines[1] == '' then
+ local prev_line = prev_lines[lastline - 1]
+ return {
+ line_idx = lastline - 1,
+ byte_idx = #prev_line + 1,
+ char_idx = compute_line_length(prev_line, offset_encoding) + 1,
+ }, { line_idx = 1, byte_idx = 1, char_idx = 1 }
+ end
-- If firstline == new_lastline, the first change occurred on a line that was deleted.
-- In this case, the last_byte...
if firstline == new_lastline then
diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua
index 238b90b57d..1e463d5117 100644
--- a/test/functional/plugin/lsp/incremental_sync_spec.lua
+++ b/test/functional/plugin/lsp/incremental_sync_spec.lua
@@ -170,7 +170,7 @@ describe('incremental synchronization', function()
}
test_edit({ 'a' }, { 'rb' }, expected_text_changes, 'utf-16', '\n')
end)
- it('deleting a line', function()
+ it('deleting the first line', function()
local expected_text_changes = {
{
range = {
@@ -183,11 +183,49 @@ describe('incremental synchronization', function()
line = 1,
},
},
- rangeLength = 12,
+ rangeLength = 6,
+ text = '',
+ },
+ }
+ test_edit({ 'hello', 'world' }, { 'ggdd' }, expected_text_changes, 'utf-16', '\n')
+ end)
+ it('deleting the last line', function()
+ local expected_text_changes = {
+ {
+ range = {
+ ['start'] = {
+ character = 0,
+ line = 1,
+ },
+ ['end'] = {
+ character = 0,
+ line = 2,
+ },
+ },
+ rangeLength = 6,
+ text = '',
+ },
+ }
+ test_edit({ 'hello', 'world' }, { '2ggdd' }, expected_text_changes, 'utf-16', '\n')
+ end)
+ it('deleting all lines', function()
+ local expected_text_changes = {
+ {
+ range = {
+ ['start'] = {
+ character = 0,
+ line = 0,
+ },
+ ['end'] = {
+ character = 5,
+ line = 1,
+ },
+ },
+ rangeLength = 11,
text = '',
},
}
- test_edit({ 'hello world' }, { 'dd' }, expected_text_changes, 'utf-16', '\n')
+ test_edit({ 'hello', 'world' }, { 'ggdG' }, expected_text_changes, 'utf-16', '\n')
end)
it('deleting an empty line', function()
local expected_text_changes = {