;; jao-maildir.el -- Utilities for reading maildirs -*- lexical-binding: t; -*- ;; Copyright (c) 2019, 2020 jao ;; Author: jao ;; Start date: Sun Dec 01, 2019 15:48 ;; Keywords: mail ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Comentary: ;; Inspecting the contents of maildirs and reporting it. ;;; Code: (require 'seq) (require 'jao-minibuffer) (defvar jao-maildirs nil) (defvar jao-maildir-counts nil) (defvar jao-maildir-debug-p nil) (defvar jao-maildir-echo-p t) (defvar jao-maildir-tracked-maildirs nil) (defun jao-maildir--maildir-new (mbox) (expand-file-name "new" mbox)) (defun jao-maildir--maildir-new-count (mbox) (- (length (directory-files (jao-maildir--maildir-new mbox))) 2)) (defun jao-maildir--update-counts () (dolist (mbox jao-maildirs) (puthash mbox (jao-maildir--maildir-new-count mbox) jao-maildir-counts))) (defun jao-maildir--init-counts (maildirs) (setq jao-maildir-counts (make-hash-table :test 'equal)) (setq jao-maildirs maildirs) (jao-maildir--update-counts) (jao-maildir--update-info-string t)) (defvar jao-maildir-tracked-maildirs) (defvar jao-maildir-info-string "") (defgroup jao-maildir-faces nil "Faces" :group 'faces) (defface jao-maildir-emph '((t :inherit font-lock-keyword-face)) "Face used to highlihgt non-boring tracked maildirs" :group 'jao-maildir-faces) (defun jao-maildir--tracked-count (track) (let ((rx (car track))) (seq-reduce (lambda (c k) (if (string-match-p rx k) (+ c (gethash k jao-maildir-counts 0)) c)) (hash-table-keys jao-maildir-counts) 0))) (defvar jao-maildir--track-strings ()) (defun jao-maildir--update-track-string (mbox) (when-let ((track (seq-find (lambda (td) (string-match-p (car td) mbox)) jao-maildir-tracked-maildirs))) (let* ((label (cadr track)) (other (assoc-delete-all label jao-maildir--track-strings)) (cnt (jao-maildir--tracked-count track))) (if (> cnt 0) (let* ((face (caddr track)) (am (format "%s%s" label cnt)) (face1 (if (eq t face) 'jao-maildir-emph face)) (str (cons label (if face (propertize am 'face face1) am)))) (setq jao-maildir--track-strings (if face (cons str other) (append other (list str))))) (setq jao-maildir--track-strings other))))) (defun jao-maildir--update-info-string (&optional mbox) (cond ((eq mbox t) (seq-do 'jao-maildir--update-track-string jao-maildirs)) ((stringp mbox) (jao-maildir--update-track-string mbox))) (let ((s (mapconcat 'identity (mapcar 'cdr jao-maildir--track-strings) " "))) (setq jao-maildir-info-string (if (string-blank-p s) "" (concat s " ")))) (when jao-maildir-echo-p (jao-minibuffer-refresh))) (defvar jao-maildir--watches nil) (defun jao-maildir-cancel-watchers () (dolist (w jao-maildir--watches) (file-notify-rm-watch w)) (setq jao-maildir--watches nil)) (defun jao-maildir--log-watch (mbox e) (when jao-maildir-debug-p (message "[%s] watch: %s: %s" (current-time-string) mbox e))) (defun jao-maildir--watcher (mbox cb) (lambda (e) (jao-maildir--log-watch e mbox) (when (memq (cadr e) '(created deleted)) (puthash mbox (jao-maildir--maildir-new-count mbox) jao-maildir-counts) (jao-maildir--update-info-string mbox) (when cb (funcall cb mbox))))) (defun jao-maildir--setup-watches (cb) (jao-maildir-cancel-watchers) (setq jao-maildir--watches (mapcar (lambda (mbox) (file-notify-add-watch (jao-maildir--maildir-new mbox) '(change attribute-change) (jao-maildir--watcher mbox cb))) jao-maildirs))) ;;;###autoload (defun jao-maildir-setup (maildirs mode-line &optional cb) (jao-maildir--init-counts maildirs) (cond ((eq 'mode-line mode-line) (add-to-list 'global-mode-string 'jao-maildir-info-string t)) (mode-line (jao-minibuffer-add-variable 'jao-maildir-info-string) (jao-maildir--update-info-string))) (jao-maildir--setup-watches cb)) (provide 'jao-maildir) ;;; jao-maildir.el ends here