mutt, mbsync, and fastmail

I stopped using mutt a while ago for reasons I no longer remember [1] but I've been wanting to use it again. I tried using the imap support built into it, but nothing beats having an offline cache of mail.

In the past, I'd used my gmail accounts but that's been made increasingly difficult and requires jumping through all manner of hoops these days. I'm also trying to move my mail off gmail and onto fastmail where it makes sense [2]. This config now has a single account [3] which admittedly makes things a lot simpler.

mutt

I previously had a long and arduous muttrc that had many arcane options set. Somehow I've lost the file (really though, it's in my backups somewhere) and I figured I should just start from scratch and see what happens. I think my original had been copied and pasted from here, there, and everywhere so it's nice to actually understand things.

## compose / editor options
set editor    = "/usr/bin/mg"
# edit_headers shows the headers when composing an email.
set edit_headers

# sorting should be first by thread, then chronologically.  I like the
# most recent messages to be at the top, which mutt calls "reverse,"
# but obviously it's mutt that's reversed...
set sort      = threads
set sort_aux  = reverse-last-date-received
set sort_re

# don't ask about deleting or purging when switching mailboxes or
# exiting mutt; shia labeouf it. Also, don't confirm when saving
# messages to a different mailbox.
set delete
set delete_untag
unset confirmappend

## custom keybindings
# Archive the current message
macro index A '<save-message>+Archive/<enter>'
# Sync with the mail server.
macro index Z '<shell-escape>mbsync -a &<enter>'

## fastmail setup
# the mailbox / path should make it clear what each
# of these options does, if they don't make sense.
set from      = "Kyle Isom <kyle@imap.cc>"
set mbox_type = Maildir
set spoolfile = "~/mail/INBOX"
set folder    = "~/mail/"
set record    = "~/mail/Sent"
set postponed = "~/mail/Drafts"
set trash     = "~/mail/Trash"

## smtp setup
set smtp_authenticators       = "login"
set ssl_force_tls             = yes
set smtp_url                  = "smtp://kyle@imap.cc@smtp.fastmail.com:587"
set smtp_pass                 = "yghtr9qxna3yv5ss"

So far this is pretty comfortable. I think I'm going to change the date format at some point to a better one, but this is reasonable without much work.

One thing to remember: moving a message is called saving. So, for example, the macro for 'A' moves messages to the archive folder.

mbsync

While researching alternatives to offlineimap, I found mbsync so I figured I'd give it a shot. Here's my ~/.mbsyncrc.

## global options
# slave in this case refers to the local maildir folder; this option
# says to create those folders that don't exist.
Create        Slave
SyncState     *

## IMAP account stores credentials. The idea is supposedly that you
# could reuse credentials across stores, but I don't really need
# that.
IMAPAccount   fastmail-creds
SSLType       IMAPS
SSLVersions   TLSv1.2
Host          imap.fastmail.com
User          kyle@imap.cc
Pass          correcthorsebatterystaple

mbsync uses the concept of stores to refer to "where the mail is." In the case of my setup, there are two stores: fastmail and my ~/mail directory. First, I tell it where my local mailbox is. The trailing slash in Path is important! I ended up with a bunch of folders like "mailINBOX" in my home directory the one time I forgot; you should learn from my mistakes and not do this unless that's what you want to do.

The Subfolders controls how the inbox subfolders are stored. The mbsync(1) man page has the dirty deets, but like it says, "Verbatim.. is the style you probably want to use."

I did, in fact, wish to use verbatim, so that's what I did.

MaildirStore  fastmail-local
Path          ~/mail/
Inbox         ~/mail/INBOX
Subfolders    Verbatim

Now, I have to tell it about the remote store. mbsync doesn't have a concept of local vs. remote; it knows about MaildirStores and IMAPStores [4]. This is

IMAPStore     fastmail-remote
Account       fastmail-creds

With our stores in hand, we need to tell them how to talk to each other. A channel does that by setting a master and slave, which is regrettable terminology and doesn't mean much here with the default setting wherein mail flows in both directions. Either way, the standard that I found is to set your "remote" store as the master and your "local" store as the slave. Patterns is important because it makes sure all the folders are copied, not just the INBOX; CopyArrivalDate preserves the arrival date when a message is moved, rather than resetting it.

Channel       fastmail
Patterns      *
Master        :fastmail-remote:
Slave         :fastmail-local:
CopyArrivalDate       yes

Finally

It's nice to be back in mutt. Things I didn't worry about this time: PGP integration (because who even uses PGP[#]_ anymore[#]_?), setting up a bunch of folder hooks and multiple accounts, or really spending a bunch of time setting things up - I probably spent more time writing this post than I did really configuring this.

[1]Probably offlineimap hijinks. I love offlineimap and it worked well for a long time but it would run into all kinds of problems (hung sessions, out of memory, etc).
[2]Photos, though, is probably the single most useful place where my gmail account is still the best choice.
[3]My work and personal machines are separate and never the twain shall meet, especially not as long as I work here.
[4]And maybe others, but these are the two relevant to my interests.
[5]Maybe I can set up signify or reop support? Do I want to?
[6]I don't remember the last time I got an email that was signed, much less encrypted to me.

Tags: