feat(picker): added notifications picker. Closes #738

This commit is contained in:
Folke Lemaitre 2025-01-28 17:16:30 +01:00
parent 0cb5bdf4ee
commit 32cffd2e60
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
5 changed files with 71 additions and 2 deletions

View file

@ -140,6 +140,10 @@ local defaults = {
show_always = false, -- only show the selected column when there are multiple selections
unselected = true, -- use the unselected icon for unselected items
},
severity = {
icons = true, -- show severity icons
level = false, -- show severity level
},
},
---@class snacks.picker.previewers.Config
previewers = {

View file

@ -508,6 +508,15 @@ M.marks = {
["local"] = true,
}
---@class snacks.picker.notifications.Config: snacks.picker.Config
---@field filter? snacks.notifier.level|fun(notif: snacks.notifier.Notif): boolean
M.notifications = {
finder = "snacks_notifier",
format = "notification",
preview = "preview",
formatters = { severity = { level = true } },
}
-- List all available sources
M.pickers = {
finder = "meta_pickers",

View file

@ -13,8 +13,14 @@ function M.severity(item, picker)
local lower = severity:lower()
local cap = severity:sub(1, 1):upper() .. lower:sub(2)
ret[#ret + 1] = { picker.opts.icons.diagnostics[cap], "Diagnostic" .. cap, virtual = true }
ret[#ret + 1] = { " ", virtual = true }
if picker.opts.formatters.severity.icons then
ret[#ret + 1] = { picker.opts.icons.diagnostics[cap], "Diagnostic" .. cap, virtual = true }
ret[#ret + 1] = { " ", virtual = true }
end
if picker.opts.formatters.severity.level then
ret[#ret + 1] = { lower:upper(), "Diagnostic" .. cap, virtual = true }
ret[#ret + 1] = { " ", virtual = true }
end
return ret
end
@ -548,4 +554,22 @@ function M.icon(item, picker)
return ret
end
function M.notification(item, picker)
local a = Snacks.picker.util.align
local ret = {} ---@type snacks.picker.Highlight[]
local notif = item.item ---@type snacks.notifier.Notif
ret[#ret + 1] = { a(os.date("%R", notif.added), 5), "SnacksPickerTime" }
ret[#ret + 1] = { " " }
if item.severity then
vim.list_extend(ret, M.severity(item, picker))
end
ret[#ret + 1] = { " " }
ret[#ret + 1] = { a(notif.title or "", 15), "SnacksNotifierHistoryTitle" }
ret[#ret + 1] = { " " }
ret[#ret + 1] = { notif.msg, "SnacksPickerNotificationMessage" }
Snacks.picker.highlight.markdown(ret)
-- ret[#ret + 1] = { " " }
return ret
end
return M

View file

@ -0,0 +1,23 @@
local M = {}
---@param opts snacks.picker.notifications.Config
function M.notifier(opts)
local notifs = Snacks.notifier.get_history({ filter = opts.filter })
local items = {} ---@type snacks.picker.finder.Item[]
for _, notif in ipairs(notifs) do
items[#items + 1] = {
text = Snacks.picker.util.text(notif, { "level", "title", "msg" }),
item = notif,
severity = notif.level,
preview = {
text = notif.msg,
ft = "markdown",
},
}
end
return items
end
return M

View file

@ -159,7 +159,13 @@ end
---@param line snacks.picker.Highlight[]
function M.markdown(line)
M.highlight(line, {
["^# .*"] = "@markup.heading.1.markdown",
["^## .*"] = "@markup.heading.2.markdown",
["^### .*"] = "@markup.heading.3.markdown",
["^#### .*"] = "@markup.heading.4.markdown",
["^##### .*"] = "@markup.heading.5.markdown",
["`.-`"] = "SnacksPickerCode",
["^%s*[%-%*]"] = "@markup.list.markdown",
["%*.-%*"] = "SnacksPickerItalic",
["%*%*.-%*%*"] = "SnacksPickerBold",
})
@ -194,6 +200,9 @@ function M.to_text(line, opts)
local col = offset
local parts = {} ---@type string[]
for _, text in ipairs(line) do
if (type(text[2]) == "string" and text[1] == nil) or vim.tbl_isempty(text) then
text[1] = ""
end
if type(text[1]) == "string" then
---@cast text snacks.picker.Text
if text.virtual then