mirror of
https://github.com/neovim/neovim.git
synced 2025-09-08 12:28:18 +00:00
fix(lsp): fix error with InsertReplaceEdit events #33973
Problem: Some LSPs cause the following completion error (reformatted slightly): Error executing vim.schedule lua callback: .../runtime/lua/vim/lsp/completion.lua:373 attempt to index field 'range' (a nil value) This is because an internal function assumes edits are either missing or of type `TextEdit`, but there's a third [possibility][0] that's not handled: the `InsertReplaceEdit`. This was previously reported in at least two issues: - https://github.com/neovim/neovim/issues/33142 - https://github.com/neovim/neovim/issues/33224 Solution: Don't assume the edit is a `TextEdit`. This implicitly handles `InsertReplaceEdit`s. Also, add a test case for this, which previously caused an error. [0]:2c07428966/runtime/lua/vim/lsp/_meta/protocol.lua (L1099)
(cherry picked from commit927927e143
)
This commit is contained in:

committed by
github-actions[bot]
![github-actions[bot]](/assets/img/avatar_default.png)
parent
e304677993
commit
b868257ef9
@@ -370,7 +370,7 @@ end
|
|||||||
local function adjust_start_col(lnum, line, items, encoding)
|
local function adjust_start_col(lnum, line, items, encoding)
|
||||||
local min_start_char = nil
|
local min_start_char = nil
|
||||||
for _, item in pairs(items) do
|
for _, item in pairs(items) do
|
||||||
if item.textEdit and item.textEdit.range.start.line == lnum then
|
if item.textEdit and item.textEdit.range and item.textEdit.range.start.line == lnum then
|
||||||
if min_start_char and min_start_char ~= item.textEdit.range.start.character then
|
if min_start_char and min_start_char ~= item.textEdit.range.start.character then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@@ -618,24 +618,53 @@ describe('vim.lsp.completion: item conversion', function()
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label = 'insert_replace_edit',
|
||||||
|
kind = 9,
|
||||||
|
textEdit = {
|
||||||
|
newText = 'foobar',
|
||||||
|
insert = {
|
||||||
|
start = { line = 0, character = 7 },
|
||||||
|
['end'] = { line = 0, character = 11 },
|
||||||
|
},
|
||||||
|
replace = {
|
||||||
|
start = { line = 0, character = 0 },
|
||||||
|
['end'] = { line = 0, character = 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
local expected = {
|
local expected = {
|
||||||
abbr = ' this_thread',
|
{
|
||||||
dup = 1,
|
abbr = ' this_thread',
|
||||||
empty = 1,
|
dup = 1,
|
||||||
icase = 1,
|
empty = 1,
|
||||||
info = '',
|
icase = 1,
|
||||||
kind = 'Module',
|
info = '',
|
||||||
menu = '',
|
kind = 'Module',
|
||||||
abbr_hlgroup = '',
|
menu = '',
|
||||||
word = 'this_thread',
|
abbr_hlgroup = '',
|
||||||
|
word = 'this_thread',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
abbr = 'insert_replace_edit',
|
||||||
|
dup = 1,
|
||||||
|
empty = 1,
|
||||||
|
icase = 1,
|
||||||
|
info = '',
|
||||||
|
kind = 'Module',
|
||||||
|
menu = '',
|
||||||
|
abbr_hlgroup = '',
|
||||||
|
word = 'foobar',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
local result = complete(' std::this|', completion_list)
|
local result = complete(' std::this|', completion_list)
|
||||||
eq(7, result.server_start_boundary)
|
eq(7, result.server_start_boundary)
|
||||||
local item = result.items[1]
|
for _, item in ipairs(result.items) do
|
||||||
item.user_data = nil
|
item.user_data = nil
|
||||||
eq(expected, item)
|
end
|
||||||
|
eq(expected, result.items)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('should search from start boundary to cursor position', function()
|
it('should search from start boundary to cursor position', function()
|
||||||
|
Reference in New Issue
Block a user