aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp/completion.lua13
-rw-r--r--test/functional/plugin/lsp/completion_spec.lua32
2 files changed, 42 insertions, 3 deletions
diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua
index edbc329939..3c7d1f1469 100644
--- a/runtime/lua/vim/lsp/completion.lua
+++ b/runtime/lua/vim/lsp/completion.lua
@@ -127,8 +127,10 @@ end
--- See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion
---
--- @param item lsp.CompletionItem
+--- @param prefix string
+--- @param match fun(text: string, prefix: string):boolean
--- @return string
-local function get_completion_word(item)
+local function get_completion_word(item, prefix, match)
if item.insertTextFormat == protocol.InsertTextFormat.Snippet then
if item.textEdit then
-- Use label instead of text if text has different starting characters.
@@ -146,7 +148,12 @@ local function get_completion_word(item)
--
-- Typing `i` would remove the candidate because newText starts with `t`.
local text = parse_snippet(item.insertText or item.textEdit.newText)
- return #text < #item.label and vim.fn.matchstr(text, '\\k*') or item.label
+ local word = #text < #item.label and vim.fn.matchstr(text, '\\k*') or item.label
+ if item.filterText and not match(word, prefix) then
+ return item.filterText
+ else
+ return word
+ end
elseif item.insertText and item.insertText ~= '' then
return parse_snippet(item.insertText)
else
@@ -276,7 +283,7 @@ function M._lsp_to_complete_items(result, prefix, client_id)
local user_convert = vim.tbl_get(buf_handles, bufnr, 'convert')
for _, item in ipairs(items) do
if matches(item) then
- local word = get_completion_word(item)
+ local word = get_completion_word(item, prefix, match_item_by_value)
local hl_group = ''
if
item.deprecated
diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua
index 15ac9da657..84c8f5864a 100644
--- a/test/functional/plugin/lsp/completion_spec.lua
+++ b/test/functional/plugin/lsp/completion_spec.lua
@@ -216,6 +216,38 @@ describe('vim.lsp.completion: item conversion', function()
})
end)
+ it('uses filterText as word if label/newText would not match', function()
+ local items = {
+ {
+ filterText = '<module',
+ insertTextFormat = 2,
+ kind = 10,
+ label = 'module',
+ sortText = 'module',
+ textEdit = {
+ newText = '<module>$1</module>$0',
+ range = {
+ start = {
+ character = 0,
+ line = 0,
+ },
+ ['end'] = {
+ character = 0,
+ line = 0,
+ },
+ },
+ },
+ },
+ }
+ local expected = {
+ {
+ abbr = 'module',
+ word = '<module',
+ },
+ }
+ assert_completion_matches('<mo', items, expected)
+ end)
+
it('fuzzy matches on label when filterText is missing', function()
assert_completion_matches('fo', {
{ label = 'foo' },