aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r--runtime/lua/vim/lsp/buf.lua19
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua63
-rw-r--r--runtime/lua/vim/lsp/handlers.lua59
-rw-r--r--runtime/lua/vim/lsp/util.lua5
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} }