<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>hi, it&#39;s mike</title>
    <link>https://mike.puddingtime.org/tags/email/</link>
    <description>Recent content on hi, it&#39;s mike</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>mike@puddingtime.org (mike)</managingEditor>
    <webMaster>mike@puddingtime.org (mike)</webMaster>
    <copyright>© 2026, mike</copyright>
    <lastBuildDate>Tue, 09 Jan 2024 10:41:05 -0800</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/email/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Daily notes for 2024-01-09 (mutt noodling edition)</title>
      <link>https://mike.puddingtime.org/posts/2024-01-09-daily-notes/</link>
      <pubDate>Tue, 09 Jan 2024 10:41:05 -0800</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2024-01-09-daily-notes/</guid>
      <description>Multi-account, GPG-secure mutt configs. Mutt message scoring with Ruby, and score color-coding.</description>
      <content:encoded><![CDATA[<h2 id="multi-account-gpg-secured-mutt-config">Multi-account, GPG-secured mutt config</h2>
<p>I keep having to reinvent this every few years, and I always stitch it together from assorted sources, mostly because Google sort of shifts around now and then. So:</p>
<ul>
<li>Given a Gmail account with IMAP access turned on</li>
<li>Given a Fastmail account using IMAP</li>
<li>Given mutt, with your configuration in <code>~/.mutt</code> and with <code>muttrc</code> and <code>macros</code> files.</li>
<li>Given a working gpg config you can use to encrypt/decrypt</li>
</ul>
<p>There are all sorts of ways to handle mutt config for assorted providers. The examples here are working right now, in early 2024. They probably have bits of cruft and lint because my config has been a work in progress since some time in the late 20th century.</p>
<h3 id="overview">Overview</h3>
<p>You&rsquo;re making profiles to do this: One for each of your accounts that will hold account specific config information. If you currently have a monolith config in mutt, you can lift a lot of stuff out of it and move it into a profile, then source the profile in your main <code>muttrc</code>.</p>
<p>You&rsquo;re also going to make and encrypt a credential file for each account. Some people do this all in one file and use account hooks to make sure <code>imap_user</code>, <code>imap_password</code> and <code>smtp_password</code> are set correcctly depending on the account you&rsquo;re operating in. I chose to make a file for each account.</p>
<p>You&rsquo;re going to make macros that source the profiles when you want to switch between them.</p>
<h3 id="0-pre-config-with-gmail-and-fastmail">0. Pre-config with Gmail and Fastmail</h3>
<p>I&rsquo;m not going to go into a ton of detail here:</p>
<ul>
<li>Gmail needs to have less secure app access turned on. Find it in your account settings. If you&rsquo;re doing this for a work account, it may be your admin hasn&rsquo;t enabled this. Have fun fighting city hall, in that case.</li>
<li>If you have a GSuite admin, they need to have enabled all IMAP clients, not just OAuth ones.</li>
<li>If you have 2FA turned on with Google, you will need to enable an application password.</li>
</ul>
<p>For Fastmail:</p>
<ul>
<li>You need to have an app password set up for mutt. <code>Settings -&gt; Privacy and Security -&gt; Integrations -&gt; App passwords</code></li>
</ul>
<h3 id="1-the-profile-files">1. The profile files</h3>
<p>Make profile files for each of your accounts. I name them <code>workplace.profile</code>, <code>fastmail.profile</code>, etc. It doesn&rsquo;t matter there&rsquo;s no required convention. It&rsquo;s a good idea to use the first one as the template for the second one.</p>
<p>This is an example of my Fastmail profile. Note line 6:</p>
<p><code>source &quot;gpg -d ~/.mutt/passwords.gpg |&quot;</code></p>
<p>That&rsquo;s where your credentials will come from. I&rsquo;ll show that file next.</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># -*- muttrc -*-</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Mutt sender profile : personal/default</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">unset</span> folder
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">smtp_authenticators</span> <span class="o">=</span> <span class="s1">&#39;gssapi:login&#39;</span> <span class="c1"># fastmail needs this</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">imap_authenticators</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">source</span> <span class="s2">&#34;gpg -d ~/.mutt/passwords.gpg |&#34;</span> 
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">spoolfile</span> <span class="o">=</span> <span class="s2">&#34;imaps://imap.fastmail.com&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">folder</span> <span class="o">=</span> <span class="s2">&#34;imaps://imap.fastmail.com/INBOX&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">postponed</span><span class="o">=</span><span class="s2">&#34;+Drafts&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">hostname</span><span class="o">=</span><span class="s2">&#34;yourdomain.com&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">signature</span><span class="o">=</span> <span class="s2">&#34;~/.mutt/personal.sig&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">from</span><span class="o">=</span> <span class="s2">&#34;Bob Jones &lt;bob@yourdomain.com&gt;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">realname</span> <span class="o">=</span> <span class="s2">&#34;Bob Jones&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">smtp_url</span> <span class="o">=</span> <span class="s2">&#34;smtps://bobjones@fastmail.com@smtp.fastmail.com:465&#34;</span> <span class="c1"># use your fastmail username, not your email address</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">imap_user</span> <span class="o">=</span> <span class="s2">&#34;bobjones@fastmail.com&#34;</span> <span class="c1"># use your fastmail username here, too</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># set the status to show which profile I&#39;m using</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">status_format</span><span class="o">=</span> <span class="s2">&#34;-%r-Fastmail: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?l? %l?]---(%s/%S)-%&gt;-(%P)---\n&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">unmy_hdr *
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">my_hdr From: Bob Jones &lt;bob@yourdomain.com&gt;
</span></span><span class="line"><span class="cl">my_hdr Organization: yourdomain.com
</span></span><span class="line"><span class="cl">my_hdr Sender: Bob Jones &lt;bob@yourdomain.com&gt;
</span></span><span class="line"><span class="cl">my_hdr Return-Path: &lt;bob@yourdomain.com&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># clear the existing mailboxes list</span>
</span></span><span class="line"><span class="cl">unmailboxes *
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># load up mailboxes appropriate to this profile</span>
</span></span><span class="line"><span class="cl">mailboxes + <span class="s2">&#34;=Spam&#34;</span>
</span></span><span class="line"><span class="cl">mailboxes + <span class="s2">&#34;=disposable&#34;</span>
</span></span><span class="line"><span class="cl">mailboxes + <span class="s2">&#34;=Newsletters&#34;</span>
</span></span><span class="line"><span class="cl">mailboxes + <span class="s2">&#34;=Sent&#34;</span>
</span></span><span class="line"><span class="cl">mailboxes + <span class="s2">&#34;=Archive&#34;</span></span></span></code></pre></div>
<h3 id="2-make-credentials-files">2. Make credentials files</h3>
<p>For each account, you need to make a file for your credentials.</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">set imap_user=bob@bobjones.com
</span></span><span class="line"><span class="cl">set imap_pass=&#34;klatu barada nikto&#34;
</span></span><span class="line"><span class="cl">set smtp_pass=&#34;klatu barada nikto&#34;</span></span></code></pre></div>
<p>Name it whatever. <code>passwords-accountname</code> works.</p>
<p>Once you&rsquo;ve created the file, encrypt it with gpg:</p>
<p><code>gpg -r your-gpg-key@yourdomain.com -e passwords-fastmail</code></p>
<p>Test it:</p>
<p><code>gpg -d passwords-fastmail.gpg</code></p>
<p>Then shred the plaintext original:</p>
<p><code>shred -u passwords-fastmail</code></p>
<p>Make sure that your profile (from the previous step) is sourcing the gpg file in line 6 of my example, e.g.</p>
<p><code>source &quot;gpg -d ~/.mutt/passwords-fastmail.gpg |&quot;</code></p>
<h3 id="3-do-a-quick-mid-config-check">3. Do a quick mid-config check</h3>
<p>Might as well test it now.  You can do that by sourcing one of your profiles in your <code>muttrc</code>:</p>
<p><code>source ~/.mutt/fastmail.profile</code></p>
<p>When you run mutt the first time in this login session, you should get a gpg prompt for your credentials so mutt can decrypt your password file and use it to log in.</p>
<p>If it&rsquo;s working, now&rsquo;s the time to make your second profile and credentials files using the above steps since it&rsquo;ll be good to know what they&rsquo;re all called for the next step, which is making macros.</p>
<h3 id="4-make-macros">4. Make macros</h3>
<p>I keep my macros in their own file under <code>~/.mutt</code> just to keep things modular. You can put these in your main <code>muttrc</code>. Whatever you prefer. If you have a separate file, make sure to source it in <code>muttrc</code>:</p>
<p><code>source ~/.mutt/macros</code></p>
<p>Now add something like this for each account:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">macro index .cf &#39;&lt;sync-mailbox&gt;&lt;enter-command&gt;source ~/.mutt/fastmail.profile&lt;enter&gt;&lt;change-folder&gt;!&lt;enter&gt;&#39;
</span></span><span class="line"><span class="cl">macro index .cg &#39;&lt;sync-mailbox&gt;&lt;enter-command&gt;source ~/.mutt/google.profile&lt;enter&gt;&lt;change-folder&gt;!&lt;enter&gt;&#39;</span></span></code></pre></div>
<p>That just does one last sync, then sources your profile, then changes folders to the inbox of that profile.</p>
<p>Restart mutt. From the index, if all is working correctly, the macro <code>.cf</code> will source your <code>fastmail.profile</code> and the macro <code>.cg</code> will source your <code>google.profile</code> file (both of which also source/decrypt their respective credential files).</p>
<h3 id="5-in-conclusion">5. In conclusion</h3>
<p>Once it&rsquo;s all wired up and running, you should be able to switch back and forth between accounts with just a few seconds of latency as the inbox syncs on exit and the new inbox syncs on login.</p>
<h2 id="the-pleasures-of-mutt">The pleasures of mutt</h2>
<p>I went on a mutt revival kick early last year. It remains a land of contrasts. I never end up sticking to it 100 percent of the time but instead prefer to use it as a quick triage tool: It&rsquo;s easy to make macros and keybindings that speed up inbox processing. Sometimes it&rsquo;s easier to just bail out to the web mail interface, but during the day it&rsquo;s helpful to just burn through the inbox never taking my hands off the keyboard.</p>
<h2 id="mutt-scoring-and-color-treatments">mutt scoring and color treatments</h2>
<p>One last thing, I guess, since I&rsquo;m documenting stuff.  One of the reasons I like mutt for triage so much is my ability to add a little visual treatment to messages based on their scores. That makes it easy to see what in my inbox has more priority.</p>
<p>I&rsquo;ve got this little script in my <code>~/.mutt</code>:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env ruby</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;mail&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;tempfile&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Wants a +/- integer, e.g. +20</span>
</span></span><span class="line"><span class="cl"><span class="n">score</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">.</span><span class="n">first</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">score_file</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="no">Dir</span><span class="o">.</span><span class="n">home</span><span class="si">}</span><span class="s2">/.mutt/scored&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">msg</span> <span class="o">=</span> <span class="no">Tempfile</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;msg&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">msg</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="vg">$stdin</span><span class="o">.</span><span class="n">read</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">mail</span> <span class="o">=</span> <span class="no">Mail</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">from</span> <span class="o">=</span> <span class="n">mail</span><span class="o">.</span><span class="n">from</span><span class="o">.</span><span class="n">first</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">score_file</span><span class="p">,</span> <span class="s2">&#34;a&#34;</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span> <span class="s2">&#34;score ~f</span><span class="si">#{</span><span class="n">from</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">score</span><span class="si">}</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">msg</span><span class="o">.</span><span class="n">close</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">msg</span><span class="o">.</span><span class="n">unlink</span></span></span></code></pre></div>
<p>And I&rsquo;ve got these macros in my <code>~/.mutt/macros</code> file:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># Score messages</span>
</span></span><span class="line"><span class="cl">macro index,browser .sp <span class="s2">&#34;&lt;pipe-entry&gt;~/.mutt/mailscore.rb +5\n&lt;enter-command&gt;source ~/.mutt/scored&lt;enter&gt;&#34;</span> <span class="c1"># score sender +5</span>
</span></span><span class="line"><span class="cl">macro index,browser .sP <span class="s2">&#34;&lt;pipe-entry&gt;~/.mutt/mailscore.rb +20\n&lt;enter-command&gt;source ~/.mutt/scored&lt;enter&gt;&#34;</span> <span class="c1"># score sender +20</span>
</span></span><span class="line"><span class="cl">macro index,browser .sm <span class="s2">&#34;&lt;pipe-entry&gt;~/.mutt/mailscore.rb -5\n&lt;enter-command&gt;source ~/.mutt/scored&lt;enter&gt;&#34;</span> <span class="c1"># score sender -5</span>
</span></span><span class="line"><span class="cl">macro index,browser .sM <span class="s2">&#34;&lt;pipe-entry&gt;~/.mutt/mailscore.rb -20\n&lt;enter-command&gt;source ~/.mutt/scored&lt;enter&gt;&#34;</span> <span class="c1"># score sender -20</span></span></span></code></pre></div>
<p>And I&rsquo;ve got a few lines in my <code>~/.mutt/colors</code> file:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">color index cyan default <span class="s2">&#34;~n 0-2 !~p&#34;</span>
</span></span><span class="line"><span class="cl">color index magenta default <span class="s2">&#34;~n &lt;5&#34;</span>
</span></span><span class="line"><span class="cl">color index brightyellow default <span class="s2">&#34;~n &gt;15&#34;</span>
</span></span><span class="line"><span class="cl">color index brightred default <span class="s2">&#34;~n &gt;19&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span></span></span></code></pre></div>
<p>The macros pipe a given message into the script, the script extracts the sender, and the script writes a line into my <code>~/.mutt/scored</code> file. Then the <code>~/.mutt/colors</code> file (which you need to source in <code>muttrc</code>) assigns colors to certain scores. I have a few other rules in <code>~/.mutt/scores</code>, as well:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># Date-based scoring penalties -- older things fall down</span>
</span></span><span class="line"><span class="cl">score ~d&gt;3d -1
</span></span><span class="line"><span class="cl">score ~d&gt;7d -3
</span></span><span class="line"><span class="cl">score ~d&gt;14d -10
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">score <span class="s2">&#34;~O&#34;</span> +10 <span class="c1"># old = +10 so I don&#39;t miss it</span>
</span></span><span class="line"><span class="cl">score <span class="s2">&#34;~F&#34;</span> +20 <span class="c1"># flagged = +20 so it stays in the interesting view for a while, even if old</span>
</span></span><span class="line"><span class="cl">score <span class="s2">&#34;!~p ~d&gt;7d&#34;</span> -10 <span class="c1"># not for me directly, getting old, let it fade away</span>
</span></span><span class="line"><span class="cl">score <span class="s2">&#34;!~l&#34;</span> +2 <span class="c1"># to a known list, give it a bump</span></span></span></code></pre></div>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-04-25</title>
      <link>https://mike.puddingtime.org/posts/2023-04-25-daily-notes/</link>
      <pubDate>Tue, 25 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-25-daily-notes/</guid>
      <description>Mail restlessness alights on MailMate, editing web forms in Emacs with Atomic Chrome, org-recur for simple and readable recurrence, GUI org-capture with Captee, more on my org PRM.</description>
      <content:encoded><![CDATA[<h2 id="mail-restlessness-alights-on-mailmate">Mail restlessness alights on MailMate</h2>
<p>I was scrolling through <a href="https://www.reddit.com/r/emacs">/r/emacs</a> today and came across someone asking for help configuring GNUS and IMAP. It has been a very long time since I did that, so I had nothing useful to contribute &ndash; that config predated me using version control &ndash; but I did notice a link to
<a href="https://useplaintext.email">https://useplaintext.email</a>, which intrigued me.</p>
<p>The last time I allowed myself to have a strong opinion about email I was writing a &ldquo;how we work&rdquo; for Puppet&rsquo;s engineering department. The boss and I believed that this was our big shot at putting a lot of email evil to rest &ndash; the scourge of top-posting, the blight of replies too widely scoped to too many groups, the simple, everyday <em>harm</em> done by needless reply-alls that add nothing.</p>
<p>It turns out the top-posters won and we just have to live with that.</p>
<p>But there was <a href="https://useplaintext.email">https://useplaintext.email</a> reminding me of a more innocent time, using the word &ldquo;harmful&rdquo; in conjunction with HTML mail, taking one more swing at putting paid to top-posting once and for all.</p>
<p>It also had a list of plaintext email clients that I gave a quick scan, and one jumped out because I&rsquo;d heard of it but never really gave it a spin: <a href="https://freron.com">MailMate</a>. It&rsquo;s a Mac email client, it defaults to plain text but will read and send HTML email (via Markdown formatting on the sending side). It&rsquo;s also super keyboard-centric. <em>And</em> it has a &ldquo;bundles&rdquo; feature that lets you write your own plugins. It comes with a bunch, including one that saves a link to a message in an org-mode file.</p>
<p>I&rsquo;ve been fiddling around with it today and like it a lot. Besides its plaintext-centricity, keyboard-centricity, and extensibility, I love that you can open up a font picker, select a piece of the interface, and define a font for it. I went through and set everything to Fira Code Retina.</p>
<figure><img src="/img/mailmate_screen.jpg"
    alt="MailMate (in Scrambled Mode) with a fixed typeface for its UI"><figcaption>
      <h4>MailMate in Scrambled Mode</h4>
    </figcaption>
</figure>

<p>So, what about mu4e? Or mutt? Still on the docket.</p>
<p>mu4e has been bugging me a little because it has a very strange and possessive set of keymappings that collide with Doom Emacs. It hijacks the space key, so my muscle memory around the spacebar as the leader key is all messed up.</p>
<p>mutt remains mutt. I have a lot of affection for it, but its main advantage over anything at all is its customizable keyboard-centric nature, and MailMate has that, too, with less fussing.</p>
<p>And there is something a little weird about running isync on two machines in the house. I mean, theoretically it is no weirder than running two IMAP clients of any kind on two machines in the house. It&rsquo;s just an IMAP client. But it&rsquo;s a busy one.</p>
<h2 id="atomic-chrome-ghosttext">Atomic Chrome/GhostText</h2>
<p>There have been a few &ldquo;use your favorite editor for text areas in your browser&rdquo; things over the years. <a href="https://github.com/alpha22jp/atomic-chrome">Atomic Chrome</a> seems to work very well with <a href="https://github.com/fregante/GhostText">GhostText</a>, an extension that works with any of Firefox, Safari, or Chrome. You just install the package in Emacs, and invoke the listener with <code>(atomic-chrome-start-server)</code> somewhere in your init. It listens for the browser extension, which can be invoked with <code>CMD SHIFT k</code>, and opens a buffer for editing.</p>
<p>As I said, this kind of thing has been around for years. The Atomic Chrome/GhostText combination just seems to be reliable in a way I haven&rsquo;t come across in the past.</p>
<h2 id="org-recur">org-recur</h2>
<p>Scheduling recurrence in org isn&rsquo;t <em>that</em> bad, but <a href="https://github.com/mrcnski/org-recur">org-recur</a> makes it really simple. It just extends org-mode&rsquo;s syntax and allows you to add recurrence rules in a heading using notation like <code>|+1|</code>, <code>|Wkdy|</code>, or <code>|1,15|</code>, for &ldquo;every day,&rdquo; &ldquo;every weekday,&rdquo; and &ldquo;1st and 15th of every month,&rdquo; respectively.</p>
<h2 id="captee">Captee</h2>
<p>org-capture, like assorted &ldquo;use your favorite editor everywhere&rdquo; plugins, is one of those things I know people have had working for a while. I remember having it set up and working a very long time ago, then I lost that config and just forgot how to do it. <a href="http://yummymelon.com/captee/">Captee</a> is a little macOS app that worked pretty much out of the box once I had an emacsclient app set up.</p>
<p>It sits in your Mac share menu and grabs URLs from browsers and browser-adjacent apps then does &hellip; stuff &hellip; to them. If you want a simple Markdown link, it&rsquo;ll do that. If you want an org-mode link, it&rsquo;ll do that, copying both to the clipboard for you. It&rsquo;ll also work with your org-capture template of choice and send a link + title + selected text to org-mode.</p>
<p>The thing I really like about it is that it works well with my RSS reader, Reeder. I&rsquo;ve just bound it to <code>C</code> in the share actions list and it saves links/titles to my org-mode inbox.</p>
<h2 id="more-on-my-org-prm">More on my org PRM</h2>
<p>I guess the thing I&rsquo;ve been calling a plaintext CRM belongs to the &ldquo;PRM&rdquo; category (for &ldquo;personal,&rdquo; not &ldquo;customers.&rdquo;) So, it&rsquo;s my org PRM now. I&rsquo;ve been getting real use out of it.</p>
<p>Building it has followed a familiar pattern of feeling a gap, thinking surely someone has filled it, realizing that is not true, then going through the same loop of &ldquo;maybe this general purpose tool?&rdquo; and a halting attempt to use it, then a realization that it doesn&rsquo;t matter how many rounded corners and AJAX transition effects the roach motel has &ndash; it&rsquo;s still a roach motel.</p>
<p>It&rsquo;s just a bad category I can only assume is as bad as it is because nobody wants to pay for it at the consumer level, and I think nobody wants to pay for it because social media has ushered in an era where we&rsquo;re all sort of performing the family holiday letter on Facebook every day of the year.  And also our &ldquo;contacts&rdquo; are all over the place. Every attempt to consolidate them and de-dup them is a minor catastrophe, with your sister-in-law manifesting nine times in the same address book and Siri forgetting where &ldquo;home&rdquo; is because something has pulled in your address-free doppelganger.</p>
<p>Anyhow, the <a href="https://mike.puddingtime.org/posts/20230413-making-a-plaintext-personal-crm-with-org-contacts/">thing I built a few weeks ago?</a> I am using it daily:</p>
<ul>
<li>Agenda reports that tell me who I haven&rsquo;t been in touch with, but want to.</li>
<li>Reminders to schedule time with people or follow up on plans.</li>
<li>Easy,fast access to past messages from contacts.</li>
<li>Quick notes about conversations.</li>
<li>Reminders to ping recruiters.</li>
</ul>
<p>There are a lot of contact management apps. There are a few apps that will issue general-purpose &ldquo;AI-driven&rdquo; reminders to contact people. There&rsquo;s nothing that feels as easy to use. I tried one that featured a lot of nice automation, but it was iOS only and there was no way to mass-select and tag contacts. Even with my relatively modest list I would have been an hour pecking in tags. With a contacts.org file, it was very fast and simple. There&rsquo;s not even a smirky &ldquo;only free if your time is worth nothing&rdquo; rejoinder, because most of these products are harder to use and take more time to deliver less, or cost astronomical amounts for what they do.</p>
<p>Being plaintext and org-mode/elisp driven, it&rsquo;s also super easy to extend and modify. If I don&rsquo;t like a decision I made about how something works, it&rsquo;s an easy change. With org-mode capture templates, the input is all uniform and structured, so I don&rsquo;t worry about backing out or moving the content elsewhere. Basically, it&rsquo;s as calming for me as text ever has been.</p>
<p>Anyhow, I use it daily, I like it a lot, and it feels good to use.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Quick mu4e notes</title>
      <link>https://mike.puddingtime.org/posts/2023-04-20-quick-mu4e-notes/</link>
      <pubDate>Thu, 20 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-20-quick-mu4e-notes/</guid>
      <description>The bear dances! And it dances &amp;hellip; pretty good?</description>
      <content:encoded><![CDATA[<p><a href="https://www.djcbsoftware.nl/code/mu/mu4e.html">mu4e</a> is pretty good!</p>
<p>I went into giving mu a shot giving myself a giant side-eye for doing anything that involved running some MDA on a laptop, which is the minimum to use something like mu.</p>
<p>The intensity of the irritation with myself just deepened when my first pick for delivery &ndash; offlineimap &ndash; didn&rsquo;t pan out and I found myself configuring <a href="https://isync.sourceforge.io/">isync</a> to see if that would do any better. But isync (dba mbsync) works pretty well. It was easy to configure, I figured out how to gpg-encrypt my credentials, and I got it all set up in <a href="https://github.com/lra/mackup">mackup</a> such that I only have to configure/reconfigure in one place.</p>
<p>Most of my aversion to fiddling around with mail comes down to the MDA part, either because of the fragility of the component itself, or the flakiness of running these things on a laptop and how they&rsquo;ll cope with being daemonized in an environment that&rsquo;s not awake all the time. isync itself seems fine after several days, and it seems to be okay running as a <a href="https://github.com/Homebrew/homebrew-services">homebrew service</a> (with one minor caveat).</p>
<p>So that&rsquo;s getting mail down to the machine.</p>
<p><a href="https://github.com/djcb/mu">mu</a> itself &ndash; the indexing/search service for the maildir that isync creates &ndash; is pretty good. I&rsquo;ve got ~231,000 messages indexed in it, and it&rsquo;s super fast. As I&rsquo;ve been working on cleaning up my contacts list it&rsquo;s been great for just <code>mu find &quot;someone&quot;</code> from the command line. In some ways it&rsquo;s almost too helpful given the volume of messages, because you get stuff like multiple reply-to&rsquo;s in headers from Google+ email notifications or whatever, so one name can return 20 or 30 results in an address search.</p>
<p>So that brings us to mu4e.</p>
<p>Most of my aversion to running anything to do with &rsquo;net activity on Emacs comes down to blocking the whole app on a slow operation. I used to use GNUS for both IMAP and Usenet, and remember sometimes just having to get up and walk away during a sync until something finally got around to downloading. It was no way to live and I swore off anything to do with mail on Emacs unless I was willing to do it with an MDA of some kind in place (with all the attendant reasons I did not want to do that applying).</p>
<p>mu4e doesn&rsquo;t even really interact with whatever we could consider a &ldquo;physical&rdquo; mail message, though. I mean, yes &hellip; when you write a message with it, it is creating a tmp of something that is eventually handed off to an MTA, but for reading and processing it is not touching Maildir messages in the filesystem &ndash; it is instead interacting with the mu database as a set of queries. It&rsquo;s super fast. Fast the way Spotlight <em>can</em> be in Apple Mail, or search <em>can</em> be in Gmail, but consistently so.</p>
<p>UI-wise, mu4e is initially puzzling.</p>
<p>It starts from a place of &ldquo;every list of mail is just a database query, not a list of files in a <code>Maildir</code> directory.&rdquo; That&rsquo;s fine. Lots of things in computing exist as vectorized representations of an object in filesystem. The difference between mu4e and some of these other styles of digital information is that not a ton of work has been done to re-translate these vectorized abstractions back into their old metaphor. So the menus, etc. talk in terms of &ldquo;lists of headers&rdquo; and not &ldquo;folders of messages.&rdquo;</p>
<p>Broadly, you can tell mu4e started from mu &ndash;  &ldquo;let&rsquo;s make a mail search engine&rdquo; &ndash;  and then found expression as an Emacs MUA. While other MUAs <em>include</em> the idea of marking and operating but tend to start from a place of direct operation on a message (mutt&rsquo;s an exception), mu4e starts from the assumption you&rsquo;re going to mark and operate. So you don&rsquo;t &ldquo;delete a message,&rdquo; you mark it for deletion (or moving, or whatever) then either execute your marks with the <code>x</code> keystroke, or sign off on executing them when you leave a given header list (i.e. what everyone else calls a folder).</p>
<p>It&rsquo;s &hellip; I hate to even make it sound like this is a thing. If you have room in your life for setting up an MDA, a search engine for mail, and an Emacs MUA, you have whatever it is one needs to interact with a thin layer of abstraction over that whole pile of other abstractions. In some ways, mu4e feels to me like what might have happened if we chucked every innovation in mail interfaces that occurred after <a href="https://en.wikipedia.org/wiki/MH_Message_Handling_System">mh</a> and went straight to &ldquo;nah, dawg, your mail is still there on disk, but it also lives in The Matrix.&rdquo; There&rsquo;s just a little ramp for your muscle memory, is all.</p>
<p>So, what do you get in exchange, I guess?</p>
<p>First, it overcomes the core objection to running an MUA on Emacs at all: Everything except composing a message is a database operation, so everything is pretty fast.</p>
<p>People report being slowed down when trying to send messages with large attachments, and the proposed workaround (an async method you can configure) reportedly flakes out now and then. A dedicated MUA like Apple Mail might just step over that by backgrounding the send operation and letting you go on your way. Some webmail apps will give you the AJAX-y spinner until they&rsquo;re done receiving the attachment, but not otherwise lock you out of using your browser. Conceivably, a big attachment with mu4e will still cost you the use of your text editor for the duration of the attachment. People who refuse to use their text editors for things besides just editing text will find that unacceptable and weird, but also know it&rsquo;s a problem they&rsquo;ll never have.  People who think it&rsquo;s right and proper to use their text editors to catch up on Mastodon, read RSS, send mail, do their calendaring, track their todos, browse the web &hellip; aaaaaaand <em>sometimes</em> edit a text file may be more put off.</p>
<p>By default, at least in Doom, it also hooks its <code>update</code> function into firing off your MDA so it can make sure the database has the latest messages. So when you check your mail with it, it wants to kick off an <code>mbsync</code> run. That doesn&rsquo;t block it. I think it&rsquo;s possible to configure it to just prompt a reindexing of your Maildir instead of a whole MDA run. I need to do a little more in-depth investigation of how well isync is working for me because right now I think mu4e and the Homebrew daemonization fight with each other, but the net effect is that one process gets isync to download my mail instead of the other.</p>
<p><em>Otherwise</em> it is very, very fast, and its keyboard-centric UI is built toward getting at stuff quickly with a bunch of terse keystrokes to navigate to bookmarked mailboxes and canned search queries. Once you get the hang of marking/operating on a list of headers (with equally efficient keystrokes you can also customize) it&rsquo;s a mail processing machine.</p>
<p>No, sorry, excuse me &ndash; it is a mail database processing machine.</p>
<p>I&rsquo;ve previously named a few of these, but besides speed and efficiency, it offers a few other benefits:</p>
<p>First, I love composing mail in org mode markup. I sent myself a few test mails and loved, for instance, that an org mode src block was correctly colorized. org markup is a little more verbose than Markdown in some places. For instance, a blockquote isn&rsquo;t done with a leading <code>&gt;</code> but with a <code>+begin_quote</code> and <code>+end_quote</code> block.</p>
<p>Second, it&rsquo;s easily hooked into <code>org-capture</code>. Here&rsquo;s a capture template for putting a message in your inbox, marked for action within two days:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="o">&#39;</span><span class="p">(</span><span class="s">&#34;M&#34;</span> <span class="s">&#34;process-soon&#34;</span> <span class="nv">entry</span> <span class="p">(</span><span class="nv">file+headline</span> <span class="s">&#34;inbox.org&#34;</span> <span class="s">&#34;Messages&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;* TODO %:fromname: %a %?\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \&#34;+2d\&#34;))&#34;</span><span class="p">)</span></span></span></code></pre></div>
<p>In Doom Emacs, you get at that with <code>SPC X M</code>. When it&rsquo;s time to deal with the message, just tap <code>enter</code> on the heading and mu4e opens the message. Excuse me, no, it retrieves the header from the database.</p>
<p>In terms of drawbacks, setup time and learning curve aside, it has a few downsides:</p>
<p>At least one keymapping doesn&rsquo;t play well with Doom Emacs. In mu4e, the <code>SPC</code> key is mapped to <code>scroll-up-command</code> to serve as a pager, whereas that&rsquo;s the leader key for Doom everywhere else. The workaround is to use <code>OPT SPC</code> to get to Doom&rsquo;s menu, but I&rsquo;m still baking that into my muscle memory.</p>
<p>While orgmail-mode is cool and all, it interacts weirdly with the rest of the package sometimes, and I wish I could toggle its HTML mail features on and off now and then.</p>
<p>Its HTML mail presentation is as woeful as any mail client that starts from plaintext land, and the remedy is the same as it is in mutt: Learn the shortcut for opening HTML mail of any complexity straight into your browser.</p>
<p>Finally, it doesn&rsquo;t interact as well with <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Convenience.html#index-winner_002dmode">winner mode</a> as I&rsquo;d like, leaving frames in a weird state after some operations. I did convince ChatGPT to write a hook for me to get mail composer frames to close instead of leaving the view split:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nv">after!</span> <span class="nv">mu4e</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">my-mu4e-close-frame-after-send</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Close the frame after sending a message in mu4e.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">and</span> <span class="p">(</span><span class="nf">eq</span> <span class="nv">major-mode</span> <span class="ss">&#39;mu4e-compose-mode</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">             <span class="p">(</span><span class="nv">not</span> <span class="p">(</span><span class="nv">mu4e~message-autopgp-p</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nf">delete-frame</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">&#39;message-sent-hook</span> <span class="nf">#&#39;</span><span class="nv">my-mu4e-close-frame-after-send</span><span class="p">))</span></span></span></code></pre></div>
<p>org-mail also seems to leave behind spare buffers it uses to put together the plaintext part of its multipart messages.</p>
<p>Net, though, it&rsquo;s so fast and efficient that I can see past most of that. I&rsquo;m sort of curious about connecting mutt to notmuch to see how that works, mostly because I know mutt very, very well and feel a little more fluent when it comes to customizing it. Some of the stuff I&rsquo;ve got set up in mu4e could be done with a little utility scripting in mutt.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily notes for 2023-04-08</title>
      <link>https://mike.puddingtime.org/posts/2023-04-08-daily-notes-for-2023-04-08/</link>
      <pubDate>Sat, 08 Apr 2023 10:26:49 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-08-daily-notes-for-2023-04-08/</guid>
      <description>As always, a plaintext revival means a mutt revival.</description>
      <content:encoded><![CDATA[<h3 id="these-things-come-in-waves">These things come in waves</h3>
<p>In the past, when I&rsquo;ve gone through a plaintext or Emacs kick of some kind, I&rsquo;ve blown past what I&rsquo;ve come to think of as a common sense limit: Eventually I&rsquo;m looking at Wanderlust, GNUS, or mu4e and thinking about the whole email in Emacs thing. Inevitably, then, you&rsquo;re looking at some sort of way to sync your IMAP account down to your local machine, and a whole layer goes in to make that work.</p>
<p>I walked up to the line this time around, asked myself what problem I&rsquo;m trying to solve, and remembered that part of what is making Doom Emacs work for me right now is how much I&rsquo;ve been keeping things limited to stuff that has to do with writing and stuff that has to do with personal organization. Those are things that don&rsquo;t stress Emacs&rsquo; single-threaded nature the way I do them, and that don&rsquo;t take me into the murky space between Emacs and the OS.</p>
<p>The problem I am trying to solve whenever I go on these kicks, is the pain of getting parts of the macOS experience into a more keyboard-centric place. Mail always sticks out because I don&rsquo;t like doing Mac Mail from the keyboard. There&rsquo;s <a href="https://smallcubed.com/">Mail Act-On</a>, but at $45 a renewal it&rsquo;s just more than I can see paying, and it doesn&rsquo;t really do much for visualization &ndash; it just makes it easy to move things into folders.</p>
<p>So my mind always goes to <a href="http://www.mutt.org">mutt</a>. It&rsquo;s not perfect &ndash; search is a challenge without something external augmenting it &ndash; but I&rsquo;m not sure it matters in the end: I use Fastmail for IMAP, and I don&rsquo;t mind punting to its web interface if I need to go dig for something.</p>
<p>I thought about mutt this time because my long-standing config has always sort of <em>felt</em> similar to the way Spacemacs and Doom put a modal UI over Emacs.  My mutt macros &ndash; here&rsquo;s a sample &ndash; use <code>.</code> as a leader and are written mnemonically:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">macro index .sn &#34;l ^a^k~N\n&#34; # Show unread/new only
</span></span><span class="line"><span class="cl">macro index .sa &#34;l ^a^kall\n&#34; # show all
</span></span><span class="line"><span class="cl">macro index .C &#34;&lt;esc&gt;V&#34; # toggle threads
</span></span><span class="line"><span class="cl">macro index .si &#34;l (~n5-100|~N)\n&#34; # show interesting 
</span></span><span class="line"><span class="cl">macro index .rs &#34;&lt;enter-command&gt;source ~/.mutt/scores&lt;enter&gt;&#34; # reprocess scores
</span></span><span class="line"><span class="cl">macro index .sf &#34;l ~F\n&#34; # show flagged
</span></span><span class="line"><span class="cl">macro index .hl &#34;l ^a^k!~l\n&#34; # hide lists
</span></span><span class="line"><span class="cl">macro index .to &#34;T ~d&gt;7d\n&#34; # &#34;tag old&#34; -- messages older than 7 days
</span></span><span class="line"><span class="cl">macro index .ab    &#34;&lt;pipe-entry&gt;/opt/homebrew/bin/lbdb-fetchaddr\n&#34;                # Store address details in lbdb.</span></span></code></pre></div>
<p>The value of mutt is less as my everything email client &ndash; I still keep up with mail from my phone or tablet &ndash; and more because over the years I&rsquo;ve tuned it to visualize and process mail from the keyboard. I still read mail with my phone or tablet every day, but don&rsquo;t like to do anything more than flag messages when I&rsquo;m out.</p>
<h3 id="html-mail-and-mutt">HTML mail and mutt</h3>
<p>mutt is sometimes hard to stick with because we lost the plaintext email battle. I know one designer who formats his email with monotype faces in what I&rsquo;d describe as a sort of problematic aesthetic revolt, but otherwise &hellip; we lost and we&rsquo;ll never be able to unsee Calibri.</p>
<p>Sticking <code>elinks</code>, <code>lynx</code> or <code>w3m</code> in your <code>~/.mailcap</code> to show HTML was best practice for a long while, provided you didn&rsquo;t mind also using <code>urlview</code> to display the links in a message once you&rsquo;d read it. I was involved in email marketing during the era when that approach worked, partially because to do HTML mail &ldquo;right&rdquo; back then meant you had someone doing it painstakingly by hand, then reviewing across a multitude of clients and platforms &ndash; you were heavily incentivized to keep it simple.  I bear the scars from a spat with a division of Siemens that was still using an old Lotus Notes and Win2000 in its marketing department. They were the customer, and the mail didn&rsquo;t look good to them, so it didn&rsquo;t look good. That was all, and we were forced to buy the next tier of service from our mail provider so we could add Lotus Notes on Win 2000 to our testing.</p>
<p>Anyhow, &ldquo;<code>elinks</code> in your mailcap and call it a day&rdquo; doesn&rsquo;t work anymore: image text, dozens of links, complex positional markup, etc. etc. etc. and it makes a lot of HTML mail a hash in a plaintext browser. There are a few ways to solve this on a Mac: One is punting to an actual browser, and the other is using the Mac Quicklook service:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">text/html;  open -a firefox %s; nametemplate=%s.html text/html; open -a firefox %s; nametemplate=%s.html; copiousoutput
</span></span><span class="line"><span class="cl">text/html; qlmanage -p %s; nametemplate=%s.html</span></span></code></pre></div>
<p>The former does about what you&rsquo;d expect from looking at it: It uses Firefox (or whatever browser you&rsquo;d care to invoke) to open the HTML part of the message, at which point you can click links, etc.</p>
<p>The latter is a little more obscure, but basically recreates what happens when you select a file and tap the spacebar to preview it on a Mac, popping up a modal window with the contents. This often works well for other kinds of attachments. With HTML mail it is enough to let you read the mail but not really interact with it (e.g. follow a link). The <code>[DEBUG]</code> label at the front of the modal&rsquo;s title suggests that nobody at Apple really took the &ldquo;plain text zealots using this to browse HTML email&rdquo; use case into account when they wrote <code>qlmanage</code>, and the man page makes clear it&rsquo;s just a debugging tool. It&rsquo;ll do if you never intend to interact with a mail.</p>
<p>I&rsquo;m sticking to the Firefox approach. It&rsquo;s super fast if Firefox is already running (it always is), and you can follow links.</p>
<h3 id="these-things-leave-in-waves-too">These things leave in waves, too</h3>
<p>At some point mutt is going to do something to annoy me. I don&rsquo;t know what it&rsquo;s going to be this time. For now, I&rsquo;m just enjoying the periodic dustoff of my config and pleasures of zipping through my inbox. If I had to guess, it&rsquo;ll have something to do with getting email messages into org-mode or calendaring, somehow. There are a few shell-based CalDav clients out there, but they&rsquo;re very sync-and-cache oriented and I just don&rsquo;t like adding services. Had mutt never added IMAP caching and built-in SMTP support, I would have a harder time justifying it.</p>
<p>But I feel more protective of my Emacs and org-mode experience than anything. This run with Doom has yielded the most stable Emacs experience I&rsquo;ve had since switching to Macs mooostly full-time ca. 2004. No mystery segfaults. No hard-locking the UI because I have IMAP, RSS, IRC, and Twitter clients running in my text editor.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
