Terminal delight with aerc and notmuch

The proliferation of communication protocols, trending toward walled, corporate gardens, has left good ol’ email in the dust. I don’t know anyone for whom email works anymore as their primary communication channel. Email is dominated by marketing, by HTML, by trackers, by subscriptions you didn’t even know you’d subscribed to.

Years ago I used to write a lot of letters by hand. So to me email seems like something worth preserving. Never mind that it doesn’t need to be corporate. You can host it yourself, or entrust it to a small Swiss company; there’s no law that says you need to submit to an advertising corporation, right?

But never mind all that. If you’re here, you’ve already played around with text-based email, and you want to know more. In my own explorations, I’ve tried a few text clients, and have always been curious about the vaunted notmuch. It has taken me forever to understand notmuch and how to get it hooked into my email. I mean, I still don’t understand it. But I’ve got it working and can explain how! Our set-up consists of three parts:

This very brief guide should be sufficient for wiring up aerc with notmuch and OfflineIMAP on an Arch Linux system. (I use Arch btw, so swap out references to pacman with your Linux distro’s package manager.) I haven’t tested this out on other Linux distributions, although the guide will likely be helpful to those users. I don’t know whether all of these programs can be made to run on BSD or macOS. Finally, the guide doesn’t go very deep into the configuration options of any of the three components, focusing instead rather tightly on those options essential to getting them working together.

OfflineIMAP

In the example we’ll be using the Maildir style of local email file structure.

  1. Create a directory to which your emails will be downloaded. We’ll use ~/Maildir.
  2. Install the package: pacman -S offlineimap
  3. N.B. In the subsequent code snippets, remember to replace home directory names (such as user ), email usernames, email domains, and email display names with your own values.
  4. Create this configuration file [source] at ~/.offlineimaprc or $XDG_CONFIG_HOME/offlineimap/config, swapping in the values for Maildir path, IMAP server address and email address:

    [general]
    # List of accounts to be synced, separated by a comma.
    accounts = main
    # Controls how many accounts may be synced simultaneously
    maxsyncaccounts = 1
        
    [Account main]
    # Identifier for the local repository; e.g. the maildir to be synced via IMAP.
    localrepository = main-local
    # Identifier for the remote repository; i.e. the actual IMAP, usually non-local.
    remoterepository = main-remote
        
    [Repository main-local]
    # OfflineIMAP supports Maildir, GmailMaildir, and IMAP for local repositories.
    type = Maildir
    # Where should the mail be placed?
    localfolders = /home/user/Maildir
        
    [Repository main-remote]
    # Remote repos can be IMAP or Gmail, the latter being a preconfigured IMAP.
    # SSL and STARTTLS are enabled by default.
    type = IMAP
    remotehost = imap.my-email-host.com
    remoteuser = user@my-email-domain.com
    # It's best not to store your email password in a file. See below.
    remotepass = my-email-password!
    # Necessary for SSL connections, if using offlineimap version > 6.5.4
    sslcacertfile = /etc/ssl/certs/ca-certificates.crt
    
  5. Now run OfflineIMAP to download your current emails: offlineimap -o. Later we’ll configure aerc to perform this step periodically. Also, note that you’re unlikely to want to store your email password in plaintext in the configuration file. Check out the Arch Wiki for more secure methods of storing the password (N.B.: The Arch Wiki is an excellent resource for open source software, even for users of other Linux distributions as well as macOS and BSD.).

notmuch and aerc

aerc can be optionally configured to work with notmuch, and even so, I was not able to get them to work together by building aerc from source, as suggested in the documentation. Rather, I needed to install aerc from the Arch User Repository. Users of other distributions or operating systems will likely need to install from source and hope for a more satisfying outcome.

  1. Install the aerc-git package from the Arch User Repository. This package supports notmuch and installs it as a dependency. If you’re building aerc from source, you’ll want to install notmuch first (pacman -S notmuch).
  2. Create the notmuch configuration at ~/.notmuch-config:

    # .notmuch-config - Configuration file for the notmuch mail system
    #
    # For more information about notmuch, see https://notmuchmail.org
        
    [database]
    path=/home/user/Maildir
        
    [user]
    name=User Name
    primary_email=user@my-email-domain.com
        
    # Maildir compatibility configuration
    #
    #   synchronize_flags      Valid values are true and false.
    #
    #   If true, then the following maildir flags (in message filenames)
    #   will be synchronized with the corresponding notmuch tags:
    #
    #       Flag    Tag
    #       ----    -------
    #       D   draft
    #       F   flagged
    #       P   passed
    #       R   replied
    #       S   unread (added when 'S' flag is not present)
    [maildir]
    synchronize_flags=true
    
  3. Now run notmuch new to set up the notmuch database. notmuch has a solid CLI. For example, if you wanted to flag all emails from a particular correspondent, you’d run notmuch tag +flagged -- from:katherine.johnson@nasa.gov. Visit the documentation for the whole picture. But generally you’ll want to interact with your emails via a notmuch-enabled frontend. There are frontends for vim, emacs, and others. But of course we’re here to set up aerc.

  4. Install aerc if you haven’t already (see no. 1 above).

  5. Install optional dependencies w3m and dante (dante-client on Debian). These will improve the rendering of HTML emails.

  6. We’ll need a few configuration files and scripts for aerc:

    • mail-sync.sh: syncs the Maildir and the IMAP server. Make this file executable and store it in your shell’s path.
    • aerc-notmuch-send.sh: properly stores sent emails in the Sent folder in Maildir; make this file executable and store it in your shell’s path.
    • $XDG_CONFIG_HOME/aerc/accounts.conf
    • $XDG_CONFIG_HOME/aerc/aerc.conf
    #!/bin/sh
    # mail-sync.sh
        
    # Syncs the Maildir and the IMAP server. Make this file executable and store it in your shell's path.
        
    OFFLINEIMAP=$(pgrep offlineimap)
    NOTMUCH=$(pgrep notmuch)
        
    if [ -n "$OFFLINEIMAP" ] || [ -n "$NOTMUCH" ]; then
        echo "Already running one instance of offlineimap or notmuch. Exiting..."
        exit 0
    fi
        
    offlineimap -o
    notmuch new
        
    # retag all "new" messages "inbox" and "unread"
    notmuch tag +inbox +unread -new -- tag:new
        
    # move items tagged "trash" to the Trash folder and retag
    notmuch search --output=files tag:trash and not folder:Trash | xargs mv -t /home/user/Maildir/Trash/cur/
    notmuch tag +trash -inbox -sent -archive -junk -drafts -- folder:Trash and not tag:trash
    
    # Tag mailing list emails
    notmuch tag +mailinglist -- to:whatever@lists.whatever.net
        
    # move messages tagged `mailinglist` (e.g.) to the trash after a couple of days
    notmuch tag +trash -inbox -- date:..2d and tag:mailinglist
    
    #!/bin/sh
    # aerc-notmuch-send.sh
    # Source: https://man.sr.ht/~rjarry/aerc/configurations/notmuch.md#emulating-copy-to-for-the-notmuch-backend
    # N.B. This does not handle encryption
        
    # ensure the script ends whenever a command exits with non-zero status
    set -e
        
    EMAIL=$(mktemp --suffix=.eml /tmp/XXXXXX)
    clean_up() {
        rm -f "$EMAIL"
    }
        
    # The account to be used is given as the first argument of this script
    account=$1
    shift
        
    # ensure clean_up() is called when we exit abnormally
    trap 'clean_up' 0 1 2 3 15
        
    # <stdin> of the script gets the email; we save it temporarily for using it twice
    cat >"$EMAIL"
        
    # First try to send the email, as it can cause more problems (i.e., connection)
    # `set -e` prevents the mail from entering the database in case this fails.
    # msmtp could be called with args from aerc, but --read-recipients already does the job
    msmtp --account="$account" --read-recipients --read-envelope-from <"$EMAIL"
        
    # assumes all maildir accounts are configured with a 'sent' directory
    # also make sure to tag it correctly
    notmuch insert --folder=Sent -inbox -unread +sent <"$EMAIL"
    
    # accounts.conf
    # Choose a nickname for each email account, to be used in the section header
    # and in the 'outgoing' property.
    [my-account]
    source        = notmuch:///home/user/Maildir
    maildir-store = /home/user/Maildir
    outgoing      = /home/user/.local/bin/aerc-notmuch-send.sh my-account
    default       = INBOX
    from          = User Name <user@my-email-domain.com>
        
    check-mail = 4m
    check-mail-cmd = /home/user/.local/bin/mail-sync.sh
    check-mail-timeout = 20s
    

    As far as aerc.conf goes, you can copy the given configuration from /usr/share/aerc/aerc.conf (or wherever it has landed, depending on your distribution and/or installation method) into $XDG_CONFIG_HOME/aerc/ and enjoy the perfectly reasonable defaults. The only suggestion I’d make here is that, since most of us receive primarily HTML email, you can handle it cleanly with these two lines:

    # In the [viewers] section:    
    alternatives=text/html,text/plain
    
    # In the [filters] section:
    text/html=html | colorize
    

Fire up aerc

Once all these configuration files and scripts are saved, go ahead and fire up aerc. Your email should quickly load in from your local file tree, and aerc should start checking for new mail immediately. This would be a good time to run the :help command within aerc and read the documentation, at least enough to perform basic operations of composing, sending, and searching for mail.

Hopefully you’ll be theming and tweaking this setup for the foreseeable future. Feel free to contact me via email or Mastodon with questions or corrections.

#aerc #notmuch #offlineimap #email #tui