<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>server_dot_jive</title>
    <link>https://blog.theadamcooper.com/</link>
    <description></description>
    <pubDate>Thu, 09 Apr 2026 20:23:21 +0000</pubDate>
    <item>
      <title>Terminal delight with aerc and notmuch</title>
      <link>https://blog.theadamcooper.com/terminal-delight-with-aerc-and-notmuch</link>
      <description>&lt;![CDATA[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.&#xA; &#xA;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?&#xA;&#xA;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:&#xA;&#xA;OfflineIMAP, which synchronizes the emails between your IMAP server and your local file system (alternative: isync)&#xA;notmuch, which manages a database of the emails in your local file system &#xA;aerc, a mail user agent with a terminal interface (alternatives: mutt/neomutt, alpine, meli).&#xA;&#xA;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.&#xA;&#xA;OfflineIMAP&#xA;In the example we’ll be using the Maildir style of local email file structure.&#xA;&#xA;Create a directory to which your emails will be downloaded. We’ll use ~/Maildir.&#xA;Install the package: pacman -S offlineimap&#xA;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.&#xA;Create this configuration file [source] at ~/.offlineimaprc or $XDGCONFIGHOME/offlineimap/config, swapping in the values for Maildir path, IMAP server address and email address:&#xA;&#xA;        [general]&#xA;    # List of accounts to be synced, separated by a comma.&#xA;    accounts = main&#xA;    # Controls how many accounts may be synced simultaneously&#xA;    maxsyncaccounts = 1&#xA;    &#xA;    [Account main]&#xA;    # Identifier for the local repository; e.g. the maildir to be synced via IMAP.&#xA;    localrepository = main-local&#xA;    # Identifier for the remote repository; i.e. the actual IMAP, usually non-local.&#xA;    remoterepository = main-remote&#xA;    &#xA;    [Repository main-local]&#xA;    # OfflineIMAP supports Maildir, GmailMaildir, and IMAP for local repositories.&#xA;    type = Maildir&#xA;    # Where should the mail be placed?&#xA;    localfolders = /home/user/Maildir&#xA;    &#xA;    [Repository main-remote]&#xA;    # Remote repos can be IMAP or Gmail, the latter being a preconfigured IMAP.&#xA;    # SSL and STARTTLS are enabled by default.&#xA;    type = IMAP&#xA;    remotehost = imap.my-email-host.com&#xA;    remoteuser = user@my-email-domain.com&#xA;    # It&#39;s best not to store your email password in a file. See below.&#xA;    remotepass = my-email-password!&#xA;    # Necessary for SSL connections, if using offlineimap version   6.5.4&#xA;    sslcacertfile = /etc/ssl/certs/ca-certificates.crt&#xA;    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.).&#xA;&#xA;notmuch and aerc&#xA;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. &#xA;&#xA;span id=&#34;install-aerc&#34;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). /span&#xA;Create the notmuch configuration at ~/.notmuch-config:&#xA;&#xA;        # .notmuch-config - Configuration file for the notmuch mail system&#xA;    #&#xA;    # For more information about notmuch, see https://notmuchmail.org&#xA;    &#xA;    [database]&#xA;    path=/home/user/Maildir&#xA;    &#xA;    [user]&#xA;    name=User Name&#xA;    primaryemail=user@my-email-domain.com&#xA;    &#xA;    # Maildir compatibility configuration&#xA;    #&#xA;    #&#x9;synchronizeflags      Valid values are true and false.&#xA;    #&#xA;    #&#x9;If true, then the following maildir flags (in message filenames)&#xA;    #&#x9;will be synchronized with the corresponding notmuch tags:&#xA;    #&#xA;    #&#x9;&#x9;Flag&#x9;Tag&#xA;    #&#x9;&#x9;----&#x9;-------&#xA;    #&#x9;&#x9;D&#x9;draft&#xA;    #&#x9;&#x9;F&#x9;flagged&#xA;    #&#x9;&#x9;P&#x9;passed&#xA;    #&#x9;&#x9;R&#x9;replied&#xA;    #&#x9;&#x9;S&#x9;unread (added when &#39;S&#39; flag is not present)&#xA;    [maildir]&#xA;    synchronizeflags=true&#xA;    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.&#xA;Install aerc if you haven’t already (see no. 1 above).&#xA;Install optional dependencies w3m and dante (dante-client on Debian). These will improve the rendering of HTML emails.&#xA;We’ll need a few configuration files and scripts for aerc:&#xA;    mail-sync.sh: syncs the Maildir and the IMAP server. Make this file executable and store it in your shell’s path.&#xA;    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.&#xA;    $XDGCONFIGHOME/aerc/accounts.conf&#xA;    $XDGCONFIGHOME/aerc/aerc.conf&#xA;&#xA;        #!/bin/sh&#xA;    # mail-sync.sh&#xA;    &#xA;    # Syncs the Maildir and the IMAP server. Make this file executable and store it in your shell&#39;s path.&#xA;    &#xA;    OFFLINEIMAP=$(pgrep offlineimap)&#xA;    NOTMUCH=$(pgrep notmuch)&#xA;    &#xA;    if [ -n &#34;$OFFLINEIMAP&#34; ] || [ -n &#34;$NOTMUCH&#34; ]; then&#xA;        echo &#34;Already running one instance of offlineimap or notmuch. Exiting...&#34;&#xA;        exit 0&#xA;    fi&#xA;    &#xA;    offlineimap -o&#xA;    notmuch new&#xA;    &#xA;    # retag all &#34;new&#34; messages &#34;inbox&#34; and &#34;unread&#34;&#xA;    notmuch tag +inbox +unread -new -- tag:new&#xA;    &#xA;    # move items tagged &#34;trash&#34; to the Trash folder and retag&#xA;    notmuch search --output=files tag:trash and not folder:Trash | xargs mv -t /home/user/Maildir/Trash/cur/&#xA;    notmuch tag +trash -inbox -sent -archive -junk -drafts -- folder:Trash and not tag:trash&#xA;&#xA;    # Tag mailing list emails&#xA;    notmuch tag +mailinglist -- to:whatever@lists.whatever.net&#xA;    &#xA;    # move messages tagged mailinglist (e.g.) to the trash after a couple of days&#xA;    notmuch tag +trash -inbox -- date:..2d and tag:mailinglist&#xA;            #!/bin/sh&#xA;    # aerc-notmuch-send.sh&#xA;    # Source: https://man.sr.ht/~rjarry/aerc/configurations/notmuch.md#emulating-copy-to-for-the-notmuch-backend&#xA;    # N.B. This does not handle encryption&#xA;    &#xA;    # ensure the script ends whenever a command exits with non-zero status&#xA;    set -e&#xA;    &#xA;    EMAIL=$(mktemp --suffix=.eml /tmp/XXXXXX)&#xA;    cleanup() {&#xA;        rm -f &#34;$EMAIL&#34;&#xA;    }&#xA;    &#xA;    # The account to be used is given as the first argument of this script&#xA;    account=$1&#xA;    shift&#xA;    &#xA;    # ensure cleanup() is called when we exit abnormally&#xA;    trap &#39;cleanup&#39; 0 1 2 3 15&#xA;    &#xA;    # stdin of the script gets the email; we save it temporarily for using it twice&#xA;    cat   &#34;$EMAIL&#34;&#xA;    &#xA;    # First try to send the email, as it can cause more problems (i.e., connection)&#xA;    # set -e prevents the mail from entering the database in case this fails.&#xA;    # msmtp could be called with args from aerc, but --read-recipients already does the job&#xA;    msmtp --account=&#34;$account&#34; --read-recipients --read-envelope-from &lt;&#34;$EMAIL&#34;&#xA;    &#xA;    # assumes all maildir accounts are configured with a &#39;sent&#39; directory&#xA;    # also make sure to tag it correctly&#xA;    notmuch insert --folder=Sent -inbox -unread +sent &lt;&#34;$EMAIL&#34;&#xA;            # accounts.conf&#xA;    # Choose a nickname for each email account, to be used in the section header&#xA;    # and in the &#39;outgoing&#39; property.&#xA;    [my-account]&#xA;    source        = notmuch:///home/user/Maildir&#xA;    maildir-store = /home/user/Maildir&#xA;    outgoing      = /home/user/.local/bin/aerc-notmuch-send.sh my-account&#xA;    default       = INBOX&#xA;    from          = User Name user@my-email-domain.com&#xA;    &#xA;    check-mail = 4m&#xA;    check-mail-cmd = /home/user/.local/bin/mail-sync.sh&#xA;    check-mail-timeout = 20s&#xA;    &#xA;    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 $XDGCONFIGHOME/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:&#xA;&#xA;        # In the [viewers] section:    &#xA;    alternatives=text/html,text/plain&#xA;&#xA;    # In the [filters] section:&#xA;    text/html=html | colorize&#xA;    &#xA;Fire up aerc&#xA;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.&#xA;&#xA;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.&#xA;&#xA;\#aerc \#notmuch \#offlineimap \#email \#tui&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>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.</p>

<p>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 <em>need</em> to be corporate. You can host it yourself, or entrust it to <a href="https://www.migadu.com">a small Swiss company</a>; there’s no law that says you need to submit to an advertising corporation, right?</p>

<p>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 <em>notmuch</em>. It has taken me forever to understand <em>notmuch</em> 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:</p>
<ul><li><a href="https://offlineimap.org"><em>OfflineIMAP</em></a>, which synchronizes the emails between your IMAP server and your local file system (alternative: <a href="https://isync.sourceforge.io"><em>isync</em></a>)</li>
<li><a href="https://notmuchmail.org"><em>notmuch</em></a>, which manages a database of the emails in your local file system</li>
<li><a href="https://git.sr.ht/~rjarry/aerc"><em>aerc</em></a>, a mail user agent with a terminal interface (alternatives: <a href="https://www.mutt.org"><em>mutt</em></a>/<a href="https://neomutt.org"><em>neomutt</em></a>, <a href="https://alpineapp.email"><em>alpine</em></a>, <a href="https://meli.delivery"><em>meli</em></a>).</li></ul>

<p>This very brief guide should be sufficient for wiring up <em>aerc</em> with <em>notmuch</em> and <em>OfflineIMAP</em> on an Arch Linux system. (<a href="https://knowyourmeme.com/memes/btw-i-use-arch">I use Arch btw</a>, so swap out references to <code>pacman</code> 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.</p>

<h4 id="offlineimap"><em>OfflineIMAP</em></h4>

<p>In the example we’ll be using the Maildir style of local email file structure.</p>
<ol><li>Create a directory to which your emails will be downloaded. We’ll use <code>~/Maildir</code>.</li>
<li>Install the package: <code>pacman -S offlineimap</code></li>
<li><strong><em>N.B. In the subsequent code snippets, remember to replace home directory names (such as</em></strong> user <strong><em>), email usernames, email domains, and email display names with your own values.</em></strong></li>

<li><p>Create this configuration file <a href="https://wiki.archlinux.org/title/OfflineIMAP#Minimal">[source]</a> at <code>~/.offlineimaprc</code> or <code>$XDG_CONFIG_HOME/offlineimap/config</code>, swapping in the values for Maildir path, IMAP server address and email address:</p>

<pre><code>[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&#39;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 &gt; 6.5.4
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
</code></pre></li>

<li><p>Now run <em>OfflineIMAP</em> to download your current emails: <code>offlineimap -o</code>. Later we’ll configure <em>aerc</em> 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 <a href="https://wiki.archlinux.org/title/OfflineIMAP#Password_management">Arch Wiki</a> 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.).</p></li></ol>

<h4 id="notmuch-and-aerc"><em>notmuch</em> and <em>aerc</em></h4>

<p><em>aerc</em> can be optionally configured to work with <em>notmuch</em>, and even so, I was not able to get them to work together by building <em>aerc</em> from source, as suggested in the documentation. Rather, I needed to install <em>aerc</em> from the <a href="https://aur.archlinux.org">Arch User Repository</a>. Users of other distributions or operating systems will likely need to install from source and hope for a more satisfying outcome.</p>
<ol><li><span id="install-aerc">Install the <code>aerc-git</code> package from the <a href="https://aur.archlinux.org/packages/aerc-git">Arch User Repository</a>. This package supports <em>notmuch</em> and installs it as a dependency. If you’re building <em>aerc</em> from source, you’ll want to install <em>notmuch</em> first (<code>pacman -S notmuch</code>). </span></li>

<li><p>Create the <em>notmuch</em> configuration at <code>~/.notmuch-config</code>:</p>

<pre><code># .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 &#39;S&#39; flag is not present)
[maildir]
synchronize_flags=true
</code></pre></li>

<li><p>Now run <code>notmuch new</code> to set up the <em>notmuch</em> database. <em>notmuch</em> has a solid CLI. For example, if you wanted to flag all emails from a particular correspondent, you’d run <code>notmuch tag +flagged -- from:katherine.johnson@nasa.gov</code>. Visit the <a href="https://notmuchmail.org/doc/latest/">documentation</a> for the whole picture. But generally you’ll want to interact with your emails via a <em>notmuch</em>-enabled frontend. There are frontends for <em>vim</em>, <em>emacs</em>, and others. But of course we’re here to set up <em>aerc</em>.</p></li>

<li><p>Install <em>aerc</em> if you haven’t already (see <a href="#install-aerc">no. 1</a> above).</p></li>

<li><p>Install optional dependencies <em>w3m</em> and <em>dante</em> (<em>dante-client</em> on Debian). These will improve the rendering of HTML emails.</p></li>

<li><p>We’ll need a few configuration files and scripts for <em>aerc</em>:</p>
<ul><li><code>mail-sync.sh</code>: syncs the Maildir and the IMAP server. Make this file executable and store it in your shell’s path.</li>
<li><code>aerc-notmuch-send.sh</code>: properly stores sent emails in the Sent folder in Maildir; make this file executable and store it in your shell’s path.</li>
<li><code>$XDG_CONFIG_HOME/aerc/accounts.conf</code></li>
<li><code>$XDG_CONFIG_HOME/aerc/aerc.conf</code></li></ul>

<pre><code>#!/bin/sh
# mail-sync.sh
    
# Syncs the Maildir and the IMAP server. Make this file executable and store it in your shell&#39;s path.
    
OFFLINEIMAP=$(pgrep offlineimap)
NOTMUCH=$(pgrep notmuch)
    
if [ -n &#34;$OFFLINEIMAP&#34; ] || [ -n &#34;$NOTMUCH&#34; ]; then
    echo &#34;Already running one instance of offlineimap or notmuch. Exiting...&#34;
    exit 0
fi
    
offlineimap -o
notmuch new
    
# retag all &#34;new&#34; messages &#34;inbox&#34; and &#34;unread&#34;
notmuch tag +inbox +unread -new -- tag:new
    
# move items tagged &#34;trash&#34; 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
</code></pre>

<pre><code>#!/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 &#34;$EMAIL&#34;
}
    
# 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 &#39;clean_up&#39; 0 1 2 3 15
    
# &lt;stdin&gt; of the script gets the email; we save it temporarily for using it twice
cat &gt;&#34;$EMAIL&#34;
    
# 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=&#34;$account&#34; --read-recipients --read-envelope-from &lt;&#34;$EMAIL&#34;
    
# assumes all maildir accounts are configured with a &#39;sent&#39; directory
# also make sure to tag it correctly
notmuch insert --folder=Sent -inbox -unread +sent &lt;&#34;$EMAIL&#34;
</code></pre>

<pre><code># accounts.conf
# Choose a nickname for each email account, to be used in the section header
# and in the &#39;outgoing&#39; 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 &lt;user@my-email-domain.com&gt;
    
check-mail = 4m
check-mail-cmd = /home/user/.local/bin/mail-sync.sh
check-mail-timeout = 20s
</code></pre>

<p>As far as <code>aerc.conf</code> goes, you can copy the given configuration from <code>/usr/share/aerc/aerc.conf</code> (or wherever it has landed, depending on your distribution and/or installation method) into <code>$XDG_CONFIG_HOME/aerc/</code> 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:</p>

<pre><code># In the [viewers] section:    
alternatives=text/html,text/plain

# In the [filters] section:
text/html=html | colorize
</code></pre></li></ol>

<h3 id="fire-up-aerc">Fire up <em>aerc</em></h3>

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

<p>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.</p>

<p>#aerc #notmuch #offlineimap #email #tui</p>
]]></content:encoded>
      <guid>https://blog.theadamcooper.com/terminal-delight-with-aerc-and-notmuch</guid>
      <pubDate>Mon, 02 Jan 2023 17:56:11 +0000</pubDate>
    </item>
  </channel>
</rss>