From 5c017afcd6491b8d48aa492e50a58d57fcfb35f9 Mon Sep 17 00:00:00 2001 From: jao Date: Sun, 18 Oct 2026 13:54:27 +0100 Subject: notmuch refactorings --- custom/jao-custom-notmuch.el | 164 +++++++------------------------------------ lib/net/jao-notmuch.el | 133 +++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 139 deletions(-) diff --git a/custom/jao-custom-notmuch.el b/custom/jao-custom-notmuch.el index 6b5be84..ed1d8fe 100644 --- a/custom/jao-custom-notmuch.el +++ b/custom/jao-custom-notmuch.el @@ -53,114 +53,29 @@ (jao-minibuffer-add-variable 'jao-notmuch-minibuffer-string -20)) ;;; saved searches -(defvar jao-notmuch--new nil) -(defvar jao-notmuch--new-rx nil) -(defvar jao-notmuch--newa nil) - -(defun jao-notmuch--tags-q (tags) - (format "tag:\"/^(%s)$/\"" (mapconcat (lambda (s) (format "%s" s)) tags "|"))) - -(defun jao-notmuch--new (&rest tags) - (cond ((listp jao-notmuch--new) - (jao-notmuch--tags-q (append jao-notmuch--new tags))) - (tags (concat jao-notmuch--new " OR " (jao-notmuch--tags-q tags))) - (t jao-notmuch--new))) - -(defun jao-notmuch--set-new-search (s) - (setq jao-notmuch--new s - jao-notmuch--new-rx (regexp-quote (jao-notmuch--new)) - jao-notmuch--newa (concat (jao-notmuch--new) " AND "))) - -(defun jao-notmuch--q (d0 &optional k d1 qs st) - (let* ((qs (when qs (mapconcat (lambda (q) (format "%s" q)) qs " AND "))) - (q (or qs - (concat (jao-notmuch--new) - (mapconcat (lambda (d) (when d (concat " AND tag:" d))) - (list d0 d1)))))) - (list :name (concat d0 (when (and d1 (not (string= "" d1))) "/") d1) - :key k :query q :search-type (or st 'tree) - :sort-order 'oldest-first))) - -(defun jao-notmuch--q-feed (q) - (apply #'jao-notmuch--q (cons "feeds" q))) - -(defun jao-notmuch-tree-widen-search () - (interactive) - (when-let* ((query (notmuch-tree-get-query))) - (let ((notmuch-show-process-crypto (notmuch-tree--message-process-crypto))) - (notmuch-tree-close-message-window) - (notmuch-tree (string-replace jao-notmuch--newa "" query))))) - -(defun jao-notmuch--widen (s &optional extra) - (let* ((q (plist-get s :query)) - (qs (string-replace jao-notmuch--newa "" q))) - (plist-put (copy-sequence s) :query (concat qs extra)))) - -(defun jao-notmuch-widen-searches (searches &optional extra) - (mapcar (lambda (s) (jao-notmuch--widen s extra)) searches)) - -(defun jao-notmuch-hello--insert-searches (searches title) - (when-let* ((searches (notmuch-hello-query-counts searches))) - (let* ((cnt (when title - (seq-reduce (lambda (c q) - (+ c (or (plist-get q :count) 0))) - searches - 0))) - (title (when title (format "%d %s" cnt title))) - (notmuch-column-control 1.0)) - (when title - (widget-insert (propertize title 'face 'jao-themes-f00)) - (newline) - (jao-notmuch-hbar 5)) - (notmuch-hello-insert-buttons searches) - (newline)))) - -(defun jao-notmuch--replace (lst s) - (let ((name (plist-get s :name))) - (set lst (seq-remove (lambda (s0) (string= name (plist-get s0 :name))) - (symbol-value lst))) - (add-to-list lst s t))) - -(defun jao-notmuch--def-searches (name searches &optional no-save) - (declare (indent 1)) - (unless no-save - (dolist (s searches) - (jao-notmuch--replace 'jao-notmuch-widened-searches - (jao-notmuch--widen s)) - (jao-notmuch--replace 'notmuch-saved-searches s))) - (add-to-list 'notmuch-hello-sections - `(jao-notmuch-hello--insert-searches ,searches ,name) - t)) - -(defvar jao-notmuch-widened-searches nil) - -(defun jao-notmuch-init-searches (s &optional other) - (jao-notmuch--set-new-search s) - - (setq notmuch-hello-sections nil - notmuch-saved-searches nil - jao-notmuch-widened-searches nil) - - (when other (jao-notmuch--def-searches (car other) (cdr other)))) +(defvar jao-notmuch-title-face 'jao-themes-f00) +(defvar jao-notmuch-alt-title-face '(:foreground "grey60")) (defun jao-notmuch-define-personal-searches () - (jao-notmuch--def-searches "inbox" + (jao-notmuch-def-searches "inbox" `(,(jao-notmuch--q "inbox" "i") ,(jao-notmuch--q "write" "w") ,(jao-notmuch--q "drivel" "d") ,(jao-notmuch--q "trove" "t") - ,(jao-notmuch--q "local" "x"))) + ,(jao-notmuch--q "local" "x")) + nil jao-notmuch-title-face) - (jao-notmuch--def-searches "news" + (jao-notmuch-def-searches "news" (mapcar 'jao-notmuch--q-feed '(("fn" "news") ("fd" "noticias") ("ff" "fun") ("fw" "words") ("fc" "computers") - ("fp" "pens")))) + ("fp" "pens"))) + nil jao-notmuch-title-face) - (jao-notmuch--def-searches "hacking" + (jao-notmuch-def-searches "hacking" `(,(jao-notmuch--q "hacking" "h") ,(jao-notmuch--q "prog" "p") ,@(mapcar 'jao-notmuch--q-feed @@ -172,43 +87,48 @@ ("ln" "notmuch") ("lr" "rust") ("ls" "scheme") - ("lx" "xmobar"))))) + ("lx" "xmobar")))) + nil jao-notmuch-title-face) - (jao-notmuch--def-searches "sci" + (jao-notmuch-def-searches "sci" (mapcar 'jao-notmuch--q-feed '(("sp" "philosophy") ("sm" "math") ("sp" "physics") ("ss" "sci") ("sg" "gr-qc") - ("sq" "quant-ph"))))) + ("sq" "quant-ph"))) + nil jao-notmuch-title-face)) (defun jao-notmuch-define-flag-searches () - (jao-notmuch--def-searches "flags" + (jao-notmuch-def-searches "flags" (jao-notmuch-widen-searches notmuch-saved-searches " AND tag:flagged") - t) - (jao-notmuch--def-searches nil + t + jao-notmuch-alt-title-face) + (jao-notmuch-def-searches nil `(,(jao-notmuch--q "flagged" "F" nil '("tag:flagged"))))) (defun jao-notmuch-define-summary-searches () (jao-notmuch-define-flag-searches) - (jao-notmuch--def-searches "today" + (jao-notmuch-def-searches "today" `(,(jao-notmuch--q "new" "N" nil (list (jao-notmuch--new) "not tag:draft")) ,(jao-notmuch--q "drafts" "D" nil '("tag:draft") t) ,(jao-notmuch--q "sent" "S" nil '("date:1d.." "tag:sent") t) ,(jao-notmuch--q "today" "T" nil '("date:24h.." "not tag:\"/(sent|feeds|spam|local)/\"") - t))) + t)) + nil jao-notmuch-alt-title-face) - (jao-notmuch--def-searches "trove" + (jao-notmuch-def-searches "trove" `((:query "tag:trove" :name "trove" :search-type tree) (:query "tag:hacking" :name "hacking" :search-type tree) (:query "not tag:trove and not tag:hacking" :name "untroved" :search-type tree) - (:query "tag:sent" :name "sent"))) + (:query "tag:sent" :name "sent")) + nil jao-notmuch-alt-title-face) - (jao-notmuch--def-searches nil + (jao-notmuch-def-searches nil '((:query "*" :name "messages" :search-type tree)))) (defun jao-notmuch-define-searches (s &optional other skip-jao) @@ -222,40 +142,6 @@ (jao-notmuch-define-searches '(unread new)) -(defun jao-notmuch-jump-search (&optional widen) - (interactive "P") - (let ((notmuch-saved-searches - (if widen jao-notmuch-widened-searches notmuch-saved-searches))) - (notmuch-jump-search))) - -(defun jao-notmuch--searches-w/new (searches) - (seq-filter (lambda (s) - (string-match-p jao-notmuch--new-rx (plist-get s :query))) - (notmuch-hello-query-counts searches))) - -(defconst jao-notmuch--search-keys '("a" "s" "d" "f" "g" "h" "j" "k" "l")) - -(defun jao-notmuch--index-searches (searches) - (seq-map-indexed (lambda (q i) - (plist-put q :key (or (elt jao-notmuch--search-keys i) - (format "%s" i)))) - searches)) - -(defun jao-notmuch-jump () - "Jump to a saved, non-zero count search." - (interactive) - (if-let* ((searches (jao-notmuch--searches-w/new notmuch-saved-searches))) - (if (= 2 (length searches)) - (let* ((q (seq-remove (lambda (q) (string= "new" (plist-get q :name))) - searches)) - (q (car q)) - (of (eq 'oldest-first (plist-get q :sort-order))) - (query (plist-get q :query))) - (notmuch-tree query nil nil nil nil nil nil of t)) - (let ((notmuch-saved-searches (jao-notmuch--index-searches searches))) - (notmuch-jump-search))) - (jao-notmuch-jump-search t))) - ;;; tags (setq notmuch-archive-tags '("+trove" "-hacking" "-new" "-drivel" "-words" "-inbox") diff --git a/lib/net/jao-notmuch.el b/lib/net/jao-notmuch.el index f7829e5..a319555 100644 --- a/lib/net/jao-notmuch.el +++ b/lib/net/jao-notmuch.el @@ -31,6 +31,139 @@ (require 'notmuch-show) +;;; searches +(defvar jao-notmuch--new nil) +(defvar jao-notmuch--new-rx nil) +(defvar jao-notmuch--newa nil) + +(defun jao-notmuch--tags-q (tags) + (format "tag:\"/^(%s)$/\"" (mapconcat (lambda (s) (format "%s" s)) tags "|"))) + +(defun jao-notmuch--new (&rest tags) + (cond ((listp jao-notmuch--new) + (jao-notmuch--tags-q (append jao-notmuch--new tags))) + (tags (concat jao-notmuch--new " OR " (jao-notmuch--tags-q tags))) + (t jao-notmuch--new))) + +(defun jao-notmuch--set-new-search (s) + (setq jao-notmuch--new s + jao-notmuch--new-rx (regexp-quote (jao-notmuch--new)) + jao-notmuch--newa (concat (jao-notmuch--new) " AND "))) + +(defun jao-notmuch--q (d0 &optional k d1 qs st) + (let* ((qs (when qs (mapconcat (lambda (q) (format "%s" q)) qs " AND "))) + (q (or qs + (concat (jao-notmuch--new) + (mapconcat (lambda (d) (when d (concat " AND tag:" d))) + (list d0 d1)))))) + (list :name (concat d0 (when (and d1 (not (string= "" d1))) "/") d1) + :key k :query q :search-type (or st 'tree) + :sort-order 'oldest-first))) + +(defun jao-notmuch--q-feed (q) + (apply #'jao-notmuch--q (cons "feeds" q))) + +;;;###autoload +(defun jao-notmuch-init-searches (s &optional other) + (jao-notmuch--set-new-search s) + + (setq notmuch-hello-sections nil + notmuch-saved-searches nil + jao-notmuch-widened-searches nil) + + (when other (jao-notmuch-def-searches (car other) (cdr other)))) + +;;;###autoload +(defun jao-notmuch-tree-widen-search () + (interactive) + (when-let* ((query (notmuch-tree-get-query))) + (let ((notmuch-show-process-crypto (notmuch-tree--message-process-crypto))) + (notmuch-tree-close-message-window) + (notmuch-tree (string-replace jao-notmuch--newa "" query))))) + +(defun jao-notmuch--widen (s &optional extra) + (let* ((q (plist-get s :query)) + (qs (string-replace jao-notmuch--newa "" q))) + (plist-put (copy-sequence s) :query (concat qs extra)))) + +;;;###autoload +(defun jao-notmuch-widen-searches (searches &optional extra) + (mapcar (lambda (s) (jao-notmuch--widen s extra)) searches)) + +(defun jao-notmuch-hello--insert-searches (searches title title-face) + (when-let* ((searches (notmuch-hello-query-counts searches))) + (let* ((cnt (when title + (seq-reduce (lambda (c q) + (+ c (or (plist-get q :count) 0))) + searches + 0))) + (title (when title (format "%d %s" cnt title))) + (notmuch-column-control 1.0) + (title-face (or title-face 'jao-themes-f00))) + (when title + (widget-insert (propertize title 'face title-face)) + (newline) + (jao-notmuch-hbar 5)) + (notmuch-hello-insert-buttons searches) + (newline)))) + +(defun jao-notmuch--replace (lst s) + (let ((name (plist-get s :name))) + (set lst (seq-remove (lambda (s0) (string= name (plist-get s0 :name))) + (symbol-value lst))) + (add-to-list lst s t))) + +;;;###autoload +(defun jao-notmuch-def-searches (name searches &optional no-save title-face) + (declare (indent 1)) + (unless no-save + (dolist (s searches) + (jao-notmuch--replace 'jao-notmuch-widened-searches + (jao-notmuch--widen s)) + (jao-notmuch--replace 'notmuch-saved-searches s))) + (add-to-list 'notmuch-hello-sections + `(jao-notmuch-hello--insert-searches ,searches ,name ,title-face) + t)) + +(defvar jao-notmuch-widened-searches nil) + +;;; jump to searches +(defun jao-notmuch--searches-w/new (searches) + (seq-filter (lambda (s) + (string-match-p jao-notmuch--new-rx (plist-get s :query))) + (notmuch-hello-query-counts searches))) + +(defconst jao-notmuch--search-keys '("a" "s" "d" "f" "g" "h" "j" "k" "l")) + +(defun jao-notmuch--index-searches (searches) + (seq-map-indexed (lambda (q i) + (plist-put q :key (or (elt jao-notmuch--search-keys i) + (format "%s" i)))) + searches)) + +;;;###autoload +(defun jao-notmuch-jump-search (&optional widen) + (interactive "P") + (let ((notmuch-saved-searches + (if widen jao-notmuch-widened-searches notmuch-saved-searches))) + (notmuch-jump-search))) + +;;;###autoload +(defun jao-notmuch-jump () + "Jump to a saved, non-zero count search." + (interactive) + (if-let* ((searches (jao-notmuch--searches-w/new notmuch-saved-searches))) + (if (= 2 (length searches)) + (let* ((q (seq-remove (lambda (q) (string= "new" (plist-get q :name))) + searches)) + (q (car q)) + (of (eq 'oldest-first (plist-get q :sort-order))) + (query (plist-get q :query))) + (notmuch-tree query nil nil nil nil nil nil of t)) + (let ((notmuch-saved-searches (jao-notmuch--index-searches searches))) + (notmuch-jump-search))) + (jao-notmuch-jump-search t))) + ;;; targetting the displayed message from the tree view (defvar-local jao-notmuch--tree-buffer nil) -- cgit v1.2.3