diff options
author | glepnir <glephunter@gmail.com> | 2024-08-23 03:42:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-22 21:42:27 +0200 |
commit | 1f5bcc7c4ed7a68ae4e23933aee04c50b4df8bb5 (patch) | |
tree | 49e13c9e7bbb791055fcd858482fb8cee8911560 | |
parent | e48179f31e6503bfa86bf08538e64456e96446a8 (diff) | |
download | rneovim-1f5bcc7c4ed7a68ae4e23933aee04c50b4df8bb5.tar.gz rneovim-1f5bcc7c4ed7a68ae4e23933aee04c50b4df8bb5.tar.bz2 rneovim-1f5bcc7c4ed7a68ae4e23933aee04c50b4df8bb5.zip |
feat(lsp): completion opts support custom item conversion (#30060)
Problem: Some items of completion results include function signatures that can
cause the pum to be very long when a function has many params, because pum
scales with the longest word/abbr.
Solution: add custom covert function that can customise abbr to remove params.
-rw-r--r-- | runtime/doc/lsp.txt | 3 | ||||
-rw-r--r-- | runtime/doc/news.txt | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/completion.lua | 16 | ||||
-rw-r--r-- | test/functional/plugin/lsp/completion_spec.lua | 21 |
4 files changed, 38 insertions, 6 deletions
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 32d414e9a7..05734c3ac1 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1630,6 +1630,9 @@ Lua module: vim.lsp.completion *lsp-completion* Fields: ~ • {autotrigger}? (`boolean`) Whether to trigger completion automatically. Default: false + • {convert}? (`fun(item: lsp.CompletionItem): table`) An optional + function used to customize the transformation of an + LSP CompletionItem to |complete-items|. *vim.lsp.completion.enable()* diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 7c842f42dd..1d1e87fd0b 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -65,7 +65,9 @@ EVENTS LSP -• TODO +• Add convert field in |vim.lsp.completion.BufferOpts| of + |vim.lsp.completion.enable()| an optional function used to customize the + transformation of an Lsp CompletionItem to |complete-items|. LUA diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 022edf5fab..89d9a0e9b1 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -23,6 +23,7 @@ local ns_to_ms = 0.000001 --- @class vim.lsp.completion.BufHandle --- @field clients table<integer, vim.lsp.Client> --- @field triggers table<string, vim.lsp.Client[]> +--- @field convert? fun(item: lsp.CompletionItem): table --- @type table<integer, vim.lsp.completion.BufHandle> local buf_handles = {} @@ -250,6 +251,8 @@ function M._lsp_to_complete_items(result, prefix, client_id) end local candidates = {} + local bufnr = api.nvim_get_current_buf() + 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) @@ -260,7 +263,7 @@ function M._lsp_to_complete_items(result, prefix, client_id) then hl_group = 'DiagnosticDeprecated' end - table.insert(candidates, { + local completion_item = { word = word, abbr = item.label, kind = protocol.CompletionItemKind[item.kind] or 'Unknown', @@ -278,7 +281,11 @@ function M._lsp_to_complete_items(result, prefix, client_id) }, }, }, - }) + } + if user_convert then + completion_item = vim.tbl_extend('keep', user_convert(item), completion_item) + end + table.insert(candidates, completion_item) end end ---@diagnostic disable-next-line: no-unknown @@ -590,14 +597,15 @@ end --- @class vim.lsp.completion.BufferOpts --- @field autotrigger? boolean Whether to trigger completion automatically. Default: false +--- @field convert? fun(item: lsp.CompletionItem): table An optional function used to customize the transformation of an LSP CompletionItem to |complete-items|. ---- @param client_id integer +---@param client_id integer ---@param bufnr integer ---@param opts vim.lsp.completion.BufferOpts local function enable_completions(client_id, bufnr, opts) local buf_handle = buf_handles[bufnr] if not buf_handle then - buf_handle = { clients = {}, triggers = {} } + buf_handle = { clients = {}, triggers = {}, convert = opts.convert } buf_handles[bufnr] = buf_handle -- Attach to buffer events. diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index aad7e350ee..766dd16541 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -495,7 +495,9 @@ describe('vim.lsp.completion: protocol', function() bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) return vim.lsp.start({ name = 'dummy', cmd = server.cmd, on_attach = function(client, bufnr) - vim.lsp.completion.enable(true, client.id, bufnr) + vim.lsp.completion.enable(true, client.id, bufnr, { convert = function(item) + return { abbr = item.label:gsub('%b()', '')} + end}) end}) ]], completion_result @@ -700,4 +702,21 @@ describe('vim.lsp.completion: protocol', function() eq(true, exec_lua('return _G.called')) end) end) + + it('custom word/abbar format', function() + create_server({ + isIncomplete = false, + items = { + { + label = 'foo(bar)', + }, + }, + }) + + feed('ifo') + trigger_at_pos({ 1, 1 }) + assert_matches(function(matches) + eq('foo', matches[1].abbr) + end) + end) end) |