diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2020-06-01 17:39:04 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2020-06-01 17:39:04 -0700 |
commit | 55f9674e3d41c27afb43612f70c807e353a55873 (patch) | |
tree | 05bb3025719524bfdeb87674427261ff39f0f06f | |
parent | 68971b3209424b56f7d55ba327eff24950980d80 (diff) | |
download | dotfiles-55f9674e3d41c27afb43612f70c807e353a55873.tar.gz |
tidy up init-notmuch.el
-rw-r--r-- | .emacs.d/init-notmuch.el | 280 |
1 files changed, 145 insertions, 135 deletions
diff --git a/.emacs.d/init-notmuch.el b/.emacs.d/init-notmuch.el index 805ef194..34eebf6c 100644 --- a/.emacs.d/init-notmuch.el +++ b/.emacs.d/init-notmuch.el @@ -1,97 +1,78 @@ -;;; notmuch-config.el --- Sean's notmuch config -*- lexical-binding: t -*- +;;; init-notmuch.el --- Sean's notmuch-emacs config -*- lexical-binding: t -*- + +;;; Code: (require 'cl-lib) (require 'dash) + (require 'notmuch) (require 'notmuch-hello) (require 'notmuch-message) -(define-key notmuch-hello-mode-map [f9] 'spw/next-unread-group) -(define-key notmuch-message-mode-map "\C-c\C-s" 'message-goto-subject) - -(define-key notmuch-show-part-map "\C-c|" 'spw/notmuch-import-gpg) -(define-key notmuch-show-part-map "a" 'spw/notmuch-show-apply-part-projectile) - -;; we want these not to be adjacent keys -(define-key notmuch-search-mode-map [f5] 'spw/spam-message) -(define-key notmuch-search-mode-map [f7] 'spw/kill-thread) -(define-key notmuch-search-mode-map [f9] 'spw/next-unread-group) - -;; ditto -(define-key notmuch-show-mode-map [f5] 'spw/spam-message) -(define-key notmuch-show-mode-map [f7] 'spw/kill-thread) - -(define-key notmuch-tree-mode-map "o" 'spw/notmuch-tree-reader) -(define-key notmuch-tree-mode-map "C" 'spw/notmuch-tree-catchup) - -;; ditto -(define-key notmuch-tree-mode-map [f5] 'spw/spam-message) -(define-key notmuch-tree-mode-map [f7] 'spw/kill-thread) -(define-key notmuch-tree-mode-map [f9] 'spw/next-unread-group) - -;;;; ---- preferences & variables ---- - -(setq notmuch-show-all-tags-list t) - -(setq - notmuch-tagging-keys '(("u" ("+unread") "Mark as unread") - ("s" ("-unread" "+spam") "Mark as spam") - - ;; 'm' for 'mute' - ("m" ("-unread" "+spw::killed") "Kill thread") - - ;; for work mail sent to a personal address, or similar - ("w" ("+spw::work") "Mark as work-related") - - ("b" ("+spw::browse") "Mark for browsing") - ("d" ("-unread" "+deleted") "Send to trash") - ("f" ("-unread" "+flagged") "Unread->flagged") - ("F" ("-flagged") "Unflag message")) - - ;; default is t, but given that notmuch searches run to the - ;; beginning of time, and we are likely to want recent mail, we want - ;; newer e-mails at the top - notmuch-search-oldest-first nil - - ;; don't collapse cited text - ;; We ought to be able to just remove - ;; `notmuch-wash-excerpt-citations' from - ;; `notmuch-show-insert-text/plain-hook', but that function is also - ;; responsible for colouring cited text (this is an upstream bug: - ;; that function does the colouring for performance reasons but the - ;; right answer is to use fontlocking, not overlays, for the colouring) - notmuch-wash-citation-lines-prefix 10000 - notmuch-wash-citation-lines-suffix 10000 - - send-mail-function 'sendmail-send-it - - ;; always decrypt & verify PGP parts - notmuch-crypto-process-mime t - - ;; have Emacs set envelope-from to bypass any MTA rewriting - mail-specify-envelope-from t - message-sendmail-envelope-from 'header - mail-envelope-from 'header - - notmuch-archive-tags '("-unread") - notmuch-maildir-use-notmuch-insert t - notmuch-fcc-dirs "sent -unread" - - ;; when 'unread' is being used as an inbox, want manual resolution - ;; of messages - notmuch-show-mark-read-function (lambda (beg end)) - notmuch-show-mark-read-tags nil - ;; but always resolve when I write a reply - notmuch-message-replied-tags '("-unread" "+replied") - - notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full) + +;;;; Preferences and variables + +(setq notmuch-show-all-tags-list t + notmuch-tagging-keys '(("u" ("+unread") "Mark as unread") + ("s" ("-unread" "+spam") "Mark as spam") + + ;; 'm' for 'mute' + ("m" ("-unread" "+spw::killed") "Kill thread") + + ;; for work mail sent to a personal + ;; address, or similar + ("w" ("+spw::work") "Mark as work-related") + + ("b" ("+spw::browse") "Mark for browsing") + ("d" ("-unread" "+deleted") "Send to trash") + ("f" ("-unread" "+flagged") "Unread->flagged") + ("F" ("-flagged") "Unflag message")) + + ;; default is t, but given that notmuch searches run to the + ;; beginning of time, and we are likely to want recent mail, we want + ;; newer e-mails at the top + notmuch-search-oldest-first nil + + ;; Don't collapse cited text. We ought to be able to just remove + ;; `notmuch-wash-excerpt-citations' from + ;; `notmuch-show-insert-text/plain-hook', but that function is also + ;; responsible for colouring cited text (this is an upstream bug: + ;; that function does the colouring for performance reasons but the + ;; right answer is to use fontlocking, not overlays, for the + ;; colouring) + notmuch-wash-citation-lines-prefix 10000 + notmuch-wash-citation-lines-suffix 10000 + + send-mail-function 'sendmail-send-it + + ;; always decrypt & verify PGP parts + notmuch-crypto-process-mime t + + ;; have Emacs set envelope-from to bypass my MTA rewriting of + ;; user@localhost + mail-specify-envelope-from t + mail-envelope-from 'header + message-sendmail-envelope-from 'header + + notmuch-archive-tags '("-unread") + notmuch-maildir-use-notmuch-insert t + notmuch-fcc-dirs "sent -unread" + + ;; when 'unread' is being used as an inbox, want manual resolution + ;; of messages + notmuch-show-mark-read-function 'ignore + notmuch-show-mark-read-tags nil + ;; but always resolve when I write a reply + notmuch-message-replied-tags '("-unread" "+replied") + + notmuch-mua-user-agent-function 'notmuch-mua-user-agent-full) ;; these three vars get set in notmuch-groups.el -(defvar spw--lists-readall nil +(defvar spw/lists-readall nil "Lists where I want to read all posts as if they're addressed directly to me -- these get inserted into my main inbox views.") -(defvar spw--lists-browse nil +(defvar spw/lists-browse nil "Lists I want to read like newsgroups, though with no expiry and manual catchup. @@ -100,24 +81,52 @@ Two ways to read: 1. Access saved searches from `notmuch-hello', then use `notmuch-search-filter' to look for something in particular. -2. Access using `spw--next-unread-group' to read new postings.") -(defvar spw--lists-archiveonly nil +2. Access using `spw/next-unread-group' to read new postings.") +(defvar spw/lists-archiveonly nil "Lists for which I'm subscribed only because I want to archive all postings. Sieve script should be configured to mark as read.") -;; indeed, all marking as read should occur server-side +;; indeed, marking as read of incoming mail should generally occur +;; server-side + + +;;;; Bindings and advising commands (advice-add 'notmuch-tree-archive-thread :after #'notmuch-tree-next-thread) - +(define-key notmuch-message-mode-map "\C-c\C-s" #'message-goto-subject) -;;;; ---- functions ---- +(define-key notmuch-show-part-map "\C-c|" #'spw/notmuch-import-gpg) +(define-key notmuch-show-part-map "a" #'spw/notmuch-show-apply-part-projectile) + +;; we want these not to be adjacent keys +(define-key notmuch-search-mode-map [f5] #'spw/spam-message) +(define-key notmuch-search-mode-map [f7] #'spw/kill-thread) +(define-key notmuch-search-mode-map [f9] #'spw/next-unread-group) -(defun spw--notmuch-import-gpg () +;; ditto +(define-key notmuch-show-mode-map [f5] #'spw/spam-message) +(define-key notmuch-show-mode-map [f7] #'spw/kill-thread) + +;; ditto +(define-key notmuch-tree-mode-map [f5] #'spw/spam-message) +(define-key notmuch-tree-mode-map [f7] #'spw/kill-thread) +(define-key notmuch-tree-mode-map [f9] #'spw/next-unread-group) + +(define-key notmuch-hello-mode-map [f9] #'spw/next-unread-group) + +(define-key notmuch-tree-mode-map "o" #'spw/notmuch-tree-reader) +(define-key notmuch-tree-mode-map "C" #'spw/notmuch-tree-catchup) + + +;;;; Commands + +(defun spw/notmuch-import-gpg () (interactive) (when (get-buffer "*notmuch-pipe*") (with-current-buffer "*notmuch-pipe*" - (let ((buffer-read-only nil)) (erase-buffer)))) + (let ((buffer-read-only nil)) + (erase-buffer)))) (notmuch-show-pipe-message t "gpg --decrypt | gpg --import") (display-buffer "*notmuch-pipe*")) @@ -125,8 +134,8 @@ Two ways to read: ;; `notmuch-extract-message-patches', it does not make sense to ;; check out a branch when performing an action which will not make ;; a commit. If that's wanted, the code which calls -;; `spw--notmuch-show-apply-part-projectile' should perform the checkout -(defun spw--notmuch-show-apply-part-projectile () +;; `spw/notmuch-show-apply-part-projectile' should perform the checkout +(defun spw/notmuch-show-apply-part-projectile () (interactive) (let* ((repo (projectile-completing-read "Select projectile project: " projectile-known-projects)) @@ -138,7 +147,7 @@ Two ways to read: ;; not available in `notmuch-search-mode' for now because we want to ;; apply spw::killed to only a single message, not a whole thread, ;; to minimise what gets committed to ~/lib/nmbug-spw -(defun spw--kill-thread () +(defun spw/kill-thread () (interactive) (case major-mode (notmuch-show-mode @@ -151,9 +160,9 @@ Two ways to read: (unless (notmuch-tree-get-match) (notmuch-tree-next-matching-message)) (notmuch-tree-show-message nil))) - (message "thread killed")) + (message "Thread killed")) -(defun spw--spam-message () +(defun spw/spam-message () (interactive) (case major-mode (notmuch-show-mode @@ -162,9 +171,9 @@ Two ways to read: (notmuch-tree-mode (notmuch-tree-tag '("-unread" "+spam")) (notmuch-tree-next-matching-message))) - (message "thread marked as spam")) + (message "Message marked as spam")) -(defun spw--notmuch-tree-reader () +(defun spw/notmuch-tree-reader () (interactive) (with-current-buffer notmuch-tree-message-buffer (re-search-forward "^URL:\\( \\|\n\\)") @@ -173,14 +182,11 @@ Two ways to read: "-new-window" (concat "about:reader?url=" url))))) - - -;;;; ---- more variables & functions, with connectives ---- - (defvar spw/lists-browse-searches nil "Internal cache variable.") (defvar spw/readall nil "Internal cache variable.") + (cl-flet* ((connective (word) (apply-partially (lambda (connec &rest queries) @@ -192,19 +198,18 @@ Two ways to read: (conjoin (connective "and")) (negate (query) (concat "not (" query ")")) (thread (query) (concat "thread:{" query "}"))) - - (defvar spw--weekday-only-mail (disjoin "to:spwhitton@email.arizona.edu" + (defvar spw/weekday-only-mail (disjoin "to:spwhitton@email.arizona.edu" "from:arizona.edu" (thread "tag:spw::work")) "Mail to be filtered out of processing views at the weekend.") - (defun spw--standard-notmuch-saved-searches () + (defun spw/standard-notmuch-saved-searches () (interactive) (setq notmuch-saved-searches nil spw/lists-browse-searches nil) (when (file-exists-p (locate-user-emacs-file "notmuch-groups.el")) (load (locate-user-emacs-file "notmuch-groups")) - (dolist (group spw--lists-browse) + (dolist (group spw/lists-browse) (let ((search (if (atom group) ;; assume we got a List: search and extract the first @@ -237,13 +242,13 @@ Two ways to read: ;; relying on 'folder:inbox' ;; (mapcar (lambda (a) (concat "to:" a)) (notmuch-user-emails)) - spw--lists-readall) + spw/lists-readall) (negate (thread "tag:spw::browse")))) ;; now prepend views for processing the day's mail addressed to me (let* ((to-process (conjoin "tag:unread" spw/readall)) (to-process-weekend (conjoin to-process - (negate spw--weekday-only-mail)))) + (negate spw/weekday-only-mail)))) (add-to-list 'notmuch-saved-searches `(:name "weekend unread" :key "w" :search-type nil :sort-order oldest-first @@ -282,8 +287,8 @@ Two ways to read: (if (atom search) search (plist-get search :queries))) - spw--lists-browse) - spw--lists-archiveonly)) + spw/lists-browse) + spw/lists-archiveonly)) (query `(:name "uncategorised unread" :key "U" :search-type nil :sort-order newest-first :query ,(conjoin "tag:unread" @@ -294,33 +299,8 @@ Two ways to read: (conjoin "tag:unread" (negate categorised))) t))) - (unless spw/lists-browse-searches - (spw--standard-notmuch-saved-searches)) - - (defun spw/next-unread-group () - (interactive) - (let ((already-looking (boundp 'spw--more-unread-groups)) - (queries (bound-and-true-p spw--more-unread-groups)) - (remaining)) - (when already-looking - (notmuch-tree-close-message-window) - (kill-buffer (current-buffer))) - (if (or (and already-looking (not queries)) - (not (setq remaining (seq-drop-while - (lambda (q) - (zerop (string-to-number - (notmuch-saved-search-count - (cdr q))))) - (or queries spw/lists-browse-searches))))) - (notmuch-hello) - (notmuch-tree (cdar remaining) nil nil - (concat "*notmuch-tree-saved-search-" - (caar remaining) "*")) - (set (make-local-variable 'spw--more-unread-groups) - (cdr remaining))))) - - ;; use on views produced by `spw--next-unread-group' - (defun spw--notmuch-tree-catchup () + ;; use on views produced by `spw/next-unread-group' + (defun spw/notmuch-tree-catchup () (interactive) (when (and (eq major-mode 'notmuch-tree-mode) (y-or-n-p "Are you sure you want to mark all as read?") @@ -328,3 +308,33 @@ Two ways to read: (notmuch-tag (conjoin (notmuch-tree-get-query) (negate spw/readall)) '("-unread")) (notmuch-refresh-this-buffer)))) + +(defun spw/next-unread-group () + (interactive) + (let ((already-looking (boundp 'spw/more-unread-groups)) + (queries (bound-and-true-p spw/more-unread-groups)) + (remaining)) + (when already-looking + (notmuch-tree-close-message-window) + (kill-buffer (current-buffer))) + (if (or (and already-looking (not queries)) + (not (setq remaining (seq-drop-while + (lambda (q) + (zerop (string-to-number + (notmuch-saved-search-count + (cdr q))))) + (or queries spw/lists-browse-searches))))) + (notmuch-hello) + (notmuch-tree (cdar remaining) nil nil + (concat "*notmuch-tree-saved-search-" + (caar remaining) "*")) + (set (make-local-variable 'spw/more-unread-groups) + (cdr remaining))))) + + +;;;; Startup + +(unless spw/lists-browse-searches + (spw/standard-notmuch-saved-searches)) + +;;; init-notmuch.el ends here |