To use this system, begin with ~SPC a m~ (after a ~SPC a n~ to asychronously download new mail ... which probably should be running regularly).
When the Notmuch interface up, hit ~J~ to jump to one of the Search boxes (described below). Typically, this is ~i~ for the Imbox, check out the focused message from people I care). Hit ~q~ to return.
Next type ~s~ to view and organize mail I've never seen before. We need to keep things focused, so regularly /making auto filtering rules/ is important. Move the point to the message and hit one of the following to automatically move the sender to a pre-defined box:
- ~I~ :: screened stuff that important enough to go to my Imbox
- ~S~ :: spam ... so much goes here
- ~P~ :: receipts go to this *Paper Trail*, which takes a *tag* as the name of the store
- ~f~ :: mailing lists and other things that might be nice to read go to *The Feed*
I need to incorporate an address book again, but in the meantime, searching through a history of past email works well enough.
#+BEGIN_SRC emacs-lisp
(setq notmuch-address-selection-function
(lambda (prompt collection initial-input)
(completing-read prompt
(cons initial-input collection)
nil
t
nil
'notmuch-address-history)))
#+END_SRC
** Sending Messages
Do I need to set up [[https://marlam.de/msmtp/][MSMTP]]? No, as Notmuch will do that work.
To do this, type ~c~ and select an option (including ~r~ to reply).
** Retrieving Messages
When we start notmuch, we need to retrieve the email and then process it. Most of this is actually contained in the Notmuch configuration.
#+BEGIN_SRC emacs-lisp
(defun notmuch-retrieve-messages ()
"Retrieve and process my mail messages."
(interactive)
(async-shell-command "notmuch new"))
#+END_SRC
* iSync Configuration
Using [[https://isync.sourceforge.io/][isync]] (or is it =mbsync=) for mail retrieval.
Currently, I have a couple of Google Mail accounts that I want connected.
The file generally can have a =Pass= entry for the encrypted passcode, but in order to demonstrate how to connect to multiple accounts, I'm using a GPG daemon:
#+BEGIN_SRC conf-unix :tangle ~/.mbsyncrc
# Note: We now tangle this file from ~/other/hamacs/ha-email.org
Create Both
SyncState *
MaxMessages 300
Sync All # New ReNew Flags
# PERSONAL ACCOUNT
IMAPAccount personal
Host imap.gmail.com
User howard@howardabrams.com
# I took out the --no-tty as we need to get the password to decrypt the password file.
# Note that the password is actually the token for the account.
The general settings file that goes into =~/.notmuch-config=:
#+BEGIN_SRC conf-unix :tangle ~/.notmuch-config
# .notmuch-config - Configuration file for the notmuch mail system
# Note: We now tangle this file from ~/other/hamacs/ha-email.org
#
# For more information about notmuch, see https://notmuchmail.org
#+END_SRC
The commentary for each of the subsections came from their man page.
*** Database configuration
The only value supported here is 'path' which should be the top-level directory where your mail currently exists and to where mail will be delivered in the future. Files should be individual email messages. Notmuch will store its database within a sub-directory of the path configured here named ".notmuch".
#+BEGIN_SRC conf-unix :tangle ~/.notmuch-config
[database]
path=.mail
#+END_SRC
*** User configuration
Here is where you can let notmuch know how you would like to be addressed. Valid settings are
- =name= :: Your full name.
- =primary_email= :: Your primary email address.
- =other_email= :: A list (separated by =;=) of other email addresses at which you receive email.
Notmuch will use the various email addresses configured here when formatting replies. It will avoid including your own addresses in the recipient list of replies, and will set the From address based on the address to which the original email was addressed.
- =tags= :: A list (separated by =;=) of the tags that will be added to all messages incorporated by "notmuch new".
- =ignore= :: A list (separated by =;=) of file and directory names that will not be searched for messages by "notmuch new".
NOTE: *Every* file/directory that goes by one of those names will be ignored, independent of its depth/location in the mail store.
#+BEGIN_SRC conf-unix :tangle ~/.notmuch-config
[new]
tags=unread;inbox;
ignore=
#+END_SRC
*** Search configuration
The following option is supported here:
- =exclude_tags= :: A ;-separated list of tags that will be excluded from search results by default. Using an excluded tag in a query will override that exclusion.
#+BEGIN_SRC conf-unix :tangle ~/.notmuch-config
[search]
exclude_tags=deleted;spam;
#+END_SRC
*** Maildir compatibility configuration
The following option is supported here:
- =synchronize_flags= :: Valid values are true and false. If true, then the following maildir flags (in message filenames) will be synchronized with the corresponding notmuch tags:
| S | unread (added when 'S' flag is not present) |
The =notmuch new= command will notice flag changes in filenames and update tags, while the =notmuch tag= and =notmuch restore= commands will notice tag changes and update flags in filenames.
#+BEGIN_SRC conf-unix :tangle ~/.notmuch-config
[maildir]
synchronize_flags=true
#+END_SRC
That should complete the Notmuch configuration.
** =pre-new=
Then we need a shell script called when beginning a retrieval, =pre-new= that simply calls =mbsync= to download all the messages:
# More info about hooks: https://notmuchmail.org/manpages/notmuch-hooks-5/
# Note: We now tangle this file from ~/other/hamacs/ha-email.org
echo "Starting not-much 'pre-new' script"
mbsync -a
echo "Completing not-much 'pre-new' script"
#+END_SRC
** =post-new=
And a =post-new= hook based on a filtering scheme that mimics the Hey.com workflow taken from [[https://gist.githubusercontent.com/frozencemetery/5042526/raw/57195ba748e336de80c27519fe66e428e5003ab8/post-new][this gist]] (note we have more to say on that later on) to filter and tag all messages after they have arrived:
export start="-1" # sanity requires this or similar
}
timer_start "ledger"
while IFS= read -r line; do
nm_tag=$(echo "$line" | cut -d' ' -f1 -)
nm_entry=$(echo "$line" | cut -d' ' -f2 -)
if [ -n "$nm_entry" ]
then
notmuch tag +archived +ledger/"$nm_tag" -inbox -- tag:inbox and tag:unread and from:"$nm_entry"
fi
echo -n "Handling entry: $nm_tag, $nm_entry"
done < $nm_maildir/.notmuch/hooks/ledger.db
timer_end "ledger"
timer_start "unsubscribable_spam"
for entry in $(cat $nm_maildir/.notmuch/hooks/spam.db)
do
if [ -n "$entry" ]
then
notmuch tag +spam +deleted +archived -inbox -unread -- tag:inbox and tag:unread and from:"$entry"
fi
done
timer_end "unsubscribable_spam"
timer_start "thefeed"
for entry in $(cat $nm_maildir/.notmuch/hooks/thefeed.db)
do
if [ -n "$entry" ]
then
notmuch tag +thefeed +archived -inbox -- tag:inbox and tag:unread and from:"$entry"
fi
done
timer_end "thefeed"
timer_start "Screened"
notmuch tag +screened 'subject:/\[Web\]/'
for entry in $(cat $nm_maildir/.notmuch/hooks/screened.db)
do
if [ -n "$entry" ]
then
notmuch tag +screened -- from:"$entry" # tag:unread and tag:inbox and
fi
done
timer_end "Screened"
# Projects...
timer_start "Old-Projects"
notmuch tag +old-project 'subject:/.*howardabrams\/node-mocks-http/'
notmuch tag +old-project 'subject:/.*Pigmice2733/'
timer_end "Old-Projects"
notmuch tag +screened 'subject:[Web]'
echo "Completing not-much 'post-new' script"
#+END_SRC
* Hey
I originally took the following configuration from [[https://youtu.be/wuSPssykPtE][Vedang Manerikar's video]], along with [[https://gist.github.com/vedang/26a94c459c46e45bc3a9ec935457c80f][the code]]. The ideas brought out were to mimic the hey.com email workflow, and while not bad, I thought that maybe I could improve upon it slowly over time.
To allow me to keep Vedang's and my code side-by-side in the same Emacs variable state, I have renamed the prefix to =hey-=, however, if you are looking to steal my code, you may want to revisit the source.
** Default Searches
A list of pre-defined searches act like "Folder buttons" at the top to quickly see files that match those /buckets/:
#+BEGIN_SRC emacs-lisp
(setq notmuch-saved-searches '((:name "Imbox"
:query "tag:inbox AND tag:screened AND tag:unread"
;; This is a dirty hack since I can't find a way to run a
;; temporary hook on `notmuch-search' completion. So instead of
;; waiting on the search to complete in the background and then
;; making tag-changes on it, I will just sleep for a short amount
;; of time. This is generally good enough and works, but is not
;; guaranteed to work every time. I'm fine with this.
(sleep-for 0.5)
(notmuch-search-tag-all tag-changes)
(when refresh
(set-buffer this-buf)
(notmuch-refresh-this-buffer))))
#+END_SRC
** Moving Mail to Buckets
We based the Hey buckets on notmuch databases, we combine the =hey-notmuch-add-addr-to-db= with the =hey-notmuch-tag-by-from= functions to move messages.
The idea of linking org documents to email could be nice, however, the =ol-notmuch= package in the [[https://elpa.nongnu.org/nongnu/org-contrib.html][org-contrib]] package needs a maintainer.
#+BEGIN_SRC emacs-lisp
(use-package ol-notmuch
:after org
:straight (:type built-in)
:config (add-to-list 'org-modules 'ol-notmuch))
#+END_SRC
To use, read a message and save a link to it with ~SPC o l~. Next, in an org document, create a link with ~SPC m l~. Now, you can return to the message from that document with ~SPC m o~. Regardless, I may need to store a local copy when I upgrade Org.
* Display Configuration
Using the [[https://github.com/seagle0128/doom-modeline][Doom Modeline]] to add notifications: