feat(lsp): use vim.ui.select for selecting lsp client

This commit is contained in:
Anshuman 2021-12-05 17:24:00 +08:00
parent afaad8b54e
commit 43cdcba476

View File

@ -116,31 +116,30 @@ end
--- asks the user to select one. --- asks the user to select one.
-- --
---@returns The client that the user selected or nil ---@returns The client that the user selected or nil
local function select_client(method) local function select_client(method, on_choice)
local clients = vim.tbl_values(vim.lsp.buf_get_clients()); validate {
clients = vim.tbl_filter(function (client) on_choice = { on_choice, 'function', false },
}
local clients = vim.tbl_values(vim.lsp.buf_get_clients())
clients = vim.tbl_filter(function(client)
return client.supports_method(method) return client.supports_method(method)
end, clients) end, clients)
-- better UX when choices are always in the same order (between restarts) -- better UX when choices are always in the same order (between restarts)
table.sort(clients, function (a, b) return a.name < b.name end) table.sort(clients, function(a, b)
return a.name < b.name
end)
if #clients > 1 then if #clients > 1 then
local choices = {} vim.ui.select(clients, {
for k,v in pairs(clients) do prompt = 'Select a language server:',
table.insert(choices, string.format("%d %s", k, v.name)) format_item = function(client)
end return client.name
local user_choice = vim.fn.confirm( end,
"Select a language server:", }, on_choice)
table.concat(choices, "\n"),
0,
"Question"
)
if user_choice == 0 then return nil end
return clients[user_choice]
elseif #clients < 1 then elseif #clients < 1 then
return nil on_choice(nil)
else else
return clients[1] on_choice(clients[1])
end end
end end
@ -152,11 +151,15 @@ end
-- --
---@see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting ---@see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
function M.formatting(options) function M.formatting(options)
local client = select_client("textDocument/formatting")
if client == nil then return end
local params = util.make_formatting_params(options) local params = util.make_formatting_params(options)
return client.request("textDocument/formatting", params, nil, vim.api.nvim_get_current_buf()) local bufnr = vim.api.nvim_get_current_buf()
select_client('textDocument/formatting', function(client)
if client == nil then
return
end
return client.request('textDocument/formatting', params, nil, bufnr)
end)
end end
--- Performs |vim.lsp.buf.formatting()| synchronously. --- Performs |vim.lsp.buf.formatting()| synchronously.
@ -172,17 +175,20 @@ end
---@param timeout_ms (number) Request timeout ---@param timeout_ms (number) Request timeout
---@see |vim.lsp.buf.formatting_seq_sync| ---@see |vim.lsp.buf.formatting_seq_sync|
function M.formatting_sync(options, timeout_ms) function M.formatting_sync(options, timeout_ms)
local client = select_client("textDocument/formatting")
if client == nil then return end
local params = util.make_formatting_params(options) local params = util.make_formatting_params(options)
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr) select_client('textDocument/formatting', function(client)
if client == nil then
return
end
local result, err = client.request_sync('textDocument/formatting', params, timeout_ms, bufnr)
if result and result.result then if result and result.result then
util.apply_text_edits(result.result, bufnr) util.apply_text_edits(result.result, bufnr)
elseif err then elseif err then
vim.notify("vim.lsp.buf.formatting_sync: " .. err, vim.log.levels.WARN) vim.notify('vim.lsp.buf.formatting_sync: ' .. err, vim.log.levels.WARN)
end end
end)
end end
--- Formats the current buffer by sequentially requesting formatting from attached clients. --- Formats the current buffer by sequentially requesting formatting from attached clients.
@ -238,12 +244,15 @@ end
---@param end_pos ({number, number}, optional) mark-indexed position. ---@param end_pos ({number, number}, optional) mark-indexed position.
---Defaults to the end of the last visual selection. ---Defaults to the end of the last visual selection.
function M.range_formatting(options, start_pos, end_pos) function M.range_formatting(options, start_pos, end_pos)
local client = select_client("textDocument/rangeFormatting")
if client == nil then return end
local params = util.make_given_range_params(start_pos, end_pos) local params = util.make_given_range_params(start_pos, end_pos)
params.options = util.make_formatting_params(options).options params.options = util.make_formatting_params(options).options
return client.request("textDocument/rangeFormatting", params) select_client('textDocument/rangeFormatting', function(client)
if client == nil then
return
end
return client.request('textDocument/rangeFormatting', params)
end)
end end
--- Renames all references to the symbol under the cursor. --- Renames all references to the symbol under the cursor.