From 3a4aa3fc58f87a295a075fe457bc78805eef7c4d Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:04:44 -0600 Subject: [PATCH] refactor: soft-deprecate diagnostic signs configured with :sign-define (#26618) Diagnostic signs should now be configured with vim.diagnostic.config(), but "legacy" sign definitions should go through the standard deprecation process to minimize the impact from breaking changes. --- runtime/doc/deprecated.txt | 3 ++ runtime/doc/diagnostic.txt | 26 ++++++++---- runtime/doc/news.txt | 3 ++ runtime/lua/vim/diagnostic.lua | 49 +++++++++++++++++++++- test/functional/lua/diagnostic_spec.lua | 55 +++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 9 deletions(-) diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 0a07f06c75..b0d4b41a98 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -116,6 +116,9 @@ internally and are no longer exposed as part of the API. Instead, use - *vim.lsp.diagnostic.set_underline()* - *vim.lsp.diagnostic.set_virtual_text()* +Configuring |diagnostic-signs| with |:sign-define| or |sign_define()| is no +longer supported. Use the "signs" key of |vim.diagnostic.config()| instead. + LSP FUNCTIONS - *vim.lsp.buf.server_ready()* Use |LspAttach| instead, depending on your use-case. "Server ready" is not diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index 94ed578823..fa5ef22e37 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -317,12 +317,24 @@ SIGNS *diagnostic-signs* Signs are defined for each diagnostic severity. The default text for each sign is the first letter of the severity name (for example, "E" for ERROR). Signs -can be customized using the following: >vim +can be customized with |vim.diagnostic.config()|. Example: >lua - sign define DiagnosticSignError text=E texthl=DiagnosticSignError linehl= numhl= - sign define DiagnosticSignWarn text=W texthl=DiagnosticSignWarn linehl= numhl= - sign define DiagnosticSignInfo text=I texthl=DiagnosticSignInfo linehl= numhl= - sign define DiagnosticSignHint text=H texthl=DiagnosticSignHint linehl= numhl= + -- Highlight entire line for errors + -- Highlight the line number for warnings + vim.diagnostic.config({ + signs = { + text = { + [vim.diagnostic.severity.ERROR] = '', + [vim.diagnostic.severity.WARN] = '', + }, + linehl = { + [vim.diagnostic.severity.ERROR] = 'ErrorMsg', + }, + numhl = { + [vim.diagnostic.severity.WARN] = 'WarningMsg', + }, + }, + }) When the "severity_sort" option is set (see |vim.diagnostic.config()|) the priority of each sign depends on the severity of the associated diagnostic. @@ -427,8 +439,8 @@ config({opts}, {namespace}) *vim.diagnostic.config()* end < - • signs: (default true) Use signs for diagnostics. - Options: + • signs: (default true) Use signs for diagnostics + |diagnostic-signs|. Options: • severity: Only show signs for diagnostics matching the given severity |diagnostic-severity| • priority: (number, default 10) Base priority to use diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 925c63f259..7def21941b 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -387,6 +387,9 @@ DEPRECATIONS *news-deprecations* The following functions are now deprecated and will be removed in a future release. +• Configuring |diagnostic-signs| using |:sign-define| or |sign_define()|. Use + the "signs" key of |vim.diagnostic.config()| instead. + • Checkhealth functions: - |health#report_error|, |vim.health.report_error()| Use |vim.health.error()| instead. - |health#report_info|, |vim.health.report_info()| Use |vim.health.info()| instead. diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index e4f694b8a2..6d2c212dfc 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -588,7 +588,7 @@ end --- return diagnostic.message --- end --- ---- - signs: (default true) Use signs for diagnostics. Options: +--- - signs: (default true) Use signs for diagnostics |diagnostic-signs|. Options: --- * severity: Only show signs for diagnostics matching the given --- severity |diagnostic-severity| --- * priority: (number, default 10) Base priority to use for signs. When @@ -883,7 +883,52 @@ M.handlers.signs = { api.nvim_create_namespace(string.format('%s/diagnostic/signs', ns.name)) end - local text = {} + --- Handle legacy diagnostic sign definitions + --- These were deprecated in 0.10 and will be removed in 0.12 + if opts.signs and not opts.signs.text and not opts.signs.numhl and not opts.signs.texthl then + for _, v in ipairs({ 'Error', 'Warn', 'Info', 'Hint' }) do + local name = string.format('DiagnosticSign%s', v) + local sign = vim.fn.sign_getdefined(name)[1] + if sign then + local severity = M.severity[v:upper()] + if vim.fn.has('nvim-0.11') == 1 then + vim.deprecate( + 'Defining diagnostic signs with :sign-define or sign_define()', + 'vim.diagnostic.config()', + '0.12', + nil, + false + ) + end + + if not opts.signs.text then + opts.signs.text = {} + end + + if not opts.signs.numhl then + opts.signs.numhl = {} + end + + if not opts.signs.linehl then + opts.signs.linehl = {} + end + + if opts.signs.text[severity] == nil then + opts.signs.text[severity] = sign.text or '' + end + + if opts.signs.numhl[severity] == nil then + opts.signs.numhl[severity] = sign.numhl + end + + if opts.signs.linehl[severity] == nil then + opts.signs.linehl[severity] = sign.linehl + end + end + end + end + + local text = {} ---@type table for k in pairs(M.severity) do if opts.signs.text and opts.signs.text[k] then text[k] = opts.signs.text[k] diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 76963cc69e..688118a085 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -1537,6 +1537,61 @@ end) eq({}, result) end end) + + it('respects legacy signs placed with :sign define or sign_define #26618', function() + -- Legacy signs for diagnostics were deprecated in 0.10 and will be removed in 0.12 + eq(0, helpers.funcs.has('nvim-0.12')) + + helpers.command('sign define DiagnosticSignError text= texthl= linehl=ErrorMsg numhl=ErrorMsg') + helpers.command('sign define DiagnosticSignWarn text= texthl= linehl=WarningMsg numhl=WarningMsg') + helpers.command('sign define DiagnosticSignInfo text= texthl= linehl=Underlined numhl=Underlined') + helpers.command('sign define DiagnosticSignHint text= texthl= linehl=Underlined numhl=Underlined') + + local result = exec_lua [[ + vim.diagnostic.config({ + signs = true, + }) + + local diagnostics = { + make_error('Error', 1, 1, 1, 2), + make_warning('Warning', 3, 3, 3, 3), + } + + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + + local ns = vim.diagnostic.get_namespace(diagnostic_ns) + local sign_ns = ns.user_data.sign_ns + + local signs = vim.api.nvim_buf_get_extmarks(diagnostic_bufnr, sign_ns, 0, -1, {type ='sign', details = true}) + local result = {} + for _, s in ipairs(signs) do + result[#result + 1] = { + lnum = s[2] + 1, + name = s[4].sign_hl_group, + text = s[4].sign_text or '', + numhl = s[4].number_hl_group, + linehl = s[4].line_hl_group, + } + end + return result + ]] + + eq({ + lnum = 2, + name = 'DiagnosticSignError', + text = '', + numhl = 'ErrorMsg', + linehl = 'ErrorMsg', + }, result[1]) + + eq({ + lnum = 4, + name = 'DiagnosticSignWarn', + text = '', + numhl = 'WarningMsg', + linehl = 'WarningMsg', + }, result[2]) + end) end) describe('open_float()', function()