Text based email workflow on macOS

But why though?

macOS has arguably the best looking, most succinct and most user friendly GUI in all the OS commonly used on personal computers.

With this comes a bunch of fantastic GUI based tools for everything – including a lot for emailing.

The following list is but a selection of some.

Just with this selection, I am quite sure a lot of people would find their match. Personally I happily used the default macOS Mail.app. It did everything, that I needed. It is well integrated into the OS and iCloud of course. Together with Calendar.app and Contacts.app this quite a potent and well oiled machinery.

Then why did I switch to a text based workflow?

A few articles ago I wrote about my obsession with Emacs. Since I started using Emacs, I have been down the rabbit hole of migrating most of my workflows into it. Emacs is a fantastic text based – for lack of a better word – environment.

Breaking things to their basic nature takes away the distraction and it does not get any more basic than plain text.

Granted, I noticed that the appeal is not just the text based nature of the application, but also the focus on fuzzy searching/finding. In Emacs one can do this on any imaginable type of list.

Most of my navigation is initiated by a fuzzy completion interface. I accomplish this with a whole host of applications, programs and add-ons.

So I handle emails in plain text. But how?

The Toolchain

First things first. Let’s take a look at the tools and programs that I user to achieve that.

Emacs & mu4e

As mentioned before I already wrote up my setup to handle emails with Emacs. This is extensively illustrated in this article.

NeoMutt

For the rare cases I don’t have Emacs running and I just want a glance into my mailboxes I can quickly launch NeoMutt on the command line. This also has the added benefit of having a backup client for my email.

Both Mu4e and NeoMutt use mbsync and the same email directory structure located in ~/.maildir. Again demonstrated in the aforementioned article.

NeoMutt, which to my knowledge is based Mutt, is a wonderful email client for the command line. It is quite customizable, both in behaviour (keybindings, email handling) and look & feel.

It is however quite intense to configure. Luckily the guide online is detailed enough.

In this post I will not go through the details on how to configure NeoMutt. I will rather layout some of the special custom settings that might not be documented in the guide.

In my case the configuration files are in the ~/.mutt directory as documented here.

├── accounts           # configuration for every account in a separate file
│   ├── aimebertrand
│   ├── icloud
│   ├── mocarchive
│   └── moclub
├── bindings           # file containing the keybindings
├── colors             # theming
├── muttrc             # main configuration
└── signatures         # signature are kept separate as well
    ├── aimebertrand-sign
    ├── icloud-sign
    ├── mocarchive-sign
    └── moclub-sign

Once configured, the result looks like this:

Some of the custom settings, that you will not find in the guide include a mailbox switcher/selector using fzf. I use a script which is then bound to a key in the binding file.

bash script muttfzf.sh:

#!/bin/bash

match_folder() {
    find $HOME/.maildir -name '*' -type d \
-mindepth 2 -maxdepth 2 |\
grep -v '.git' | grep -v '\/mu' |\
        fzf --reverse
}

folder=$(match_folder)

echo "push 'c$folder<enter>'"

Keybinding:

macro index,pager J ":source ~/.dotfiles/bin/muttfzf.sh|<enter>"

Notmuch

Notmuch is an email indexing and search tool – just like mu/mu4e – based on Xapian. This provides a way to index my emails from the ~/.maildir. However separate to the mu xapian database.

This is useful because I can use the terminal to quickly fuzzy search for an email and display it quite fast on the command line. To achieve I use a custom function, that chains notmuch, fzf, mu & nvim.

function nmail() {
    set -o pipefail
    mail=$(notmuch show --format=text \
                   $(notmuch search date:1970..2021 | \
                         fzf --reverse --preview \
                             "echo {} | cut -d' ' -f1 | cut -d':' -f2 | \
xargs notmuch show --format=text | \
grep 'message{' | head -n 1 | cut -d':' -f6,7 | \
sed 's/\ /\\\ /g' | xargs mu view" | \
                         cut -d' ' -f1 | cut -d':' -f2) | \
               grep 'message{' | head -n 1 | cut -d':' -f6,7 | \
               sed 's/\ /\\\ /g' | xargs mu view) && \
        echo $mail | nvim -c 'set ft=mail' -c 'nmap q :q!<CR>'
}

This is beautifully convenient and fast, when I just want to quickly fuzzy match a subject in all of my emails and take a peak of the content. And I don’t need to open a fully fledged client and search.

Conclusion

Looking at this from a purely sober perspective it looks like a lot of hoops to go through. And granted the overhead is quite challenging. But the result speaks for itself. the convenience of finding emails at the speed of thought is a great one. Plus I have the added benefit of having all my email archive stored in a format that is readable by almost any sort of digital device.