nvim-notify icon indicating copy to clipboard operation
nvim-notify copied to clipboard

Group repeated notifications

Open kommander opened this issue 1 year ago • 4 comments

Hey, I love this! Thanks for this plugin.

I was wondering if there is any way I can group notifications for triggers that are repeated in short succession, which then completely clutters the screen and the notifications take a while to cycle through all the triggered messages.

This mostly never happens, but when it does, it's really bothering. It can happen when some plugin goes wrong after an update and any action in neovim causes a plethora of notifications to be triggered.

kommander avatar May 11 '24 19:05 kommander

This is actually something that I am trying to implement in my own config right now. I've gotten this far, however, I get a No matching notification found to replace even though the notification is clearly still on the screen. First two work fine, but 3+ notifs fail.


local match_groups = { "%(mini%.deps%) %(%d+/%d+%) Downloaded update for" }

local cache = {}
vim.notify = function(msg, log_level)
  local opts = {}

  for _, val in ipairs(match_groups) do
    if msg:match(val) then
      opts = {
        replace = cache[val],
        on_open = function(_, record)
          cache[val] = record
        end,
        on_close = function(_)
          cache[val] = nil
        end,
      }
    end
  end

  req("notify").notify(msg, log_level, opts)
end

vim.notify("(mini.deps) (1/100) Downloaded update for a")
vim.notify("(mini.deps) (2/100) Downloaded update for b")
vim.notify("(mini.deps) (3/100) Downloaded update for c")

sarmong avatar May 20 '24 19:05 sarmong

So, basically, on_open is not called when the window is replaced. But the window has new id anyways. I think this behaviour can be improved.

Here's working example:

local match_groups = { "%(mini%.deps%) %(%d+/%d+%) Downloaded update for" }

local cache = {}
vim.notify = function(msg, log_level)
  local opts = {}

  for _, val in ipairs(match_groups) do
    if msg:match(val) then
      opts = {
        replace = cache[val],
        on_open = function(_, record)
          cache[val] = record.id
        end,
        on_close = function()
          cache[val] = nil
        end,
      }

      cache[val] = req("notify").notify(msg, log_level, opts).id
    else
      req("notify").notify(msg, log_level, opts)
    end
  end
end

sarmong avatar May 20 '24 20:05 sarmong

+1 to this

speelbarrow avatar Jun 16 '24 17:06 speelbarrow

+1

hectordommo avatar Jul 19 '24 16:07 hectordommo