aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lingelbach <m.j.lbach@gmail.com>2021-11-15 08:51:30 -0800
committerGitHub <noreply@github.com>2021-11-15 08:51:30 -0800
commit87a053f126c79f5eeb1654e35beb31d9fe733163 (patch)
treebdfbe6fbbd03f391561b7e9884b376fd606e04ec
parent8f984dc1f29aa6ce41f233b983453bfd795e8238 (diff)
downloadrneovim-87a053f126c79f5eeb1654e35beb31d9fe733163.tar.gz
rneovim-87a053f126c79f5eeb1654e35beb31d9fe733163.tar.bz2
rneovim-87a053f126c79f5eeb1654e35beb31d9fe733163.zip
fix(lsp): fix edge cases in incremental sync (#16308)
-rw-r--r--runtime/lua/vim/lsp/sync.lua8
-rw-r--r--test/functional/plugin/lsp/incremental_sync_spec.lua150
2 files changed, 116 insertions, 42 deletions
diff --git a/runtime/lua/vim/lsp/sync.lua b/runtime/lua/vim/lsp/sync.lua
index 37247c61b9..585c14a00f 100644
--- a/runtime/lua/vim/lsp/sync.lua
+++ b/runtime/lua/vim/lsp/sync.lua
@@ -219,6 +219,10 @@ local function compute_end_range(prev_lines, curr_lines, start_range, firstline,
-- Iterate from end to beginning of shortest line
local prev_end_byte_idx = prev_line_length - byte_offset + 1
+ -- Handle case where lines match
+ if prev_end_byte_idx == 0 then
+ prev_end_byte_idx = 1
+ end
local prev_byte_idx, prev_char_idx = align_position(prev_line, prev_end_byte_idx, 'start', offset_encoding)
local prev_end_range = { line_idx = prev_line_idx, byte_idx = prev_byte_idx, char_idx = prev_char_idx }
@@ -228,6 +232,10 @@ local function compute_end_range(prev_lines, curr_lines, start_range, firstline,
curr_end_range = { line_idx = start_line_idx, byte_idx = 1, char_idx = 1 }
else
local curr_end_byte_idx = curr_line_length - byte_offset + 1
+ -- Handle case where lines match
+ if curr_end_byte_idx == 0 then
+ curr_end_byte_idx = 1
+ end
local curr_byte_idx, curr_char_idx = align_position(curr_line, curr_end_byte_idx, 'start', offset_encoding)
curr_end_range = { line_idx = curr_line_idx, byte_idx = curr_byte_idx, char_idx = curr_char_idx }
end
diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua
index fe4f8f3593..890db4abf5 100644
--- a/test/functional/plugin/lsp/incremental_sync_spec.lua
+++ b/test/functional/plugin/lsp/incremental_sync_spec.lua
@@ -66,6 +66,7 @@ local function test_edit(prev_buffer, edit_operations, expected_text_changes, of
exec_lua("test_unreg = 'test1'")
end
+
describe('incremental synchronization', function()
describe('single line edit', function()
it('inserting a character in an empty buffer', function()
@@ -163,54 +164,119 @@ describe('incremental synchronization', function()
}
test_edit({"a"}, {"rb"}, expected_text_changes, 'utf-16', '\n')
end)
- describe('multi-byte edits', function()
- it('join and undo', function()
- local expected_text_changes = {
- {
- range = {
- ['start'] = {
- character = 11,
- line = 0
- },
- ['end'] = {
- character = 11,
- line = 0
- }
+ end)
+
+ describe('multi-operation edits', function()
+ it('mult-line substitution', function()
+ local expected_text_changes = {
+ {
+ range = {
+ ["end"] = {
+ character = 11,
+ line = 2 },
+ ["start"] = {
+ character = 10,
+ line = 2 } },
+ rangeLength = 1,
+ text = '',
+ },{
+ range = {
+ ["end"] = {
+ character = 10,
+ line = 2 },
+ start = {
+ character = 10,
+ line = 2 } },
+ rangeLength = 0,
+ text = '2',
+ },{
+ range = {
+ ["end"] = {
+ character = 11,
+ line = 3 },
+ ["start"] = {
+ character = 10,
+ line = 3 } },
+ rangeLength = 1,
+ text = ''
+ },{
+ range = {
+ ['end'] = {
+ character = 10,
+ line = 3 },
+ ['start'] = {
+ character = 10,
+ line = 3 } },
+ rangeLength = 0,
+ text = '3' },
+ {
+ range = {
+ ['end'] = {
+ character = 0,
+ line = 3 },
+ ['start'] = {
+ character = 12,
+ line = 2 } },
+ rangeLength = 1,
+ text = '\n'
+ }
+ }
+ local original_lines = {
+ "\\begin{document}",
+ "\\section*{1}",
+ "\\section*{1}",
+ "\\section*{1}",
+ "\\end{document}"
+ }
+ test_edit(original_lines, {"3gg$h<C-V>jg<C-A>"}, expected_text_changes, 'utf-16', '\n')
+ end)
+ it('join and undo', function()
+ local expected_text_changes = {
+ {
+ range = {
+ ['start'] = {
+ character = 11,
+ line = 0
},
- rangeLength = 0,
- text = ' test3'
- },{
- range = {
- ['start'] = {
- character = 0,
- line = 1
- },
- ['end'] = {
- character = 0,
- line = 2
- }
+ ['end'] = {
+ character = 11,
+ line = 0
+ }
+ },
+ rangeLength = 0,
+ text = ' test3'
+ },{
+ range = {
+ ['start'] = {
+ character = 0,
+ line = 1
},
- rangeLength = 6,
- text = ''
- },{
- range = {
- ['start'] = {
- character = 11,
- line = 0
- },
- ['end'] = {
- character = 17,
- line = 0
- }
+ ['end'] = {
+ character = 0,
+ line = 2
+ }
+ },
+ rangeLength = 6,
+ text = ''
+ },{
+ range = {
+ ['start'] = {
+ character = 11,
+ line = 0
},
- rangeLength = 6,
- text = '\ntest3'
+ ['end'] = {
+ character = 17,
+ line = 0
+ }
},
- }
- test_edit({"test1 test2", "test3"}, {"J", "u"}, expected_text_changes, 'utf-16', '\n')
- end)
+ rangeLength = 6,
+ text = '\ntest3'
+ },
+ }
+ test_edit({"test1 test2", "test3"}, {"J", "u"}, expected_text_changes, 'utf-16', '\n')
end)
end)
+
describe('multi-byte edits', function()
it('deleting a multibyte character', function()
local expected_text_changes = {