fix(lsp): prevent desync due to empty buffer (#29904)

Problem:
Some language servers (e.g., rust-analyzer, texlab) are desynced when
the user deletes the entire contents of the buffer. This is due to the
discrepancy between how nvim computes diff and how nvim treats empty
buffer.
* diff: If the buffer became empty, then the diff includes the last
  line's eol.
* empty buffer: Even if the buffer is empty, nvim regards it as having
  a single empty line with eol.

Solution:
Add special case for diff computation when the buffer becomes empty so
that it does not include the eol of the last line.
This commit is contained in:
Jaehwang Jung
2024-07-31 23:18:24 +09:00
committed by GitHub
parent 4e90bc3023
commit 6bb40f3dbf
2 changed files with 53 additions and 4 deletions

View File

@@ -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' }, { 'dd' }, expected_text_changes, 'utf-16', '\n')
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' }, { 'ggdG' }, expected_text_changes, 'utf-16', '\n')
end)
it('deleting an empty line', function()
local expected_text_changes = {