mirror of
https://github.com/neovim/neovim.git
synced 2025-12-12 01:22:41 +00:00
fix(lsp): enable insertReplaceSupport for use in adjust_start_col #36569
Problem: With the typescript LSes typescript-language-server and vtsls, omnicompletion on partial tokens for certain types, such as array methods, and functions that are attached as attributes to other functions, either results in no entries populated in the completion menu (typescript-language-server), or an unfiltered completion menu with all array methods included, even if they don't share the same prefix as the partial token being completed (vtsls). Solution: Enable insertReplaceSupport and uses the insert portion of the lsp completion response in adjust_start_col if it's included in the response. Completion results are still filtered client side.
This commit is contained in:
@@ -301,7 +301,7 @@ function M._lsp_to_complete_items(result, prefix, client_id)
|
|||||||
return match_item_by_value(item.filterText, prefix)
|
return match_item_by_value(item.filterText, prefix)
|
||||||
end
|
end
|
||||||
|
|
||||||
if item.textEdit then
|
if item.textEdit and not item.textEdit.newText then
|
||||||
-- server took care of filtering
|
-- server took care of filtering
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -370,11 +370,18 @@ 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 and item.textEdit.range.start.line == lnum then
|
if item.textEdit then
|
||||||
|
if 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
|
||||||
min_start_char = item.textEdit.range.start.character
|
min_start_char = item.textEdit.range.start.character
|
||||||
|
elseif item.textEdit.insert and item.textEdit.insert.start.line == lnum then
|
||||||
|
if min_start_char and min_start_char ~= item.textEdit.insert.start.character then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
min_start_char = item.textEdit.insert.start.character
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if min_start_char then
|
if min_start_char then
|
||||||
|
|||||||
@@ -478,6 +478,7 @@ function protocol.make_client_capabilities()
|
|||||||
preselectSupport = false,
|
preselectSupport = false,
|
||||||
deprecatedSupport = true,
|
deprecatedSupport = true,
|
||||||
documentationFormat = { constants.MarkupKind.Markdown, constants.MarkupKind.PlainText },
|
documentationFormat = { constants.MarkupKind.Markdown, constants.MarkupKind.PlainText },
|
||||||
|
insertReplaceSupport = true,
|
||||||
resolveSupport = {
|
resolveSupport = {
|
||||||
properties = {
|
properties = {
|
||||||
'additionalTextEdits',
|
'additionalTextEdits',
|
||||||
|
|||||||
@@ -149,10 +149,6 @@ describe('vim.lsp.completion: item conversion', function()
|
|||||||
abbr = 'foo',
|
abbr = 'foo',
|
||||||
word = 'foo',
|
word = 'foo',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
abbr = 'bar',
|
|
||||||
word = 'bar',
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
result = vim.tbl_map(function(x)
|
result = vim.tbl_map(function(x)
|
||||||
return {
|
return {
|
||||||
@@ -618,21 +614,6 @@ 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 = {
|
||||||
@@ -647,17 +628,6 @@ describe('vim.lsp.completion: item conversion', function()
|
|||||||
abbr_hlgroup = '',
|
abbr_hlgroup = '',
|
||||||
word = 'this_thread',
|
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)
|
||||||
@@ -806,6 +776,53 @@ describe('vim.lsp.completion: item conversion', function()
|
|||||||
eq('hello', text)
|
eq('hello', text)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it('uses the start boundary from an insertReplace response', function()
|
||||||
|
local completion_list = {
|
||||||
|
isIncomplete = false,
|
||||||
|
items = {
|
||||||
|
{
|
||||||
|
data = { cacheId = 1 },
|
||||||
|
kind = 2,
|
||||||
|
label = 'foobar',
|
||||||
|
sortText = '11',
|
||||||
|
textEdit = {
|
||||||
|
insert = {
|
||||||
|
start = { character = 4, line = 4 },
|
||||||
|
['end'] = { character = 8, line = 4 },
|
||||||
|
},
|
||||||
|
newText = 'foobar',
|
||||||
|
replace = {
|
||||||
|
start = { character = 4, line = 4 },
|
||||||
|
['end'] = { character = 8, line = 4 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data = { cacheId = 2 },
|
||||||
|
kind = 2,
|
||||||
|
label = 'bazqux',
|
||||||
|
sortText = '11',
|
||||||
|
textEdit = {
|
||||||
|
insert = {
|
||||||
|
start = { character = 4, line = 4 },
|
||||||
|
['end'] = { character = 5, line = 4 },
|
||||||
|
},
|
||||||
|
newText = 'bazqux',
|
||||||
|
replace = {
|
||||||
|
start = { character = 4, line = 4 },
|
||||||
|
['end'] = { character = 5, line = 4 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local result = complete('foo.f|', completion_list)
|
||||||
|
eq(1, #result.items)
|
||||||
|
local text = result.items[1].user_data.nvim.lsp.completion_item.textEdit.newText
|
||||||
|
eq('foobar', text)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- @param name string
|
--- @param name string
|
||||||
|
|||||||
Reference in New Issue
Block a user