aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Fußenegger <mfussenegger@users.noreply.github.com>2024-08-01 16:01:15 +0200
committerGitHub <noreply@github.com>2024-08-01 16:01:15 +0200
commit720b309c786c4a258adccc9c468d433fb0f755b9 (patch)
treefd3f02f5fc9f8eccf8bb76d5ba1732bd789549fc
parent32e128f20992e350b3e39c7469baa1f692418203 (diff)
downloadrneovim-720b309c786c4a258adccc9c468d433fb0f755b9.tar.gz
rneovim-720b309c786c4a258adccc9c468d433fb0f755b9.tar.bz2
rneovim-720b309c786c4a258adccc9c468d433fb0f755b9.zip
fix(lsp): don't send foreign diagnostics to servers in buf.code_action (#29501)
`buf.code_action` always included diagnostics on a given line from all clients. Servers should only receive diagnostics they published, and in the exact same format they sent it. Should fix https://github.com/neovim/neovim/issues/29500
-rw-r--r--runtime/lua/vim/lsp/buf.lua18
-rw-r--r--runtime/lua/vim/lsp/diagnostic.lua18
-rw-r--r--test/functional/plugin/lsp/diagnostic_spec.lua27
3 files changed, 21 insertions, 42 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
index f20730b8e6..a512d48a06 100644
--- a/runtime/lua/vim/lsp/buf.lua
+++ b/runtime/lua/vim/lsp/buf.lua
@@ -852,14 +852,10 @@ function M.code_action(opts)
if opts.diagnostics or opts.only then
opts = { options = opts }
end
- local context = opts.context or {}
+ local context = opts.context and vim.deepcopy(opts.context) or {}
if not context.triggerKind then
context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked
end
- if not context.diagnostics then
- local bufnr = api.nvim_get_current_buf()
- context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(bufnr)
- end
local mode = api.nvim_get_mode().mode
local bufnr = api.nvim_get_current_buf()
local win = api.nvim_get_current_win()
@@ -901,6 +897,18 @@ function M.code_action(opts)
else
params = util.make_range_params(win, client.offset_encoding)
end
+ if not context.diagnostics then
+ local ns_push = vim.lsp.diagnostic.get_namespace(client.id, false)
+ local ns_pull = vim.lsp.diagnostic.get_namespace(client.id, true)
+ local diagnostics = {}
+ local lnum = api.nvim_win_get_cursor(0)[1] - 1
+ vim.list_extend(diagnostics, vim.diagnostic.get(bufnr, { namespace = ns_pull, lnum = lnum }))
+ vim.list_extend(diagnostics, vim.diagnostic.get(bufnr, { namespace = ns_push, lnum = lnum }))
+ ---@diagnostic disable-next-line: no-unknown
+ context.diagnostics = vim.tbl_map(function(d)
+ return d.user_data.lsp
+ end, diagnostics)
+ end
params.context = context
client.request(ms.textDocument_codeAction, params, on_result, bufnr)
end
diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua
index 08cea13548..5ed42700e3 100644
--- a/runtime/lua/vim/lsp/diagnostic.lua
+++ b/runtime/lua/vim/lsp/diagnostic.lua
@@ -122,13 +122,7 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
code = diagnostic.code,
_tags = tags_lsp_to_vim(diagnostic, client_id),
user_data = {
- lsp = {
- -- usage of user_data.lsp.code is deprecated in favor of the top-level code field
- code = diagnostic.code,
- codeDescription = diagnostic.codeDescription,
- relatedInformation = diagnostic.relatedInformation,
- data = diagnostic.data,
- },
+ lsp = diagnostic,
},
}
end, diagnostics)
@@ -157,8 +151,11 @@ local function diagnostic_vim_to_lsp(diagnostics)
---@param diagnostic vim.Diagnostic
---@return lsp.Diagnostic
return vim.tbl_map(function(diagnostic)
- return vim.tbl_extend('keep', {
- -- "keep" the below fields over any duplicate fields in diagnostic.user_data.lsp
+ local user_data = diagnostic.user_data or {}
+ if user_data.lsp then
+ return user_data.lsp
+ end
+ return {
range = {
start = {
line = diagnostic.lnum,
@@ -174,7 +171,7 @@ local function diagnostic_vim_to_lsp(diagnostics)
source = diagnostic.source,
code = diagnostic.code,
tags = tags_vim_to_lsp(diagnostic),
- }, diagnostic.user_data and (diagnostic.user_data.lsp or {}) or {})
+ }
end, diagnostics)
end
@@ -366,6 +363,7 @@ end
--- Structured: { [1] = {...}, [5] = {.... } }
---@private
function M.get_line_diagnostics(bufnr, line_nr, opts, client_id)
+ vim.deprecate('vim.lsp.diagnostic.get_line_diagnostics', 'vim.diagnostic.get', '0.12')
convert_severity(opts)
local diag_opts = {} --- @type vim.diagnostic.GetOpts
diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua
index c5e14ffdc2..779c4641b9 100644
--- a/test/functional/plugin/lsp/diagnostic_spec.lua
+++ b/test/functional/plugin/lsp/diagnostic_spec.lua
@@ -98,33 +98,6 @@ describe('vim.lsp.diagnostic', function()
clear()
end)
- describe('vim.lsp.diagnostic', function()
- it('maintains LSP information when translating diagnostics', function()
- local result = exec_lua [[
- local diagnostics = {
- make_error("Error 1", 1, 1, 1, 5),
- }
-
- diagnostics[1].code = 42
- diagnostics[1].data = "Hello world"
-
- vim.lsp.diagnostic.on_publish_diagnostics(nil, {
- uri = fake_uri,
- diagnostics = diagnostics,
- }, {client_id=client_id})
-
- return {
- vim.diagnostic.get(diagnostic_bufnr, {lnum=1})[1],
- vim.lsp.diagnostic.get_line_diagnostics(diagnostic_bufnr, 1)[1],
- }
- ]]
- eq({ code = 42, data = 'Hello world' }, result[1].user_data.lsp)
- eq(42, result[1].code)
- eq(42, result[2].code)
- eq('Hello world', result[2].data)
- end)
- end)
-
describe('vim.lsp.diagnostic.on_publish_diagnostics', function()
it('allows configuring the virtual text via vim.lsp.with', function()
local expected_spacing = 10