rcarriga / nvim-notify

A fancy, configurable, notification manager for NeoVim
MIT License
2.91k stars 74 forks source link

Set notification frequence or possibly a DND mode? #210

Closed 2KAbhishek closed 1 month ago

2KAbhishek commented 1 year ago

In cases where a plugin does multiple notify calls, is it possible to set the frequency at which notifications can be shown?

e.g - Show notification after every 15 mins

Another approach would be to add something like a :DNDToggle command that disables and enables notifications

2KAbhishek commented 1 year ago

Asking cause this is a very common issue that hampers workflow focus sometimes, lsp being the most noisy

e.g:

image

rcarriga commented 1 year ago

The API is meant to be quite simple and to be extended by users. You can implement a do-not-disturb mode quite easily:

local notify = require("notify")

local dnd = false
vim.api.nvim_create_user_command("NotifyDND", function()
  dnd = not dnd
end)

vim.notify = function(...)
  if not dnd then
    notify(...)
  end
end

but blanket silencing might be overkill. You could instead use the replace functionality to prevent noisy messages showing more than once at a time:

local notify = require("notify")

local buffered_messages = {
  "Client %d+ quit",
}
local message_notifications = {}

vim.notify = function(msg, level, opts)
  opts = opts or {}
  for _, pattern in ipairs(buffered_messages) do
    if string.find(msg, pattern) then

      if message_notifications[pattern] then
        opts.replace = message_notifications[pattern]
      end

      opts.on_close = function()
        message_notifications[pattern] = nil
      end
      message_notifications[pattern] = notify.notify(msg, level, opts)
      return
    end
  end

  notify.notify(msg, level, opts)
end

and if you wanted the noisy messages to also have a timeout:

local notify = require("notify")

local MIN = 1000 * 60 * 60

local buffered_messages = {
  ["Client %d+ quit"] = false
}
local message_notifications = {}

vim.notify = function(msg, level, opts)
  opts = opts or {}

  for pattern, is_visible in pairs(buffered_messages) do
    if string.find(msg, pattern) then
      if message_notifications[pattern] then
        if not is_visible then
          return
        end
        opts.replace = message_notifications[pattern]
      end

      buffered_messages[pattern] = true
      opts.on_close = function()
        buffered_messages[pattern] = false
        vim.defer_fn(function()
          message_notifications[pattern] = nil
        end, MIN * 15)
      end
      message_notifications[pattern] = notify.notify(msg, level, opts)
      return
    end
  end

  notify.notify(msg, level, opts)
end

Those are just for example, there are lots of small customisations you could make which is why keeping it outside of this plugin is preferable :smile:

2KAbhishek commented 1 year ago

Thanks a lot for the answer, I'll try it out