mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	feat(lsp): use vim.ui.select for selecting lsp client (#16782)
				
					
				
			(cherry picked from commit 43cdcba476)
Co-authored-by: Anshuman <amedhi@connect.ust.hk>
			
			
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							571609fb89
						
					
				
				
					commit
					14357c83c5
				
			@@ -116,31 +116,30 @@ end
 | 
			
		||||
--- asks the user to select one.
 | 
			
		||||
--
 | 
			
		||||
---@returns The client that the user selected or nil
 | 
			
		||||
local function select_client(method)
 | 
			
		||||
  local clients = vim.tbl_values(vim.lsp.buf_get_clients());
 | 
			
		||||
  clients = vim.tbl_filter(function (client)
 | 
			
		||||
local function select_client(method, on_choice)
 | 
			
		||||
  validate {
 | 
			
		||||
    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)
 | 
			
		||||
  end, clients)
 | 
			
		||||
  -- 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
 | 
			
		||||
    local choices = {}
 | 
			
		||||
    for k,v in pairs(clients) do
 | 
			
		||||
      table.insert(choices, string.format("%d %s", k, v.name))
 | 
			
		||||
    end
 | 
			
		||||
    local user_choice = vim.fn.confirm(
 | 
			
		||||
      "Select a language server:",
 | 
			
		||||
      table.concat(choices, "\n"),
 | 
			
		||||
      0,
 | 
			
		||||
      "Question"
 | 
			
		||||
    )
 | 
			
		||||
    if user_choice == 0 then return nil end
 | 
			
		||||
    return clients[user_choice]
 | 
			
		||||
    vim.ui.select(clients, {
 | 
			
		||||
      prompt = 'Select a language server:',
 | 
			
		||||
      format_item = function(client)
 | 
			
		||||
        return client.name
 | 
			
		||||
      end,
 | 
			
		||||
    }, on_choice)
 | 
			
		||||
  elseif #clients < 1 then
 | 
			
		||||
    return nil
 | 
			
		||||
    on_choice(nil)
 | 
			
		||||
  else
 | 
			
		||||
    return clients[1]
 | 
			
		||||
    on_choice(clients[1])
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@@ -152,11 +151,15 @@ end
 | 
			
		||||
--
 | 
			
		||||
---@see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting
 | 
			
		||||
function M.formatting(options)
 | 
			
		||||
  local client = select_client("textDocument/formatting")
 | 
			
		||||
  if client == nil then return end
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
--- Performs |vim.lsp.buf.formatting()| synchronously.
 | 
			
		||||
@@ -172,17 +175,20 @@ end
 | 
			
		||||
---@param timeout_ms (number) Request timeout
 | 
			
		||||
---@see |vim.lsp.buf.formatting_seq_sync|
 | 
			
		||||
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 bufnr = vim.api.nvim_get_current_buf()
 | 
			
		||||
  local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
 | 
			
		||||
  if result and result.result then
 | 
			
		||||
    util.apply_text_edits(result.result, bufnr)
 | 
			
		||||
  elseif err then
 | 
			
		||||
    vim.notify("vim.lsp.buf.formatting_sync: " .. err, vim.log.levels.WARN)
 | 
			
		||||
  end
 | 
			
		||||
  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
 | 
			
		||||
      util.apply_text_edits(result.result, bufnr)
 | 
			
		||||
    elseif err then
 | 
			
		||||
      vim.notify('vim.lsp.buf.formatting_sync: ' .. err, vim.log.levels.WARN)
 | 
			
		||||
    end
 | 
			
		||||
  end)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- 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.
 | 
			
		||||
---Defaults to the end of the last visual selection.
 | 
			
		||||
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)
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
--- Renames all references to the symbol under the cursor.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user