aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp.lua4
-rw-r--r--runtime/lua/vim/lsp/callbacks.lua3
-rw-r--r--runtime/lua/vim/lsp/util.lua17
3 files changed, 21 insertions, 3 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 94f0d62d8d..bc0da25ae5 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -945,12 +945,14 @@ function lsp.omnifunc(findstart, base)
-- Get the start position of the current keyword
local textMatch = vim.fn.match(line_to_cursor, '\\k*$')
+ local prefix = line_to_cursor:sub(textMatch+1)
+
local params = util.make_position_params()
local items = {}
lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, _, result)
if err or not result then return end
- local matches = util.text_document_completion_list_to_complete_items(result)
+ local matches = util.text_document_completion_list_to_complete_items(result, prefix)
-- TODO(ashkan): is this the best way to do this?
vim.list_extend(items, matches)
vim.fn.complete(textMatch+1, items)
diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua
index 794140ee2e..e76e07ca96 100644
--- a/runtime/lua/vim/lsp/callbacks.lua
+++ b/runtime/lua/vim/lsp/callbacks.lua
@@ -63,8 +63,9 @@ M['textDocument/completion'] = function(_, _, result)
local line = assert(api.nvim_buf_get_lines(0, row-1, row, false)[1])
local line_to_cursor = line:sub(col+1)
local textMatch = vim.fn.match(line_to_cursor, '\\k*$')
+ local prefix = line_to_cursor:sub(textMatch+1)
- local matches = util.text_document_completion_list_to_complete_items(result)
+ local matches = util.text_document_completion_list_to_complete_items(result, prefix)
vim.fn.complete(textMatch+1, matches)
end
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 428874f2b7..620037d24d 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -129,6 +129,19 @@ function M.extract_completion_items(result)
end
end
+-- Some lanuguage servers return complementary candidates whose prefixes do not match are also returned.
+-- So we exclude completion candidates whose prefix does not match.
+function M.remove_unmatch_completion_items(items, prefix)
+ local matched_items = {}
+ for _, item in ipairs(items) do
+ local word = item.insertText or item.label
+ if vim.startswith(word, prefix) then
+ table.insert(matched_items, item)
+ end
+ end
+ return matched_items
+end
+
--- Apply the TextDocumentEdit response.
-- @params TextDocumentEdit [table] see https://microsoft.github.io/language-server-protocol/specification
function M.apply_text_document_edit(text_document_edit)
@@ -151,12 +164,14 @@ end
--- Getting vim complete-items with incomplete flag.
-- @params CompletionItem[], CompletionList or nil (https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
-- @return { matches = complete-items table, incomplete = boolean }
-function M.text_document_completion_list_to_complete_items(result)
+function M.text_document_completion_list_to_complete_items(result, prefix)
local items = M.extract_completion_items(result)
if vim.tbl_isempty(items) then
return {}
end
+ items = M.remove_unmatch_completion_items(items, prefix)
+
local matches = {}
for _, completion_item in ipairs(items) do