87 lines
2.2 KiB
Lua
87 lines
2.2 KiB
Lua
-- mail-count.lua - Async mail count for statusline
|
|
local M = {}
|
|
|
|
---@class MailCountAccount
|
|
---@field name string Display name (e.g., "U" for uchicago)
|
|
---@field query string Notmuch query for this account
|
|
|
|
---@class MailCountConfig
|
|
---@field accounts MailCountAccount[] List of accounts to check
|
|
---@field interval? number Check interval in milliseconds (default: 60000)
|
|
---@field icon? string Icon to display (default: "")
|
|
---@field hide_zero? boolean Hide when all counts are zero (default: false)
|
|
|
|
---@type MailCountConfig
|
|
local config = {
|
|
accounts = {},
|
|
interval = 60000,
|
|
icon = '',
|
|
hide_zero = false,
|
|
}
|
|
|
|
local counts = {}
|
|
local last_check = 0
|
|
local timer = nil
|
|
|
|
local function update_count(account)
|
|
vim.fn.jobstart({ 'notmuch', 'count', account.query }, {
|
|
stdout_buffered = true,
|
|
on_stdout = function(_, data)
|
|
if data and data[1] then counts[account.name] = tonumber(data[1]) or 0 end
|
|
end,
|
|
})
|
|
end
|
|
|
|
function M.refresh()
|
|
for _, account in ipairs(config.accounts) do
|
|
update_count(account)
|
|
end
|
|
last_check = vim.uv.now()
|
|
end
|
|
|
|
function M.get()
|
|
if #config.accounts == 0 then return '' end
|
|
|
|
local now = vim.uv.now()
|
|
if now - last_check > config.interval then M.refresh() end
|
|
|
|
local total = 0
|
|
local parts = {}
|
|
for _, account in ipairs(config.accounts) do
|
|
local count = counts[account.name] or 0
|
|
total = total + count
|
|
table.insert(parts, string.format('%s:%d', account.name, count))
|
|
end
|
|
|
|
if config.hide_zero and total == 0 then return '' end
|
|
|
|
return string.format('%s %s', config.icon, table.concat(parts, ' | '))
|
|
end
|
|
|
|
---@param opts? MailCountConfig
|
|
function M.setup(opts)
|
|
-- Skip setup if notmuch is not available
|
|
if vim.fn.executable 'notmuch' ~= 1 then return end
|
|
|
|
config = vim.tbl_deep_extend('force', config, opts or {})
|
|
|
|
-- Initialize counts
|
|
for _, account in ipairs(config.accounts) do
|
|
counts[account.name] = 0
|
|
end
|
|
|
|
-- Initial fetch on load
|
|
vim.schedule(function() M.refresh() end)
|
|
|
|
-- Stop existing timer if any
|
|
if timer then
|
|
timer:stop()
|
|
timer:close()
|
|
end
|
|
|
|
-- Refresh on timer
|
|
timer = vim.uv.new_timer()
|
|
timer:start(config.interval, config.interval, vim.schedule_wrap(function() M.refresh() end))
|
|
end
|
|
|
|
return M
|