diff options
author | Mathias Fußenegger <mfussenegger@users.noreply.github.com> | 2024-08-01 16:01:15 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-01 16:01:15 +0200 |
commit | 720b309c786c4a258adccc9c468d433fb0f755b9 (patch) | |
tree | fd3f02f5fc9f8eccf8bb76d5ba1732bd789549fc | |
parent | 32e128f20992e350b3e39c7469baa1f692418203 (diff) | |
download | rneovim-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.lua | 18 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 18 | ||||
-rw-r--r-- | test/functional/plugin/lsp/diagnostic_spec.lua | 27 |
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 |