From ee7ac469c6f0f15a2d75991ef053a18d93e01756 Mon Sep 17 00:00:00 2001 From: Ashkan Kiani Date: Fri, 20 Dec 2019 22:49:29 -0800 Subject: [PATCH] LSP: Use async completion for omnifunc. (#11578) --- runtime/lua/vim/lsp.lua | 49 +++++++++++++------------------ runtime/lua/vim/lsp/callbacks.lua | 5 ++-- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 501cc6f670..0ecf57f50c 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -858,39 +858,30 @@ function lsp.omnifunc(findstart, base) end end - if findstart == 1 then - -- First, just return the current cursor column, we only really need that - return vim.fn.col('.') - else - -- Then, perform standard completion request - log.info("base ", base) + -- Then, perform standard completion request + local _ = log.info() and log.info("base ", base) - local pos = vim.api.nvim_win_get_cursor(0) - 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 pos = vim.api.nvim_win_get_cursor(0) + 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) - -- Get the start postion of the current keyword - local textMatch = vim.fn.match(line_to_cursor, '\\k*$') - local params = util.make_position_params() + -- Get the start postion of the current keyword + local textMatch = vim.fn.match(line_to_cursor, '\\k*$') + local params = util.make_position_params() - -- TODO handle timeout error differently? Like via an error? - local client_responses = lsp.buf_request_sync(bufnr, 'textDocument/completion', params) or {} - local matches = {} - for _, response in pairs(client_responses) do - -- TODO how to handle errors? - if not response.error then - local data = response.result - local completion_items = util.text_document_completion_list_to_complete_items(data or {}) - local _ = log.trace() and log.trace("omnifunc.completion_items", completion_items) - vim.list_extend(matches, completion_items) - end - end + 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) + -- TODO(ashkan): is this the best way to do this? + vim.list_extend(items, matches) + vim.fn.complete(textMatch+1, items) + end) - -- Instead of returning matches call complete instead - vim.fn.complete(textMatch+1, matches) - return {} - end + -- Return -2 to signal that we should continue completion so that we can + -- async complete. + return -2 end function lsp.client_is_stopped(client_id) diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua index a3cd521b86..794140ee2e 100644 --- a/runtime/lua/vim/lsp/callbacks.lua +++ b/runtime/lua/vim/lsp/callbacks.lua @@ -62,9 +62,10 @@ M['textDocument/completion'] = function(_, _, result) local row, col = unpack(api.nvim_win_get_cursor(0)) 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 matches = util.text_document_completion_list_to_complete_items(result, line_to_cursor) - vim.fn.complete(col, matches) + local matches = util.text_document_completion_list_to_complete_items(result) + vim.fn.complete(textMatch+1, matches) end M['textDocument/hover'] = function(_, method, result)