From 3adeab2bed42597c8495fbe3a2376c746232f2e3 Mon Sep 17 00:00:00 2001 From: William Boman Date: Wed, 21 Apr 2021 02:48:29 +0200 Subject: [PATCH] fix: support multiple clients in lsp code actions (#722) * fix: support multiple clients in lsp code actions * no goto * reduce diff a bit * use displayer, also include lsp client name for each entry * review comments --- lua/telescope/builtin/git.lua | 2 +- lua/telescope/builtin/lsp.lua | 64 ++++++++++++++++++++++++++++------- lua/telescope/utils.lua | 3 +- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/lua/telescope/builtin/git.lua b/lua/telescope/builtin/git.lua index f7c0096..198abae 100644 --- a/lua/telescope/builtin/git.lua +++ b/lua/telescope/builtin/git.lua @@ -15,7 +15,7 @@ git.files = function(opts) local show_untracked = utils.get_default(opts.show_untracked, true) local recurse_submodules = utils.get_default(opts.recurse_submodules, false) if show_untracked and recurse_submodules then - error("Git does not suppurt both --others and --recurse-submodules") + error("Git does not support both --others and --recurse-submodules") end -- By creating the entry maker after the cwd options, diff --git a/lua/telescope/builtin/lsp.lua b/lua/telescope/builtin/lsp.lua index 285a047..91097ba 100644 --- a/lua/telescope/builtin/lsp.lua +++ b/lua/telescope/builtin/lsp.lua @@ -3,6 +3,7 @@ local action_state = require('telescope.actions.state') local finders = require('telescope.finders') local make_entry = require('telescope.make_entry') local pickers = require('telescope.pickers') +local entry_display = require('telescope.pickers.entry_display') local utils = require('telescope.utils') local a = require('plenary.async_lib') local async, await = a.async, a.await @@ -131,20 +132,56 @@ lsp.code_actions = function(opts) return end - local _, response = next(results_lsp) - if not response then + local idx = 1 + local results = {} + local widths = { + idx = 0, + command_title = 0, + client_name = 0, + } + + for client_id, response in pairs(results_lsp) do + if response.result then + local client = vim.lsp.get_client_by_id(client_id) + + for _, result in pairs(response.result) do + local entry = { + idx = idx, + command_title = result.title, + client_name = client and client.name or "", + command = result, + } + + for key, value in pairs(widths) do + widths[key] = math.max(value, utils.strdisplaywidth(entry[key])) + end + + table.insert(results, entry) + idx = idx + 1 + end + end + end + + if #results == 0 then print("No code actions available") return end - local results = response.result - if not results or #results == 0 then - print("No code actions available") - return - end + local displayer = entry_display.create { + separator = " ", + items = { + { width = widths.idx + 1 }, -- +1 for ":" suffix + { width = widths.command_title }, + { width = widths.client_name }, + }, + } - for i,x in ipairs(results) do - x.idx = i + local function make_display(entry) + return displayer { + {entry.idx .. ":", "TelescopePromptPrefix"}, + {entry.command_title}, + {entry.client_name, "TelescopeResultsComment"}, + } end pickers.new(opts, { @@ -154,9 +191,12 @@ lsp.code_actions = function(opts) entry_maker = function(line) return { valid = line ~= nil, - value = line, - ordinal = line.idx .. line.title, - display = line.idx .. ': ' .. line.title + value = line.command, + ordinal = line.idx .. line.command_title, + command_title = line.command_title, + idx = line.idx, + client_name = line.client_name, + display = make_display, } end }, diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua index 4e8c1d3..85e8723 100644 --- a/lua/telescope/utils.lua +++ b/lua/telescope/utils.lua @@ -259,13 +259,14 @@ utils.strdisplaywidth = (function() return function(str, col) local startcol = col or 0 + str = tostring(str) local s = ffi.new('char[?]', #str + 1) ffi.copy(s, str) return ffi.C.linetabsize_col(startcol, s) - startcol end else return function(str, col) - return #str - (col or 0) + return #(tostring(str)) - (col or 0) end end end)()