p0̷nt1ff's weblog

Using mu4e for reading emails in Emacs, on macOS: a Fastmail setup


This is guide is based on this one and this Reddit post, but at one point I had to diverge from the mentioned guide: on my system (macOS Sonoma 14.2.1) mu4e wasn't on the same path and I also had issues indexing my email, unpopulated Maildir section on mu4e-main, I had to fix an authentication issue and figure out how to configure the connection to SMTP. So here's my working setup (current guide assumes Emacs and homebrew are installed and working). Also, I treat this guide as a note, in case I'll need it in the future, but if anyone else thinks it's useful, I'm glad.

Getting emails into Maildir

This section isn't necessarily tied to mu4e, since it describes how to fetch emails from an IMAP server using Emacs-agnostic tools. Thus, it can be used as a starting point for other approaches, like using notmuch instead of mu4e.

First things first:

% brew install isync

This will actually install isync that has a binary called mbsync, which is what we need to fetch and synchronize the email messages from IMAP server.

If you like plaintext emails (and you probably do, if you want to use Emacs to read them), then you might want to install w3m; it's not mandatory, but it helps format your messages. However, you can skip this or use another piece of software, I've only mentioned this for consistency reasons (it will be used further down, in the Emacs configuration section).

% brew install w3m

Now, let's get back to emails. Create the folder needed by mbsync or else you'll get an error:

% mkdir ~/Maildir

Before you begin, make sure you create an app password in your Fastmail account and put that in ~/.mbsync-fastmail. Now, it must be noted that if you're using a custom domain for your Fastmail account, there's a difference between <YOUR_FASTMAIL_ACCOUNT> and <YOUR_MAIL_ADDRESS>, so keep this in mind as you read along. Here's my ~/.mbsyncrc, the configuration file for mbsync:

IMAPAccount fastmail
Host imap.fastmail.com
Port 993
AuthMechs LOGIN
# For simplicity, this is how to read the password from another file.
# For better security you should use GPG https://gnupg.org/
PassCmd "cat ~/.mbsync-fastmail"
SSLVersions TLSv1.2

IMAPStore fastmail-remote
Account fastmail

# This section describes the local storage
MaildirStore fastmail-local
Path ~/Maildir/
Inbox ~/Maildir/INBOX
# The SubFolders option allows to represent all
# IMAP subfolders as local subfolders
SubFolders Verbatim

# This section a "channel", a connection between remote and local
Channel fastmail
Far :fastmail-remote:
Near :fastmail-local:
Patterns *
Expunge None
CopyArrivalDate yes
Sync All
Create Near
SyncState *

Now the following command should download all the emails, so it will take a few minutes, depending on how many messages you have in your account:

% mbsync -a

Install and configure mu4e

Let's install mu, initialize it and let it index your messages:

% brew install mu
% mu init --maildir ~/Maildir --my-address=<YOUR_MAIL_ADDRESS>
% mu index

The --my-address part isn't mandatory, but using it would avoid some warnings from Emacs later on.

Test that's everything is fine by running:

% mu find hello

Now we're ready to integrate mu with Emacs. Find out where mu is on your system, by running:

% which mu

In my case, mu installed on /opt/homebrew/bin/mu, so we need to let Emacs know where mu is, by having this line in your Emacs config file (`~./emacs.d/init.el' by default):

(setq mu4e-mu-binary "/opt/homebrew/bin/mu")

The rest of my mu4e configuration looks like this:

(require 'mu4e)
 mue4e-headers-skip-duplicates t
 mu4e-headers-leave-behavior 'apply
 mu4e-headers-date-format "%Y-%m-%d"
 mu4e-view-show-images t
 mu4e-view-show-addresses t
 mu4e-compose-format-flowed t
 mu4e-compose-dont-reply-to-self t
 mu4e-compose-reply-ignore-address '("no-?reply")
 mu4e-compose-signature-auto-include nil
 mu4e-date-format "%y-%m-%d"
 mu4e-change-filenames-when-moving t
 mu4e-attachments-dir "~/Downloads"
 mu4e-get-mail-command "mbsync -a"
 mu4e-view-use-gnus t
 mu4e-html2text-command "w3m -T text/html"
 mu4e-update-interval (* 10 60) ;;this setting allows to re-sync and re-index mail by pressing U refresh mbsync  every 10 minutes

 mu43-use-fancy-chars t
 mu4e-maildir       "~/Maildir"   ;; top-level Maildir
 mu4e-refile-folder "/Archive"
 mu4e-sent-folder   "/Sent"
 mu4e-drafts-folder "/Drafts"
 mu4e-trash-folder  "/Trash"
 mu4e-reply-to-address "<YOUR_MAIL_ADDRESS>"
 user-mail-address "<YOUR_MAIL_ADDRESS>"
 user-full-name "<YOUR_FULL_NAME>")

(setq mu4e-maildir-shortcuts
  '( (:maildir "/inbox"     :key  ?i)
     (:maildir "/archive"   :key  ?a)
     (:maildir "/sent"      :key  ?s)

(fset 'my-move-to-trash "mTrash")
(define-key mu4e-headers-mode-map (kbd "d") 'my-move-to-trash)
(define-key mu4e-view-mode-map (kbd "d") 'my-move-to-trash)

 message-send-mail-function   'smtpmail-send-it
 smtpmail-default-smtp-server "smtp.fastmail.com"
 smtpmail-smtp-server         "smtp.fastmail.com"
 smtpmail-smtp-service        587)

;; Show emails as plain text, if possible
(with-eval-after-load "mm-decode"
 (add-to-list 'mm-discouraged-alternatives "text/html")
 (add-to-list 'mm-discouraged-alternatives "text/richtext"))

For sending email, mu uses the ~/.authinfo file, which has the following format:

machine smtp.fastmail.com login <YOUR_FASTMAIL_ACCOUNT> password "YOUR_PASSWORD" port 587

Run M-x mu4e inside Emacs and you'll be in mu4e-main buffer. Follow the on-screen instructions to move around, or use these default key bindings if you get lost:

 j - Jump to maildir folder
 C - Compose a new email
 F - Forward message to third party
 R - Reply to sender/all as prompted
 s - Search
 S - Edit current search string
 / - Narrow search within current result set
 n,p - Move to next, prior message
 ],[ - Move to next, prior unread message
 y   - Move between header and message view
 O   - Change sort order of headers
 P   - Toggle threading of message headers
 q   - Leave view

That's it. Happy Emacsing!

Recent posts