diff options
Diffstat (limited to 'runtime/lua/vim/lsp/handlers.lua')
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 86 |
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) |