aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/handlers.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/lsp/handlers.lua')
-rw-r--r--runtime/lua/vim/lsp/handlers.lua86
1 files changed, 51 insertions, 35 deletions
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 41852b9d88..797ff762cb 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -18,10 +18,8 @@ local function err_message(...)
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
-M['workspace/executeCommand'] = function(err, _)
- if err then
- error("Could not execute code action: "..err.message)
- end
+M['workspace/executeCommand'] = function()
+ -- Error handling is done implicitly by wrapping all handlers; see end of this file
end
-- @msg of type ProgressParams
@@ -158,13 +156,12 @@ M['workspace/applyEdit'] = function(_, _, workspace_edit)
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_configuration
-M['workspace/configuration'] = function(err, _, params, client_id)
+M['workspace/configuration'] = function(_, _, params, client_id)
local client = vim.lsp.get_client_by_id(client_id)
if not client then
err_message("LSP[id=", client_id, "] client has shut down after sending the message")
return
end
- if err then error(vim.inspect(err)) end
if not params.items then
return {}
end
@@ -191,30 +188,33 @@ M['textDocument/codeLens'] = function(...)
return require('vim.lsp.codelens').on_codelens(...)
end
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
-M['textDocument/references'] = function(_, _, result)
- if not result then return end
- util.set_qflist(util.locations_to_items(result))
- api.nvim_command("copen")
-end
---@private
---- Prints given list of symbols to the quickfix list.
---@param _ (not used)
---@param _ (not used)
---@param result (list of Symbols) LSP method name
---@param result (table) result of LSP method; a location or a list of locations.
----(`textDocument/definition` can return `Location` or `Location[]`
-local symbol_handler = function(_, _, result, _, bufnr)
- if not result or vim.tbl_isempty(result) then return end
- util.set_qflist(util.symbols_to_items(result, bufnr))
- api.nvim_command("copen")
+--@private
+--- Return a function that converts LSP responses to quickfix items and opens the qflist
+--
+--@param map_result function `((resp, bufnr) -> list)` to convert the response
+--@param entity name of the resource used in a `not found` error message
+local function response_to_qflist(map_result, entity)
+ return function(_, _, result, _, bufnr)
+ if not result or vim.tbl_isempty(result) then
+ vim.notify('No ' .. entity .. ' found')
+ else
+ util.set_qflist(map_result(result, bufnr))
+ api.nvim_command("copen")
+ end
+ end
end
+
+
+--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
+M['textDocument/references'] = response_to_qflist(util.locations_to_items, 'references')
+
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol
-M['textDocument/documentSymbol'] = symbol_handler
+M['textDocument/documentSymbol'] = response_to_qflist(util.symbols_to_items, 'document symbols')
+
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_symbol
-M['workspace/symbol'] = symbol_handler
+M['workspace/symbol'] = response_to_qflist(util.symbols_to_items, 'symbols')
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename
M['textDocument/rename'] = function(_, _, result)
@@ -223,15 +223,15 @@ M['textDocument/rename'] = function(_, _, result)
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rangeFormatting
-M['textDocument/rangeFormatting'] = function(_, _, result)
+M['textDocument/rangeFormatting'] = function(_, _, result, _, bufnr)
if not result then return end
- util.apply_text_edits(result)
+ util.apply_text_edits(result, bufnr)
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting
-M['textDocument/formatting'] = function(_, _, result)
+M['textDocument/formatting'] = function(_, _, result, _, bufnr)
if not result then return end
- util.apply_text_edits(result)
+ util.apply_text_edits(result, bufnr)
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion
@@ -316,6 +316,7 @@ M['textDocument/typeDefinition'] = location_handler
M['textDocument/implementation'] = location_handler
--- |lsp-handler| for the method "textDocument/signatureHelp"
+--- The active parameter is highlighted with |hl-LspSignatureActiveParameter|
--- <pre>
--- vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(
--- vim.lsp.handlers.signature_help, {
@@ -328,23 +329,33 @@ M['textDocument/implementation'] = location_handler
--- - border: (default=nil)
--- - Add borders to the floating window
--- - See |vim.api.nvim_open_win()|
-function M.signature_help(_, method, result, _, bufnr, config)
+function M.signature_help(_, method, result, client_id, bufnr, config)
config = config or {}
config.focus_id = method
-- When use `autocmd CompleteDone <silent><buffer> lua vim.lsp.buf.signature_help()` to call signatureHelp handler
-- If the completion item doesn't have signatures It will make noise. Change to use `print` that can use `<silent>` to ignore
if not (result and result.signatures and result.signatures[1]) then
- print('No signature help available')
+ if config.silent ~= true then
+ print('No signature help available')
+ end
return
end
+ local client = vim.lsp.get_client_by_id(client_id)
+ local triggers = client.resolved_capabilities.signature_help_trigger_characters
local ft = api.nvim_buf_get_option(bufnr, 'filetype')
- local lines = util.convert_signature_help_to_markdown_lines(result, ft)
+ local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft, triggers)
lines = util.trim_empty_lines(lines)
if vim.tbl_isempty(lines) then
- print('No signature help available')
+ if config.silent ~= true then
+ print('No signature help available')
+ end
return
end
- return util.open_floating_preview(lines, "markdown", config)
+ local fbuf, fwin = util.open_floating_preview(lines, "markdown", config)
+ if hl then
+ api.nvim_buf_add_highlight(fbuf, -1, "LspSignatureActiveParameter", 0, unpack(hl))
+ end
+ return fbuf, fwin
end
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp
@@ -436,7 +447,12 @@ for k, fn in pairs(M) do
})
if err then
- return err_message(tostring(err))
+ -- LSP spec:
+ -- interface ResponseError:
+ -- code: integer;
+ -- message: string;
+ -- data?: string | number | boolean | array | object | null;
+ return err_message(tostring(err.code) .. ': ' .. err.message)
end
return fn(err, method, params, client_id, bufnr, config)