diff options
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 19 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 63 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 59 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 5 |
4 files changed, 108 insertions, 38 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index ced1747ee0..29f8d6c3bc 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -422,6 +422,21 @@ function M.clear_references() util.buf_clear_references() end +--- Requests code actions from all clients and calls the handler exactly once +--- with all aggregated results +--@private +local function code_action_request(params) + local bufnr = vim.api.nvim_get_current_buf() + local method = 'textDocument/codeAction' + vim.lsp.buf_request_all(bufnr, method, params, function(results) + local actions = {} + for _, r in pairs(results) do + vim.list_extend(actions, r.result or {}) + end + vim.lsp.handlers[method](nil, method, actions, nil, bufnr) + end) +end + --- Selects a code action from the input list that is available at the current --- cursor position. -- @@ -432,7 +447,7 @@ function M.code_action(context) context = context or { diagnostics = vim.lsp.diagnostic.get_line_diagnostics() } local params = util.make_range_params() params.context = context - request('textDocument/codeAction', params) + code_action_request(params) end --- Performs |vim.lsp.buf.code_action()| for a given range. @@ -447,7 +462,7 @@ function M.range_code_action(context, start_pos, end_pos) context = context or { diagnostics = vim.lsp.diagnostic.get_line_diagnostics() } local params = util.make_given_range_params(start_pos, end_pos) params.context = context - request('textDocument/codeAction', params) + code_action_request(params) end --- Executes an LSP server command. diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 1342df529f..9a97e5db2f 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -208,6 +208,9 @@ local diagnostic_cache_lines = setmetatable({}, bufnr_and_client_cacher_mt) local diagnostic_cache_counts = setmetatable({}, bufnr_and_client_cacher_mt) local diagnostic_attached_buffers = {} +-- Disabled buffers and clients +local diagnostic_disabled = setmetatable({}, bufnr_and_client_cacher_mt) + local _bufs_waiting_to_update = setmetatable({}, bufnr_and_client_cacher_mt) --- Store Diagnostic[] by line @@ -816,10 +819,7 @@ end ---@param diagnostic_ns number|nil Associated diagnostic namespace ---@param sign_ns number|nil Associated sign namespace function M.clear(bufnr, client_id, diagnostic_ns, sign_ns) - validate { bufnr = { bufnr, 'n' } } - - bufnr = (bufnr == 0 and api.nvim_get_current_buf()) or bufnr - + bufnr = get_bufnr(bufnr) if client_id == nil then return vim.lsp.for_each_buffer_client(bufnr, function(_, iter_client_id, _) return M.clear(bufnr, iter_client_id) @@ -1092,6 +1092,10 @@ end --@private --- Display diagnostics for the buffer, given a configuration. function M.display(diagnostics, bufnr, client_id, config) + if diagnostic_disabled[bufnr][client_id] then + return + end + config = vim.lsp._with_extend('vim.lsp.diagnostic.on_publish_diagnostics', { signs = true, underline = true, @@ -1282,6 +1286,57 @@ function M.set_loclist(opts) vim.cmd [[lopen]] end end + +--- Disable diagnostics for the given buffer and client +--- @param bufnr (optional, number): Buffer handle, defaults to current +--- @param client_id (optional, number): Disable diagnostics for the given +--- client. The default is to disable diagnostics for all attached +--- clients. +-- Note that when diagnostics are disabled for a buffer, the server will still +-- send diagnostic information and the client will still process it. The +-- diagnostics are simply not displayed to the user. +function M.disable(bufnr, client_id) + if not client_id then + return vim.lsp.for_each_buffer_client(bufnr, function(client) + M.disable(bufnr, client.id) + end) + end + + diagnostic_disabled[bufnr][client_id] = true + M.clear(bufnr, client_id) +end + +--- Enable diagnostics for the given buffer and client +--- @param bufnr (optional, number): Buffer handle, defaults to current +--- @param client_id (optional, number): Enable diagnostics for the given +--- client. The default is to enable diagnostics for all attached +--- clients. +function M.enable(bufnr, client_id) + if not client_id then + return vim.lsp.for_each_buffer_client(bufnr, function(client) + M.enable(bufnr, client.id) + end) + end + + if not diagnostic_disabled[bufnr][client_id] then + return + end + + diagnostic_disabled[bufnr][client_id] = nil + + -- We need to invoke the publishDiagnostics handler directly instead of just + -- calling M.display so that we can preserve any custom configuration options + -- the user may have set with vim.lsp.with. + vim.lsp.handlers["textDocument/publishDiagnostics"]( + nil, + "textDocument/publishDiagnostics", + { + diagnostics = M.get(bufnr, client_id), + uri = vim.uri_from_bufnr(bufnr), + }, + client_id + ) +end -- }}} return M diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 797ff762cb..acd20a3e0b 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -17,13 +17,12 @@ local function err_message(...) api.nvim_command("redraw") end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand M['workspace/executeCommand'] = function() -- Error handling is done implicitly by wrapping all handlers; see end of this file end --- @msg of type ProgressParams --- Basically a token of type number/string +--@private local function progress_handler(_, _, params, client_id) local client = vim.lsp.get_client_by_id(client_id) local client_name = client and client.name or string.format("id=%d", client_id) @@ -59,10 +58,10 @@ local function progress_handler(_, _, params, client_id) vim.api.nvim_command("doautocmd <nomodeline> User LspProgressUpdate") end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress M['$/progress'] = progress_handler ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_workDoneProgress_create +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_workDoneProgress_create M['window/workDoneProgress/create'] = function(_, _, params, client_id) local client = vim.lsp.get_client_by_id(client_id) local token = params.token -- string or number @@ -74,7 +73,7 @@ M['window/workDoneProgress/create'] = function(_, _, params, client_id) return vim.NIL end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest M['window/showMessageRequest'] = function(_, _, params) local actions = params.actions @@ -95,7 +94,7 @@ M['window/showMessageRequest'] = function(_, _, params) end end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#client_registerCapability M['client/registerCapability'] = function(_, _, _, client_id) local warning_tpl = "The language server %s triggers a registerCapability ".. "handler despite dynamicRegistration set to false. ".. @@ -107,7 +106,7 @@ M['client/registerCapability'] = function(_, _, _, client_id) return vim.NIL end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction M['textDocument/codeAction'] = function(_, _, actions) if actions == nil or vim.tbl_isempty(actions) then print("No code actions available") @@ -141,7 +140,7 @@ M['textDocument/codeAction'] = function(_, _, actions) end end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit M['workspace/applyEdit'] = function(_, _, workspace_edit) if not workspace_edit then return end -- TODO(ashkan) Do something more with label? @@ -155,7 +154,7 @@ M['workspace/applyEdit'] = function(_, _, workspace_edit) } end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_configuration +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_configuration M['workspace/configuration'] = function(_, _, params, client_id) local client = vim.lsp.get_client_by_id(client_id) if not client then @@ -207,34 +206,34 @@ local function response_to_qflist(map_result, entity) end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references +--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 +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol 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 +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_symbol M['workspace/symbol'] = response_to_qflist(util.symbols_to_items, 'symbols') ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename M['textDocument/rename'] = function(_, _, result) if not result then return end util.apply_workspace_edit(result) end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rangeFormatting +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rangeFormatting M['textDocument/rangeFormatting'] = function(_, _, result, _, bufnr) if not result then return end util.apply_text_edits(result, bufnr) end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting M['textDocument/formatting'] = function(_, _, result, _, bufnr) if not result then return end util.apply_text_edits(result, bufnr) end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion M['textDocument/completion'] = function(_, _, result) if vim.tbl_isempty(result or {}) then return end local row, col = unpack(api.nvim_win_get_cursor(0)) @@ -276,7 +275,7 @@ function M.hover(_, method, result, _, _, config) return util.open_floating_preview(markdown_lines, "markdown", config) end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover M['textDocument/hover'] = M.hover --@private @@ -306,17 +305,17 @@ local function location_handler(_, method, result) end end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration M['textDocument/declaration'] = location_handler ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition M['textDocument/definition'] = location_handler ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_typeDefinition +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_typeDefinition M['textDocument/typeDefinition'] = location_handler ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_implementation +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_implementation M['textDocument/implementation'] = location_handler ---- |lsp-handler| for the method "textDocument/signatureHelp" ---- The active parameter is highlighted with |hl-LspSignatureActiveParameter| +--- |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, { @@ -358,10 +357,10 @@ function M.signature_help(_, method, result, client_id, bufnr, config) return fbuf, fwin end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp M['textDocument/signatureHelp'] = M.signature_help ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentHighlight +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentHighlight M['textDocument/documentHighlight'] = function(_, _, result, _, bufnr, _) if not result then return end util.buf_highlight_references(bufnr, result) @@ -394,13 +393,13 @@ local make_call_hierarchy_handler = function(direction) end end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy/incomingCalls +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_incomingCalls M['callHierarchy/incomingCalls'] = make_call_hierarchy_handler('from') ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy/outgoingCalls +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#callHierarchy_outgoingCalls M['callHierarchy/outgoingCalls'] = make_call_hierarchy_handler('to') ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window/logMessage +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_logMessage M['window/logMessage'] = function(_, _, result, client_id) local message_type = result.type local message = result.message @@ -421,7 +420,7 @@ M['window/logMessage'] = function(_, _, result, client_id) return result end ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window/showMessage +--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessage M['window/showMessage'] = function(_, _, result, client_id) local message_type = result.type local message = result.message diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index f047a12dff..dc15d67e1c 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -990,6 +990,7 @@ function M.make_floating_popup_options(width, height, opts) style = 'minimal', width = width, border = opts.border or default_border, + zindex = opts.zindex or 50, } end @@ -1868,10 +1869,10 @@ function M.get_effective_tabstop(bufnr) return (sts > 0 and sts) or (sts < 0 and bo.shiftwidth) or bo.tabstop end ---- Creates a `FormattingOptions` object for the current buffer and cursor position. +--- Creates a `DocumentFormattingParams` object for the current buffer and cursor position. --- --@param options Table with valid `FormattingOptions` entries ---@returns `FormattingOptions object +--@returns `DocumentFormattingParams` object --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting function M.make_formatting_params(options) validate { options = {options, 't', true} } |