fix(lsp): when prefix is non word add all result into matches (#30044)

Problem: prefix can be a symbol like period, the fuzzy matching can't
handle it correctly.

Solution: when prefix is empty or a symbol add all lsp completion
result into matches.
This commit is contained in:
glepnir
2024-08-31 02:23:49 +08:00
committed by GitHub
parent 5f95f1249f
commit 42ed0ffad9
2 changed files with 28 additions and 7 deletions

View File

@ -238,7 +238,7 @@ function M._lsp_to_complete_items(result, prefix, client_id)
---@type fun(item: lsp.CompletionItem):boolean ---@type fun(item: lsp.CompletionItem):boolean
local matches local matches
if prefix == '' then if not prefix:find('%w') then
matches = function(_) matches = function(_)
return true return true
end end

View File

@ -18,35 +18,36 @@ local create_server_definition = t_lsp.create_server_definition
---@param candidates lsp.CompletionList|lsp.CompletionItem[] ---@param candidates lsp.CompletionList|lsp.CompletionItem[]
---@param lnum? integer 0-based, defaults to 0 ---@param lnum? integer 0-based, defaults to 0
---@return {items: table[], server_start_boundary: integer?} ---@return {items: table[], server_start_boundary: integer?}
local function complete(line, candidates, lnum) local function complete(line, candidates, lnum, server_boundary)
lnum = lnum or 0 lnum = lnum or 0
-- nvim_win_get_cursor returns 0 based column, line:find returns 1 based -- nvim_win_get_cursor returns 0 based column, line:find returns 1 based
local cursor_col = line:find('|') - 1 local cursor_col = line:find('|') - 1
line = line:gsub('|', '') line = line:gsub('|', '')
return exec_lua( return exec_lua(
[[ [[
local line, cursor_col, lnum, result = ... local line, cursor_col, lnum, result, server_boundary = ...
local line_to_cursor = line:sub(1, cursor_col) local line_to_cursor = line:sub(1, cursor_col)
local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$') local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$')
local items, server_start_boundary = require("vim.lsp.completion")._convert_results( local items, new_server_boundary = require("vim.lsp.completion")._convert_results(
line, line,
lnum, lnum,
cursor_col, cursor_col,
1, 1,
client_start_boundary, client_start_boundary,
nil, server_boundary,
result, result,
"utf-16" "utf-16"
) )
return { return {
items = items, items = items,
server_start_boundary = server_start_boundary server_start_boundary = new_server_boundary
} }
]], ]],
line, line,
cursor_col, cursor_col,
lnum, lnum,
candidates candidates,
server_boundary
) )
end end
@ -162,6 +163,26 @@ describe('vim.lsp.completion: item conversion', function()
eq(expected, result) eq(expected, result)
end) end)
it('works on non word prefix', function()
local completion_list = {
{ label = ' foo', insertText = '->foo' },
}
local result = complete('wp.|', completion_list, 0, 2)
local expected = {
{
abbr = ' foo',
word = '->foo',
},
}
result = vim.tbl_map(function(x)
return {
abbr = x.abbr,
word = x.word,
}
end, result.items)
eq(expected, result)
end)
it('trims trailing newline or tab from textEdit', function() it('trims trailing newline or tab from textEdit', function()
local range0 = { local range0 = {
start = { line = 0, character = 0 }, start = { line = 0, character = 0 },