mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
LSP: fix omnifunc findstart (#11522)
This commit is contained in:
parent
65aca4d857
commit
d00c624ba4
@ -859,29 +859,21 @@ function lsp.omnifunc(findstart, base)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if findstart == 1 then
|
if findstart == 1 then
|
||||||
|
-- First, just return the current cursor column, we only really need that
|
||||||
return vim.fn.col('.')
|
return vim.fn.col('.')
|
||||||
else
|
else
|
||||||
|
-- Then, perform standard completion request
|
||||||
|
log.info("base ", base)
|
||||||
|
|
||||||
local pos = vim.api.nvim_win_get_cursor(0)
|
local pos = vim.api.nvim_win_get_cursor(0)
|
||||||
local line = assert(nvim_buf_get_lines(bufnr, pos[1]-1, pos[1], false)[1])
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
local line_to_cursor = line:sub(1, pos[2])
|
||||||
local _ = log.trace() and log.trace("omnifunc.line", pos, line)
|
local _ = log.trace() and log.trace("omnifunc.line", pos, line)
|
||||||
local line_to_cursor = line:sub(1, pos[2]+1)
|
|
||||||
local _ = log.trace() and log.trace("omnifunc.line_to_cursor", line_to_cursor)
|
-- Get the start postion of the current keyword
|
||||||
local params = {
|
local textMatch = vim.fn.match(line_to_cursor, '\\k*$')
|
||||||
textDocument = {
|
local params = util.make_position_params()
|
||||||
uri = vim.uri_from_bufnr(bufnr);
|
|
||||||
};
|
|
||||||
position = {
|
|
||||||
-- 0-indexed for both line and character
|
|
||||||
line = pos[1] - 1,
|
|
||||||
character = vim.str_utfindex(line, pos[2]),
|
|
||||||
};
|
|
||||||
-- The completion context. This is only available if the client specifies
|
|
||||||
-- to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
|
|
||||||
-- context = nil or {
|
|
||||||
-- triggerKind = protocol.CompletionTriggerKind.Invoked;
|
|
||||||
-- triggerCharacter = nil or "";
|
|
||||||
-- };
|
|
||||||
}
|
|
||||||
-- TODO handle timeout error differently? Like via an error?
|
-- TODO handle timeout error differently? Like via an error?
|
||||||
local client_responses = lsp.buf_request_sync(bufnr, 'textDocument/completion', params) or {}
|
local client_responses = lsp.buf_request_sync(bufnr, 'textDocument/completion', params) or {}
|
||||||
local matches = {}
|
local matches = {}
|
||||||
@ -889,12 +881,15 @@ function lsp.omnifunc(findstart, base)
|
|||||||
-- TODO how to handle errors?
|
-- TODO how to handle errors?
|
||||||
if not response.error then
|
if not response.error then
|
||||||
local data = response.result
|
local data = response.result
|
||||||
local completion_items = util.text_document_completion_list_to_complete_items(data or {}, line_to_cursor)
|
local completion_items = util.text_document_completion_list_to_complete_items(data or {})
|
||||||
local _ = log.trace() and log.trace("omnifunc.completion_items", completion_items)
|
local _ = log.trace() and log.trace("omnifunc.completion_items", completion_items)
|
||||||
vim.list_extend(matches, completion_items)
|
vim.list_extend(matches, completion_items)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return matches
|
|
||||||
|
-- Instead of returning matches call complete instead
|
||||||
|
vim.fn.complete(textMatch+1, matches)
|
||||||
|
return {}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -19,21 +19,6 @@ local function npcall(fn, ...)
|
|||||||
return ok_or_nil(pcall(fn, ...))
|
return ok_or_nil(pcall(fn, ...))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Find the longest shared prefix between prefix and word.
|
|
||||||
-- e.g. remove_prefix("123tes", "testing") == "ting"
|
|
||||||
local function remove_prefix(prefix, word)
|
|
||||||
local max_prefix_length = math.min(#prefix, #word)
|
|
||||||
local prefix_length = 0
|
|
||||||
for i = 1, max_prefix_length do
|
|
||||||
local current_line_suffix = prefix:sub(-i)
|
|
||||||
local word_prefix = word:sub(1, i)
|
|
||||||
if current_line_suffix == word_prefix then
|
|
||||||
prefix_length = i
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return word:sub(prefix_length + 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO(ashkan) @performance this could do less copying.
|
-- TODO(ashkan) @performance this could do less copying.
|
||||||
function M.set_lines(lines, A, B, new_lines)
|
function M.set_lines(lines, A, B, new_lines)
|
||||||
-- 0-indexing to 1-indexing
|
-- 0-indexing to 1-indexing
|
||||||
@ -161,15 +146,11 @@ end
|
|||||||
--- Getting vim complete-items with incomplete flag.
|
--- Getting vim complete-items with incomplete flag.
|
||||||
-- @params CompletionItem[], CompletionList or nil (https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
|
-- @params CompletionItem[], CompletionList or nil (https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
|
||||||
-- @return { matches = complete-items table, incomplete = boolean }
|
-- @return { matches = complete-items table, incomplete = boolean }
|
||||||
function M.text_document_completion_list_to_complete_items(result, line_prefix)
|
function M.text_document_completion_list_to_complete_items(result)
|
||||||
local items = M.extract_completion_items(result)
|
local items = M.extract_completion_items(result)
|
||||||
if vim.tbl_isempty(items) then
|
if vim.tbl_isempty(items) then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
-- Only initialize if we have some items.
|
|
||||||
if not line_prefix then
|
|
||||||
line_prefix = M.get_current_line_to_cursor()
|
|
||||||
end
|
|
||||||
|
|
||||||
local matches = {}
|
local matches = {}
|
||||||
|
|
||||||
@ -187,10 +168,8 @@ function M.text_document_completion_list_to_complete_items(result, line_prefix)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local word = completion_item.insertText or completion_item.label
|
local word = completion_item.insertText or completion_item.label
|
||||||
|
|
||||||
-- Ref: `:h complete-items`
|
|
||||||
table.insert(matches, {
|
table.insert(matches, {
|
||||||
word = remove_prefix(line_prefix, word),
|
word = word,
|
||||||
abbr = completion_item.label,
|
abbr = completion_item.label,
|
||||||
kind = protocol.CompletionItemKind[completion_item.kind] or '',
|
kind = protocol.CompletionItemKind[completion_item.kind] or '',
|
||||||
menu = completion_item.detail or '',
|
menu = completion_item.detail or '',
|
||||||
|
Loading…
Reference in New Issue
Block a user