Emacs: GMail and Lore Mailing Lists
With lots of help from the tireless Tobias Waldekranz, I think I’ve finally found the perfect “magit like” email setup. With Emacs, of course. This is the story of how I did it.
First install notmuch, mbsync (from the isync package), and afew:
sudo apt install notmuch isync afew
Do initial setup of notmuch for your user. I’ve opted to store my
mail in ~/mail
, this is used throughout the text below, ymmv.
notmuch setup
Clone Tobias’ GitHub notmuch-lore
repo, we will be using his pre-new
hook later on to fetch mailing
lists from lore, along with a post-new
hook to do some tagging of new
mail.
cd ~/src
git clone https://github.com/wkz/notmuch-lore
Set up isync/mbsync to fetch my own email from Gmail. Here a note on
Gmail folder structure may be in order. The view you see in the Google
web interface does not reflect the IMAP hierarchy. Here’s what it looks
like, with exception for countries where Google had to change [Gmail]
to use [Google Mail]
instead, e.g., Germany:
/
|-- Drafts
|-- [Gmail]/
| |-- Spam
| |-- your-own
| |-- folders-here
| `-- ...
|-- INBOX
|-- Sent
`-- Trash
Most of the standard standard folders are available in the root, in my
case only Spam
goes in the same [Gmail]/
folder as my own folders
do. This is important to keep track of when configuring your channels
in mbsync
.
Here’s my ~/.mbsyncrc
for GMail, I’ve included the BusyBox folder,
which is that project’s mailing list. Filtering of incoming mail to
that list is done by GMail, not documented here. Make sure to create
the parent directory ~/mail/gmail
.
Please notice that I’ve removed my application-specific password, you’ll have to get your own for you account.
IMAPAccount gmail
Host imap.gmail.com
User troglobit@gmail.com
Pass heresyourappassword
SSLType IMAPS
SSLVersion TLSv1.2
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore gmail-remote
Account gmail
MaildirStore gmail-local
SubFolders Verbatim
# The trailing "/" is important
Path ~/mail/gmail/
Inbox ~/mail/gmail/Inbox
Trash ~/mail/gmail/trash
Channel sync-gmail-default
Master :gmail-remote:
Slave :gmail-local:
# Select some mailboxes to sync
Patterns "INBOX"
Remove Both
Channel sync-gmail-sent
Master :gmail-remote:"Sent"
Slave :gmail-local:sent
Create Slave
Channel sync-gmail-trash
Master :gmail-remote:"Trash"
Slave :gmail-local:trash
Create Slave
Channel sync-gmail-busybox
Master :gmail-remote:"[Gmail]/BusyBox"
Slave :gmail-local:busybox
Create Slave
Channel sync-gmail-buildroot
Master :gmail-remote:"[Gmail]/Buildroot"
Slave :gmail-local:buildroot
Create Slave
Remove Both
# Get all the channels together into a group.
Group gmail
Channel sync-gmail-default
Channel sync-gmail-busybox
Channel sync-gmail-sent
Channel sync-gmail-trash
NOTE: empty lines in
.mbsyncrc
not allowed just anywhere. This bit me initially and is likely a common error for others as well.
Test your mbsync setup first, see the manual page for details.
As you’ve probably already learned from the GitHub repo, to fetch mail from the public inbox mailing lists on lore, you need small .ini file detailing which subsystems you’re interested in:
# ~/mail/.notmuch/.lore/sources
[netdev]
url=https://lore.kernel.org/netdev
[mtd]
url=https://lore.kernel.org/linux-mtd
Now we can proceed to combine it all in notmuch! After notmuch setup
you should have a ~/mail/.notmuch/hooks/
directory. Let’s create a
pre-hook
to fetch gmail and mailing lists from lore:
#!/bin/sh
# ~/mail/.notmuch/hooks/pre-new
# Fetch mail from Gmail
mbsync -a
# Pull relevant kernel mailing lists using git, of course
~/src/notmuch-lore/pre-new
Remember to
chown +x pre-new
and thepost-new
, below!
For help with tagging, or sorting, you can either use the nmsort()
shell script function that Tobias made, or other tools like afew
.
The latter needs a small configuration file:
# ~/.config/afew/config
# This is the default filter chain
[SpamFilter]
[KillThreadsFilter]
[ListMailsFilter]
[ArchiveSentMailsFilter]
[InboxFilter]
Set up the post-new
for notmuch as follows. It goes the same
directory as pre-new
:
#!/bin/sh
# ~/mail/.notmuch/hooks/post-new
nmsort()
{
notmuch tag -new $1 -- tag:new "$2"
}
echo "Me" >&2
nmsort "+me +unread" "to:troglobit OR cc:troglobit"
nmsort "+me +unread" "troglobit"
echo "Various Mailing Lists" >&2
nmsort "+lists/pidp-11" "subject:[PiDP-11]"
#nmsort "+busybox" "list:busybox"
#nmsort "+buildroot" "list:buildroot"
echo "Subsystems" >&2
nmsort "+bridge +subsys" "subject:bridge:"
nmsort "+switchdev +subsys" "subject:switchdev:"
nmsort "+ethtool +subsys" "subject:ethtool:"
nmsort "+phylink +subsys" "subject:phylink:"
nmsort "+devlink +subsys" "subject:devlink:"
nmsort "+dsa +subsys" "subject:dsa"
echo "Hardware" >&2
nmsort "+dsa +hw" "subject:mv88e6"
nmsort "+mdio +hw" "subject:mdio"
nmsort "+phy +hw" "subject:phy"
nmsort "+mlxsw +hw" "subject:mlxsw"
echo "Vendors" >&2
nmsort "+marvell +vendor" "subject:marvell"
nmsort "+microchip +vendor" "subject:microchip"
# If you don't use afew, uncomment this
#nmsort "" "*"
echo "Let afew handle the remaining ... " >&2
afew --tag --new
Set up SMTP in Emacs, also stolen from Tobias.
;; Who am I?
(setq user-full-name "Joachim Wiberg")
(setq user-mail-address "troglobit@gmail.com")
;; Email setup
(setq message-directory "~/.mail"
notmuch-fcc-dirs nil
read-mail-command (quote notmuch)
message-citation-line-format "On %a, %b %d, %Y at %R, %f wrote:"
message-citation-line-function 'message-insert-formatted-citation-line
)
;; Currently gmail as SMTP server
(setq message-send-mail-function 'smtpmail-send-it
smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
smtpmail-auth-credentials '(("smtp.gmail.com" 587 "troglobit@gmail.com" nil))
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
starttls-use-gnutls t
)
Done.