mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	Merge pull request #14115 from mfussenegger/lsp-commands
lsp: Add a registry for client side code action commands
This commit is contained in:
		@@ -896,7 +896,7 @@ function lsp.start_client(config)
 | 
			
		||||
 | 
			
		||||
    local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, handler, bufnr)
 | 
			
		||||
    return rpc.request(method, params, function(err, result)
 | 
			
		||||
      handler(err, result, {method=method, client_id=client_id, bufnr=bufnr})
 | 
			
		||||
      handler(err, result, {method=method, client_id=client_id, bufnr=bufnr, params=params})
 | 
			
		||||
    end)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
@@ -1534,5 +1534,34 @@ function lsp._with_extend(name, options, user_config)
 | 
			
		||||
  return resulting_config
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
--- Registry for client side commands.
 | 
			
		||||
--- This is an extension point for plugins to handle custom commands which are
 | 
			
		||||
--- not part of the core language server protocol specification.
 | 
			
		||||
---
 | 
			
		||||
--- The registry is a table where the key is a unique command name,
 | 
			
		||||
--- and the value is a function which is called if any LSP action
 | 
			
		||||
--- (code action, code lenses, ...) triggers the command.
 | 
			
		||||
---
 | 
			
		||||
--- If a LSP response contains a command for which no matching entry is
 | 
			
		||||
--- available in this registry, the command will be executed via the LSP server
 | 
			
		||||
--- using `workspace/executeCommand`.
 | 
			
		||||
---
 | 
			
		||||
--- The first argument to the function will be the `Command`:
 | 
			
		||||
--    Command
 | 
			
		||||
--      title: String
 | 
			
		||||
--      command: String
 | 
			
		||||
--      arguments?: any[]
 | 
			
		||||
--
 | 
			
		||||
--- The second argument is the `ctx` of |lsp-handler|
 | 
			
		||||
lsp.commands = setmetatable({}, {
 | 
			
		||||
  __newindex = function(tbl, key, value)
 | 
			
		||||
    assert(type(key) == 'string', "The key for commands in `vim.lsp.commands` must be a string")
 | 
			
		||||
    assert(type(value) == 'function', "Command added to `vim.lsp.commands` must be a function")
 | 
			
		||||
    rawset(tbl, key, value)
 | 
			
		||||
  end;
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
return lsp
 | 
			
		||||
-- vim:sw=2 ts=2 et
 | 
			
		||||
 
 | 
			
		||||
@@ -110,7 +110,7 @@ M['client/registerCapability'] = function(_, _, ctx)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
 | 
			
		||||
M['textDocument/codeAction'] = function(_, result)
 | 
			
		||||
M['textDocument/codeAction'] = function(_, result, ctx)
 | 
			
		||||
  if result == nil or vim.tbl_isempty(result) then
 | 
			
		||||
    print("No code actions available")
 | 
			
		||||
    return
 | 
			
		||||
@@ -127,19 +127,28 @@ M['textDocument/codeAction'] = function(_, result)
 | 
			
		||||
  if choice < 1 or choice > #result then
 | 
			
		||||
    return
 | 
			
		||||
  end
 | 
			
		||||
  local action_chosen = result[choice]
 | 
			
		||||
  -- textDocument/codeAction can return either Command[] or CodeAction[].
 | 
			
		||||
  -- If it is a CodeAction, it can have either an edit, a command or both.
 | 
			
		||||
  -- Edits should be executed first
 | 
			
		||||
  if action_chosen.edit or type(action_chosen.command) == "table" then
 | 
			
		||||
    if action_chosen.edit then
 | 
			
		||||
      util.apply_workspace_edit(action_chosen.edit)
 | 
			
		||||
    end
 | 
			
		||||
    if type(action_chosen.command) == "table" then
 | 
			
		||||
      buf.execute_command(action_chosen.command)
 | 
			
		||||
    end
 | 
			
		||||
  local action = result[choice]
 | 
			
		||||
  -- textDocument/codeAction can return either Command[] or CodeAction[]
 | 
			
		||||
  --
 | 
			
		||||
  -- CodeAction
 | 
			
		||||
  --  ...
 | 
			
		||||
  --  edit?: WorkspaceEdit    -- <- must be applied before command
 | 
			
		||||
  --  command?: Command
 | 
			
		||||
  --
 | 
			
		||||
  -- Command:
 | 
			
		||||
  --  title: string
 | 
			
		||||
  --  command: string
 | 
			
		||||
  --  arguments?: any[]
 | 
			
		||||
  --
 | 
			
		||||
  if action.edit then
 | 
			
		||||
    util.apply_workspace_edit(action.edit)
 | 
			
		||||
  end
 | 
			
		||||
  local command = type(action.command) == 'table' and action.command or action
 | 
			
		||||
  local fn = vim.lsp.commands[command.command]
 | 
			
		||||
  if fn then
 | 
			
		||||
    fn(command, ctx)
 | 
			
		||||
  else
 | 
			
		||||
    buf.execute_command(action_chosen)
 | 
			
		||||
    buf.execute_command(command)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user