mirror of
https://github.com/neovim/neovim.git
synced 2026-06-30 15:01:13 +00:00
feat(lua): add notify_once() (#17010)
Like vim.notify(), but only displays the notification once. This function prints a warning message to the user only once per Nvim session. This is useful for things we want the user to see without being overwhelmed with warning messages (for example, the deprecation messages in LSP diagnostics).
This commit is contained in:
committed by
GitHub
parent
11dafcaf05
commit
f365e68293
@@ -1206,19 +1206,32 @@ inspect({object}, {options}) *vim.inspect()*
|
||||
https://github.com/kikito/inspect.lua
|
||||
https://github.com/mpeterv/vinspect
|
||||
|
||||
notify({msg}, {log_level}, {opts}) *vim.notify()*
|
||||
Notification provider
|
||||
notify({msg}, {level}, {opts}) *vim.notify()*
|
||||
Display a notification to the user.
|
||||
|
||||
Without a runtime, writes to :Messages
|
||||
This function can be overridden by plugins to display
|
||||
notifications using a custom provider (such as the system
|
||||
notification provider). By default, writes to |:messages|.
|
||||
|
||||
Parameters: ~
|
||||
{msg} string Content of the notification to show to
|
||||
the user
|
||||
{log_level} number|nil enum from vim.log.levels
|
||||
{opts} table|nil additional options (timeout, etc)
|
||||
{msg} string Content of the notification to show to the
|
||||
user.
|
||||
{level} number|nil One of the values from
|
||||
|vim.log.levels|.
|
||||
{opts} table|nil Optional parameters. Unused by default.
|
||||
|
||||
See also: ~
|
||||
:help nvim_notify
|
||||
notify_once({msg}, {level}, {opts}) *vim.notify_once()*
|
||||
Display a notification only one time.
|
||||
|
||||
Like |vim.notify()|, but subsequent calls with the same
|
||||
message will not display a notification.
|
||||
|
||||
Parameters: ~
|
||||
{msg} string Content of the notification to show to the
|
||||
user.
|
||||
{level} number|nil One of the values from
|
||||
|vim.log.levels|.
|
||||
{opts} table|nil Optional parameters. Unused by default.
|
||||
|
||||
on_key({fn}, {ns_id}) *vim.on_key()*
|
||||
Adds Lua function {fn} with namespace id {ns_id} as a listener
|
||||
|
||||
@@ -243,7 +243,7 @@ end
|
||||
---@param client_id number
|
||||
---@private
|
||||
function M.save(diagnostics, bufnr, client_id)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.save is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.save is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
local namespace = M.get_namespace(client_id)
|
||||
vim.diagnostic.set(namespace, bufnr, diagnostic_lsp_to_vim(diagnostics, bufnr, client_id))
|
||||
end
|
||||
@@ -257,7 +257,7 @@ end
|
||||
--- If nil, diagnostics of all clients are included.
|
||||
---@return table with diagnostics grouped by bufnr (bufnr: Diagnostic[])
|
||||
function M.get_all(client_id)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_all is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_all is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
local result = {}
|
||||
local namespace
|
||||
if client_id then
|
||||
@@ -279,7 +279,7 @@ end
|
||||
--- Else, return just the diagnostics associated with the client_id.
|
||||
---@param predicate function|nil Optional function for filtering diagnostics
|
||||
function M.get(bufnr, client_id, predicate)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
predicate = predicate or function() return true end
|
||||
if client_id == nil then
|
||||
local all_diagnostics = {}
|
||||
@@ -341,7 +341,7 @@ end
|
||||
---@param severity DiagnosticSeverity
|
||||
---@param client_id number the client id
|
||||
function M.get_count(bufnr, severity, client_id)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_count is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_count is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
severity = severity_lsp_to_vim(severity)
|
||||
local opts = { severity = severity }
|
||||
if client_id ~= nil then
|
||||
@@ -358,7 +358,7 @@ end
|
||||
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
||||
---@return table Previous diagnostic
|
||||
function M.get_prev(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_prev is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_prev is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if opts then
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -376,7 +376,7 @@ end
|
||||
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
||||
---@return table Previous diagnostic position
|
||||
function M.get_prev_pos(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_prev_pos is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_prev_pos is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if opts then
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -393,7 +393,7 @@ end
|
||||
---
|
||||
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
||||
function M.goto_prev(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.goto_prev is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.goto_prev is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if opts then
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -411,7 +411,7 @@ end
|
||||
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
||||
---@return table Next diagnostic
|
||||
function M.get_next(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_next is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_next is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if opts then
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -429,7 +429,7 @@ end
|
||||
---@param opts table See |vim.lsp.diagnostic.goto_next()|
|
||||
---@return table Next diagnostic position
|
||||
function M.get_next_pos(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_next_pos is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_next_pos is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if opts then
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -444,7 +444,7 @@ end
|
||||
---
|
||||
---@deprecated Prefer |vim.diagnostic.goto_next()|
|
||||
function M.goto_next(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.goto_next is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.goto_next is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if opts then
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -468,7 +468,7 @@ end
|
||||
--- - severity_limit (DiagnosticSeverity):
|
||||
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
|
||||
function M.set_signs(diagnostics, bufnr, client_id, _, opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.set_signs is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.set_signs is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
local namespace = M.get_namespace(client_id)
|
||||
if opts and not opts.severity and opts.severity_limit then
|
||||
opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
|
||||
@@ -489,7 +489,7 @@ end
|
||||
--- - severity_limit (DiagnosticSeverity):
|
||||
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
|
||||
function M.set_underline(diagnostics, bufnr, client_id, _, opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.set_underline is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.set_underline is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
local namespace = M.get_namespace(client_id)
|
||||
if opts and not opts.severity and opts.severity_limit then
|
||||
opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
|
||||
@@ -511,7 +511,7 @@ end
|
||||
--- - severity_limit (DiagnosticSeverity):
|
||||
--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid.
|
||||
function M.set_virtual_text(diagnostics, bufnr, client_id, _, opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.set_virtual_text is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.set_virtual_text is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
local namespace = M.get_namespace(client_id)
|
||||
if opts and not opts.severity and opts.severity_limit then
|
||||
opts.severity = {min=severity_lsp_to_vim(opts.severity_limit)}
|
||||
@@ -530,7 +530,7 @@ end
|
||||
---@return an array of [text, hl_group] arrays. This can be passed directly to
|
||||
--- the {virt_text} option of |nvim_buf_set_extmark()|.
|
||||
function M.get_virtual_text_chunks_for_line(bufnr, _, line_diags, opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.get_virtual_text_chunks_for_line is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.get_virtual_text_chunks_for_line is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
return vim.diagnostic._get_virt_text_chunks(diagnostic_lsp_to_vim(line_diags, bufnr), opts)
|
||||
end
|
||||
|
||||
@@ -548,7 +548,7 @@ end
|
||||
---@param position table|nil The (0,0)-indexed position
|
||||
---@return table {popup_bufnr, win_id}
|
||||
function M.show_position_diagnostics(opts, buf_nr, position)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.show_position_diagnostics is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.show_position_diagnostics is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
opts = opts or {}
|
||||
opts.scope = "cursor"
|
||||
opts.pos = position
|
||||
@@ -572,7 +572,7 @@ end
|
||||
---@param client_id number|nil the client id
|
||||
---@return table {popup_bufnr, win_id}
|
||||
function M.show_line_diagnostics(opts, buf_nr, line_nr, client_id)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.show_line_diagnostics is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.show_line_diagnostics is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
opts = opts or {}
|
||||
opts.scope = "line"
|
||||
opts.pos = line_nr
|
||||
@@ -596,7 +596,7 @@ end
|
||||
--- client. The default is to redraw diagnostics for all attached
|
||||
--- clients.
|
||||
function M.redraw(bufnr, client_id)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.redraw is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.redraw is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
bufnr = get_bufnr(bufnr)
|
||||
if not client_id then
|
||||
return vim.lsp.for_each_buffer_client(bufnr, function(client)
|
||||
@@ -624,7 +624,7 @@ end
|
||||
--- - {workspace}: (boolean, default true)
|
||||
--- - Set the list with workspace diagnostics
|
||||
function M.set_qflist(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.set_qflist is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.set_qflist is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
opts = opts or {}
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -656,7 +656,7 @@ end
|
||||
--- - {workspace}: (boolean, default false)
|
||||
--- - Set the list with workspace diagnostics
|
||||
function M.set_loclist(opts)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.set_loclist is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.set_loclist is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
opts = opts or {}
|
||||
if opts.severity then
|
||||
opts.severity = severity_lsp_to_vim(opts.severity)
|
||||
@@ -684,7 +684,7 @@ end
|
||||
-- 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)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.disable is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.disable is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if not client_id then
|
||||
return vim.lsp.for_each_buffer_client(bufnr, function(client)
|
||||
M.disable(bufnr, client.id)
|
||||
@@ -705,7 +705,7 @@ end
|
||||
--- client. The default is to enable diagnostics for all attached
|
||||
--- clients.
|
||||
function M.enable(bufnr, client_id)
|
||||
vim.api.nvim_echo({{'vim.lsp.diagnostic.enable is deprecated. See :h deprecated', 'WarningMsg'}}, true, {})
|
||||
vim.notify_once('vim.lsp.diagnostic.enable is deprecated. See :h deprecated', vim.log.levels.WARN)
|
||||
if not client_id then
|
||||
return vim.lsp.for_each_buffer_client(bufnr, function(client)
|
||||
M.enable(bufnr, client.id)
|
||||
|
||||
@@ -10,14 +10,6 @@ local uv = vim.loop
|
||||
local npcall = vim.F.npcall
|
||||
local split = vim.split
|
||||
|
||||
local _warned = {}
|
||||
local warn_once = function(message)
|
||||
if not _warned[message] then
|
||||
vim.api.nvim_err_writeln(message)
|
||||
_warned[message] = true
|
||||
end
|
||||
end
|
||||
|
||||
local M = {}
|
||||
|
||||
local default_border = {
|
||||
@@ -1933,7 +1925,6 @@ function M.lookup_section(settings, section)
|
||||
end
|
||||
|
||||
M._get_line_byte_from_position = get_line_byte_from_position
|
||||
M._warn_once = warn_once
|
||||
|
||||
M.buf_versions = {}
|
||||
|
||||
|
||||
@@ -419,23 +419,43 @@ function vim.defer_fn(fn, timeout)
|
||||
end
|
||||
|
||||
|
||||
--- Notification provider
|
||||
--- Display a notification to the user.
|
||||
---
|
||||
--- Without a runtime, writes to :Messages
|
||||
---@see :help nvim_notify
|
||||
---@param msg string Content of the notification to show to the user
|
||||
---@param log_level number|nil enum from |vim.log.levels|
|
||||
---@param opts table|nil additional options (timeout, etc)
|
||||
function vim.notify(msg, log_level, opts) -- luacheck: no unused
|
||||
if log_level == vim.log.levels.ERROR then
|
||||
--- This function can be overridden by plugins to display notifications using a
|
||||
--- custom provider (such as the system notification provider). By default,
|
||||
--- writes to |:messages|.
|
||||
---
|
||||
---@param msg string Content of the notification to show to the user.
|
||||
---@param level number|nil One of the values from |vim.log.levels|.
|
||||
---@param opts table|nil Optional parameters. Unused by default.
|
||||
function vim.notify(msg, level, opts) -- luacheck: no unused args
|
||||
if level == vim.log.levels.ERROR then
|
||||
vim.api.nvim_err_writeln(msg)
|
||||
elseif log_level == vim.log.levels.WARN then
|
||||
elseif level == vim.log.levels.WARN then
|
||||
vim.api.nvim_echo({{msg, 'WarningMsg'}}, true, {})
|
||||
else
|
||||
vim.api.nvim_echo({{msg}}, true, {})
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local notified = {}
|
||||
|
||||
--- Display a notification only one time.
|
||||
---
|
||||
--- Like |vim.notify()|, but subsequent calls with the same message will not
|
||||
--- display a notification.
|
||||
---
|
||||
---@param msg string Content of the notification to show to the user.
|
||||
---@param level number|nil One of the values from |vim.log.levels|.
|
||||
---@param opts table|nil Optional parameters. Unused by default.
|
||||
function vim.notify_once(msg, level, opts) -- luacheck: no unused args
|
||||
if not notified[msg] then
|
||||
vim.notify(msg, level, opts)
|
||||
notified[msg] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@private
|
||||
function vim.register_keystroke_callback()
|
||||
|
||||
@@ -2200,6 +2200,40 @@ describe('lua stdlib', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('vim.notify_once', function()
|
||||
local screen = Screen.new(60,5)
|
||||
screen:set_default_attr_ids({
|
||||
[0] = {bold=true, foreground=Screen.colors.Blue},
|
||||
[1] = {foreground=Screen.colors.Red},
|
||||
})
|
||||
screen:attach()
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
|
|
||||
]]}
|
||||
exec_lua [[vim.notify_once("I'll only tell you this once...", vim.log.levels.WARN)]]
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{1:I'll only tell you this once...} |
|
||||
]]}
|
||||
feed('<C-l>')
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
{0:~ }|
|
||||
|
|
||||
]]}
|
||||
exec_lua [[vim.notify_once("I'll only tell you this once...")]]
|
||||
screen:expect_unchanged()
|
||||
end)
|
||||
|
||||
describe('vim.schedule_wrap', function()
|
||||
it('preserves argument lists', function()
|
||||
exec_lua [[
|
||||
|
||||
Reference in New Issue
Block a user