From ba6761eafe615a7f904c585dba3b7d6e98f665e1 Mon Sep 17 00:00:00 2001 From: Lajos Koszti Date: Thu, 26 Oct 2023 22:40:36 +0200 Subject: [PATCH] fix(lsp): fix omnicomplete in middle of the line (#25787) Fixes a regression from 5e5f5174e3faa862a9bc353aa7da41487911140b Until that commit we had a logic like this: `local prefix = startbyte and line:sub(startbyte + 1) or line_to_cursor:sub(word_boundary)` The commit changed the logic and no longer cut off the line at the cursor, resulting in a prefix that included trailing characters --- runtime/lua/vim/lsp/_completion.lua | 4 +- .../functional/plugin/lsp/completion_spec.lua | 58 ++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/runtime/lua/vim/lsp/_completion.lua b/runtime/lua/vim/lsp/_completion.lua index f0e3af7f03..7a607d6c13 100644 --- a/runtime/lua/vim/lsp/_completion.lua +++ b/runtime/lua/vim/lsp/_completion.lua @@ -137,6 +137,7 @@ end function M._convert_results( line, lnum, + cursor_col, client_start_boundary, server_start_boundary, result, @@ -164,7 +165,7 @@ function M._convert_results( elseif curstartbyte ~= nil and curstartbyte ~= server_start_boundary then server_start_boundary = client_start_boundary end - local prefix = line:sub((server_start_boundary or client_start_boundary) + 1) + local prefix = line:sub((server_start_boundary or client_start_boundary) + 1, cursor_col) local matches = M._lsp_to_complete_items(result, prefix) return matches, server_start_boundary end @@ -212,6 +213,7 @@ function M.omnifunc(findstart, base) matches, server_start_boundary = M._convert_results( line, lnum, + cursor_col, client_start_boundary, server_start_boundary, result, diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index aa13d6f4b1..9354654afe 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -12,7 +12,8 @@ local exec_lua = helpers.exec_lua ---@return {items: table[], server_start_boundary: integer?} local function complete(line, candidates, lnum) lnum = lnum or 0 - local cursor_col = line:find("|") + -- nvim_win_get_cursor returns 0 based column, line:find returns 1 based + local cursor_col = line:find("|") - 1 line = line:gsub("|", "") return exec_lua([[ local line, cursor_col, lnum, result = ... @@ -21,6 +22,7 @@ local function complete(line, candidates, lnum) local items, server_start_boundary = require("vim.lsp._completion")._convert_results( line, lnum, + cursor_col, client_start_boundary, nil, result, @@ -180,4 +182,58 @@ describe("vim.lsp._completion", function() item.user_data = nil eq(expected, item) end) + + it("should search from start boundary to cursor position", function() + local completion_list = { + isIncomplete = false, + items = { + { + filterText = "this_thread", + insertText = "this_thread", + insertTextFormat = 1, + kind = 9, + label = " this_thread", + score = 1.3205767869949, + sortText = "4056f757this_thread", + textEdit = { + newText = "this_thread", + range = { + start = { line = 0, character = 7 }, + ["end"] = { line = 0, character = 11 }, + }, + } + }, + { + filterText = "notthis_thread", + insertText = "notthis_thread", + insertTextFormat = 1, + kind = 9, + label = " notthis_thread", + score = 1.3205767869949, + sortText = "4056f757this_thread", + textEdit = { + newText = "notthis_thread", + range = { + start = { line = 0, character = 7 }, + ["end"] = { line = 0, character = 11 }, + }, + } + }, + } + } + local expected = { + abbr = ' this_thread', + dup = 1, + empty = 1, + icase = 1, + kind = 'Module', + menu = '', + word = 'this_thread', + } + local result = complete(" std::this|is", completion_list) + eq(1, #result.items) + local item = result.items[1] + item.user_data = nil + eq(expected, item) + end) end)