mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(lsp): revert text edit application order change (#29877)
Reverts https://github.com/neovim/neovim/pull/29212 and adds a few additional test cases From the spec > All text edits ranges refer to positions in the document they are > computed on. They therefore move a document from state S1 to S2 without > describing any intermediate state. Text edits ranges must never overlap, > that means no part of the original document must be manipulated by more > than one edit. However, it is possible that multiple edits have the same > start position: multiple inserts, or any number of inserts followed by a > single remove or replace edit. If multiple inserts have the same > position, the order in the array defines the order in which the inserted > strings appear in the resulting text. The previous fix seems wrong. The important part: > If multiple inserts have the same position, the order in the array > defines the order in which the inserted strings appear in the > resulting text. Emphasis on _appear in the resulting text_ Which means that in: local edits1 = { make_edit(0, 3, 0, 3, { 'World' }), make_edit(0, 3, 0, 3, { 'Hello' }), } `World` must appear before `Hello` in the final text. That means the old logic was correct, and the fix was wrong.
This commit is contained in:
parent
aee4254b76
commit
bdff50dee5
@ -396,10 +396,7 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
|
|||||||
if a.range.start.character ~= b.range.start.character then
|
if a.range.start.character ~= b.range.start.character then
|
||||||
return a.range.start.character > b.range.start.character
|
return a.range.start.character > b.range.start.character
|
||||||
end
|
end
|
||||||
if a._index ~= b._index then
|
return a._index > b._index
|
||||||
return a._index < b._index
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- save and restore local marks since they get deleted by nvim_buf_set_lines
|
-- save and restore local marks since they get deleted by nvim_buf_set_lines
|
||||||
|
@ -1756,6 +1756,58 @@ describe('LSP', function()
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe('apply vscode text_edits', function()
|
||||||
|
it('single replace', function()
|
||||||
|
insert('012345678901234567890123456789')
|
||||||
|
local edits = {
|
||||||
|
make_edit(0, 3, 0, 6, { 'Hello' }),
|
||||||
|
}
|
||||||
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
||||||
|
eq({ '012Hello678901234567890123456789' }, buf_lines(1))
|
||||||
|
end)
|
||||||
|
it('two replaces', function()
|
||||||
|
insert('012345678901234567890123456789')
|
||||||
|
local edits = {
|
||||||
|
make_edit(0, 3, 0, 6, { 'Hello' }),
|
||||||
|
make_edit(0, 6, 0, 9, { 'World' }),
|
||||||
|
}
|
||||||
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
||||||
|
eq({ '012HelloWorld901234567890123456789' }, buf_lines(1))
|
||||||
|
end)
|
||||||
|
it('same start pos insert are kept in order', function()
|
||||||
|
insert('012345678901234567890123456789')
|
||||||
|
local edits1 = {
|
||||||
|
make_edit(0, 3, 0, 3, { 'World' }),
|
||||||
|
make_edit(0, 3, 0, 3, { 'Hello' }),
|
||||||
|
}
|
||||||
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits1, 1, 'utf-16')
|
||||||
|
eq({ '012WorldHello345678901234567890123456789' }, buf_lines(1))
|
||||||
|
end)
|
||||||
|
it('same start pos insert and replace are kept in order', function()
|
||||||
|
insert('012345678901234567890123456789')
|
||||||
|
local edits1 = {
|
||||||
|
make_edit(0, 3, 0, 3, { 'World' }),
|
||||||
|
make_edit(0, 3, 0, 3, { 'Hello' }),
|
||||||
|
make_edit(0, 3, 0, 8, { 'No' }),
|
||||||
|
}
|
||||||
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits1, 1, 'utf-16')
|
||||||
|
eq({ '012WorldHelloNo8901234567890123456789' }, buf_lines(1))
|
||||||
|
end)
|
||||||
|
it('multiline', function()
|
||||||
|
exec_lua([[
|
||||||
|
vim.api.nvim_buf_set_lines(1, 0, 0, true, {' {', ' "foo": "bar"', ' }'})
|
||||||
|
]])
|
||||||
|
eq({ ' {', ' "foo": "bar"', ' }', '' }, buf_lines(1))
|
||||||
|
local edits = {
|
||||||
|
make_edit(0, 0, 3, 0, { '' }),
|
||||||
|
make_edit(3, 0, 3, 0, { '{\n' }),
|
||||||
|
make_edit(3, 0, 3, 0, { ' "foo": "bar"\n' }),
|
||||||
|
make_edit(3, 0, 3, 0, { '}\n' }),
|
||||||
|
}
|
||||||
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
||||||
|
eq({ '{', ' "foo": "bar"', '}', '' }, buf_lines(1))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
describe('apply_text_edits', function()
|
describe('apply_text_edits', function()
|
||||||
before_each(function()
|
before_each(function()
|
||||||
insert(dedent([[
|
insert(dedent([[
|
||||||
@ -1794,9 +1846,9 @@ describe('LSP', function()
|
|||||||
}
|
}
|
||||||
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
||||||
eq({
|
eq({
|
||||||
'3',
|
'',
|
||||||
'foo',
|
'123',
|
||||||
'12Fbar',
|
'fooFbar',
|
||||||
'123irst guy',
|
'123irst guy',
|
||||||
'baz line of text',
|
'baz line of text',
|
||||||
'The next line of text',
|
'The next line of text',
|
||||||
@ -1818,9 +1870,9 @@ describe('LSP', function()
|
|||||||
}
|
}
|
||||||
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1, 'utf-16')
|
||||||
eq({
|
eq({
|
||||||
'3',
|
'',
|
||||||
'foo',
|
'123',
|
||||||
'12Fbar',
|
'fooFbar',
|
||||||
'123irst guy',
|
'123irst guy',
|
||||||
'baz line of text',
|
'baz line of text',
|
||||||
'The next line of text',
|
'The next line of text',
|
||||||
|
Loading…
Reference in New Issue
Block a user