rcarriga / nvim-notify

A fancy, configurable, notification manager for NeoVim
MIT License
2.97k stars 78 forks source link

Multiple notifications with the same information #135

Closed marcelarie closed 1 year ago

marcelarie commented 1 year ago

All the LSP notifcations are repeated, this happens with tsserver and sumenko_lua. Is there anything I can do to fix this?

Here an example:

Screenshot 2022-09-27 at 12 11 15 Screenshot 2022-09-27 at 12 13 49

This is the config that I am using:

vim.notify = require "notify"

require("notify").setup {
    -- render = "minimal",
    width = 0,
    timeout = 5,
    on_open = function(win)
        vim.api.nvim_win_set_option(win, "wrap", true)
    end,
}

-- Utility functions shared between progress reports for LSP and DAP

local client_notifs = {}

local function get_notif_data(client_id, token)
    if not client_notifs[client_id] then
        client_notifs[client_id] = {}
    end

    if not client_notifs[client_id][token] then
        client_notifs[client_id][token] = {}
    end

    return client_notifs[client_id][token]
end

local spinner_frames = {
    "⣾",
    "⣽",
    "⣻",
    "⢿",
    "⡿",
    "⣟",
    "⣯",
    "⣷",
}

local function update_spinner(client_id, token)
    local notif_data = get_notif_data(client_id, token)

    if notif_data.spinner then
        local new_spinner = (notif_data.spinner + 1) % #spinner_frames
        notif_data.spinner = new_spinner

        notif_data.notification = vim.notify(nil, nil, {
            hide_from_history = true,
            icon = spinner_frames[new_spinner],
            replace = notif_data.notification,
        })

        vim.defer_fn(function()
            update_spinner(client_id, token)
        end, 100)
    end
end

local function format_title(title, client_name)
    return client_name .. (#title > 0 and ": " .. title or "")
end

local function format_message(message, percentage)
    return (percentage and percentage .. "%\t" or "") .. (message or "")
end

-- LSP integration
-- Make sure to also have the snippet with the common helper functions in your config!

vim.lsp.handlers["$/progress"] = function(_, result, ctx)
    local client_id = ctx.client_id
    local lsp_name = vim.lsp.get_client_by_id(client_id).name

    if lsp_name == "null-ls" or lsp_name == "ltex" then
        return
    end

    local val = result.value

    local notif_data = get_notif_data(client_id, result.token)

    if val.kind == "begin" then
        local message = format_message(val.message, val.percentage)

        notif_data.notification = vim.notify(message, "info", {
            title = format_title(val.title, lsp_name),
            icon = spinner_frames[1],
            timeout = 500,
            hide_from_history = false,
        })

        notif_data.spinner = 1
        update_spinner(client_id, result.token)
    elseif val.kind == "report" and notif_data then
        notif_data.notification =
            vim.notify(format_message(val.message, val.percentage), "info", {
                replace = notif_data.notification,
                hide_from_history = false,
            })
    elseif val.kind == "end" and notif_data then
        notif_data.notification = vim.notify(
            val.message and format_message(val.message) or "Complete",
            "info",
            {
                icon = "",
                replace = notif_data.notification,
                timeout = 500,
            }
        )

        notif_data.spinner = nil
    end
end
rcarriga commented 1 year ago

Yes those language servers are quite noisy. You could alter the code to only show one message per client at a time but it might still be a bit too much. I don't actually use this myself because of this issue, instead I just use https://github.com/nvim-lua/lsp-status.nvim to put the info in the statusline where it's less intrusive