My E-Mail Setup

I sent my first E-Mails in Outlook 2003 (mind you this was in 2011), but quickly moved on to Thunderbird. I messed around with mutt about two years ago. I set up everything for one address, but never got comfortable with the tool because I had no clue what I was doing. What certainly didn’t help was copying some ‘cool’ muttrc I’d found online.

I Switched to claws-mail shortly thereafter because I wanted something less sluggish than Thunderbird and I liked the idea of not having HTML email.

It’s a great piece of software, but I felt like messing about with mutt again because I thoroughly enjoy software that I can navigate with my keyboard.

# mbsync and notmuch

I use mbsync to synchronize my local mail directories at ~/mail.

My ~/.mbsyncrc consists of a bunch of entries like this:

IMAPAccount example
Host imap.strato.de
User me@example.com
PassCmd "pass mail/example"
SSLType IMAPS

IMAPStore example-remote
Account example

MaildirStore example-local
Subfolders Verbatim
Path ~/mail/example/
Inbox ~/mail/example/inbox

Channel example
Master :example-remote:
Slave :example-local:
Patterns *
Create Both
SyncState *

I’d always refer to this account as sample: It’s mailbox lives at ~/mail/sample, I can sync with mbsync sample and will be able to open it with mutt sample – more on that later.

It’s pretty much a bog standard config. Perhaps worthy of note is the use of my password manager pass for all passwords.

I do that for all my accounts, although Gmail accounts are a bit special as they use a [Gmail] folder in addition to the ones you’d expect. I only ever use the [Gmail] ones so as not to end up with duplicate mail. Note that you’ll have to create and use an application password instead of your regular Google password.

IMAPAccount gsm
Host imap.gmail.com
User example@gmail.com
PassCmd "pass mail/gsm"
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt

IMAPStore gsm-remote
Account gsm

MaildirStore gsm-local
Subfolders Verbatim
Path ~/mail/gsm/
Inbox ~/mail/gsm/inbox

Channel gsm-default
Master :gsm-remote:
Slave :gsm-local:inbox
#Patterns INBOX

Channel gsm-sent
Master :gsm-remote:"[Gmail]/Sent Mail"
slave  :gsm-local:Sent

Channel gsm-trash
Master :gsm-remote:"[Gmail]/Trash"
slave  :gsm-local:Trash

Channel gsm-junk
Master :gsm-remote:"[Gmail]/Spam"
slave  :gsm-local:Junk

Create Both
SyncState *

Group gsm
Channel gsm-default
Channel gsm-trash
Channel gsm-sent
Channel gsm-junk

I’ve called this one gsm, for ‘Gmail sample’ – I like to keep the names short.

I can fetch all mail with mbsync -a, or fetch selectively, e.g. mbsync gsm.

Next up in the list of tools is notmuch. It doesn’t do much currently, except tag unread messages as unread. I can then get an overview of unread mail like this:

[jakob@argon ~]$ notmuch search "tag:unread"
thread:00000000000046e4  4 mins. ago [1/1] someone@example.com; Hey, what's up? (inbox unread)

I’ve wrapped these steps into a script called ms (mail sync):

[jakob@argon ~]$ ms
C: 12/12  B: 40/40  M: +0/0 *0/0 #0/0  S: +1/1 *0/0 #0/0
Processed 81 total files in almost no time.
Added 1 new message to the database.
Unread messages:
sample    5 mins. ago    someone@exa…    Hey, what's up?

Like this, it runs mbsync -a but can be invoked as ms sample to run run mbsync sample. Then it shows unread messages by passing notmuch JSON output through a pretty-printing script:

notmuch show --format=json --entire-thread=false "tag:unread" | ~/.mutt/scripts/nmpp

The main motivation for this is wanting to see the mailbox in which the mails actually are.

# mutt

I’ve heard that mutt can be a bit iffy when it comes to settings for multiple accounts, so I strictly separate them.

Each directory in ~/mail contains a separate muttrc:

[jakob@argon ~]$ tree ~/mail
/home/jakob/mail
├── gsm
│   ├── inbox
│   ├── Junk
│   ├── muttrc
│   ├── Sent
│   └── Trash
└── sample
    ├── Drafts
    ├── inbox
    ├── muttrc
    ├── Queue
    ├── Sent
    └── Trash

These are rather small and configure a number of common my_-variables that are used further by ~/.mutt/muttrc_postmy.

[jakob@argon ~]$ cat ~/mail/sample/muttrc
source ~/.mutt/muttrc

set my_acc = "sample"
set my_user = "me@example.com"
set my_server = "smtp.example.com"
set my_inbox = +inbox

source ~/.mutt/muttrc_postmy

My ~/.mutt/muttrc is pretty standard:

set folder = "~/mail"
set realname = "Jakob Ruckel"

set sort = "threads"
set sort_aux = "last-date-sent"

set my_sync = ~/.mutt/scripts/ms

bind pager j next-line
bind pager k previous-line
bind attach,index,pager \CD next-page
bind attach,index,pager \CU previous-page

alternative_order text/plain text/html
set mailcap_path = ~/.mutt/mailcap
auto_view text/html

my_hdr User-Agent: Every email client sucks, this one just sucks less.

set record = "+Sent"

The muttrc_postmy does a number of unsurprising things with all the my_ variables in each ~/mail/*/muttrc:

# muttrc to be sourced after the following have been set:
#   my_acc
#   my_inbox
#   my_pass
#   my_server
#   my_sync
#   my_user

set folder = ~/mail/$my_acc
set spoolfile = $my_inbox
set mbox = $my_inbox

set from = $my_user
set use_from = yes

macro index G "<shell-escape>$my_sync $my_acc<enter>" "run mbsync+notmuch"

set smtp_url=smtp://$my_user@$my_server
set smtp_pass=$my_pass
set ssl_force_tls = yes

I have mutt aliased to easily start it with these configurations:

/usr/bin/mutt -F ~/mail/$1/muttrc || /usr/bin/mutt "$@"

# TODO

I’ve still got to set up a systemd service to periodically fetch mail and notify-send me accordingly.

Update 2022: I’ve since also setup filtering with imapfilter for filtering out some mailing lists into a separate inbox. The config looks something like this.