-- 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