feat: Implement comprehensive notification system and fix overlapping issues

- Create custom notification manager to handle overlapping notifications
- Fix notification positioning to avoid dashboard overlap
- Improve alpha dashboard appearance and message suppression
- Add smart notification routing for different contexts
- Implement notification stacking and positioning logic
- Add notification management keymaps for better control
- Enhance startup message handling to prevent overlapping
- Improve UI layout and reduce visual clutter
- Add context-aware notifications (dashboard vs regular mode)
- Implement notification clearing and testing functionality

New features:
- <leader>nc - Clear all notifications
- <leader>nn - Test notification system
- Smart notification positioning
- Context-aware notification display
- Notification stacking and management

UI improvements:
- Better dashboard appearance
- Reduced overlapping elements
- Cleaner startup experience
- Improved notification aesthetics
- Better message routing
This commit is contained in:
Carlos Gutierrez
2025-08-12 02:36:57 -04:00
parent 22352723cf
commit 0071aa4485
5 changed files with 349 additions and 4 deletions

View File

@@ -0,0 +1,231 @@
-- Custom notification manager to handle overlapping and improve UX
local M = {}
-- Track active notifications to prevent overlapping
local active_notifications = {}
local notification_queue = {}
-- Function to show a notification without overlapping
function M.show_notification(message, level, opts)
level = level or vim.log.levels.INFO
opts = opts or {}
-- Default options
local default_opts = {
timeout = 3000,
title = "CarGDev Neovim",
render = "minimal",
stages = "fade_in_slide_out",
position = "top_right",
max_width = 50,
max_height = 8,
background_colour = "#000000",
border_style = "rounded",
}
-- Merge options
for k, v in pairs(default_opts) do
if opts[k] == nil then
opts[k] = v
end
end
-- Check if we're in alpha dashboard
local current_buf = vim.api.nvim_get_current_buf()
local current_ft = vim.api.nvim_buf_get_option(current_buf, "filetype")
if current_ft == "alpha" then
-- If in dashboard, use a different approach
M.show_dashboard_notification(message, level, opts)
return
end
-- Use nvim-notify if available
local notify_available = pcall(require, "notify")
if notify_available then
local notify = require("notify")
-- Position notification to avoid overlapping
opts.on_open = function(win)
-- Calculate position to avoid overlapping with other notifications
local row = 2
local col = vim.o.columns - 60
-- Adjust position if there are other notifications
for _, notif in ipairs(active_notifications) do
if notif.win and vim.api.nvim_win_is_valid(notif.win) then
row = row + 10 -- Stack notifications vertically
end
end
-- Ensure notification doesn't go off-screen
if row > vim.o.lines - 15 then
row = 2
col = col - 20
end
vim.api.nvim_win_set_config(win, {
row = row,
col = col,
relative = "editor",
width = opts.max_width,
height = opts.max_height,
})
-- Track this notification
table.insert(active_notifications, {
win = win,
message = message,
timestamp = vim.loop.now(),
})
end
opts.on_close = function(win)
-- Remove from active notifications
for i, notif in ipairs(active_notifications) do
if notif.win == win then
table.remove(active_notifications, i)
break
end
end
end
-- Show notification
local notification_id = notify(message, level, opts)
return notification_id
else
-- Fallback to vim.notify
vim.notify(message, level, opts)
end
end
-- Function to show notifications specifically for dashboard
function M.show_dashboard_notification(message, level, opts)
-- In dashboard, show minimal notifications
local icon = "💬"
if level == vim.log.levels.ERROR then
icon = ""
elseif level == vim.log.levels.WARN then
icon = "⚠️"
elseif level == vim.log.levels.INFO then
icon = ""
end
-- Show message in status line or use echo
local short_message = message:sub(1, 50)
if #message > 50 then
short_message = short_message .. "..."
end
-- Use echo for dashboard notifications to avoid overlapping
vim.cmd("echo '" .. icon .. " " .. short_message .. "'")
-- Clear message after a delay
vim.defer_fn(function()
vim.cmd("echo ''")
end, opts.timeout or 3000)
end
-- Function to clear all notifications
function M.clear_all_notifications()
for _, notif in ipairs(active_notifications) do
if notif.win and vim.api.nvim_win_is_valid(notif.win) then
vim.api.nvim_win_close(notif.win, true)
end
end
active_notifications = {}
end
-- Function to show performance notification
function M.show_performance_notification(message, level)
M.show_notification("📊 " .. message, level, {
title = "Performance Monitor",
timeout = 4000,
position = "top_right",
})
end
-- Function to show LSP notification
function M.show_lsp_notification(message, level)
M.show_notification("🔧 " .. message, level, {
title = "LSP Status",
timeout = 3000,
position = "top_right",
})
end
-- Function to show file operation notification
function M.show_file_notification(message, level)
M.show_notification("📁 " .. message, level, {
title = "File Operation",
timeout = 2500,
position = "top_right",
})
end
-- Function to show plugin notification
function M.show_plugin_notification(message, level)
M.show_notification("🦥 " .. message, level, {
title = "Plugin Manager",
timeout = 3000,
position = "top_right",
})
end
-- Function to show startup notification
function M.show_startup_notification(message, level)
M.show_notification("🚀 " .. message, level, {
title = "Startup",
timeout = 2000,
position = "top_right",
})
end
-- Function to handle startup messages
function M.handle_startup_messages()
-- Clear any existing messages
vim.cmd("redraw!")
-- Suppress startup messages
vim.opt.shortmess = vim.opt.shortmess + "I" -- No intro message
vim.opt.shortmess = vim.opt.shortmess + "c" -- No completion messages
vim.opt.shortmess = vim.opt.shortmess + "F" -- No file info message
vim.opt.shortmess = vim.opt.shortmess + "W" -- No "written" message
vim.opt.shortmess = vim.opt.shortmess + "A" -- No attention message
vim.opt.shortmess = vim.opt.shortmess + "o" -- No overwrite messages
-- Clear any existing messages
vim.cmd("echo ''")
end
-- Function to setup notification system
function M.setup()
-- Create autocmd to handle startup messages
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
M.handle_startup_messages()
end,
once = true,
})
-- Create autocmd to handle alpha dashboard
vim.api.nvim_create_autocmd("FileType", {
pattern = "alpha",
callback = function()
M.handle_startup_messages()
end,
})
-- Override vim.notify to use our custom system
local original_notify = vim.notify
vim.notify = function(msg, level, opts)
M.show_notification(msg, level, opts)
end
print("Notification manager initialized")
end
-- Initialize notification manager
M.setup()
return M

View File

@@ -4,6 +4,9 @@ require("cargdev.core.compatibility").setup()
-- Load startup optimizations early
require("cargdev.core.startup_optimization")
-- Load notification manager for better UX
require("cargdev.core.function.notification_manager")
require("cargdev.core.options")
require("cargdev.core.keymaps")

View File

@@ -25,4 +25,8 @@ keymap.set("n", "<leader>pb", "<cmd>lua require('cargdev.core.function.performan
-- LSP health and troubleshooting keymaps
keymap.set("n", "<leader>pl", "<cmd>lua require('cargdev.core.function.performance_monitor').check_lsp_health()<CR>", { desc = "Check LSP health" })
keymap.set("n", "<leader>pr", "<cmd>lua require('cargdev.core.function.performance_monitor').restart_lsp()<CR>", { desc = "Restart LSP" })
keymap.set("n", "<leader>pr", "<cmd>lua require('cargdev.core.function.performance_monitor').restart_lsp()<CR>", { desc = "Restart LSP" })
-- Notification management keymaps
keymap.set("n", "<leader>nc", "<cmd>lua require('cargdev.core.function.notification_manager').clear_all_notifications()<CR>", { desc = "Clear all notifications" })
keymap.set("n", "<leader>nn", "<cmd>lua require('cargdev.core.function.notification_manager').show_notification('Test notification', vim.log.levels.INFO)<CR>", { desc = "Test notification" })

View File

@@ -30,7 +30,7 @@ return {
-- 📂 Set menu with improved icons and performance tools
dashboard.section.buttons.val = {
dashboard.button("f", "🔎 Find File (Safe)", "<cmd>Telescope find_files<CR>"),
dashboard.button("n", "📜 New File", "<cmd>ene<CR>"),
dashboard.button("n", "📄 New File", "<cmd>ene<CR>"),
dashboard.button("g", "📝 Find Text", "<cmd>Telescope live_grep<CR>"),
dashboard.button("r", "📚 Recent Files", "<cmd>Telescope oldfiles<CR>"),
dashboard.button("c", "⚙️ Config", "<cmd>e ~/.config/nvim/init.lua<CR>"),
@@ -103,5 +103,42 @@ return {
-- 🔥 Disable folding on alpha buffer
vim.cmd([[autocmd FileType alpha setlocal nofoldenable]])
-- 🚫 Suppress startup messages that can overlap with dashboard
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
-- Clear any startup messages
vim.cmd("redraw!")
-- Suppress specific startup messages
vim.opt.shortmess = vim.opt.shortmess + "I" -- No intro message
vim.opt.shortmess = vim.opt.shortmess + "c" -- No completion messages
vim.opt.shortmess = vim.opt.shortmess + "F" -- No file info message
vim.opt.shortmess = vim.opt.shortmess + "W" -- No "written" message
vim.opt.shortmess = vim.opt.shortmess + "A" -- No attention message
vim.opt.shortmess = vim.opt.shortmess + "o" -- No overwrite messages
-- Clear any existing messages
vim.cmd("echo ''")
end,
once = true,
})
-- 🎨 Improve dashboard appearance and reduce overlapping
vim.api.nvim_create_autocmd("FileType", {
pattern = "alpha",
callback = function()
-- Set buffer options for better appearance
vim.opt_local.number = false
vim.opt_local.relativenumber = false
vim.opt_local.cursorline = false
vim.opt_local.cursorcolumn = false
vim.opt_local.signcolumn = "no"
vim.opt_local.foldcolumn = "0"
-- Clear any messages that might overlap
vim.cmd("redraw!")
end,
})
end,
}

View File

@@ -1,10 +1,46 @@
return {
-- Enhanced notifications
-- Enhanced notifications with better positioning
{
"rcarriga/nvim-notify",
event = "VeryLazy",
config = function()
vim.notify = require("notify")
-- Configure notifications to avoid overlapping
require("notify").setup({
-- Position notifications to avoid overlapping with dashboard
stages = "fade_in_slide_out",
timeout = 3000,
background_colour = "#000000",
max_width = 50,
max_height = 10,
default_timeout = 4000,
top_down = false, -- Show newer notifications at the bottom
render = "minimal",
minimum_width = 20,
icons = {
ERROR = " ",
WARN = " ",
INFO = " ",
DEBUG = " ",
TRACE = " ",
},
-- Position notifications away from dashboard
on_open = function(win)
-- Move notification window to avoid overlapping with alpha dashboard
local config = vim.api.nvim_win_get_config(win)
if config.relative == "editor" then
-- Position notifications in the top-right, but not overlapping dashboard
vim.api.nvim_win_set_config(win, {
row = 2,
col = vim.o.columns - 60, -- Position from right side
relative = "editor",
width = 55,
height = 8,
})
end
end,
})
end,
},
@@ -126,7 +162,7 @@ return {
end,
},
-- Better completion menu
-- Better completion menu with improved positioning
{
"folke/noice.nvim",
event = "VeryLazy",
@@ -156,6 +192,19 @@ return {
},
view = "mini",
},
-- Route startup messages to avoid overlapping with dashboard
{
filter = {
event = "msg_show",
any = {
{ find = "ideaDrop loaded!" },
{ find = "noice.nvim" },
{ find = "lazyredraw" },
},
},
view = "notify",
opts = { timeout = 2000 },
},
},
presets = {
bottom_search = true,
@@ -163,6 +212,25 @@ return {
long_message_to_split = true,
inc_rename = true,
},
-- Position command palette and other UI elements to avoid overlapping
cmdline = {
position = {
row = "50%",
col = "50%",
},
},
popupmenu = {
position = {
row = "50%",
col = "50%",
},
},
notify = {
-- Position notifications to avoid dashboard overlap
position = "top_right",
max_width = 50,
max_height = 10,
},
},
},
@@ -175,6 +243,8 @@ return {
theme = "auto",
globalstatus = true,
disabled_filetypes = { statusline = { "dashboard", "alpha" } },
component_separators = { left = "", right = "" },
section_separators = { left = "", right = "" },
},
sections = {
lualine_a = { "mode" },