From e9534d188eb47a1510da7c971351bd4633a58928 Mon Sep 17 00:00:00 2001 From: jao Date: Wed, 30 Jun 2021 23:59:48 +0100 Subject: independent notmuch.org --- email.org | 311 +----------------------------------------------------------- notmuch.org | 304 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 308 insertions(+), 307 deletions(-) create mode 100644 notmuch.org diff --git a/email.org b/email.org index 1ee477f..cf76ff0 100644 --- a/email.org +++ b/email.org @@ -190,8 +190,8 @@ (add-to-list 'mailcap-mime-extensions '(".JPG" . "image/jpeg")) (defun jao-icalendar-import-buffer () - (let ((icalendar-import-format "%s%u%l")) - (icalendar-import-buffer diary-file)) + (let ((icalendar-import-format "%s%u%l%d")) + (icalendar-import-buffer diary-file t nil)) (kill-buffer)) :custom ((mailcap-user-mime-data @@ -303,7 +303,8 @@ #+begin_src emacs-lisp (setq gnus-init-file "~/.emacs.d/gnus.el" gnus-home-directory "~/.emacs.d/gnus" - gnus-directory gnus-home-directory) + gnus-directory gnus-home-directory + mail-source-directory (expand-file-name "Mail" gnus-home-directory)) #+end_src *** Notifications #+begin_src emacs-lisp @@ -316,307 +317,3 @@ (let ((inhibit-message t)) (gnus-demon-scan-news))))) #+end_src -* notmuch -*** minibuffer notifications - #+begin_src emacs-lisp - (defvar jao-notmuch-minibuffer-string "") - - (defvar jao-notmuch-minibuffer-queries - '((:name "" :query "tag:new" :face jao-themes-f00) - (:name "B" :query "tag:new and tag:bigml and tag:inbox") - (:name "b" :query "tag:new and tag:bigml and tag:bugs" - :face jao-themes-error) - (:name "S" :query "tag:new and tag:bigml and tag:support") - (:name "W" :query "tag:new and tag:bigml" :face jao-themes-dimm) - (:name "I" :query "tag:new and tag:jao and tag:inbox") - (:name "H" :query "tag:new and tag:jao and tag:hacking") - (:name "E" :query "tag:new and tag:emacs" :face jao-themes-dimm) - (:name "J" :query - "tag:new and tag:jao and not tag:\"/emacs|hacking|feeds/\"" - :face jao-themes-dimm) - (:name "N" :query "tag:new and tag:gmane and not tag:emacs" - :face jao-themes-dimm) - (:name "F" :query "tag:new and tag:feeds and not tag:emacs" - :face jao-themes-dimm))) - - (defun jao-notmuch-notify () - (let ((cnts (notmuch-hello-query-counts jao-notmuch-minibuffer-queries))) - (setq jao-notmuch-minibuffer-string - (mapconcat (lambda (c) - (propertize (format "%s%s" - (plist-get c :name) - (plist-get c :count)) - 'face (plist-get c :face))) - cnts - " ")) - (jao-minibuffer-refresh))) - - (when (eq jao-afio-mail-function 'notmuch) - (jao-minibuffer-add-variable 'jao-notmuch-minibuffer-string -20)) - #+end_src -*** searches - #+begin_src emacs-lisp - (setq notmuch-tree-result-format - '(("date" . "%12s ") - ("authors" . "%-35s") - ((("tree" . "%s ")("subject" . "%s")) . " %-100s") - ("tags" . " (%s)")) - notmuch-search-result-format - '(("date" . "%12s ") - ("count" . "%-7s ") - ("authors" . "%-35s") - ("subject" . "%-100s") - ("tags" . "(%s)")) - notmuch-unthreaded-result-format notmuch-tree-result-format) - - (defun jao-notmuch--q (d0 d1 &optional k qs st) - (let ((q (or (when qs (mapconcat #'identity qs " AND ")) - (concat "tag:\"/^(unread|new)$/\" AND " - (mapconcat (lambda (d) (when d (concat "tag:" d))) - (list d0 d1) " AND "))))) - (list :name (concat d0 (when d1 "/") d1) - :key k :query q :search-type (or st 'tree) - :sort-order 'oldest-first))) - - (defun jao-notmuch--mboxes-search (box &rest excluded) - (let ((ms (seq-difference (jao-list-mailboxes box) excluded)) - (bp (substring box 0 1))) - (mapcar (lambda (m) (jao-notmuch--q box (car m) (concat bp (cdr m)))) - (shorten-strings (sort ms #'string<))))) - - (setq notmuch-saved-searches - `(,(jao-notmuch--q "bigml" "inbox" "bi") - ,(jao-notmuch--q "bigml" "support" "bs") - ,(jao-notmuch--q "bigml" "bug" "bb") - ,@(jao-notmuch--mboxes-search "bigml" "inbox" "support") - ,@(jao-notmuch--mboxes-search "jao") - ,(jao-notmuch--q "local" nil "l" '("tag:local" "tag:new")) - ,(jao-notmuch--q "gmane" "emacs" "e") - ,(jao-notmuch--q "gmane" nil "g" - '("tag:gmane" "tag:new" "not tag:emacs")) - ,@(jao-notmuch--mboxes-search "feeds") - ,(jao-notmuch--q "bml" "today" "tb" '("tag:bigml" "date:1d..") t) - ,(jao-notmuch--q "jao" "today" "tj" - '("tag:jao" "date:1d.." - "not tag:\"/(feeds|spam)/\"") - t) - ,(jao-notmuch--q "flagged" nil "r" '("tag:flagged") t) - ,(jao-notmuch--q "new" nil "n" '("tag:new")) - ,(jao-notmuch--q "draft" nil "d" '("tag:draft")))) - #+end_src -*** enclosures - #+begin_src emacs-lisp - (with-eval-after-load "notmuch-show" - (defun jao-notmuch-open-enclosure (add) - (interactive "P") - (with-current-notmuch-show-message - (goto-char (point-min)) - (if (not (search-forward "Enclosure:" nil t)) - (user-error "No enclosure in message body") - (re-search-forward "https?://" nil t) - (if-let (url (thing-at-point-url-at-point)) - (progn - (message "%s %s ..." (if add "Adding" "Playing") url) - (unless add (jao-mpc-clear)) - (jao-mpc-add-url url) - (unless add (jao-mpc-play))) - (error "Found an enclosure, but not a link!")))))) - #+end_src -*** package - #+begin_src emacs-lisp - (if (< emacs-major-version 28) - (jao-load-path "notmuch") - (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/")) - - (use-package notmuch - :init - (setq notmuch-draft-folder "trove/drafts" - notmuch-draft-quoted-tags '("part") - notmuch-hello-sections '(notmuch-hello-insert-saved-searches - notmuch-hello-insert-alltags - notmuch-hello-insert-header) - notmuch-hello-thousands-separator "," - notmuch-hello-auto-refresh t - notmuch-show-all-tags-list t - notmuch-show-logo nil - notmuch-show-empty-saved-searches nil - notmuch-show-part-button-default-action 'notmuch-show-view-part - notmuch-show-mark-read-tags '("-new" "-unread") - notmuch-archive-tags '("+trove" "-new") - notmuch-fcc-dirs - '((".*@bigml.com" . "bigml/sent +bigml +sent -new") - (".*" . "jao/sent +jao +sent -new")) - notmuch-maildir-use-notmuch-insert t - notmuch-message-headers '("Subject" "To" "Cc" "Date" "List-Id") - notmuch-wash-signature-lines-max 0 - notmuch-wash-wrap-lines-length 80 - notmuch-wash-citation-lines-prefix 10 - notmuch-wash-citation-lines-suffix 20) - - :config - - (when (eq 'notmuch jao-afio-mail-function) - (setq mm-text-html-renderer 'shr - message-directory "~/var/mail/" - message-auto-save-directory "/tmp") - (with-eval-after-load "notmuch-message" - (define-key message-mode-map (kbd "C-c C-d") - #'notmuch-draft-postpone))) - - (defun jao-mail-clean-address (fun address) - (let ((address - (if (string-match ".+ updates on arXiv.org: \\(.+\\)" address) - (with-temp-buffer - (insert (match-string 1 address)) - (let ((shr-width 1000)) - (shr-render-region (point-min) (point-max))) - (buffer-string)) - (string-replace "ElDiario.es - ElDiario.es" "D.es" address)))) - (funcall fun address))) - - (advice-add 'notmuch-clean-address :around #'jao-mail-clean-address) - - (defun jao-notmuch-refresh-agenda () - (interactive) - (save-window-excursion (org-agenda-list))) - - (defun jao-notmuch-hello-first () - (interactive) - (let ((inhibit-message t)) - (beginning-of-buffer) - (widget-forward 2))) - - (defun jao-notmuch-refresh-hello () - (interactive) - (ignore-errors - (when (and (string= "Mail" (jao-afio-current-frame)) - (derived-mode-p 'notmuch-hello-mode)) - (when (not (string-blank-p jao-notmuch-minibuffer-string)) - (let ((notmuch-hello-auto-refresh nil)) (notmuch-hello))) - (jao-notmuch-hello-first)))) - - :hook ((notmuch-hello-refresh . jao-notmuch-notify) - (jao-afio-switch . jao-notmuch-refresh-hello)) - - :bind (:map notmuch-hello-mode-map - (("a" . jao-notmuch-refresh-agenda) - ("S" . consult-notmuch) - ("g" . jao-notmuch-refresh-hello) - ("." . jao-notmuch-hello-first) - ("SPC" . widget-button-press)) - :map notmuch-common-keymap - (("E" . jao-notmuch-open-enclosure)))) - #+end_src -*** tree view - #+begin_src emacs-lisp - (use-package jao-notmuch - :demand t - :config (setq jao-notmuch-mailboxes (jao-mailbox-folders))) - - (use-package notmuch-tree - :config - - (let ((fg (face-attribute 'jao-themes-dimm :foreground))) - (dolist (f '(notmuch-tree-match-tree-face - notmuch-tree-no-match-tree-face)) - (set-face-attribute f nil :family "Fira Code" :foreground fg))) - - (defun jao-notmuch--format-field (fun field &rest args) - (let ((rs (apply fun field args))) - (cond ((and (stringp field) (string= field "tree")) - (replace-regexp-in-string "►" "" rs)) ;; "→" - ((not (stringp field)) (truncate-string-to-width rs 100)) - (t rs)))) - - (advice-add 'notmuch-tree-format-field - :around #'jao-notmuch--format-field) - - :bind (:map notmuch-tree-mode-map - (("." . jao-notmuch-toggle-mime-parts) - ("C" . jao-notmuch-echo-count) - ("d" . jao-notmuch-tree-delete-message) - ("D" . jao-notmuch-tree-delete-thread) - ("h" . jao-notmuch-goto-message-buffer) - ("H" . jao-notmuch-click-message-buffer) - ("i" . jao-notmuch-toggle-images) - ("K" . jao-notmuch-tag-jump-and-next) - ("k" . jao-notmuch-tree-read-thread) - ("M" . jao-notmuch-move-message) - ("n" . jao-notmuch-tree-next) - ("s" . jao-notmuch-tree-spam) - ("u" . jao-notmuch-tree-flag) - ("RET" . jao-notmuch-tree-show-or-scroll) - ("SPC" . jao-notmuch-tree-scroll-or-next)) - :map notmuch-show-mode-map - (("h" . jao-notmuch-goto-tree-buffer)) - :map notmuch-common-keymap - (("B" . jao-notmuch-browse-urls)))) - #+end_src -*** hydras - #+begin_src emacs-lisp - (major-mode-hydra-define notmuch-search-mode nil - ("Tagging" - (("*" notmuch-search-tag-all "tag all") - ("+" notmuch-search-add-tag "add tag") - ("-" notmuch-search-remove-tag "add tag") - ("k" notmuch-tag-jump "jump to tag")) - "Search" - (("l" notmuch-search-filter "filter with additional query") - ("t" notmuch-search-filter-by-tag "filter by tag") - ("y" notmuch-stash-query "stash current query")) - "Moving around" - (("b" notmuch-search-scroll-down "scroll down") - ("<" notmuch-search-first-thread "first thread") - (">" notmuch-search-last-thread "last thread")))) - - (major-mode-hydra-define notmuch-tree-mode nil - ("View" - (("." jao-notmuch-toggle-mime-parts "toggle mime parts") - ("i" jao-notmuch-toggle-images "toggle images") - ("a" notmuch-tree-archive-thread-then-next "archive thread") - ("C" jao-notmuch-echo-count "echo unread count")) - "Mark" - (("d" jao-notmuch-tree-delete-message "delete message") - ("D" jao-notmuch-tree-delete-thread "delete thread") - ("u" (jao-notmuch-tree-delete-message t) "undelete message") - ("k" jao-notmuch-tree-read-thread "kill thread")) - "Edit/send" - (("r" notmuch-tree-reply-sender "reply sender") - ("R" notmuch-tree-reply "reply all") - ("f" notmuch-tree-forward-message "forward") - ("e" notmuch-tree-resume-message "edit draft")))) - #+end_src -*** consult - #+begin_src emacs-lisp - (jao-load-path "consult-notmuch") - (setq consult-notmuch-authors-width 30) - (require 'consult-notmuch) - (consult-customize consult-notmuch :preview-key 'any) - - (defvar jao-consult-notmuch-history nil) - - (defun jao-consult-notmuch-folder (&optional tree folder) - (interactive "P") - (let* ((root "~/var/mail/") - (folder (if folder - (file-name-as-directory folder) - (completing-read "Folder: " - jao-mailbox-folders - nil nil nil - jao-consult-notmuch-history - "."))) - (folder (replace-regexp-in-string "/\\(.\\)" ".\\1" folder)) - (init (read-string "Initial query: ")) - (init (format "folder:/%s/ %s" folder init))) - (if tree (consult-notmuch-tree init) (consult-notmuch init)))) - - (with-eval-after-load "notmuch-hello" - (define-key notmuch-hello-mode-map "f" #'jao-consult-notmuch-folder)) - #+end_src -*** org mode integration - Stolen and adapted from [[https://gist.github.com/fedxa/fac592424473f1b70ea489cc64e08911][Fedor Bezrukov]]. - #+begin_src emacs-lisp - (jao-load-path "ol-notmuch") - (use-package ol-notmuch - :demand t) - #+end_src diff --git a/notmuch.org b/notmuch.org new file mode 100644 index 0000000..5ba0027 --- /dev/null +++ b/notmuch.org @@ -0,0 +1,304 @@ +#+property: header-args:emacs-lisp :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t; -*-" :tangle-mode (identity #o644) +#+title: notmuch configuration + +* minibuffer notifications + #+begin_src emacs-lisp + (defvar jao-notmuch-minibuffer-string "") + + (defvar jao-notmuch-minibuffer-queries + '((:name "" :query "tag:new" :face jao-themes-f00) + (:name "B" :query "tag:new and tag:bigml and tag:inbox") + (:name "b" :query "tag:new and tag:bigml and tag:bugs" + :face jao-themes-error) + (:name "S" :query "tag:new and tag:bigml and tag:support") + (:name "W" :query "tag:new and tag:bigml" :face jao-themes-dimm) + (:name "I" :query "tag:new and tag:jao and tag:inbox") + (:name "H" :query "tag:new and tag:jao and tag:hacking") + (:name "E" :query "tag:new and tag:emacs" :face jao-themes-dimm) + (:name "J" :query + "tag:new and tag:jao and not tag:\"/emacs|hacking|feeds/\"" + :face jao-themes-dimm) + (:name "N" :query "tag:new and tag:gmane and not tag:emacs" + :face jao-themes-dimm) + (:name "F" :query "tag:new and tag:feeds and not tag:emacs" + :face jao-themes-dimm))) + + (defun jao-notmuch-notify () + (let ((cnts (notmuch-hello-query-counts jao-notmuch-minibuffer-queries))) + (setq jao-notmuch-minibuffer-string + (mapconcat (lambda (c) + (propertize (format "%s%s" + (plist-get c :name) + (plist-get c :count)) + 'face (plist-get c :face))) + cnts + " ")) + (jao-minibuffer-refresh))) + + (when (eq jao-afio-mail-function 'notmuch) + (jao-minibuffer-add-variable 'jao-notmuch-minibuffer-string -20)) + #+end_src +* searches + #+begin_src emacs-lisp + (setq notmuch-tree-result-format + '(("date" . "%12s ") + ("authors" . "%-35s") + ((("tree" . "%s ")("subject" . "%s")) . " %-100s") + ("tags" . " (%s)")) + notmuch-search-result-format + '(("date" . "%12s ") + ("count" . "%-7s ") + ("authors" . "%-35s") + ("subject" . "%-100s") + ("tags" . "(%s)")) + notmuch-unthreaded-result-format notmuch-tree-result-format) + + (defun jao-notmuch--q (d0 d1 &optional k qs st) + (let ((q (or (when qs (mapconcat #'identity qs " AND ")) + (concat "tag:\"/^(unread|new)$/\" AND " + (mapconcat (lambda (d) (when d (concat "tag:" d))) + (list d0 d1) " AND "))))) + (list :name (concat d0 (when d1 "/") d1) + :key k :query q :search-type (or st 'tree) + :sort-order 'oldest-first))) + + (defun jao-notmuch--mboxes-search (box &rest excluded) + (let ((ms (seq-difference (jao-list-mailboxes box) excluded)) + (bp (substring box 0 1))) + (mapcar (lambda (m) (jao-notmuch--q box (car m) (concat bp (cdr m)))) + (shorten-strings (sort ms #'string<))))) + + (setq notmuch-saved-searches + `(,(jao-notmuch--q "bigml" "inbox" "bi") + ,(jao-notmuch--q "bigml" "support" "bs") + ,(jao-notmuch--q "bigml" "bug" "bb") + ,@(jao-notmuch--mboxes-search "bigml" "inbox" "support") + ,@(jao-notmuch--mboxes-search "jao") + ,(jao-notmuch--q "local" nil "l" '("tag:local" "tag:new")) + ,(jao-notmuch--q "gmane" "emacs" "e") + ,(jao-notmuch--q "gmane" nil "g" + '("tag:gmane" "tag:new" "not tag:emacs")) + ,@(jao-notmuch--mboxes-search "feeds") + ,(jao-notmuch--q "bml" "today" "tb" '("tag:bigml" "date:1d..") t) + ,(jao-notmuch--q "jao" "today" "tj" + '("tag:jao" "date:1d.." + "not tag:\"/(feeds|spam)/\"") + t) + ,(jao-notmuch--q "flagged" nil "r" '("tag:flagged") t) + ,(jao-notmuch--q "new" nil "n" '("tag:new")) + ,(jao-notmuch--q "draft" nil "d" '("tag:draft")))) + #+end_src +* enclosures + #+begin_src emacs-lisp + (with-eval-after-load "notmuch-show" + (defun jao-notmuch-open-enclosure (add) + (interactive "P") + (with-current-notmuch-show-message + (goto-char (point-min)) + (if (not (search-forward "Enclosure:" nil t)) + (user-error "No enclosure in message body") + (re-search-forward "https?://" nil t) + (if-let (url (thing-at-point-url-at-point)) + (progn + (message "%s %s ..." (if add "Adding" "Playing") url) + (unless add (jao-mpc-clear)) + (jao-mpc-add-url url) + (unless add (jao-mpc-play))) + (error "Found an enclosure, but not a link!")))))) + #+end_src +* package + #+begin_src emacs-lisp + (if (< emacs-major-version 28) + (jao-load-path "notmuch") + (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/")) + + (use-package notmuch + :init + (setq notmuch-draft-folder "jao/drafts" + notmuch-draft-quoted-tags '("part") + notmuch-hello-sections '(notmuch-hello-insert-saved-searches + notmuch-hello-insert-alltags + notmuch-hello-insert-header) + notmuch-hello-thousands-separator "," + notmuch-hello-auto-refresh t + notmuch-show-all-tags-list t + notmuch-show-logo nil + notmuch-show-empty-saved-searches nil + notmuch-show-part-button-default-action 'notmuch-show-view-part + notmuch-show-mark-read-tags '("-new" "-unread") + notmuch-archive-tags '("+trove" "-new") + notmuch-fcc-dirs + '((".*@bigml.com" . "bigml/sent +bigml +sent -new") + (".*" . "jao/sent +jao +sent -new")) + notmuch-maildir-use-notmuch-insert t + notmuch-message-headers '("Subject" "To" "Cc" "Date" "List-Id") + notmuch-wash-signature-lines-max 0 + notmuch-wash-wrap-lines-length 80 + notmuch-wash-citation-lines-prefix 10 + notmuch-wash-citation-lines-suffix 20) + + :config + + (when (eq 'notmuch jao-afio-mail-function) + (setq mm-text-html-renderer 'shr + message-directory "~/var/mail/" + message-auto-save-directory "/tmp") + (with-eval-after-load "notmuch-message" + (define-key message-mode-map (kbd "C-c C-d") + #'notmuch-draft-postpone))) + + (defun jao-mail-clean-address (fun address) + (let ((address + (if (string-match ".+ updates on arXiv.org: \\(.+\\)" address) + (with-temp-buffer + (insert (match-string 1 address)) + (let ((shr-width 1000)) + (shr-render-region (point-min) (point-max))) + (buffer-string)) + (string-replace "ElDiario.es - ElDiario.es" "D.es" address)))) + (funcall fun address))) + + (advice-add 'notmuch-clean-address :around #'jao-mail-clean-address) + + (defun jao-notmuch-refresh-agenda () + (interactive) + (save-window-excursion (org-agenda-list))) + + (defun jao-notmuch-hello-first () + (interactive) + (let ((inhibit-message t)) + (beginning-of-buffer) + (widget-forward 2))) + + (defun jao-notmuch-refresh-hello () + (interactive) + (ignore-errors + (when (and (string= "Mail" (jao-afio-current-frame)) + (derived-mode-p 'notmuch-hello-mode)) + (when (not (string-blank-p jao-notmuch-minibuffer-string)) + (let ((notmuch-hello-auto-refresh nil)) (notmuch-hello))) + (jao-notmuch-hello-first)))) + + :hook ((notmuch-hello-refresh . jao-notmuch-notify) + (jao-afio-switch . jao-notmuch-refresh-hello)) + + :bind (:map notmuch-hello-mode-map + (("a" . jao-notmuch-refresh-agenda) + ("S" . consult-notmuch) + ("g" . jao-notmuch-refresh-hello) + ("." . jao-notmuch-hello-first) + ("SPC" . widget-button-press)) + :map notmuch-common-keymap + (("E" . jao-notmuch-open-enclosure)))) + #+end_src +* tree view + #+begin_src emacs-lisp + (use-package jao-notmuch + :demand t + :config (setq jao-notmuch-mailboxes (jao-mailbox-folders))) + + (use-package notmuch-tree + :config + + (let ((fg (face-attribute 'jao-themes-dimm :foreground))) + (dolist (f '(notmuch-tree-match-tree-face + notmuch-tree-no-match-tree-face)) + (set-face-attribute f nil :family "Fira Code" :foreground fg))) + + (defun jao-notmuch--format-field (fun field &rest args) + (let ((rs (apply fun field args))) + (cond ((and (stringp field) (string= field "tree")) + (replace-regexp-in-string "►" "" rs)) ;; "→" + ((not (stringp field)) (truncate-string-to-width rs 100)) + (t rs)))) + + (advice-add 'notmuch-tree-format-field + :around #'jao-notmuch--format-field) + + :bind (:map notmuch-tree-mode-map + (("." . jao-notmuch-toggle-mime-parts) + ("C" . jao-notmuch-echo-count) + ("d" . jao-notmuch-tree-delete-message) + ("D" . jao-notmuch-tree-delete-thread) + ("h" . jao-notmuch-goto-message-buffer) + ("H" . jao-notmuch-click-message-buffer) + ("i" . jao-notmuch-toggle-images) + ("K" . jao-notmuch-tag-jump-and-next) + ("k" . jao-notmuch-tree-read-thread) + ("M" . jao-notmuch-move-message) + ("n" . jao-notmuch-tree-next) + ("s" . jao-notmuch-tree-spam) + ("u" . jao-notmuch-tree-flag) + ("RET" . jao-notmuch-tree-show-or-scroll) + ("SPC" . jao-notmuch-tree-scroll-or-next)) + :map notmuch-show-mode-map + (("h" . jao-notmuch-goto-tree-buffer)) + :map notmuch-common-keymap + (("B" . jao-notmuch-browse-urls)))) + #+end_src +* hydras + #+begin_src emacs-lisp + (major-mode-hydra-define notmuch-search-mode nil + ("Tagging" + (("*" notmuch-search-tag-all "tag all") + ("+" notmuch-search-add-tag "add tag") + ("-" notmuch-search-remove-tag "add tag") + ("k" notmuch-tag-jump "jump to tag")) + "Search" + (("l" notmuch-search-filter "filter with additional query") + ("t" notmuch-search-filter-by-tag "filter by tag") + ("y" notmuch-stash-query "stash current query")) + "Moving around" + (("b" notmuch-search-scroll-down "scroll down") + ("<" notmuch-search-first-thread "first thread") + (">" notmuch-search-last-thread "last thread")))) + + (major-mode-hydra-define notmuch-tree-mode nil + ("View" + (("." jao-notmuch-toggle-mime-parts "toggle mime parts") + ("i" jao-notmuch-toggle-images "toggle images") + ("a" notmuch-tree-archive-thread-then-next "archive thread") + ("C" jao-notmuch-echo-count "echo unread count")) + "Mark" + (("d" jao-notmuch-tree-delete-message "delete message") + ("D" jao-notmuch-tree-delete-thread "delete thread") + ("u" (jao-notmuch-tree-delete-message t) "undelete message") + ("k" jao-notmuch-tree-read-thread "kill thread")) + "Edit/send" + (("r" notmuch-tree-reply-sender "reply sender") + ("R" notmuch-tree-reply "reply all") + ("f" notmuch-tree-forward-message "forward") + ("e" notmuch-tree-resume-message "edit draft")))) + #+end_src +* consult + #+begin_src emacs-lisp + (jao-load-path "consult-notmuch") + (setq consult-notmuch-authors-width 30) + (require 'consult-notmuch) + (consult-customize consult-notmuch :preview-key 'any) + + (defvar jao-consult-notmuch-history nil) + + (defun jao-consult-notmuch-folder (&optional tree folder) + (interactive "P") + (let* ((root "~/var/mail/") + (folder (if folder + (file-name-as-directory folder) + (completing-read "Folder: " + jao-mailbox-folders + nil nil nil + jao-consult-notmuch-history + "."))) + (folder (replace-regexp-in-string "/\\(.\\)" ".\\1" folder)) + (init (read-string "Initial query: ")) + (init (format "folder:/%s/ %s" folder init))) + (if tree (consult-notmuch-tree init) (consult-notmuch init)))) + + (with-eval-after-load "notmuch-hello" + (define-key notmuch-hello-mode-map "f" #'jao-consult-notmuch-folder)) + #+end_src +* org mode integration + #+begin_src emacs-lisp + (jao-load-path "ol-notmuch") + (use-package ol-notmuch :demand t) + #+end_src -- cgit v1.2.3