<?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/orgmode/</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>Thu, 11 Jan 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/orgmode/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Daily Notes for 2024-01-11</title>
      <link>https://mike.puddingtime.org/posts/2024-01-11-daily-notes/</link>
      <pubDate>Thu, 11 Jan 2024 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2024-01-11-daily-notes/</guid>
      <description>Secrets of the ancients.</description>
      <content:encoded><![CDATA[<h2 id="secrets-of-the-ancients">Secrets of the Ancients</h2>
<p>I felt a little nostalgic for my old <a href="https://github.com/kaushalmodi/ox-hugo">ox-hugo setup</a> today. What was so great about it?</p>
<ul>
<li>One big org file.</li>
<li>Your stuff ends up in a regular Markdown file for portability.</li>
<li>Pretty nicely wired up in Doom&rsquo;s menu structure: <code>SPC X b d</code> and a daily post is underway.</li>
</ul>
<p>I took a look in <code>config.org</code> and it looked like all the config was still there, so I started a daily post. type type type type type &hellip; saaaaave? What was supposed to happen next? Whatever it was, it didn&rsquo;t happen. I tried the whole &ldquo;close your eyes and start typing&rdquo; thing to see if muscle memory would take over, but no &hellip; I hadn&rsquo;t used this setup since last June and it was gone from my fingers.</p>
<p>More fiddling and fussing &ndash; it turned out there was no muscle memory to forget because I&rsquo;d had it set up to autopublish on save. One of the cool things about <code>ox-hugo</code> is that if you leave a post heading in <code>TODO</code> state, it&rsquo;s a draft, so saving and auto-publishing is safe, even if you forget and wander off and push another commit somewhere.</p>
<p>But saving availed me nothing &hellip; huh &hellip; more poking.</p>
<p>Oh, right &hellip; I took <code>ox-hugo</code> out of my <code>packages.el</code> when I stopped using it to keep things light.</p>
<p>Now it&rsquo;s working again.</p>
<p>And wow did I just elide a ton of stuff I had so step back through to get it to where it &ldquo;just worked&rdquo; again. My <code>config.org</code> was full of helpful notes like:</p>
<blockquote>
<p>Of particular interest: <code>org-hugo-auto-set-lastmod</code>, which is set <code>'t</code> in a lot of examples. This one is pesky because when set <code>'t</code> it will bump the date on posts that don&rsquo;t have a <code>date:</code> property set (in favor of org-hugos <code>EXPORT_HUGO_DATE</code>). You don&rsquo;t get bit until you have <code>org-hugo-auto-export-on-save</code> set, at which point fat-fingering a save in the wrong post will change its mod date and hence its published date, teleporting it into the future.</p>
</blockquote>
<p>&hellip; but the whole setup was still littered with stuff I couldn&rsquo;t understand. Like &hellip;</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lisp" data-lang="lisp"><span class="line"><span class="cl"> <span class="nv">COMMENT</span> <span class="nv">Local</span> <span class="nv">Variables</span> <span class="ss">:ARCHIVE:</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="nv">Local</span> <span class="nv">Variables:</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="nv">eval:</span> <span class="p">(</span><span class="nv">org-hugo-auto-export-mode</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="nv">End:</span></span></span></code></pre></div>
<p>Why the COMMENT thing? Why the ARCHIVE thing? Why &ldquo;End:&rdquo;  I don&rsquo;t remember how I learned that stuff or why it is what it is. I am pretty sure there were 10th century Saxon peasants who understood more about how ancient Roman highways were engineered than I was able to understand about my own setup.</p>
<p>I don&rsquo;t think, the day before I was let go from, er, &ldquo;Puppet by Perforce&rdquo; that I imagined I&rsquo;d spend as much time as I did doinking around with org-mode blogging, but wow did I. It was fun. I can tell it was fun because I was leaving myself paragraph-long notes on minor configuration issues.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-29</title>
      <link>https://mike.puddingtime.org/posts/2023-05-29-daily-notes/</link>
      <pubDate>Mon, 29 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-29-daily-notes/</guid>
      <description>More writing about a camera I both covet and find unfathomable. All in on Denote. Keycast for influencing and debugging. Succession ended with integrity.</description>
      <content:encoded><![CDATA[<h2 id="leica-q3">Leica Q3</h2>
<p><a href="https://baty.net/journal/2023-05-27">Via Jack Baty</a>, here&rsquo;s <a href="https://om.co/2023/05/26/whats-wrong-with-leica-q3/">Om Malik on &ldquo;What&rsquo;s Wrong with Leica Q3,&rdquo;</a> which, okay: &ldquo;introducing the flippy-tilty screen takes away from Leica’s uniqueness. The company has been able to charge more for offering less.&rdquo; Citing their monochrome cameras as an example of that is &hellip; a take.</p>
<p>Tilting screens add to the versatility of the device. That&rsquo;s all. They make certain situations easier to manage, especially with the kinds of things you want to shoot macro, and they give you more flexibility in street shooting situations where you don&rsquo;t want to have a camera up to your face.</p>
<p>A camera like a Q3, I&rsquo;d argue, <em>should</em> be making some concessions on design austerity, because the machines themselves exist for the times you can&rsquo;t take everything with you that you wish you could, so you&rsquo;re compromising and taking just one thing.</p>
<p>Now, he goes on to <a href="https://www.theverge.com/2023/5/25/23736639/leica-q3-camera-28mm-fixed-lens-compact-8k-availability-price-specs">point to the Verge review</a>, where it sounds like the implementation is lacking:</p>
<blockquote>
<p>&ldquo;&hellip; the worst part of the screen, aside from it looking like it’s just been grafted on and makes the camera appear and feel bulkier, is that there’s no groove or grip on its left side to dig your nail into or grab with your finger. It has grooves on its top and bottom, meaning you have to make a much bigger reach to move it.&rdquo;</p>
</blockquote>
<p>That doesn&rsquo;t sound great. I do like the way the Fuji X100V and X-T5 are built. It&rsquo;s a simpler, easier motion, sort of planting your thumb and kind of twisting each hand to get the screen undogged and moving. I don&rsquo;t like anything I need to pry open.</p>
<p>Om&rsquo;s concern that the Q3 &ldquo;design disaster&rdquo; is going to infect other Leica product lines didn&rsquo;t ring great with me because I don&rsquo;t like the button layout on the Q2 as well as I like it on an X100, or X-T. The Q3 looks more like a Fujifilm camera in that regard this time around (well, now the Leica people are <em>really</em> gonna hate it). Yeah, you have an extra target to distinguish when the camera is up to your face, but you figure it out.</p>
<p>I&rsquo;ll also admit that when it comes to a Q-series camera &ndash; $6k just to get in the door, then close to another $1k to get it fully provisioned &ndash; it&rsquo;s a little harder to smile and say &ldquo;well, they&rsquo;ll get it right in the next rev.&rdquo; I did that with three generations of Fujfilm X100s, but they hold their value about as well as a Leica (I checked a few generations and used street prices for <a href="/posts/2023-05-25-daily-notes/#leica-q3-arrives">my last post on the Q3</a>) so that&rsquo;s less of a sting.</p>
<p>Anyhow, I welcome the addition even if it sounds like it&rsquo;s imperfect.</p>
<p>Every time I&rsquo;ve tried to compare the Q-series to the X100-series, I walk away with a sense that the X100s are inferior on every spec (except the hybrid viewfinder), but manage to stay in the ring because they&rsquo;re scrappier and looser cameras.</p>
<p>The thing that blunts my joy about the Q-series is pretty similar to what makes me unhappy about very early Apple products and tools: There&rsquo;s a bias toward the austere that sometimes stifles. It was an easy matter for me, for instance, to perambulate between OS X and Linux for a period, because Apple was doing the &ldquo;slow layering&rdquo; thing and the customization ecosystem hadn&rsquo;t caught up yet. Once people figured out how to leverage the BSD userland and third party people began to figure out the new APIs, we were off and running.</p>
<p>Even a not-perfectly-realized tilt screen, and a reconfiguration of the control scheme to introduce more flexibility and easier one-thumb use while shooting, feels less to me like Violation of Holiest Ascetic Precepts and more like an opening up and loosening appropriate to a camera that manages to be both shockingly expensive <em>and</em> be the thing you shrug and grab when you can&rsquo;t take everything you&rsquo;d like, or make up your mind about what you need.</p>
<h2 id="succession-ended-with-integrity">Succession ended with integrity</h2>
<p>Spoiler culture is out of control, but &hellip; spoiler.</p>
<p><a href="/posts/2023-05-26-succession-finale-hot-take/">I wrote that Succession was a tragicomedy</a> and therefore needed to end a particular way to keep its integrity. It ended about the way I felt it should have, and even smeared a little spit on the rims of select audience brandy snifters with its elevation of the closest thing to a lens character had to a kind of hollow power that nonetheless commands deference from people newly laid low.</p>
<p>Tom Wambsgans disgusted you all along? You felt a warm glow when Shiv perforated him with as a grasping climber? Reminded you of that one VP you worked for who never fooled you but somehow fooled everybody else? Well, he&rsquo;s here to put a sticker on your forehead, and he doesn&rsquo;t need you to mean it when you hold his hand.</p>
<p>Who will win? The cockroach won. But it isn&rsquo;t even winning.</p>
<p>A reviewer referred to Roman&rsquo;s final little smile as &ldquo;twisted.&rdquo;  I think he was the only one of the three who knew enough to feel liberated. The other three siblings were clowns masquerading as serious people. Roman was the clown who knew better than any of it. He drives Kendall to rip of his own mask, then quietly declares them all shit. His comedic aspect is reunion with himself. His tragic aspect is the relationship he lost one of the few times he tried to play things straight.</p>
<p>With a good ending, it joins <em>The Wire</em>, <em>Breaking Bad</em>, <em>Mad Men</em>, <em>Justified</em>, <em>Halt and Catch Fire</em>, <em>Six Feet Under</em>, and <em>The Sopranos</em> in the &ldquo;stuck the landing&rdquo; club.</p>
<h2 id="denote-just-makes-sense-to-my-brain">Denote just makes sense to my brain</h2>
<p>Well, after a few days of fiddling and trying this and that, I think I&rsquo;m all in on Denote:</p>
<ul>
<li>No external dependencies</li>
<li>Convention-based naming</li>
<li>Portable</li>
<li>Simple</li>
</ul>
<p>&hellip; and an ecosystem is forming around it that respects its conventions but smooths out its UI. So if you want to just manage Denote via <code>dired</code>, you&rsquo;re welcome to do that. The fontification of Denote directories is enough to make the titles and tags clear when you&rsquo;re looking at a simple directory listing.</p>
<p>But there are also packages like <a href="https://github.com/namilus/denote-menu#">denote-menu</a> and <a href="https://github.com/mclear-tools/consult-notes">consult-notes</a> that provide light wrappers and convenience functions if you&rsquo;d like a cleaner view, where, for instance, the title, keywords, and date are all displayed in their own columns; and there are features that help quickly filter down your view based on keyword, etc.</p>
<p>I sort of want to compare it to what I admire about Markdown: Fine on its own, able to support more, probably you could go a little nuts trying to do more with it. I appreciate that it participates in the broader org ecosystem, and equally admire that you&rsquo;re welcome to use Markdown/YAML if that suits you.</p>
<p>This is occurring to me because I spent a bunch of time fiddling around with a few Denote wrappers over the weekend and ended up in that weird &ldquo;why did I do this&rdquo; state of mind where all the single-minded optimizing and tweaking felt sort of like a high-carb meal. Then I just opened up my notes directory in dired and realized Denote is great at its most basic.</p>
<p>If you use zsh, this will give you a colorized <code>ls</code> for a Denote directory, btw:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">dls<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    ls -1 <span class="p">|</span> <span class="nv">GREP_COLORS</span><span class="o">=</span><span class="s1">&#39;mt=1;32&#39;</span> egrep --color<span class="o">=</span>always <span class="s1">&#39;[0-9]{8}T[0-9]{6}&#39;</span> <span class="p">|</span> <span class="nv">GREP_COLORS</span><span class="o">=</span><span class="s1">&#39;mt=1;34&#39;</span> egrep --color<span class="o">=</span>always <span class="s1">&#39;__.*$&#39;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span></span></span></code></pre></div>
<h2 id="keycast">keycast</h2>
<p>While I was watching Prot&rsquo;s Denote demo video I noticed his keystrokes and commands were echoed to the modeline, which seemed pretty cool, and was also helpful to me trying to figure out what on Earth he was doing.  Then it occurred to me this afternoon that one thing I&rsquo;ve been struggling with as I try to <a href="/posts/2023-05-24-daily-notes/#batteries-included-situations-and-their-discontents">untangle what&rsquo;s going on in Doom</a> with some of the stuff I&rsquo;ve wanted to fix, has been <em>what&rsquo;s going on in Doom</em> when I use certain commands.</p>
<p>Like &hellip; previewing a file under point, which you invoke with <code>CTRL SPC</code>.</p>
<p>The sort of low-rent debug method I&rsquo;ve observed is that people just ripgrep their <code>~/.emacs/</code> for any mention of <code>C-SPC</code> to see what&rsquo;s bound to that.</p>
<p>Well, joke was on me:</p>
<p>Maybe it was <code>ivy-call-and-recenter</code>, maybe <code>company-complete-common</code>, prolly not <code>org-agenda-show-and-scroll-up</code>. PROBABLY <code>+vertico/embark-preview</code>, but who can say in these troubled times?</p>
<p>So I went looking for whatever it is Prot was using, and found something called <a href="https://github.com/tarsius/keycast">keycast</a>.</p>
<p>Its obvious utility is for screencasting, but it also has <code>keycast-log-mode</code>, which sends all your commands to a buffer, and which helped me establish it was, indeed, <code>+vertico/embark-preview</code>.</p>
<p>To get it to work in Doom Emacs you need to add something to your config:</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="nb">use-package</span> <span class="nv">keycast</span>
</span></span><span class="line"><span class="cl">  <span class="nb">:config</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">define-minor-mode</span> <span class="nv">keycast-mode</span>
</span></span><span class="line"><span class="cl">    <span class="s">&#34;Show current command and its key binding in the mode line (fix for use with doom-mode-line).&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">:global</span> <span class="no">t</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">if</span> <span class="nv">keycast-mode</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">add-hook</span> <span class="ss">&#39;pre-command-hook</span> <span class="ss">&#39;keycast--update</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nv">remove-hook</span> <span class="ss">&#39;pre-command-hook</span> <span class="ss">&#39;keycast--update</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">&#39;global-mode-string</span> <span class="o">&#39;</span><span class="p">(</span><span class="s">&#34;&#34;</span> <span class="nv">keycast-mode-line</span><span class="p">)))</span></span></span></code></pre></div>
<p>There are a bunch of issues mentioning problems with Doom and Spacemacs all over the place, but this is what worked for me, here in late May, 2023.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-24</title>
      <link>https://mike.puddingtime.org/posts/2023-05-24-daily-notes/</link>
      <pubDate>Wed, 24 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-24-daily-notes/</guid>
      <description>Cleaning up results in literate config files. Portland and the JOHS. Some Doom discontent.</description>
      <content:encoded><![CDATA[<h2 id="cleaning-up-my-literate-config-file">Cleaning up my literate config file</h2>
<p>I like keeping my Doom Emacs config file in config.org. I didn&rsquo;t like the <code>#RESULTS</code> drawers cluttering up the file, especially for longer functions with copious output.</p>
<p>The way to selectively disable that for a given src block is to append <code>:results output silent</code> to the block opener, e.g.</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="err">#</span><span class="nv">+begin_src</span> <span class="nv">emacs-lisp</span> <span class="nb">:results</span> <span class="nv">output</span> <span class="nv">silent</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">vertico-reverse-mode</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">setq</span> <span class="nv">vertico-count</span> <span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">setq</span> <span class="nv">vertico-resize</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span><span class="nv">+end_src</span></span></span></code></pre></div>
<p>The way to do it for an entire file is to put <code>#+property: header-args :results silent</code> at the top.</p>
<p>You can still evaluate a given src block by tapping return on either the first or <code>#+end_src</code> lines, but the output goes to the minibuffer instead of a <code>#RESULTS</code> drawer. If you need to really read through the output, there&rsquo;s always the <code>*Messages*</code> buffer, or tacking <code>:results output replace</code> onto the src block opener to get your <code>#RESULTS</code> drawer back.</p>
<h2 id="johs-and-the-city">JOHS and the city</h2>
<p>The city and the county are <a href="https://www.wweek.com/news/city/2023/05/23/city-council-will-vote-to-extend-joint-office-agreement-with-multnomah-county-to-allow-for-further-negotiations-again/">again considering extending the JOHS for just a year</a>. I still don&rsquo;t understand the division of labor there. It&rsquo;s the worst of both worlds: The city drops a pallet of money on the county&rsquo;s dock, but remains on the hook for the tactical response. The county takes the money, claims the high ground of long-term, strategic perspective, then has an effective veto over elements of the city&rsquo;s tactical response even as it fails to allocate half its budget, and actual providers on the ground <a href="https://www.wweek.com/news/2023/04/05/joint-office-of-homeless-services-contracting-woes-create-instability-for-survivors-of-domestic-violence/">struggle to retain help with a living wage, or even get decent contracts through the JOHS</a>.</p>
<p>If the JOHS were a <em>joint</em> office, performing some actual coordinative role, maybe it&rsquo;d be different. But it&rsquo;s a county office: Its reporting structure roles up to the chair, it uses county administrative structures and processes, and it is beholden to county leadership. It&rsquo;s also profoundly dysfunctional, leaving millions and millions of dollars on the table, and failing in its most basic data-gathering, reporting, and contracting commitments.</p>
<p>But we&rsquo;re in one of those situations where the dysfunction seems to be politically expedient. The city and county are at fundamental odds on homelessness policy, and the people in this policy area at the county level view themselves as a sort of superego governing the city&rsquo;s id. Once one partner in a relationship predicates their participation on the notion that they&rsquo;re mostly there to keep their partner from doing something they don&rsquo;t like, the relationship is sunk. Burn it down and start over with a new charter.</p>
<h2 id="batteries-included-situations-and-their-discontents">Batteries-included situations and their discontents</h2>
<p>I think I&rsquo;ve hit the first thing using Doom Emacs that is not sitting well with me. Well, let&rsquo;s scope out a little: I think I&rsquo;ve hit the first time something <em>that is inevitable</em> with &ldquo;batteries-included&rdquo; situations has annoyed me as I&rsquo;ve used Doom in particular.</p>
<p>Emacs has a bunch of &ldquo;completion frameworks,&rdquo; which control what happens when you go to issue a command, open a file, look up a definition or whatever. The last time I used Emacs a lot <a href="https://github.com/emacs-helm/helm">Helm</a> was sort of the big deal, but since then plenty of others have come along. If you look in the part of Doom&rsquo;s config that offers pre-packaged completion frameworks, you get several choices:</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="nb">:completion</span>
</span></span><span class="line"><span class="cl"><span class="nv">company</span>           <span class="c1">; the ultimate code completion backend</span>
</span></span><span class="line"><span class="cl"><span class="c1">;; helm              ; the *other* search engine for love and life</span>
</span></span><span class="line"><span class="cl"><span class="c1">;; ido               ; the other *other* search engine...</span>
</span></span><span class="line"><span class="cl"><span class="c1">;; ivy               ; a search engine for love and life</span>
</span></span><span class="line"><span class="cl"><span class="nv">vertico</span>           <span class="c1">; the search engine of the future</span></span></span></code></pre></div>
<p>Which, so far so good. As near as I can parse the conversation, newer completion frameworks like <a href="https://github.com/minad/vertico/blob/main/README.org">Vertico</a> are built around the idea that it&rsquo;s better to build off of core Emacs functionality and think in a more modular manner. So then you look up what happens when you enable Vertico, that involves a series of complementary packages:</p>
<ul>
<li>consult</li>
<li>consult-flycheck</li>
<li>embark</li>
<li>embark-consult</li>
<li>marginalia</li>
<li>orderless</li>
<li>vertico</li>
<li>vertico-posframe (maybe)</li>
<li>wgrep</li>
</ul>
<p>Because I do not want to make this about the problem I&rsquo;m dealing with at this particular moment, I just want to say <em>holy cow what a stew of possible starting points for solving a problem</em>.</p>
<p>I&rsquo;ve spent this morning trying to track down a UI annoyance and the mere act of changing word order in my searches has implicated four of the packages on that list.  Because the Emacs community is a relatively small one &mdash; at least by the time you get done subdividing it into &ldquo;Emacs users who also use Doom and who are using Vertico within Doom&rdquo; &mdash; you exhaust possible resolutions quickly, and begin to realize you&rsquo;ve seen the same configuration go by several different times as people in this relatively small subset share it around.</p>
<p>Anyhow, I&rsquo;m not here to bag on Doom or complain about copypasta configs. I&rsquo;m just noting that at a certain point in the world of batteries-included frameworks you are sorting through a metric ton of batteries, all tucked away behind a very smooth housing requiring a variety of Torx and jeweler&rsquo;s screwdrivers to get open. One of those paradoxes, I guess, where your lower-skilled people (me) get a ton of leverage from all the layers of abstraction and affordance, but then wander into situations where it would take a very highly skilled person (not me) to sort out where the magic is going wrong (or just not going the way you wished, since &ldquo;wrong&rdquo; is sort of fraught, here.)</p>
<p>And I fall on the maximizer end of <a href="https://www.psychologistworld.com/cognitive/maximizers-satisficers-decision-making">the satisficer/maximizer spectrum</a>, so it&rsquo;s hard to say of some UI glitch &ldquo;well, that&rsquo;s an annoyance I&rsquo;ll be living with,&rdquo; even if there are ample workarounds or even simple &ldquo;then quit moving your arm that way&rdquo; solutions.</p>
<p>Okay. I think I&rsquo;ve gotten that off my chest. Time to go to the Doom Discourse, <a href="https://discourse.doomemacs.org/t/trying-to-get-a-handle-on-fixing-file-preview-during-find-file/3896">mention the issue</a>, and see what I get.</p>
<h2 id="monodraw">Monodraw</h2>
<p>Even if you don&rsquo;t follow that link, I had an excuse to use <a href="https://monodraw.helftone.com">Monodraw</a> to illustrate my problem. Monodraw makes it super easy to make ASCII diagrams then copies them in a pre block to your clipboard.</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">┌──────────────────────────┐  ┌──────────────────────────┐
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│     Original window      │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │      Preview window      │
</span></span><span class="line"><span class="cl">├──────────────────────────┤  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│      Preview window      │  │                          │
</span></span><span class="line"><span class="cl">│                          │  ├──────────────────────────┤
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">├──────────────────────────┤  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │      Vertico window      │
</span></span><span class="line"><span class="cl">│      Vertico window      │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">│                          │  │                          │
</span></span><span class="line"><span class="cl">└──────────────────────────┘  └──────────────────────────┘</span></span></code></pre></div>
<p>There is a world somewhere that I could use Monodraw in a business context and not have it be a complete distraction, but for anything other than &ldquo;a box with words in it,&rdquo; e.g. a more complex organizational diagram or flow chart, it is utterly distracting, either by people who want there to be boxes with colors or people who want to know how on Earth you made such a complex diagram with pipes and dashes.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-14</title>
      <link>https://mike.puddingtime.org/posts/2023-05-14-daily-notes/</link>
      <pubDate>Sun, 14 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-14-daily-notes/</guid>
      <description>org-mode evolution, fixing mu4e/Doom&amp;rsquo;s busted leader key, Guardians Vol. 3, not taking pictures lately</description>
      <content:encoded><![CDATA[<h2 id="guardians-of-the-galaxy-vol-dot-3">Guardians of the Galaxy, Vol. 3</h2>
<p>This weekend Al and I went down to Eugene to see Ben and have a small getaway, with a trip to the movies, too. We saw <em>Guardians of the Galaxy Vol. 3</em> and walked out of it feeling like we&rsquo;d seen a good conclusion to the trilogy. I always appreciate a good trailer fakeout, and the one they did for this one was sort of a double head-fake, making you think you&rsquo;d seen the high-stakes thing, then pulling that rug out from under in the first five minutes, then making the stakes high again.</p>
<p>It was a darker, more violent movie than the previous <em>Guardians</em> installments, maybe to raise the stakes high enough to make it all feel like a good sendoff. Parts of it are heart-rending. There&rsquo;s a little <em>Wizard of Oz</em> stuff going on at the end I choose to give a pass, because James Gunn appears to be decamping from the MCU to go do DC stuff and I get the need to provide a little closure I&rsquo;m not sure anyone was asking for.</p>
<p>I was a pretty big Howard the Duck fan as a grade schooler, so I&rsquo;ve always appreciated the way Cosmic Marvel balances the, er, cosmic stakes with a little silliness. <em>Guardians Vol. 3</em> keeps the silliness, pulls the stakes in a little, and manages more darkness than usual. It was an interesting balacing act that seemed to work.</p>
<p>We couldn&rsquo;t go to a normal showing so we had to do a 3D show, and that didn&rsquo;t do much for my opinion of 3D. Always seems like the screen is a little more dim and some detail is lost for not a ton of benefit.  I&rsquo;ll be happy to see it at home when it starts streaming.</p>
<p>Also, Portland movie-going audiences are, on balance, better than the Eugene one we dealt with. Lots more people in their phones, more chatter in the audience. The glare of the phones is worse than the chatter, which was at least sort of participatory and topical vs., like, random couple behind you is processing their relationship for 140 minutes (my <em>Magnolia</em> experience years ago). OTOH, it was Saturday night of the second week of the run. We tend to do the movies that matter to us at quiet matinees and don&rsquo;t go to many weekend evening shows anymore, so maybe the crowds we&rsquo;re used to are not going because it&rsquo;s a social event.</p>
<h2 id="dug-out-my-old-org-mode-config">Dug out my old org-mode config</h2>
<p>Maybe seven or eight years ago I was working in a group that had an intense progeress reporting culture. I was entrenched in org-mode and had things set up such that I could make a status report out of my <code>work.org</code> file with a quick export. It was not a bad way to live: If I was just keeping track of the things my team was doing, my status report was pre-written on Friday morning.</p>
<p>I went digging around in the config I had set up from that period and it&rsquo;s interesting how much weight I was putting on tags for my organization. I&rsquo;ve got a ton of custom agenda views set up for people, teams, and contexts. Now that I look at it again, I guess I was still trying to do gtd in some form or another, because I can also see custom agenda views for <code>NEXT</code> items.</p>
<p>The emphasis on tags was also about the benefit of emergent organization. My custom agenda commands were really simple affairs, organized around a top-level &ldquo;people, teams, contexts&rdquo; scheme. So if I was walking into a 1:1 with, say, &ldquo;Isaac,&rdquo; I could invoke the agenda dispatcher and tap <code>p i</code> (&ldquo;people&rdquo; &ldquo;isaac&rdquo;) to get all our topics. In the context of my weekly status reports, which were director-level things, you could scan down all the work in flight in my group and see the people tags if you wanted to know who was on what.</p>
<p>Anyhow, by making simple configs, like this:</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="s">&#34;g&#34;</span> <span class="o">.</span>  <span class="s">&#34;Groups&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="s">&#34;gd&#34;</span> <span class="s">&#34;Docs&#34;</span> <span class="nv">tags-todo</span> <span class="s">&#34;docs&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="s">&#34;gD&#34;</span> <span class="s">&#34;DIO&#34;</span> <span class="nv">tags-todo</span> <span class="s">&#34;DIO&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="s">&#34;gs&#34;</span> <span class="s">&#34;Staff&#34;</span> <span class="nv">tags-todo</span> <span class="s">&#34;staff&#34;</span><span class="p">)</span></span></span></code></pre></div>
<p>&hellip; I could easily add new tags to the agenda dispatch as they came into prominence, or retire old ones.</p>
<p>This time around, I&rsquo;ve got a lot more up-front organization. I guess I didn&rsquo;t really know about categories back then, because I see no evidence I ever used them. Now, every file has a category, and most of the top-level headings in any of my files have a <code>:CATEGORY:</code> property. It makes the agenda view cleaner (category names, not file names) and  it&rsquo;s easy to quick-filter by category (tap <code>s c</code> to &ldquo;filter on category at point&rdquo;).</p>
<p>Part of what makes that work is also a growing hierarchy of org-capture templates. I was wondering why I didn&rsquo;t do more with that back then until I found a bunch of config around <code>org-remember</code>. That was still the &ldquo;get this thing out of your head&rdquo; option when I first started using org-mode. I can see some generic <code>org-capture</code> stuff I pasted in, but it&rsquo;s rudimentary and I am pretty sure I never really used it. Now, I have a variety of org-capture templates that target specific headings in my org-mode files. I tend to work in transient capture buffers, not within files.</p>
<p>With a more robust org-capture hierarchy, categorization of headings, more active use of the agenda, and increasing use of org-roam, I don&rsquo;t spend much less time in my org-mode files this time around.</p>
<p>Once a week, given my current employment circumstances, I have to go through and read some log entries I capture. When I work on a daily post, I have a capture template to instantiate the entry, but I quickly move it to an indirect buffer. I&rsquo;m writing this subheading in an indirect buffer that started from a &ldquo;blog idea&rdquo; capture template with an <code>IDEA</code> type, to make sure I can see all my blogging ideas in the agenda. When an idea doesn&rsquo;t pan out to my liking but I invested time in it, I atomize it into org-roam with <code>org-roam-extract-subtree</code> and tag it. I need to rewrite some of my PRM functions to operate from the agenda, but I&rsquo;d otherwise never actually touch my <code>contacts.org</code> file, either.</p>
<p>I guess what I&rsquo;m getting at is that the trend feels more and more like atomization and abstraction toward the construction of a plaintext database, and less like &ldquo;working on individual text files.&rdquo;</p>
<p>Which I&rsquo;m really happy about. You can do a ton to make org-mode files look nice and do some auto-formatting, but it&rsquo;s easy to get hung up on everything lining up nicely instead of remembering it&rsquo;s all just data that tends to be readable in its own context, even if it isn&rsquo;t perfectly tidy in a wider context.</p>
<p>It&rsquo;s the smarts I was talking about <a href="/posts/2023-05-12-daily-notes/#my-things-link-to-org-stuff">when I wrote about linking stuff in Things</a> that org-mode running in Emacs gives you that doesn&rsquo;t exist in the org syntax highlighters you get in other editors, and that apps like Ulysses get close to but can&rsquo;t quite manage.</p>
<h2 id="fixing-doom-s-busted-leader-key-in-mu4e">Fixing Doom&rsquo;s busted leader key in mu4e</h2>
<p>I am not using mu4e (much), and one of the reasons it was easy to set aside was some brokenness in the way its keybindings interact with Doom Emacs: The space key stopped being the normal Doom leader key and started being the scroll key. I tried to remap it using what I understood of Doom keymapping, but nothing doing. About three weeks ago I posted a question in the Doom Emacs subreddit and on the Doom Discourse, but the best I got was &ldquo;yeah, upstream&rsquo;s broken.&rdquo;</p>
<p>Yesterday <a href="https://old.reddit.com/r/DoomEmacs/comments/12t98y6/using_mu4e_in_doom_how_can_i_get_the_spacebar/jk132gw/">someone on the subreddit finally replied</a> with a recipe:</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="nv">evil-define-key*</span> <span class="o">&#39;</span><span class="p">(</span><span class="nv">emacs</span><span class="p">)</span> <span class="nv">mu4e-main-mode-map</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">&#34;SPC&#34;</span><span class="p">)</span> <span class="ss">&#39;doom/leader</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">evil-define-key*</span> <span class="o">&#39;</span><span class="p">(</span><span class="nv">emacs</span><span class="p">)</span> <span class="nv">mu4e-headers-mode-map</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">&#34;SPC&#34;</span><span class="p">)</span> <span class="ss">&#39;doom/leader</span><span class="p">))</span></span></span></code></pre></div>
<p>That syntax is &hellip; <em>impossible</em> &hellip; to me. But it works.</p>
<h2 id="picture-taking-dot-i-m-not-doing-it-much-dot">Picture taking. I&rsquo;m not doing it much.</h2>
<p>After months of constant photography, I just stopped taking pictures. I know my Fujifilm has a few dozen pictures sitting on the card, and I haven&rsquo;t even taken pictures on the phone except to do things like grab a picture of a receipt or remember which floor of a parking garage I&rsquo;m on.</p>
<p>I remember the morning Al and I were going to head out the door for a coffee walk and I grabbed the camera, then thought about the photos I hadn&rsquo;t even processed still sitting on the card, and just put it down. I also remember taking it with me to Astoria and just not wanting to shoot anything: I left it in the hotel and maybe took a phone picture or two that I promptly forgot.</p>
<p>I go through periodic no-pictures phases. This one has lasted a while. Looking in Lightroom, this is the last picture I took that really mattered much to me, from February:</p>
<figure><img src="/img/blizzard.jpg"
    alt="Monochrome. Two people cross a street at night during a snowstorm."><figcaption>
      <h4>Late February snow storm</h4>
    </figcaption>
</figure>

<p>And in that picture is probably what passes for &ldquo;the issue.&rdquo;  That was an interesting evening I was excited to get out into and shoot. The camera ended up being caked in snow and ice and it was a miserable experience to be out walking around in it.</p>
<p>Since then and up until the past week or so, it has mostly been &ldquo;normal Portland late winter and early spring,&rdquo; so, flat and kinda gray. We haven&rsquo;t traveled at all.</p>
<p>But the other part of it is that I&rsquo;ve been happy to let things be that way. The last time I went on a long hiatus from regular shooting I felt sort of weird and guilty about it. Like I was not being Mr. Picture Guy, and that meant something was wrong with me because I&rsquo;m supposed to be Mr. Picture Guy.</p>
<p>This time around I thought about it after a few weeks of feeling weird about it and remembered something a writing professor once suggested to me about the times I wasn&rsquo;t being Mr. Writing Guy, which is that it&rsquo;s fine to go through periods where that sense of drive and need isn&rsquo;t there, and that it&rsquo;s even good to let a sense of pressure and drive build up a little before giving it voice.</p>
<p>This weekend I saw some things in Eugene that left me wishing I had a camera besides my phone handy. I paused and watched those scenes and thought about what I was missing &hellip; what I could be capturing &hellip; and felt a twinge of regret that I hadn&rsquo;t grabbed a camera on the way out the door.</p>
<p>Nice to have that feeling.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-12</title>
      <link>https://mike.puddingtime.org/posts/2023-05-12-daily-notes/</link>
      <pubDate>Fri, 12 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-12-daily-notes/</guid>
      <description>Automation vs. Augmentation, ChatGPT and ideology, day one of the Things/org experiment.</description>
      <content:encoded><![CDATA[<h2 id="automation-vs-dot-augementation">Automation vs. Augementation</h2>
<p><a href="http://www.zephoria.org/thoughts/archives/2023/04/21/deskilling-on-the-job.html">This is a thoughtful piece by danah boyd</a> that gets to some things I&rsquo;ve been thinking about re: AI.</p>
<blockquote>
<p>Whether you are in Camp Augmentation or Camp Automation, it’s really important to look holistically about how skills and jobs fit into society. Even if you dream of automating away all of the jobs, consider what happens on the other side. How do you ensure a future with highly skilled people? This is a lesson that too many war-torn countries have learned the hard way. I’m not worried about the coming dawn of the Terminator, but I am worried that we will use AI to wage war on our own labor forces in pursuit of efficiency. As with all wars, it’s the unintended consequences that will matter most. Who is thinking about the ripple effects of those choices?</p>
</blockquote>
<p>There is a lot of commentary <a href="https://www.reddit.com/r/MetaFilterMeta/comments/13chd82/how_many_people_are_feeling_or_fearing_the_impact/">in this r/metafiltermeta thread about AI</a>, which was framed from a place of anxiety:</p>
<blockquote>
<p>I&rsquo;m reading about AI&rsquo;s impact on coding, graphic design, video, motion graphics, architecture and law. I hear proponents say that they think AI will change jobs, and that smart workers will learn how to use it as an assistant, but when I review Silicon Valley&rsquo;s contributions to labor in the U.S., mostly I see entire fields gutted, and folks moved over to poorly paying gig economy work.</p>
</blockquote>
<p>The more thoughtful responses pointed, I think correctly, to the eventual Gartner Hype Cycle state of equilibrium you get to once you get unrealistic expectations out of the way, trudge through the salty marshes of &ldquo;told you it was all bullshit,&rdquo; and get to &ldquo;how is this thing going to be used day-to-day?&rdquo;</p>
<p>The people at the Peak of Inflated Expectations do what they always do: Try to solve their problems in a manner ill suited to the tool in front of them, or in a manner that is not reflective of the limitations of the model. The chorus waiting for them down at the bottom of the Trough of Disillusionment has no single motivation: Some of it is wise realism, forward thinking, and experience; some of it is whistling past the graveyard or just missing that &ldquo;productivity gains,&rdquo; like many things in technology and business, are not a series of home runs and grand slams, but rather singles and the occasional double. Reframed more bleakly, grinding down labor&rsquo;s ability to resist induced precarity is a game of inches.</p>
<p>Which is the long way around to saying that if the people who are pointing to offshoring and content-farming mania of the naughts and tens are correct in saying they&rsquo;re the closest analogies we have, and if danah boyd is right that &ldquo;we tend to optimize towards more intense work schedules whenever we introduce new technologies while downgrading the status of the highly skilled person,&rdquo; then it&rsquo;s going to mean fewer people working in AI-effected systems that are biased toward always looking for one more headcount they can get away with removing. It&rsquo;ll look different from the &ldquo;prompt engineering&rdquo; everyone imagines today. It&rsquo;ll be software companies figuring out how to integrate existing &ldquo;dumb&rdquo; systems with generative AI systems acting as synthesizers, with a few humans acting as QA on top of that process, working from a weakened position.</p>
<h2 id="chatgpt-is-an-ideology-machine">&ldquo;ChatGPT Is an Ideology Machine&rdquo;</h2>
<p><a href="https://jacobin.com/2023/04/chatgpt-ai-language-models-ideology-media-production/">Jacobin last month</a>:</p>
<blockquote>
<p>A wide variety of Marxists have also seen ideology as a form of kitsch. First articulated by the Marxist art critic Clement Greenberg in 1937, the notion of kitsch is “pre-digested form.” Among all the things we might say or think, some pathways are better traveled than others. The form of those paths is given; we don’t need to forge them in the first place. The constant release of sequels now has this quality of kitsch — we know exactly where we are when we start watching a Marvel movie. For Greenberg, the avant-garde was the formal adventurer, creating new meaning by making new paths. Hegemony and kitsch are combined in the output of GPT systems’ semantic packages, which might miss aspects of “the world” but faithfully capture ideology.</p>
</blockquote>
<h2 id="my-things-link-to-org-stuff">My Things link to org stuff</h2>
<p>Today I started using the org-protocol stuff <a href="/posts/2023-05-11-daily-notes/#connecting-things-todos-to-org-headings">I talked about yesterday</a> with a set of regular todos I added to Things. For my daily writing and journaling todos, I captured links to the headings from the org documents and pasted them into the notes field of the Things todo before marking them done. Clicking on those links brings up a new Emacs frame that jumps straight to the heading in the correct file.</p>
<p>That pretty much recreates the workflow I had with Bear and Things for other kinds of task/notes combinations, and it shows me how to use org-protocol and org-capture to do similar kinds of workflows where Emacs participates in the rest of my tools ecosystem.</p>
<p>So, promising trial experience. I&rsquo;m a little becalmed on heavy-duty task/work tracking right now, so I&rsquo;m satisfied to just note that the idea works and that I&rsquo;ll keep using it to find out where the edge cases are: Something always comes up.</p>
<p>The idea that keeps popping up in my head is that a lot of my past &ldquo;emacsimalism&rdquo; &ndash; a recurring phase I&rsquo;ve experienced over several decades &ndash; was due to the fact that Emacs was pretty much a technology island. The Mac builds weren&rsquo;t always very good, and the ways in which it could speak to the system around it were sort of flaky. But things like org-protocol and a little bit of utility glue with osascript do a lot to make it easier to find your way into and out of Emacs. You don&rsquo;t <em>have</em> to make it your everything because it can work well <em>alongside</em> other things that might suit your individual style better. The idea I&rsquo;m sort of nibbling around right now is that I don&rsquo;t like org-mode for <em>organization of work and tasks</em> so much as I like it for <em>organization of text and ideas</em>. It&rsquo;s less &ldquo;a smarter Things, OmniFocus, or Reminders,&rdquo; and more &ldquo;what I wish Ulysses had been.&rdquo;</p>
<p>Maybe that&rsquo;s why assorted org syntax implementations in more modern text editors (e.g. BBEdit, Sublime, Atom, VSCode) are always disappointing: They&rsquo;re usually just syntax highlighting and no smarts. Might as well just be doing Markdown at that point, because the <em>smarts</em> of org-mode pretty much live in Emacs and lisp. Without that, you&rsquo;re just quibbling over whether a backslash or an asterisk is better <code>emph</code> notation.</p>
<p>Anyhow, we&rsquo;ll leave it at that until there&rsquo;s something new to say. I think I&rsquo;ve visited this topic plenty.</p>
<h2 id="twitter">Twitter</h2>
<p>I disabled my Twitter account late last month, so I think I have a bit under two weeks for it to fully deactivate. I think I will thread the needle between making an <em>announcement</em> and merely noting that I have embarked on the process of closing my account by making it the last heading of today&rsquo;s post, unmentioned in the summary.</p>
<p>There&rsquo;s a needle to thread because my strong preference would be for people to give up on Twitter. So if you&rsquo;re someone with whom I might have some influence, I&rsquo;m happy for you to read this and do the primate thing &ndash; &ldquo;Hm, Mike is a thoughtful, ethical person whose ideas I tend to take under advisement, and he sees Twitter as, on balance, negative and harmful, so I will take that idea under advisement, as well.&rdquo;</p>
<p>That&rsquo;s all.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-11</title>
      <link>https://mike.puddingtime.org/posts/2023-05-11-daily-notes/</link>
      <pubDate>Thu, 11 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-11-daily-notes/</guid>
      <description>BBEdit turns 30, Emacs update, Things, OmniFocus, etc.</description>
      <content:encoded><![CDATA[<h2 id="bbedit-turns-30">BBEdit turns 30</h2>
<p>Just after <a href="https://mike.puddingtime.org/posts/2023-05-10-daily-notes/">I was remembering it yesterday</a>, there&rsquo;s a <a href="https://news.ycombinator.com/item?id=35904320">nice appreciation of BBEdit going on over at HackerNews.</a> One comment captured my opinion pretty well:</p>
<blockquote>
<p>I read about BBEdit on HN a few months ago and realized it has one use-case where it excels: text transformation and regex search/replace across files. When it comes to this, no other editor I know can hold water: neither Sublime, nor VS Code, nor Vim. And forget about Emacs, as regexes need to be awkwardly double or triple backslashed.</p>
<p>Text transformations can be done via regex, predefined functions, or any scripting language, where the scripts will be listed in the menu.
Regex search/replace has a history of used patterns, so you can reuse them.</p>
<p>All in all, it is a very lightweight editor with excellent text transformation features that no other editor can offer.</p>
</blockquote>
<p>It is definitely my go-to for that kind of thing. I used to feel sort of guilty that I wasn&rsquo;t trying to get heavy-duty text transforms done from the shell, then I wised up: BBEdit makes it fast, reversible, repeatable, and visually discoverable. And it will plow through large files like nothing else. I keep a license around just for scenarios like &ldquo;need to do something to 2,000 Markdown files&rdquo; or what have you.</p>
<p>Also, my interactions with BareBones for support have been so amazingly helpful and cordial.</p>
<p>Thirty years old and still an evolving, high quality product that I reach for when &ldquo;I just need to get this task done.&rdquo;</p>
<h2 id="emacs-update">Emacs update</h2>
<p>The last few days I&rsquo;ve started getting reminders of a fundamental truth of Emacs life, which is that you will eventually push it a little too far with the new stuff and it starts getting punchy and stops feeling trustworthy.</p>
<p>I got a little excited about some tweaks, and I&rsquo;m glad I was applying them one at a time and seeing what happened, because when one of them hard-locked Emacs it was simple to just go back into my <code>config.org</code> file,  <code>:tangle no</code> the offending config, and comment out the problematic package in <code>packages.el</code>.</p>
<p>This is a part of Emacs life, though, that Doom Emacs has made better: It makes configuration simple. I love being able to organize config blocks under headings I can manage with org-mode structure editing, and I appreciate the simplicity of package management. There are a few more steps to get some things done, but they&rsquo;re simpler steps than how I used to manage Emacs.</p>
<p>When I hard-locked it yesterday it was a small bummer but it was also easy to undo the change and get back up and running. I&rsquo;ve felt the difference in how I feel when I sit down to use Emacs over the past while: It has gone from &ldquo;well, I wonder what sort of fatal self-own I&rsquo;m going to suffer from today&rdquo; to &ldquo;this is a stable tool I like using and don&rsquo;t worry about much.&rdquo;</p>
<p>It&rsquo;s such an open ecosystem, and extending it involves so much complexity, that the bits like &ldquo;oh, added that package and it crashed trying to open a file&rdquo; are just going to be part of it. But you deal with that by following a &ldquo;no new toys with an unsaved buffer of something that matters to you&rdquo; rule and making incremental changes.</p>
<h2 id="organizing-work-todo-apps">Organizing work &ndash; todo apps</h2>
<p>I spent a little time watching reviews and comparisons of Things and OmniFocus 3 today. Last night I started putting together a 90-day plan in org-mode and was enjoying the &ldquo;actions/prose&rdquo; hybrid of org-mode, but also thinking &ldquo;this is getting complex and these lists are pretty sequential and interdependent &hellip; I wonder if I want to put this weight on org-mode.&rdquo;</p>
<p>So I watched the videos, downloaded OmniFocus 3 again (I&rsquo;ve had a license for a few years), and took a stab at entering a few small chunks of work to see how it felt.</p>
<p>Not great.</p>
<p>I don&rsquo;t spend a lot of time worrying too much about how apps look, but OF is just sort of unappealing in that regard.</p>
<p>When I look at Things, there&rsquo;s a lot of visual appeal. You can&rsquo;t do much to control it, but you don&rsquo;t need to. The color scheme and roominess of the interface really work for me. When I look at an org-mode buffer, it is a very different aesthetic. I recently stopped doing mixed-mode and just live in good old Fira Code in a single size. But I&rsquo;ve got good light and dark themes and once I figured out how to control line-spacing it opened things up a little and made it feel less like a &hellip; like smelly ASCII cave. Looking over at MailMate, I can also exercise a little bit of control, so even though it is a visually simple app, the bit of decoration it does have is clean and I can pick my typefaces.</p>
<p>OmniFocus has some customization options, but I&rsquo;ve always struggled with its font sizes, sort of resenting the iOS-style &ldquo;small/medium/large/larger/very larger&rdquo; restriction on my choices, especially because there&rsquo;s a wide range of text size going on within the UI. It is also cramped. The UI is packed tight and even lists of project headings feel claustrophobic and closed in.</p>
<p>Things 3, one might respond, has next to no customization, either. Fewer choices than OF3, even. But it&rsquo;s just better done out of the box. It reminds me of something the UX designers at Puppet would have come up with in that it feels light and open.</p>
<p>That&rsquo;s a lot of time on looks, but if you have to look at the thing all day, they start mattering.</p>
<p>I think mostly I just managed to remind myself that I really loved the <em>idea</em> of OmniFocus years and years ago, but in practice it never stuck for long.</p>
<p>Things is harder to discard. It&rsquo;s just pleasant to work with, it&rsquo;s logically organized, the mobile apps are very good, and I really like the way you can organize a project with headings that are loose enough to have whatever meaning you care to give them: Milestones, themes, phases, or whatever. There&rsquo;s light Markdown sprinkled into the text areas, too. If you were not hung up on ultimate portability, the typography is clean and legible enough that you could manage prose notes in Things.</p>
<p>Back in the day, when I was using <a href="https://bear.app">Bear</a> a lot for note-taking in conjunction with Things as my task manager, I would just include a link to a Bear note in the notes field in Things. So, for instance, the Things project I had set up for my team had a heading for each member of the team where followup items went, and a link to the individual team member&rsquo;s note in Bear for prose. It worked pretty well.</p>
<h3 id="connecting-things-todos-to-org-headings">Connecting Things todos to org headings</h3>
<p>I wondered if I could do that with Emacs and an org-mode heading, and yes, I can.</p>
<p><a href="https://emacs.stackexchange.com/questions/47986/jump-to-org-mode-heading-from-external-application">This StackOverflow post</a> provided two bits of code to add navigation to a given org-mode heading using <code>org-protocol</code> and to yank the link from a given heading. It points to <a href="https://github.com/xuchunyang/setup-org-protocol-on-mac">this page</a> on how to make a simple little AppleScript app that registers <code>org-protocol</code> as a valid URL handler in macOS. I bound the link-grabbing function to <code>SPC n L</code> in Doom, and gave it a try by pasting the link into a Things note &hellip; yup &hellip; worked: Dropped me into a new Emacs GUI window with the point on the org-heading.</p>
<figure><img src="/img/things_emacs.jpg"
    alt="Screenshot of a Things todo with a link to a heading in an org-mode buffer"><figcaption>
      <h4>Things with an org-protocol link pointing to an org-mode blog post heading</h4>
    </figcaption>
</figure>

<p>Will I use it?</p>
<p>I don&rsquo;t know!</p>
<p>I remember my Things/Bear workflow being a very nice harmonization of two different kinds of work that lived in single-function apps. org-mode blurs those lines all on its own. I <a href="/posts/2023-05-02-daily-notes/#my-org-contacts-file-and-things">wrote a little about this several days ago</a> in relationship to my plaintext PRM.</p>
<p>I really like how clean Things is for capturing stuff from all sorts of places on my phone and computer. I like its seamless integration with existing macOS and iOS calendars and Reminders. I can do that stuff in org-mode and Emacs, but it takes a little extra work and feels more brittle. There are mobile apps for org-mode, like beorg, but they do feel a little clunkier than Things.</p>
<p>So I guess I&rsquo;ll take that small chunk of planning I was working on in Things, expand it to more stuff,  and see how it feels when I can link in to org-mode documents as easily as I can now.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-03</title>
      <link>https://mike.puddingtime.org/posts/2023-05-03-daily-notes/</link>
      <pubDate>Wed, 03 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-03-daily-notes/</guid>
      <description>A Ruby/CLI-based plaintext PRM, Robert DeNiro on exporting org-mode to JSON, blogging with ox-hugo, that Royal Enfield Himalayan</description>
      <content:encoded><![CDATA[<h2 id="friends-a-plaintext-ruby-based-prm">&ldquo;friends&rdquo; - a plaintext, Ruby-based PRM</h2>
<p>Looking around for other people who have done CRM/PRM-ish things in plaintext, I found <a href="https://github.com/JacobEvelyn/friends">JacobEvelyn/friends</a>. It&rsquo;s written in Ruby, uses Markdown for its home format, and gives you a command line interface to a record of your friends and activities.  I appreciate how thoroughly it thinks about what it is trying to do, and I sense a set of concerns similar to mine about the &ldquo;keeping up with personal contacts&rdquo; challenge.</p>
<p>Some things I like about it:</p>
<ul>
<li>Simple CLI data entry syntax</li>
<li>Some &ldquo;habit tracking&rdquo; style reporting to help you understand if you&rsquo;re keeping up your practice.</li>
<li>Clean reporting with a lot of flexibility that would let you build more reporting.</li>
<li>Simple use of Markdown, with no elaborate syntactical overlay.  If you gave up on friends, your data would be easily readable.</li>
</ul>
<p>It&rsquo;s probably good to note that friends isn&rsquo;t a full contact management system. It&rsquo;s better to think of it as a sort of journaling and habit tracking tool with a tight focus on keeping up with people, not a way to manage all your contact details. If I could extend one thing about it, it would probably be to be able to store email addresses with contacts: Email addresses aren&rsquo;t <em>great</em> keys, but also they&rsquo;re fine keys sometimes, and they&rsquo;d open friends up to interacting with other tools.</p>
<h2 id="ox-json-and-the-wisdom-of-neil-mccauley">ox-json and the wisdom of Neil McCauley</h2>
<p>As I was looking through the docs for friends and waming up to it some I wondered how readily I could migrate my org-contacts information. My home language is Ruby, so I tend to start there when I&rsquo;m looking for a library. There&rsquo;s one org-mode gem I&rsquo;m aware of, but its primary preoccupation is converting org-mode to HTML or Textile for presentation purposes.</p>
<p>Another way to come at the problem is to get the org markup into something more universally parseable, which is where <a href="https://github.com/jlumpe/ox-json">ox-json</a> could help. Does what it says on the tin: Converts an org-mode file into JSON, including, crucially, the data stored in the  <code>:PROPERTIES:</code>  drawer. Currently it passes by the <code>:LOGBOOK:</code> drawer, so that limits what you can do with it, but it still opens up possibilities.</p>
<p>Why?</p>
<div style="text-align:center;">
<iframe width="560" height="315" src="https://www.youtube.com/embed/rGPWW9Pjzto" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
<h2 id="ox-hugo-update">ox-hugo update</h2>
<p>I started blogging with <a href="https://github.com/kaushalmodi/ox-hugo">ox-hugo</a> several weeks ago, going into it a little warily.</p>
<p>Recap:</p>
<ul>
<li>You write all your posts in a monolithic org-mode file.</li>
<li>Each heading is a post.</li>
<li>Heading tags become post tags.</li>
<li>Headings in a <code>TODO</code> state are drafts.</li>
<li>Metadata can be stored in the <code>:PROPERTIES:</code> drawer (tidy, but the templating syntax gets cluttery if you&rsquo;re not a lisp native) or additional metadata src blocks (more visually cluttered when writing, but easier to read the template  if you&rsquo;re a YAML native)</li>
<li>You can set it up to automatically export the Markdown version into your Hugo content hierarchy whenever you save the buffer.</li>
</ul>
<p>Why would you want to do this?</p>
<p>As someone who does a lot of digest posts, I like having my pre-publication notes, links, etc. in the org-mode ecosystem, with all of its text manipulation affordances.  If a topic I&rsquo;m working on isn&rsquo;t ready when it&rsquo;s time to publish that day, I just <code>refile</code> the subheading under my <code>* Daily Post Overflow</code>  heading and keep going. I also like org-mode&rsquo;s structure editing features. It&rsquo;s simple to move headings and their content around within a post.</p>
<p>I thought the &ldquo;all-in-one-file&rdquo; thing would annoy me, and there is part of me that still doesn&rsquo;t like seeing all the surrounding context, but that&rsquo;s what <code>subtree to indirect buffer</code> is for. I drop into an indirect buffer for the long-haul writing, then pop back out of it if I need to pull things in from the overflow area or check on something from a previous post.</p>
<p>I did stub my toe on one thing, which was that the org-capture template I found to make the post setup simpler was setting <code>:EXPORT-HUGO-DATE:</code>, which updates dynamically when you save a post heading. I went back to make some edits to a post, saved my work, and it altered the date metadata in the Markdown output and jumbled my post order. The answer seemed to be to switch that to <code>:EXPORT_DATE:</code>, and now it behaves.</p>
<p>I also put off cleaning up my capture template so all the metadata could go in the <code>:PROPERTIES:</code> drawer. At first It was easier  to just embed some YAML at the top of the post body with <code>#+begin_src yaml :front_matter_extra t</code> rather than working out the Lispier syntax for post image and cover image in the context of writing a capture template.  It just took a few minutes to fix once I decided to bother with it, and the template now outputs <code>:PROPERTIES:</code> metadata:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-org" data-lang="org"><span class="line"><span class="cl">:EXPORT_HUGO_CUSTOM_FRONT_MATTER<span class="gd">+: :cover &#39;((image . &#34;&#34; ) (caption . &#34;&#34; ))
</span></span></span><span class="line"><span class="cl"><span class="gd">:EXPORT_HUGO_CUSTOM_FRONT_MATTER+</span>: :images &#39;(/momo-logo.jpg)
</span></span><span class="line"><span class="cl">:EXPORT_DESCRIPTION:</span></span></code></pre></div>
<p>I only sometimes use cover images, but I like to include my site logo in social posts, etc. when I don&rsquo;t have some other image to show, so the template defaults to an empty cover image and <code>image</code> metadata that Hugo&rsquo;s OpenGraph templating can pull in.</p>
<p>Several weeks in, I like the workflow. One tiny part of my soul is troubled that I have org source and Markdown output, but on the other hand the org source overwrites the Markdown output on edit, so the two don&rsquo;t drift. Realistically, the Markdown would be the more migratable content were I to shift off of Hugo, and it&rsquo;s simply better to author in org-mode.  So there&rsquo;s no associated toil and each format gets to be useful in the way it is best suited to be so.</p>
<h2 id="that-royal-enfield-himalayan">That Royal Enfield Himalayan</h2>
<p>I complained a little about my Royal Enfield Himalayan a few days ago: a little big for the power it has, and it had some QA problems that took some time to track down  I am pretty sure I am going to sell it to fund something similar.  But I did swap in a fresh battery and cleaned it up from winter storage, and rode it up to St. Johns for lunch yesterday, which meant a few dozen miles. It ran pretty well!</p>
<p>Last year, after dealing with rough idling and stalls, I finally broke down and installed a <a href="https://www.boosterplug.com/shop/frontpage.html">BoosterPlug</a>. Himalayans run too lean out of the factory, and the difference after installing one was pretty amazing. It was about a five-minute operation and it made the difference between a very rough first five minutes and &ldquo;let it idle for 30 seconds and it&rsquo;ll be fine.&rdquo; The machine never stalls now. I do think it still idles a little low, but that&rsquo;s a fine-tuning thing.</p>
<p>Anyhow, it was nice to ride around. Yeah, it&rsquo;s a little big, but it&rsquo;s not a big bike. There&rsquo;s plenty of pep for the city. Running up HWY 30, it did fine with the lunch crowd and there was plenty of power to overtake or squeeze out of spots at urban parkway speeds. I&rsquo;d do exit-to-exit on the Portland bypasses with it.</p>
<p>I was also glad to see <a href="https://www.sabatinomoto.com">an RE dealership up in St. John.</a>  Wasn&rsquo;t a fan of the Harley dealership I was getting service at and had to do a lot of research on my own to get help when it was suffering from factory QA problems.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-05-02</title>
      <link>https://mike.puddingtime.org/posts/2023-05-02-daily-notes/</link>
      <pubDate>Tue, 02 May 2023 00:00:00 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-02-daily-notes/</guid>
      <description>A Mackup/Dropbox glitch, integrating org-contacts and Things, conversations not interviews.</description>
      <content:encoded><![CDATA[<h2 id="mackup-and-dropbox">Mackup and Dropbox</h2>
<p>I recently recommended <a href="https://github.com/lra/mackup">Mackup</a>, a Mac config syncronization tool, but I&rsquo;m having a few issues with it now. In general, it does a pretty good job with most apps, but I ran into a weird bug with Mailmate where it kept forgetting all my settings. After a few go-rounds I opened up the Console and searched for Mailmate messages and found it wasn&rsquo;t able to write to its prefs file. I put Mailmate in Mackup&rsquo;s skip list, removed the symlinks and let it write its files again and all was well. Searching Mackup&rsquo;s issues, <a href="https://github.com/lra/mackup/issues/1891">I found someone experiencing a similar issue with Xcode</a> and learned it seems to be a thing with Dropbox and iCloud and certain apps. In the case of Dropbox, it has come with that app&rsquo;s move to the <code>CloudStorage</code> folder.</p>
<p>I&rsquo;m not sure this is enough to get me quit using it. It works quite well with my Emacs config, gpg, ssh, zsh, and other stuff. I also like using it for syncing my <code>~/bin</code>.  It doesn&rsquo;t work so well with Terminal.app, and gets a little weird now and then with a few other things.</p>
<p>Just &hellip; proceed with caution, I guess is the advice.  For now I&rsquo;ve got Mailmate, Terminal.app, karabiner, and Bartender on the skip list. That&rsquo;s fine for most of them: They&rsquo;re generally best configured a little different between laptop and desktop anyhow.</p>
<h2 id="my-org-contacts-file-and-things">My  org-contacts file and Things</h2>
<p>I stopped using mu4e. I was uncomfortable with the interplay between several different clients (both automated and user-facing) and my Maildir and IMAP. That left a a small hole in the functionality I&rsquo;d built into my org-mode PRM: being able to quickly mail a contact from a Doom Emacs menu. So I made a quick function that just turns the email address in the org-contacts record into a <code>mailto:</code> link and <code>open</code> call to the system that invokes my preferred mail client (Mailmate at this point). So if the point is over an org-contacts heading I can <code>SPC C m</code> (&ldquo;leader - CRM - mail&rdquo;)  and get a new message.</p>
<p>I&rsquo;m on the record somewhere about not liking the emphasis on URL schemes for Mac automation. I don&rsquo;t like the ins and outs of encoding values and cramming data into that format. At the same time, it <em>does</em> seem to have kept the idea of Mac end-user automation from fading away. So as I sat there looking at my new mailto function, I wondered about how all the contact data I&rsquo;m keeping could interact with the wider Mac ecosystem in a sort of &ldquo;if needed&rdquo; manner, hence this little thing.</p>
<p>It just provides an interactive menu for selecting a contact activity (ping, call, write, etc.) and an interactive date picker, then makes a Thing todo that includes the tags for the contact, with a &ldquo;start date.&rdquo; I can get at it with <code>SPC C g</code> (&ldquo;leader CRM thinGs&rdquo;).  I don&rsquo;t mean to use it? I was just curious. I&rsquo;m not sure.</p>
<p>What I am learning as I use org-mode day-to-day again is that there are things that come naturally to it and that do not come naturally to it. I&rsquo;ve got working integrations with my calendar, for instance, but calendar syncing is another one of those things that eats the one thread you have to work with when it runs, and sometimes it does mysterious things if you mess with a plaintext representation of a more complex data structure that was never written with direct human interaction in mind.</p>
<p>That&rsquo;s always the struggle with Emacs: What <em>can</em> it do, and what <em>should</em> it do?</p>
<p>The temptation is to crawl into a uni-environment and torture everything into some kind of alignment, but that&rsquo;s brittle. It might <em>feel</em> good if your temperament or proclivities lead you to feeling comfortable with that particular shape, but there are tradeoffs whether you acknowledge them or not. In this particular case, the line I am sensing is the line between &ldquo;getting things done&rdquo; in a very mixed, tactical, &ldquo;chores, obligations, and interrupts&rdquo; kind of way, and getting things done in a very &ldquo;life is an information problem&rdquo; kind of way.</p>
<p>I love org-mode as a way of organizing information and thoughts. In particular, I am very fond of all the refiling capabilities it offers, because ideas and information can be shuffled around between different contexts inside the broader org-mode context without lifting a hand from the keyboard. As a day-to-day &ldquo;chores and household projects&rdquo; tool, I&rsquo;m a little less certain about it, mainly because of the mobile piece. <a href="https://beorgapp.com">beorg</a> is great, but it is also a little bit of work to use, and its syncing model is borrowed, so it&rsquo;s not as good as a purpose-built solution. Further, it is not consistent with my desktop org-mode environments when it comes to things like the agenda views.</p>
<p>So, you know, the interesting thing to me becomes &ldquo;how can this sophisticated text manipulation environment fit into a broader toolkit?&rdquo; How can all these things interconnect and complement each other? What are the kinds of work that makes sense living in a purpose-built tool because their typical context favors less thinking and less complexity, vs. the kinds of work that are broadly the same thing (&ldquo;a thing I need to do&rdquo;) that benefit from more thinking and more complexity? What kinds of tasks can be &ldquo;dead&rdquo; and in a little purpose-built silo, and what kinds of tasks benefit from a little bit of added complexity to exist in a better context? How could a thing move from one environment to the other?</p>
<p>Interesting to me, anyhow, because my tendency, at rest &ndash; my unconscious tendency &ndash; is to want everything in one tool, but I continue to learn over time that the one-tool outlook breeds its own kinds of complexity.</p>
<p>Anyhow, here&rsquo;s that function. It works okay so far. The one glitch is that the Things URL scheme won&rsquo;t make a tag if it doesn&rsquo;t exist, so I had to go in and tag an existing todo with all my contact types (friend, network, recruiter, etc.) to get the function to properly tag a contact todo.</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="nb">defun</span> <span class="nv">mph/org-contacts-to-things</span> <span class="p">(</span><span class="nv">contact-kind</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Create a Things to-do item based on the current Org Contacts record.
</span></span></span><span class="line"><span class="cl"><span class="s">   CONTACT-KIND is a string that specifies the kind of contact (&#39;ping&#39;, &#39;call&#39;, &#39;write&#39;, &#39;schedule&#39;, or &#39;follow up&#39;).&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span>
</span></span><span class="line"><span class="cl">   <span class="p">(</span><span class="nf">list</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nf">completing-read</span> <span class="s">&#34;Contact Kind: &#34;</span> <span class="o">&#39;</span><span class="p">(</span><span class="s">&#34;ping&#34;</span> <span class="s">&#34;call&#34;</span> <span class="s">&#34;write&#34;</span> <span class="s">&#34;schedule&#34;</span> <span class="s">&#34;follow up&#34;</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let*</span> <span class="p">((</span><span class="nv">name</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="no">nil</span> <span class="s">&#34;Name&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">email</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="no">nil</span> <span class="s">&#34;Email&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">phone</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="no">nil</span> <span class="s">&#34;Phone&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">note</span> <span class="p">(</span><span class="nf">read-string</span> <span class="s">&#34;Note: &#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">notes</span> <span class="p">(</span><span class="nf">format</span> <span class="s">&#34;Email: %s\nPhone: %s\nNote: %s&#34;</span> <span class="nv">email</span> <span class="nv">phone</span> <span class="nv">note</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">start-date</span> <span class="p">(</span><span class="nv">org-read-date</span> <span class="no">nil</span> <span class="no">nil</span> <span class="no">nil</span> <span class="s">&#34;Start Date: &#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">start-date-string</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;%Y-%m-%d&#34;</span> <span class="p">(</span><span class="nv">org-time-string-to-time</span> <span class="nv">start-date</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">tags</span> <span class="p">(</span><span class="nv">org-get-tags</span> <span class="no">nil</span> <span class="no">t</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">tag-string</span> <span class="p">(</span><span class="nb">if</span> <span class="nv">tags</span> <span class="p">(</span><span class="nf">mapconcat</span> <span class="ss">&#39;identity</span> <span class="nv">tags</span> <span class="s">&#34;,&#34;</span><span class="p">)</span> <span class="s">&#34;&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">title</span> <span class="p">(</span><span class="nf">format</span> <span class="s">&#34;%s: %s&#34;</span> <span class="nv">contact-kind</span> <span class="nv">name</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">url</span> <span class="p">(</span><span class="nf">format</span> <span class="s">&#34;things:///add?title=%s&amp;notes=%s&amp;when=%s&amp;tags=%s&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="p">(</span><span class="nv">url-encode-url</span> <span class="nv">title</span><span class="p">)</span> <span class="p">(</span><span class="nv">url-encode-url</span> <span class="nv">notes</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                      <span class="p">(</span><span class="nv">url-encode-url</span> <span class="nv">start-date-string</span><span class="p">)</span> <span class="p">(</span><span class="nv">url-encode-url</span> <span class="nv">tag-string</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">start-process-shell-command</span> <span class="s">&#34;open&#34;</span> <span class="no">nil</span> <span class="p">(</span><span class="nf">format</span> <span class="s">&#34;open \&#34;%s\&#34;&#34;</span> <span class="nv">url</span><span class="p">))))</span></span></span></code></pre></div>
<h2 id="conversations-not-interviews">Conversations, not interviews</h2>
<p>Refreshing interview closer of the month:</p>
<p>&ldquo;We have a few minutes left, any questions of me?&rdquo;</p>
<p>&ldquo;No. I came into this thinking you&rsquo;d either say &lsquo;did you even read the job description? Now good day while I go fire the recruiter,&rsquo; or you&rsquo;d see something that would lead you to want a conversation, which I hope we&rsquo;ll continue so I can learn more.&rdquo;</p>
<p>And there we were, having a conversation.</p>
<p>I&rsquo;ve been very lucky to have had several <em>conversations</em> recently. It&rsquo;s reminding me of the times I had <em>interviews</em> and how those things went wrong down the road. It&rsquo;s great to end a conversation hearing the person you were conversing with say &ldquo;wow, the time flew by &hellip; but this felt so organic.&rdquo; You can enter a conversation with curiosity, and with a good conversational partner you can see where things go, make connections to your experience in the moment, change course or call up other experiences when they say &ldquo;well, that&rsquo;s not quite what we&rsquo;re dealing with here.&rdquo; That&rsquo;s much better than  pre-thinking a bunch of answers and poring over &ldquo;ten most common questions&rdquo; or (if Nigel or Chris are reading) &ldquo;you&rsquo;re trapped in a 20&rsquo; blender&rdquo; scenarios.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Finding an org-contact record&#39;s emails in MailMate and events in Google Calendar</title>
      <link>https://mike.puddingtime.org/posts/2023-05-02-finding-an-org-contact-record-s-emails-in-mailmate/</link>
      <pubDate>Tue, 02 May 2023 00:00:00 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-02-finding-an-org-contact-record-s-emails-in-mailmate/</guid>
      <description>Looking up email histories and past Google Calendar events from org-contacts, and a few ideas about how to schedule time with people.</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been digging <a href="https://freron.com">MailMate</a>, but missing a function I&rsquo;d added to my Doom Emacs setup that let me search mu4e for mails from a contact in my <code>contacts.org</code> file.  I set out to fix that this evening thinking it&rsquo;d probably be an AppleScript thing, but <a href="https://manual.mailmate-app.com/extended_url_scheme">it turns out MailMate has its own URL scheme</a> (<code>mlmt:</code>) that includes queries. From the command line, for instance, you&rsquo;d just do something like <span class="inline-src language-sh" data-lang="sh"><code>open mlmt:quicksearch?string=&quot;foo@bar.com&quot;</code></span>  to search for that address.</p>
<p>(I learned about that from this post by James Sulak (another Emacs person, as it turns out), who shared <a href="https://boxkitemachine.net/posts/mailmate-and-alfred/">a set of helpful Alfred workflows for working with MailMate</a>.)</p>
<p>This function grabs the <code>EMAIL</code> property of a given org-contacts heading and runs the <code>open</code> shell command:</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="nb">defun</span> <span class="nv">mph/open-mlmt-quicksearch</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Open a quicksearch URL for the email address at point.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">email</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="p">(</span><span class="nf">point</span><span class="p">)</span> <span class="s">&#34;EMAIL&#34;</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">if</span> <span class="p">(</span><span class="nv">not</span> <span class="p">(</span><span class="nv">string-empty-p</span> <span class="nv">email</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">shell-command</span> <span class="p">(</span><span class="nf">format</span> <span class="s">&#34;open &#39;mlmt:quicksearch?string=%s&#39;&#34;</span> <span class="nv">email</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nf">message</span> <span class="s">&#34;No email address found&#34;</span><span class="p">))))</span></span></span></code></pre></div>
<p>MailMate search is very fast. The results are there in an eyeblink.</p>
<p>&hellip; and that sort of led to this, which searches Google Calendar for an email address from a contact:</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="nb">defun</span> <span class="nv">mph/open-gcal-search-for-email</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Open a Google Calendar search page for the email address at point.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">email</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="p">(</span><span class="nf">point</span><span class="p">)</span> <span class="s">&#34;EMAIL&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">search-url</span> <span class="s">&#34;https://calendar.google.com/calendar/u/0/r/search?q=%s&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">if</span> <span class="p">(</span><span class="nv">not</span> <span class="p">(</span><span class="nv">string-empty-p</span> <span class="nv">email</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nb">progn</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nf">message</span> <span class="s">&#34;Searching Google Calendar for events with email %s...&#34;</span> <span class="nv">email</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">           <span class="p">(</span><span class="nv">browse-url</span> <span class="p">(</span><span class="nf">format</span> <span class="nv">search-url</span> <span class="nv">email</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nf">message</span> <span class="s">&#34;No email address found&#34;</span><span class="p">))))</span></span></span></code></pre></div>
<p>&hellip; and that suggested this one, which gets a date from the interactive org date picker and creates an all-day  Google Calendar event with the contact as an invitee:</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="nb">defun</span> <span class="nv">mph/create-gcal-all-day-appointment-with-contact</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Create a new all-day appointment in Google Calendar and invite the contact at point.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let*</span> <span class="p">((</span><span class="nv">date</span> <span class="p">(</span><span class="nv">org-read-date</span> <span class="no">nil</span> <span class="no">t</span> <span class="no">nil</span> <span class="s">&#34;Date: &#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">formatted-date</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;%Y%m%d&#34;</span> <span class="nv">date</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">next-day</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;%Y%m%d&#34;</span> <span class="p">(</span><span class="nf">time-add</span> <span class="nv">date</span> <span class="p">(</span><span class="nf">*</span> <span class="mi">24</span> <span class="mi">60</span> <span class="mi">60</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">contact-email</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="p">(</span><span class="nf">point</span><span class="p">)</span> <span class="s">&#34;EMAIL&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">url</span> <span class="p">(</span><span class="nf">concat</span> <span class="s">&#34;https://calendar.google.com/calendar/u/0/r/eventedit?dates=&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="nv">formatted-date</span>
</span></span><span class="line"><span class="cl">                      <span class="s">&#34;/&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="nv">next-day</span>
</span></span><span class="line"><span class="cl">                      <span class="s">&#34;&amp;pli=1&amp;sf=true&amp;action=TEMPLATE&amp;add=&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="nv">contact-email</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">browse-url</span> <span class="nv">url</span><span class="p">)))</span></span></span></code></pre></div>
<p>I preferred just setting it to all-day, because I&rsquo;ve learned a few things about scheduling time to catch up with people in a non-business context:</p>
<ol>
<li>It&rsquo;s usually gonna be a few weeks out. PTO, busy, etc.</li>
<li>Setting a day is pretty easy, but setting a good time can be hard when it&rsquo;s that far out. Schedules do things, or we know a given day is <em>usually</em> our good day, but specifics can shift around.</li>
<li>Setting an all-day item and a reminder to lock down the details several days out makes it easier to agree to <em>something</em> and work out the details when calendars are a little more clear. No constant shuffling if one party or the other isn&rsquo;t in complete control of their own calendar.</li>
</ol>
<p>I wonder if I should go read a book about how to stay in touch with people. I know there are several.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Were you to attempt something like this in AppleScript</title>
      <link>https://mike.puddingtime.org/posts/2023-04-27-were-you-to-attempt-this-with-applescript/</link>
      <pubDate>Thu, 27 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-27-were-you-to-attempt-this-with-applescript/</guid>
      <description>&lt;p&gt;I started down the path of &lt;a href=&#34;https://mike.puddingtime.org/posts/20230413-making-a-plaintext-personal-crm-with-org-contacts/&#34;&gt;building some sort of PRM in org-mode&lt;/a&gt; because I couldn&amp;rsquo;t find anything that worked the way I wanted. I did briefly look at Apple&amp;rsquo;s Contacts app, and also at &lt;a href=&#34;https://flexibits.com/cardhop&#34;&gt;Cardhop&lt;/a&gt;, which builds on top of your Contacts database but still makes some assumptions about how good you are at all at remembering to reach out to people.&lt;/p&gt;
&lt;p&gt;I also looked at &lt;a href=&#34;https://monicahq.com&#34;&gt;Monica&lt;/a&gt;, an open source PRM. The promising part of Monica is its API. The web UI itself shows comprehensive data for each contact, but does not do anything in the way of bulk editing and has no automation at all. It&amp;rsquo;s laborious to bootstrap.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I started down the path of <a href="https://mike.puddingtime.org/posts/20230413-making-a-plaintext-personal-crm-with-org-contacts/">building some sort of PRM in org-mode</a> because I couldn&rsquo;t find anything that worked the way I wanted. I did briefly look at Apple&rsquo;s Contacts app, and also at <a href="https://flexibits.com/cardhop">Cardhop</a>, which builds on top of your Contacts database but still makes some assumptions about how good you are at all at remembering to reach out to people.</p>
<p>I also looked at <a href="https://monicahq.com">Monica</a>, an open source PRM. The promising part of Monica is its API. The web UI itself shows comprehensive data for each contact, but does not do anything in the way of bulk editing and has no automation at all. It&rsquo;s laborious to bootstrap.</p>
<p>In the process of trying to figure out how I could write some automation to move Contacts information beyond the basic vCard fields into Monica I did end up having to learn about how macOS Contacts work and realized you can create custom labels for date fields then add them to your card editing template in Contacts&rsquo; preferences.</p>
<p>The data entry widget for these fields expects a date and is tolerant of not entering a year (which helps it support, er, &ldquo;polite&rdquo; birthdays). You can, in turn, use it somewhat opaquely in a Contacts smart list: There&rsquo;s a generic &ldquo;Date&rdquo; field you can filter on that looks at date fields in the card.  Paired with a &ldquo;within/not within,&rdquo; or &ldquo;in the next&rdquo; parameter, you can make a smart list of &ldquo;people not contacted in the past 30 days,&rdquo; etc.</p>
<p>If Contacts smart lists could also use groups, you could do a lot by just setting a &ldquo;last contacted&rdquo; date field and making a set of smart lists based on group membership. Contacts smart lists <em>can&rsquo;t</em> use groups, though, which is a strange oversight.</p>
<p>As I was trying to figure out, though, how to get my contacts uploaded to Monica in a way that would let me use its API to add tags to them once they were imported, I worked out some AppleScript that let me prepend a contact&rsquo;s group into its note as a hashtag. Contacts smart lists <em>can</em> filter on the contents of notes.</p>
<p>As a solution goes, it&rsquo;s in the category of &ldquo;cheap and cheerful.&rdquo; If you wanted to use macOS Contacts to keep track of your most recent touchpoint with someone, and drive a little automation to surface contacts you haven&rsquo;t reached out to in a while, you could do it with one custom field and adopting a simple convention for notes. You&rsquo;re also well into the territory of things AppleScript can do to help out, too: It is trivial to write scripts that automate logging, etc. or even write reminders or make events in a contacts calendar. In fact, here&rsquo;s a script that operates on the selected contact and lets you log activity in its note:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-applescript" data-lang="applescript"><span class="line"><span class="cl"><span class="k">set</span> <span class="nv">theDate</span> <span class="k">to</span> <span class="nb">current date</span>
</span></span><span class="line"><span class="cl"><span class="k">set</span> <span class="nv">noteDate</span> <span class="k">to</span> <span class="nb">do shell script</span> <span class="s2">&#34;date &#39;+%Y-%m-%d&#39;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">tell</span> <span class="nb">application</span> <span class="s2">&#34;Contacts&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">selectedPeople</span> <span class="k">to</span> <span class="nv">selection</span>
</span></span><span class="line"><span class="cl">	<span class="k">repeat</span> <span class="k">with</span> <span class="nv">thePerson</span> <span class="k">in</span> <span class="nv">selectedPeople</span>
</span></span><span class="line"><span class="cl">		<span class="k">set</span> <span class="nv">customDates</span> <span class="k">to</span> <span class="nv">custom</span> <span class="nv">dates</span> <span class="k">of</span> <span class="nv">thePerson</span>
</span></span><span class="line"><span class="cl">		<span class="k">set</span> <span class="nv">lastContactedExists</span> <span class="k">to</span> <span class="no">false</span>
</span></span><span class="line"><span class="cl">		<span class="k">repeat</span> <span class="k">with</span> <span class="nv">aCustomDate</span> <span class="k">in</span> <span class="nv">customDates</span>
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="na">label</span> <span class="k">of</span> <span class="nv">aCustomDate</span> <span class="ow">is</span> <span class="s2">&#34;last contacted&#34;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">				<span class="k">set</span> <span class="nv">value</span> <span class="k">of</span> <span class="nv">aCustomDate</span> <span class="k">to</span> <span class="nv">theDate</span>
</span></span><span class="line"><span class="cl">				<span class="k">set</span> <span class="nv">lastContactedExists</span> <span class="k">to</span> <span class="no">true</span>
</span></span><span class="line"><span class="cl">			<span class="k">end</span> <span class="k">if</span>
</span></span><span class="line"><span class="cl">		<span class="k">end</span> <span class="k">repeat</span>
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="ow">not</span> <span class="nv">lastContactedExists</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="nv">length</span> <span class="k">of</span> <span class="nv">customDates</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">				<span class="k">set</span> <span class="nv">firstCustomDate</span> <span class="k">to</span> <span class="nb">first</span> <span class="nb">item</span> <span class="k">of</span> <span class="nv">customDates</span>
</span></span><span class="line"><span class="cl">				<span class="k">set</span> <span class="nv">newCustomDate</span> <span class="k">to</span> <span class="nb">make</span> <span class="nb">new</span> <span class="nv">custom</span> <span class="nv">date</span> <span class="nb">at</span> <span class="nb">after</span> <span class="nv">firstCustomDate</span>
</span></span><span class="line"><span class="cl">			<span class="k">else</span>
</span></span><span class="line"><span class="cl">				<span class="nb">make</span> <span class="nb">new</span> <span class="nv">custom</span> <span class="nv">date</span> <span class="nb">at</span> <span class="k">end</span> <span class="k">of</span> <span class="nv">custom</span> <span class="nv">dates</span> <span class="k">of</span> <span class="nv">thePerson</span> <span class="k">with</span> <span class="na">properties</span> <span class="p">{</span><span class="na">label</span><span class="p">:</span><span class="s2">&#34;last contacted&#34;</span><span class="p">,</span> <span class="nv">value</span><span class="p">:</span><span class="nv">theDate</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">			<span class="k">end</span> <span class="k">if</span>
</span></span><span class="line"><span class="cl">		<span class="k">end</span> <span class="k">if</span>
</span></span><span class="line"><span class="cl">		<span class="k">set</span> <span class="nv">theNote</span> <span class="k">to</span> <span class="nv">note</span> <span class="k">of</span> <span class="nv">thePerson</span> <span class="k">as </span><span class="nc">string</span>
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="nv">theNote</span> <span class="ow">is</span> <span class="s2">&#34;missing value&#34;</span> <span class="k">then</span> <span class="k">set</span> <span class="nv">theNote</span> <span class="k">to</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="k">set</span> <span class="nv">prependText</span> <span class="k">to</span> <span class="na">text returned</span> <span class="k">of</span> <span class="p">(</span><span class="nb">display dialog</span> <span class="s2">&#34;Enter text to prepend to the note of &#34;</span> <span class="o">&amp;</span> <span class="na">name</span> <span class="k">of</span> <span class="nv">thePerson</span> <span class="o">&amp;</span> <span class="s2">&#34;:&#34;</span> <span class="nv">default</span> <span class="nv">answer</span> <span class="s2">&#34;&#34;</span> <span class="nb">buttons</span> <span class="p">{</span><span class="s2">&#34;Cancel&#34;</span><span class="p">,</span> <span class="s2">&#34;OK&#34;</span><span class="p">}</span> <span class="nv">default</span> <span class="nb">button</span> <span class="s2">&#34;OK&#34;</span> <span class="nv">cancel</span> <span class="nb">button</span> <span class="s2">&#34;Cancel&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="k">set</span> <span class="nv">noteUpdated</span> <span class="k">to</span> <span class="s2">&#34;[&#34;</span> <span class="o">&amp;</span> <span class="nv">noteDate</span> <span class="o">&amp;</span> <span class="s2">&#34;] &#34;</span> <span class="o">&amp;</span> <span class="nv">prependText</span>
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="nv">theNote</span> <span class="ow">is not</span> <span class="s2">&#34;&#34;</span> <span class="k">then</span> <span class="k">set</span> <span class="nv">noteUpdated</span> <span class="k">to</span> <span class="nv">noteUpdated</span> <span class="o">&amp;</span> <span class="no">return</span> <span class="o">&amp;</span> <span class="nv">theNote</span> <span class="o">&amp;</span> <span class="no">return</span> <span class="o">&amp;</span> <span class="s2">&#34; &#34;</span> <span class="o">&amp;</span> <span class="no">return</span>
</span></span><span class="line"><span class="cl">		<span class="k">set</span> <span class="nv">note</span> <span class="k">of</span> <span class="nv">thePerson</span> <span class="k">to</span> <span class="nv">noteUpdated</span>
</span></span><span class="line"><span class="cl">		<span class="nv">save</span> <span class="nv">thePerson</span>
</span></span><span class="line"><span class="cl">	<span class="k">end</span> <span class="k">repeat</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">tell</span></span></span></code></pre></div>
<p>So, looking at that, would you <em>want</em> to glue all this together with Applescript?</p>
<p>I don&rsquo;t think so. I don&rsquo;t, anyhow. It just took me a morning to figure that out.</p>
<p>In the process of roughing out automation for creating reminders, for instance, I managed to get Reminders.app to beachball on every run with a simple five-liner. Why? I don&rsquo;t know. Stack Overflow didn&rsquo;t know. But after a good 15 years of using AppleScript for jobs large and small, I know that sometimes you find its weird little corner cases and that&rsquo;s all there is to it. I&rsquo;d rather <a href="https://www.jwz.org/blog/2003/05/no-good-deed-goes-unpunished/">tell Jamie Zawinski that I don&rsquo;t know who the author of XScreensaver is</a> than ask Apple to fix it.</p>
<p>When I ask myself &ldquo;would I want to build something on top of this ecosystem that I mean to use forever?&rdquo; I can&rsquo;t even figure out three scripts I would need to write then get to the end of debugging the second one before I know the answer is &ldquo;no.&rdquo;</p>
<p>I mean, what does <em>forever</em> mean? Because my personal belief is that we have to assess the foreverness of the competing candidates, and probably think about how amenable data kept in the least forever of those formats is to being migrated to a more forever format/system:</p>
<ul>
<li>macOS Contacts</li>
<li>org-mode</li>
<li>vCard</li>
<li>plain text with moderately elaborate markup amenable to some automated processing</li>
</ul>
<p>(I put that list in ascending order of longevity/permanence, feeling very appreciative that org-mode allowed me to reorder it with <code>opt arrow</code>).</p>
<p>I trust macOS Contacts a bit. I don&rsquo;t how much money I would be willing to risk on a series of bets about it working as it does today in 2, 5, or 10 years. While trying to understand my AppleScript options with it I was brought face-to-face with changes to the underlying scripting model several times. In all fairness, those changes played out over decades and it&rsquo;s only because I&rsquo;m at a point in life where I can still think &ldquo;OS X is new&rdquo; that they even seem mentionable. It&rsquo;s also completely possible to get Contacts info out into some other format. There&rsquo;s also just the whole &ldquo;ramming your head against AppleScript&rdquo; aspect of the problem.</p>
<p>Moving up the Pyramid of Forever, I trust org-mode to be around for a very long time, but can also see how the API is still subject to change. Functions come and go so automation can break and make it hard to keep a contacts list maintained. On the other hand, I&rsquo;m not doing much now that couldn&rsquo;t be done by hand until I figured it out, and the things I&rsquo;ve bumped into are pretty small so far: changes in the namespace, functional replacements, etc.</p>
<p>Moving on:</p>
<p>I trust the vCard standard to stay how it is a bit more. It&rsquo;s on &hellip; version 3 or 4? &hellip; of the spec? There&rsquo;s a spec. There are a lot of stakeholders interested in that spec. Even Apple quietly crams a whole vCard property into each contact, even if it has its own version of each property you&rsquo;d find in a vCard anyhow.</p>
<p>So, moving on to the top of the pyramid:</p>
<p>I trust structured plain text to be useful for the rest of my life.</p>
<p>So something built on org-mode seems like the smart play for data longevity? Even if all my automation broke, core org-mode makes it easy to do the things I do: change todo states, add values to the <code>PROPERTIES</code> drawer, add tags, log changes, etc.</p>
<p>The one thing that I&rsquo;ve <em>mostly</em> decided not to worry about is the disconnect between my contacts list and my org-contacts file.</p>
<p>One useful feature of contacts via Fastmail is the dynamic &ldquo;Autosaved&rdquo; group. If I write someone, they go into that group. Periodically moving contacts that surface there into one of my permanent groups then removing them from &ldquo;Autosaved&rdquo; provides a simple, organic workflow for keeping up with new people. There is also a bunch of useful automation present in macOS/iOS for surfacing things about contacts from other apps, so you&rsquo;re constantly being offered the opportunity to pull in new information. This morning, for instance, going through my Contacts list, I noticed that something somewhere in the bowels of macOS or iOS was beginning to notice connections between my contacts and Ivory, the Mastodon client. That&rsquo;s pretty cool.</p>
<p>On the other hand, <em>this</em> is well within AppleScript&rsquo;s wheelhouse:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-applescript" data-lang="applescript"><span class="line"><span class="cl"><span class="k">tell</span> <span class="nb">application</span> <span class="s2">&#34;Contacts&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">selectedContacts</span> <span class="k">to</span> <span class="nv">selection</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span> <span class="nv">length</span> <span class="k">of</span> <span class="nv">selectedContacts</span> <span class="ow">is not</span> <span class="mi">1</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">		<span class="nb">display alert</span> <span class="s2">&#34;Please select exactly one contact.&#34;</span>
</span></span><span class="line"><span class="cl">		<span class="no">return</span>
</span></span><span class="line"><span class="cl">	<span class="k">end</span> <span class="k">if</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">theContact</span> <span class="k">to</span> <span class="nb">first</span> <span class="nb">item</span> <span class="k">of</span> <span class="nv">selectedContacts</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">theName</span> <span class="k">to</span> <span class="na">name</span> <span class="k">of</span> <span class="nv">theContact</span> <span class="k">as </span><span class="nc">text</span>
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">theEmails</span> <span class="k">to</span> <span class="nv">value</span> <span class="k">of</span> <span class="nv">emails</span> <span class="k">of</span> <span class="nv">theContact</span> <span class="k">as </span><span class="nc">text</span>
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">thePhones</span> <span class="k">to</span> <span class="nv">value</span> <span class="k">of</span> <span class="nv">phones</span> <span class="k">of</span> <span class="nv">theContact</span> <span class="k">as </span><span class="nc">text</span>
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">theNote</span> <span class="k">to</span> <span class="nv">note</span> <span class="k">of</span> <span class="nv">theContact</span> <span class="k">as </span><span class="nc">text</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">-- Format the contact data as an org contacts string</span>
</span></span><span class="line"><span class="cl">	<span class="k">set</span> <span class="nv">theContactString</span> <span class="k">to</span> <span class="s2">&#34;** &#34;</span> <span class="o">&amp;</span> <span class="nv">theName</span> <span class="o">&amp;</span> <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">:PROPERTIES:
</span></span></span><span class="line"><span class="cl"><span class="s2">:EMAIL: &#34;</span> <span class="o">&amp;</span> <span class="nv">theEmails</span> <span class="o">&amp;</span> <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">:PHONE: &#34;</span> <span class="o">&amp;</span> <span class="nv">thePhones</span> <span class="o">&amp;</span> <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">:NOTE: &#34;</span> <span class="o">&amp;</span> <span class="nv">theNote</span> <span class="o">&amp;</span> <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">:NAME: &#34;</span> <span class="o">&amp;</span> <span class="nv">theName</span> <span class="o">&amp;</span> <span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">:END:&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c">-- Copy the contact string to the clipboard</span>
</span></span><span class="line"><span class="cl">	<span class="nb">set the clipboard to</span> <span class="nv">theContactString</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">tell</span></span></span></code></pre></div>
<p>&ldquo;Look through new contacts, run that script from a keyboard shortcut, paste the new contact into my <code>contacts.org</code> file.&rdquo;</p>
<p>I could go one step further and <em>append</em> the text to my <code>contacts.org</code> file, but I don&rsquo;t like operating on busy files like that.</p>
<p>AppleScript was plainly built to do little things like that. You have to learn its sort of crabbed, verbose way of doing things, but it&rsquo;s not too hard (and Shortcuts is getting pretty good if you can deal with the sudden drop in functionality that can appear out of nowhere when you hit the limits of some Apple engineer&rsquo;s imagination or time).</p>
<p>Anyhow, it all just comes down to aesthetics and preferences, right?</p>
<p>I&rsquo;ve got a draft heading sitting in my blog.org file with a title of &ldquo;Plain text is calming.&rdquo; I&rsquo;m not sure where that little essay is going, but I know where it started: When I&rsquo;m staring at a text editor I feel much better than when I&rsquo;m staring at a web or app UI. I might have some challenges with discoverability, or a lack of forgiveness for little slips of the finger, or whatever. But I still feel better because I&rsquo;ve been a happy citizen of Plaintext Land for over 30 years, and there is a governing mentality there that does not exist in other parts of the technology world. I&rsquo;m not saying the <a href="https://www.puppet.com/docs/puppet/8/http_api/pson.html">occasional wheel doesn&rsquo;t get reinvented,</a> but I am saying that with most plaintext stuff you get to choose your tools, or make them for yourself if there are no good choices. So it&rsquo;s calming because I don&rsquo;t have that feeling of always looking for the exit when I encounter a plaintext system. I know it&rsquo;s there.  That&rsquo;s the preference, anyhow. I made money for a few years being really, really good at turning CMS databases into plaintext and massaging them into other CMSes, so my patience for finding the structure and working with it is high. I don&rsquo;t worry about where the exit is because in my 40-year history with computers, it has never eluded me in the plaintext world.</p>
<p>The aesthetics are another kettle of fish, and plaintext people run a weird gamut from &ldquo;text editors are like samurai swords&rdquo; to &ldquo;mastery of a plaintext interface is a kind of performance art.&rdquo; Right now I&rsquo;m sort of luxuriating in Evil mode, because I finally get the emphasis on ruthless elimination of motion vi engenders. I&rsquo;ve  <a href="/img/Joy04.pdf">made terrible fun of people over this in the distant past</a> and feel a little bad about that, but less than two months into this particular experiment, I don&rsquo;t want to go back. Evil mode is like the end of the first Star Trek movie as far as I&rsquo;m concerned.</p>
<figure><img src="/img/decker_ilia.gif"
    alt="Will Decker and Ilia merging into some sort of computer overmind in Star Trek: TMP">
</figure>

<p>Anyhow, I do want to get back to the whole &ldquo;plaintext is calming&rdquo; idea and do some more writing about it. Today&rsquo;s jaunt into &ldquo;what if I could make what I wanted in the macOS ecosystem?&rdquo; was one of those processes I go through when I&rsquo;ve gone so far with an idea and wonder if I really want to commit &ndash; if I&rsquo;m not making life a little harder on myself than I need to, or if there&rsquo;s not some simpler way to do it (even if still in the DIY mode,) and the answer came back &ldquo;don&rsquo;t think there is.&rdquo; I&rsquo;m at home in what I made.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-04-26</title>
      <link>https://mike.puddingtime.org/posts/2023-04-26-daily-notes/</link>
      <pubDate>Wed, 26 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-26-daily-notes/</guid>
      <description>A little on me and Zettelkasten, getting the TW200 out for spring.</description>
      <content:encoded><![CDATA[<h2 id="linking-and-the-thing-about-zettelkasten">Linking and the thing about zettelkasten</h2>
<p>Last year I went on a tear around personal knowledge management (PKM). It started with discovering Obsidian and really appreciating its out-of-the-box capabilities. I do think, if Emacs is just more than you can bear the thought of, that Obsidian is an excellent choice for the sort of text-as-organizing-data approach org-mode is simply best at.</p>
<p>That said, its fatal flaw is basically Markdown, which is not meant to bear the load of text as organizing data. You <em>can</em> use it that way, but after &hellip; two decades? &hellip; of Markdown, we are not conditioned to think of it that way, and any superset of the core emph/strong/link/image markup comes at the expense of its overall <em>feel</em>. I&rsquo;m not saying it <em>can&rsquo;t</em> bear more, I&rsquo;m saying that the more you add, especially when you start getting into multiple characters to do things like wedge in HTML or what&rsquo;s essentially XML, the more burdensome it becomes and the more unreadable your source text becomes.</p>
<p>Realistically, org-mode has a similar problem: To get the really good stuff out of it you are adding metadata at at least the heading level. The difference is that for the balance of its lifespan it has been like that, and its development is both enhanced and constrained by the fact that it is a creature of Emacs. There are affordances that can hide the worst of the clutter, and the inline formatting syntax is not much more verbose than Markdown when it is at all. Deciding to use org-mode is not a &ldquo;buy the ticket, take the ride&rdquo; proposition. You bought the ticket when you edited your init.el the first time, and org-mode is just part of the ride.</p>
<p>Anyhow, You can&rsquo;t really get into Obsidian without being exposed to the whole Zettelkasten thing.  It led me to Sönke Ahrens&rsquo; <em><a href="/posts/2022-02-13-currently-reading-how/">How to Take Smart Notes</a></em>, a small book about how to build a Zettelkasten system and what to do with it, and I found that book very compelling.</p>
<p>When I contextualize my reaction to it, I&rsquo;m going to own a few things up front:</p>
<ul>
<li>Like a lot of people, I was in the process of climbing out of a few years of lockdown, isolation, and anxiety. I had a certain kind of mental energy that was very inward-focused.</li>
<li>I had a strong sense that my job was not going to be long for this world, but was just beginning to get some traction on things that mattered to me, so that energy was searching for an outlet.</li>
<li>I had a few ideas for projects that I&rsquo;d shelved for a period, but I was beginning to think that I needed to get going on them as part of my preparation for either being displaced or hitting the job market.</li>
</ul>
<p>So I was primed for the Zettelkasten pitch.</p>
<p>But I&rsquo;ve also been a sort of tech/nerd-adjacent type for decades, and was around during the heyday of GTD, 43 Folders, &ldquo;lifehacks&rdquo; before &ldquo;lifehack&rdquo; meant &ldquo;refrigerate bologna and you won&rsquo;t get sick eating it!&rdquo; or &ldquo;don&rsquo;t run up the balance on your credit cards!&rdquo;, and all the other productivity manias that blew through. This is me in 2005:</p>
<blockquote>
<p>Sometimes I read a comment from someone who insists that his routine involves some insanely arcane and convoluted use of yarn and a special shell script he whipped up that reads crap down from his Backpack account and then squirts it into his Palm, makes a redundant backup on the server he maintains in Malaysia and produces printed 3x5 copies in triplicate, one of which he pins to his infant son&rsquo;s sleeve before leaving for the morning (&ldquo;If I died, I couldn&rsquo;t live with him thinking his father went out the door without an action list and a plan!&rdquo;).</p>
</blockquote>
<p>&hellip; and me again in 2007:</p>
<blockquote>
<p>While looking around for some info on &ldquo;Getting Things Done&rdquo; so I could share a summary, I came across:</p>
<p>&ldquo;Allen says his martial arts background helped him appreciate the value of eliminating distractions.</p>
<p>&ldquo;&lsquo;If four people jump out at you in a dark alley, you don&rsquo;t want to be thinking about two e-mails you haven&rsquo;t answered,&rsquo; he said.</p>
<p><em>Fending Off Four People - A Plan</em></p>
<p>@street, by alley</p>
<ul>
<li>run down street flapping arms and yelling for help (?) (save breath by not yelling?)</li>
<li>run into nearby store?  (make &ldquo;nearby store&rdquo; context?)</li>
<li>make Bruce Lee noises to see if that works then run? (split into two actions? or is that too much?)</li>
<li>prioritize possible ambush choices &hellip; by absolute order or relative priority?  (make note:  plan this ahead of time for future &ndash; someday)</li>
<li>make folder and list for &ldquo;@street&rdquo; context &hellip; hasn&rsquo;t come up before</li>
<li>muggers in @mugger agenda list or defer due to one-time nature of encounter?</li>
<li>followup &ndash; could I have run faster or yelled louder?</li>
</ul>
</blockquote>
<p>Basically, I guess, there is a part of me that reads these things as largely aspirational (which is fine), but also very hung up on the idea that we are one special system or weird trick away from realizing our greatness (perhaps naive, but also fine), and that once we&rsquo;ve mastered it we will finally become <em>productive</em> (which is fine(ish?) to the extent it means &ldquo;does enough work to keep job&rdquo; but is terrible when such a mushy word becomes a proxy for human worth).</p>
<p><em>How to Take Smart Notes</em> hits all those aspirational notes, recounting the remarkable tale of Niklas Luhmann and his astounding lifetime run of 60+ books and hundreds of articles. It&rsquo;s an inspiring story, and I&rsquo;m going to grant one point for sure: If one choice is to be inspired by a prolific academic who expanded the sum of human knowledge with his little slipbox, and <em>the other</em> choice is to be inspired by someone whose productivity system is self-evidently great because he has used it to organize a small empire of retail productivity enhancement books and accessories, I&rsquo;m goin&rsquo; with the perfesser over there.</p>
<p>So I tossed myself into Zettelkasten-via-Obsidian. I had a few things I wanted to work on, I had years of material in different formats that needed to be atomized, and I was reading two or three books a week, plus dozens of articles. Like I said, I had a <em>ton</em> of nervous energy to displace because a ten-year run was about to end, and the last time I&rsquo;d felt thrown out of the nest my comfort zone was &ldquo;crabby, introverted autodidact.&rdquo;</p>
<p>In the end, it just wasn&rsquo;t for me. I tried it, and Obsidian is an excellent tool for organizing your work that way, but I think the problem I had with it was that the ratio of &ldquo;volume of stuff that&rsquo;s just there in my head&rdquo; to &ldquo;volume of stuff I need to keep in a second brain&rdquo; didn&rsquo;t justify the existence of the second brain, or at least not one organized in classic Zettelkasten fashion. That&rsquo;s not to say I can hold every consideration of a writing project in my head. I benefit greatly, for instance, from the whole project notes thing that integrates magit and Projectile: I have an org-capture template that adds a note to a todo file in the top level of a given project (read: &ldquo;repo&rdquo;) linked to the parent heading. If I&rsquo;m out and about and think about something material to my writing project, I put it in my inbox. It&rsquo;s a vestige of GTD and the idea of a trusted system. I just don&rsquo;t think it will help me in a mugging, and the way I write, share experience, and organize my thinking isn&rsquo;t amenable to the atomicity of Zettelkasten.</p>
<p>Maybe I could have gotten there! I believe other people who say it helps them! I understand the gentle pull of tending a little digital garden! I just don&rsquo;t think <em>organizing knowledge</em> is my particular life struggle, and I do not think getting better at it will be a huge life enhancer.</p>
<p>So, all that said, I really appreciated <a href="https://taonaw-blog.netlify.app/2022-03-13/">this post (somewhat) about org-super-links</a>, which describes how you can get automatic back-linking into your org-mode headings. Even though Zettelkasten isn&rsquo;t for me, I did come to appreciate automatic back-linking in Obsidian (and my brief excursion into org-roam).</p>
<h2 id="spring-is-here-so-time-to-take-lou-out">Spring is here, so time to take Lou out</h2>
<figure><img src="/img/tw200.jpg"
    alt="A Yamaha TW200 parked in front of a suspension bridge on a sunny day."><figcaption>
      <h4>Lou at Sauvie Island</h4>
    </figcaption>
</figure>

<p>&ldquo;Lou&rdquo; is my Yamaha TW200, a little farm bike I bought as a compromise between the tiny and &ldquo;bounce it between your thighs at stop  lights&rdquo; Honda Grom and the bulkier, vaguely miserable Royal Enfield Himalayan 400. &ldquo;Vaguely miserable&rdquo; because mine was a victim of a bunch of factory QA problems that left me feeling like I could never really trust it during break-in.</p>
<p>It is meaningful to me that when the tender cable for my Grom came undone and I didn&rsquo;t notice it for six months the Grom had so little in the way of parasitic drain that the battery still had life when I got back to it. The Himalayan? It needs to be on a tender 24/7, and never off one and parked for more than maaaaaybe two weeks at a time. It&rsquo;s just like that, and who knows, and the dealer I bought it from shook the whole issue off with &ldquo;that&rsquo;s how this price point is,&rdquo; which helped me clarify why a Harley dealer was selling Indian-made motorcycles to begin with: You walk in, run over to that Harley, surreptitiously glance at the price tag, realize you&rsquo;re in over your head but cannot abide the thought of not riding your new bike off the lot on that particular sunny Saturday afternoon, so maybe that Royal Enfield that looks sort of classic will do the trick, for about as much as the down-payment on your Harley was gonna be.</p>
<p>I mean, I went in <em>wanting</em> to buy mine up front. I&rsquo;d read good reviews, liked the looks, and wanted something of about that displacement and size. The QA stuff, though, is miserable. It took two goes just to figure out that the bleed lines from the fuel tank were tied too tightly to the frame, creating a vacuum that constantly caused stalls. The dealership was plainly sick of my face before I could even get 500 miles on it, and it lives in this weird space where it is too big and not powerful enough. If anyone asked me today, and if they were not interested in the &ldquo;adventure&rdquo; pedigree, I&rsquo;d tell them anything but an RE Himalayan. A Rebel 300 would probably out-perform it, and my TW200, at half the displacement, comes pretty close without having to wrestle the bulk.</p>
<p>Anyhow, Lou is my Yamaha TW200 and I love it. Fat tires, low-slung, pleasant, low rumble. It is simple and sturdy and it is the perfect bike for SE Portland&rsquo;s pothole alleys and torn-up 82nd Ave. It goes just enough to hold its own for a ride up to Sauvie Island or maybe the back way out to Estacada. It&rsquo;s a great in-city commuter.</p>
<p>This week it was finally warm enough and dry enough to start Lou up for the first time this spring.</p>
<p>TW200&rsquo;s (t-dubs) are notoriously cold-blooded, so it didn&rsquo;t want to go. I dumped some fuel treatment in and shot some starter spray in its intake and it turned over. I let it sit on high choke for a while, then turned it off, rinsed, repeated an hour later and then took it up the side of Mt. Scott.  It was still sounding a tiny bit uneven while it ran the old fuel through, but the two runs since it has sounded smooth and healthy, and it turns over right away.</p>
<p>I love it.</p>
<p>Al&rsquo;s still up in the air about finishing up her motorcycle endorsement, so we have the TW200 and the Grom sitting here. If she decides nothing doing on motorcycling, I&rsquo;ll find the Grom a home and consider something that can handle two-up a little more gracefully. We enjoy summer date nights on a motorcycle, and the TW200 isn&rsquo;t quite up to that.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Extending the plaintext CRM to mail contacts</title>
      <link>https://mike.puddingtime.org/posts/2023-04-18-extending-the-plaintext-crm-to-mail-contacts/</link>
      <pubDate>Tue, 18 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-18-extending-the-plaintext-crm-to-mail-contacts/</guid>
      <description>Added a little automation to contacts.org with a function that auto-populates a message buffer in mu4e.</description>
      <content:encoded><![CDATA[<p>I did some menu cleanup and refactor today to get my plaintext CRM into a slightly more mnemonic state. Here are the mappings, which are readable enough:</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">map!</span> <span class="nb">:mode</span> <span class="nv">org</span>
</span></span><span class="line"><span class="cl">      <span class="nb">:leader</span>
</span></span><span class="line"><span class="cl">     <span class="p">(</span><span class="nb">:prefix-map</span> <span class="p">(</span><span class="s">&#34;C&#34;</span> <span class="o">.</span> <span class="s">&#34;CRM&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;Schedule Contact&#34;</span> <span class="s">&#34;s&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-schedule-heading</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;Clear TODO states&#34;</span> <span class="s">&#34;z&#34;</span> <span class="nf">#&#39;</span><span class="nv">my/org-remove-todo</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;Update CONTACTED to today&#34;</span> <span class="s">&#34;t&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-set-contacted-today</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;Update CONTACTED to ...&#34;</span> <span class="s">&#34;d&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-set-contacted-date</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;SCHEDULE a date&#34;</span> <span class="s">&#34;S&#34;</span> <span class="nf">#&#39;</span><span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">my/org-set-heading-state-and-time</span> <span class="s">&#34;&#34;</span> <span class="mi">30</span> <span class="ss">&#39;s</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;Mail this contact&#34;</span> <span class="s">&#34;m&#34;</span> <span class="nf">#&#39;</span><span class="nv">my-org-contacts-email</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">     <span class="p">(</span><span class="nb">:prefix-map</span> <span class="p">(</span><span class="s">&#34;C r&#34;</span><span class="o">.</span> <span class="s">&#34;Remember to ...&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">       <span class="nb">:desc</span> <span class="s">&#34;... write within 7 days&#34;</span> <span class="s">&#34;w&#34;</span> <span class="nf">#&#39;</span><span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">my/org-set-heading-state-and-time</span> <span class="s">&#34;WRITE&#34;</span> <span class="mi">7</span> <span class="ss">&#39;d</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">       <span class="nb">:desc</span> <span class="s">&#34;... followup in 3 days&#34;</span> <span class="s">&#34;f&#34;</span> <span class="nf">#&#39;</span><span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">my/org-set-heading-state-and-time</span> <span class="s">&#34;FOLLOWUP&#34;</span> <span class="mi">3</span> <span class="ss">&#39;s</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">       <span class="nb">:desc</span> <span class="s">&#34;... ping within 7 days&#34;</span> <span class="s">&#34;p&#34;</span> <span class="nf">#&#39;</span><span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">my/org-set-heading-state-and-time</span> <span class="s">&#34;PING&#34;</span> <span class="mi">3</span> <span class="ss">&#39;d</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">       <span class="nb">:desc</span> <span class="s">&#34;... invite within 3 days&#34;</span> <span class="s">&#34;i&#34;</span> <span class="nf">#&#39;</span><span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span> <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span> <span class="p">(</span><span class="nv">my/org-set-heading-state-and-time</span> <span class="s">&#34;INVITE&#34;</span> <span class="mi">3</span> <span class="ss">&#39;d</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre></div>
<p>It&rsquo;s a bunch of &ldquo;tap the leader key, tap &ldquo;<code>C</code>&rdquo; for &ldquo;CRM,&rdquo; then do some common stuff,&rdquo; like setting deadlines to write someone, or update the <code>:CONTACTED:</code> property, or just set the <code>SCHEDULED:</code> date on a record. This is the <code>my/org-set-heading-state-and-time</code> function:</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="nb">defun</span> <span class="nv">my/org-set-heading-state-and-time</span> <span class="p">(</span><span class="nv">state</span> <span class="nv">days</span> <span class="kp">&amp;optional</span> <span class="nv">time-type</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Sets the TODO state and deadline or scheduled date of the current heading.
</span></span></span><span class="line"><span class="cl"><span class="s">   STATE is the new TODO state to set, and DAYS is the number
</span></span></span><span class="line"><span class="cl"><span class="s">   of days from the current date to set the new time. If TIME-TYPE
</span></span></span><span class="line"><span class="cl"><span class="s">   is &#39;d&#39;, sets a deadline; if &#39;s&#39;, sets a scheduled date; otherwise,
</span></span></span><span class="line"><span class="cl"><span class="s">   prompts the user for the time type. Removes any existing schedules
</span></span></span><span class="line"><span class="cl"><span class="s">   or deadlines before setting the new time.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span> <span class="p">(</span><span class="nf">list</span> <span class="s">&#34;WRITE&#34;</span> <span class="mi">7</span> <span class="no">nil</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">org-entry-put</span> <span class="no">nil</span> <span class="s">&#34;TODO&#34;</span> <span class="nv">state</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="no">nil</span> <span class="s">&#34;DEADLINE&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">org-entry-delete</span> <span class="no">nil</span> <span class="s">&#34;DEADLINE&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="no">nil</span> <span class="s">&#34;SCHEDULED&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">org-entry-delete</span> <span class="no">nil</span> <span class="s">&#34;SCHEDULED&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">new-time</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;&lt;%Y-%m-%d %a&gt;&#34;</span>
</span></span><span class="line"><span class="cl">                                      <span class="p">(</span><span class="nf">time-add</span> <span class="p">(</span><span class="nf">current-time</span><span class="p">)</span> <span class="p">(</span><span class="nv">days-to-time</span> <span class="nv">days</span><span class="p">)))))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">cond</span> <span class="p">((</span><span class="nf">equal</span> <span class="nv">time-type</span> <span class="ss">&#39;d</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">           <span class="p">(</span><span class="nv">org-deadline</span> <span class="no">nil</span> <span class="nv">new-time</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">          <span class="p">((</span><span class="nf">equal</span> <span class="nv">time-type</span> <span class="ss">&#39;s</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">           <span class="p">(</span><span class="nv">org-schedule</span> <span class="no">nil</span> <span class="nv">new-time</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="no">t</span>
</span></span><span class="line"><span class="cl">           <span class="p">(</span><span class="nb">setq</span> <span class="nv">time-type</span> <span class="p">(</span><span class="nf">completing-read</span> <span class="s">&#34;Set time type (d/s): &#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">           <span class="p">(</span><span class="nv">my/org-set-heading-state-and-time</span> <span class="nv">state</span> <span class="nv">days</span> <span class="p">(</span><span class="nb">if</span> <span class="p">(</span><span class="nv">string=</span> <span class="nv">time-type</span> <span class="s">&#34;d&#34;</span><span class="p">)</span> <span class="ss">&#39;d</span> <span class="ss">&#39;s</span><span class="p">))))))</span></span></span></code></pre></div>
<p>It&rsquo;s written with the menu system in mind. It&rsquo;d be too clunky to use interactively &ndash; too many possible states to remember, etc. but as part of a bunch of canned menu options you can get to with one or two taps it saves a bunch of typing and cursor motion for common operations.</p>
<p>Then I thought, &ldquo;it&rsquo;d be handy to just visit a record and have an option to compose a mail,&rdquo; so <code>my-org-contacts-email</code> was born:</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="nb">defun</span> <span class="nv">my-org-contacts-email</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Open am email message to the email address in the EMAIL property of the current org-contacts heading.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nf">eq</span> <span class="nv">major-mode</span> <span class="ss">&#39;org-mode</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">email</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="p">(</span><span class="nf">point</span><span class="p">)</span> <span class="s">&#34;EMAIL&#34;</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nb">if</span> <span class="nv">email</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nb">progn</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nb">featurep</span> <span class="ss">&#39;mu4e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">(</span><span class="nv">mu4e</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">mu4e-compose-new</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">message-goto-to</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nf">insert</span> <span class="nv">email</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">message-goto-body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nf">insert</span> <span class="s">&#34;\n\n&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nf">message</span> <span class="s">&#34;No email address found.&#34;</span><span class="p">)))))</span></span></span></code></pre></div>
<p>It has some behavioral issues I need to straighten out, but if mu4e is running and I tap <code>SPC C m</code> while positioned over a contact, it opens and pre-addresses a new message in mu4e.</p>
<p>I think it&rsquo;s beyond the ken of <code>org-caldav</code>, but I suppose a call out to AppleScript could create similar functionality for scheduling things with a contact.</p>
<p>I really like the Doom menu system (and I suppose I&rsquo;d like Spacemacs&rsquo; as well). The last time I was all-in on org mode I had so much trouble with all the Emacs chords that I ended up setting up <a href="https://gitlab.com/phillord/org-drill/">org-drill</a> to periodically train. With Doom&rsquo;s menus, there are decent mnemonics up front, then visual reminders along the way. It still takes time to learn everything, but you get reminders and you can stop to study the menu if you forget. I don&rsquo;t know how many times I have mashed <code>CTRL g</code> when I lost track of my fingers during a complex vanilla Emacs sequence.</p>
]]></content:encoded>
    </item>
    <item>
      <title>An org-contacts source for lbdb</title>
      <link>https://mike.puddingtime.org/posts/2023-04-16-an-org-contacts-source-for-lbdb/</link>
      <pubDate>Sun, 16 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-16-an-org-contacts-source-for-lbdb/</guid>
      <description>I modified a Perl lbdb backend by ‪@publicvoit@graz.social ‬to use my org-contacts with mutt</description>
      <content:encoded><![CDATA[<p>This is a ruby-based back-end for <a href="https://www.spinnaker.de/lbdb/">The Little Brother&rsquo;s Database (lbdb)</a> that looks at a hard-coded <code>org-contacts</code> file. The idea comes from <a href="https://lists.gnu.org/archive/html/emacs-orgmode/2011-10/msg01059.html">a 2011 Perl implementation by Karl Voit</a>. Because I am not a Perl person, when it didn&rsquo;t work out of the box I converted it to Ruby.</p>
<p>And because I&rsquo;ve chosen to treat org-contacts as <code>TODO</code> items for purposes of remembering who to <code>PING</code>, <code>FOLLOWUP</code>, <code>SKED</code>, etc. it has to take the extra step of stripping those keywords from the returned name. Otherwise, my mails to Joe Grudd would be addressed to <code>FOLLOWUP Joe Grudd</code>.</p>
<p>That&rsquo;s a small bit of inelegance in my plaintext CRM setup:  As I&rsquo;ve figured out more about how <code>org-super-agenda</code> works, I&rsquo;ve had glimpses of how the plaintext CRM metadata could just be content in the <code>:PROPERTIES:</code> drawer, and hence invisible for purposes of tools like this, but a few other pieces of passive automation would have to become some sort of org-mode hook and I&rsquo;d lose the utility of tools like Beorg, which can&rsquo;t provide the automation of native Emacs.</p>
<p>For now, it&rsquo;s one of those &ldquo;this design isn&rsquo;t the cleanest, but it&rsquo;s simple and only creates a few easily solved problems&rdquo; things.</p>
<p>Here&rsquo;s the script itself. I put it in <code>~/bin</code> as <code>orgcontact.rb</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="c1"># Get the query string</span>
</span></span><span class="line"><span class="cl"><span class="n">query</span> <span class="o">=</span> <span class="no">ARGV</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set the path to your Org-contacts file</span>
</span></span><span class="line"><span class="cl"><span class="n">orgmodefile</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;HOME&#39;</span><span class="o">]</span><span class="si">}</span><span class="s2">/org/contacts.org&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Read in the whole contact file</span>
</span></span><span class="line"><span class="cl"><span class="n">raw_contacts</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">orgmodefile</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;</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="c1"># Iterate through each contact</span>
</span></span><span class="line"><span class="cl"><span class="n">raw_contacts</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">contact</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="n">contact</span><span class="o">.</span><span class="n">match?</span><span class="p">(</span><span class="sr">/</span><span class="si">#{</span><span class="n">query</span><span class="si">}</span><span class="sr">/i</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Extract the name and email from the contact</span>
</span></span><span class="line"><span class="cl">    <span class="nb">name</span> <span class="o">=</span> <span class="n">contact</span><span class="o">[</span><span class="sr">/^[^\n]*/</span><span class="o">].</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/(PING|INVITE|WRITE|PINGED|FOLLOWUP|SKED|NOTES|SCHEDULED|TIMEOUT|OK)\s+/i</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span>
</span></span><span class="line"><span class="cl">    <span class="n">email</span> <span class="o">=</span> <span class="n">contact</span><span class="o">[</span><span class="sr">/:EMAIL:\s+(.*)$/</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Remove tags from the name</span>
</span></span><span class="line"><span class="cl">    <span class="nb">name</span><span class="o">.</span><span class="n">gsub!</span><span class="p">(</span><span class="sr">/:\S+:/</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">puts</span> <span class="s2">&#34;</span><span class="si">#{</span><span class="n">email</span><span class="si">}</span><span class="se">\t</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="se">\t</span><span class="s2">(org-contacts)&#34;</span> <span class="k">if</span> <span class="nb">name</span> <span class="o">&amp;&amp;</span> <span class="n">email</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span></span></span></code></pre></div>
<p>Adding <code>m_org_contacts</code> to the <code>METHODS</code> setting then including a little wrapper in <code>~/.lbdbrc</code> doesn&rsquo;t follow the canonical advice on how to configure an lbdb backend, but it works, and it&rsquo;s one less file to put somewhere:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">METHODS=&#34;m_osx_addressbook m_org_contacts&#34;
</span></span><span class="line"><span class="cl">MODULES_PATH=&#34;$MODULES_PATH $HOME/bin/lbdb&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">m_org_contacts_query() {
</span></span><span class="line"><span class="cl">   ~/bin/orgcontact.rb &#34;$1&#34;
</span></span><span class="line"><span class="cl">}</span></span></code></pre></div>
<p>So, the outcome is just:</p>
<ol>
<li>
<p>Start a new message in mutt and start typing the name/address/etc.</p>
</li>
<li>
<p>lbdb provides a list of matches from a few sources I&rsquo;ve set up: org-contacts and macOS address book</p>
</li>
<li>
<p><code>ENTER</code> to select a candidate</p>
<p>b</p>
</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>Making a plaintext personal CRM with org-contacts</title>
      <link>https://mike.puddingtime.org/posts/2023-04-13-making-a-plaintext-personal-crm-with-org-contacts/</link>
      <pubDate>Thu, 13 Apr 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-13-making-a-plaintext-personal-crm-with-org-contacts/</guid>
      <description>I don&amp;rsquo;t like the looks of any of the personal CRM software out there, so I&amp;rsquo;m making a plaintext one.</description>
      <content:encoded><![CDATA[<p>This morning Al and I took our coffee walk, but she had to hop on a call, so for the two-mile walk back home I had some time to think about the habit on my list that popped up today: <code>Social Maintenance</code> and I also happen to have, for assorted reasons, a massive amount of poorly directed nervous energy. I am scattered and my thoughts are darting all over the place, and there&rsquo;s enough jittery energy built up  that the thought of cycling through a bunch of &ldquo;what if I try <em>this</em>&rdquo; stuff is sort of comforting.</p>
<p>I started trying to cultivate a social maintenance habit with the thought in mind that I had no idea what I was really thinking, just that during this current period it is important to me to keep up social contact in ways large and small. Pretty soon thereafter I realized I had an organizational problem on my hands: My address books were kind of a mess. Not very well organized, old data, a ton of contacts with old work addresses, etc. I spent a day straightening that out and got to a place of mostly clean.</p>
<p>The next problem that presented itself was that &ldquo;personal CRM&rdquo; is just an  awful software category. Whenever I see a new contact management app, I think &ldquo;oh, this is surely the one that will let you do something with your existing information, or add useful information,&rdquo; but it never seems to be. The more competent looking entries in the market cost a lot. Searching yields a lot of &ldquo;make one in Trello,&rdquo; &ldquo;make one in Notion,&rdquo; etc.</p>
<p>I just stopped thinking about it and decided &ldquo;do it off the top of your head until something comes up for you.&rdquo;</p>
<p>So this morning, Al was on her call, and I had a <code>Social Maintenance</code> habit popping up on my agenda as a thing I was supposed to do today, and I&rsquo;d been reading about <code>org-contacts</code>, <code>org-vcard</code>, and the ways they can integrate with an org-mode agenda to show birthdays or other anniversaries. By a few blocks later I&rsquo;d thought of how I might wedge CRM-like data into that system with org <code>:PROPERTIES:</code> drawers:</p>
<ul>
<li>desired frequency</li>
<li>date last contacted</li>
<li>notes on the last contact</li>
</ul>
<p>This is all stuff you could do in a spreadsheet, and I think a lot of people do it that way. I have an aversion to spreadsheet applications, though.</p>
<p>By the time we were home, I had the beginnings of a plan: Export my macOS address book to a big vcard file, use <code>org-vcard</code> to import it into a contacts file, then start figuring out the mechanics of adding the fields I needed to drive org agenda views.</p>
<h2 id="getting-my-contacts-into-org-contacts">Getting my contacts into org-contacts</h2>
<p>There&rsquo;s an <code>org-vcard</code> package that theoretically handles the process of moving a vcard file into an org file. The maintainer has announced that they&rsquo;re not going to work on it any longer, and it seems to have problems with macOS Contacts output.</p>
<p>I put together a script (well, ChatGPT and I put together a script) that parses a VCF file and dumps the contacts out into the right format. I just cat&rsquo;d its output into the right file. It is probably best described as a menace to your data. I had so recently scrubbed my contacts that I trusted it enough.</p>
<p>An org-contacts record looks like this:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">\* Joe Grudd :social:
</span></span><span class="line"><span class="cl">:PROPERTIES:
</span></span><span class="line"><span class="cl">:EMAIL: joe@grudd.com
</span></span><span class="line"><span class="cl">:WEBSITE: http://joe.grudd.com
</span></span><span class="line"><span class="cl">:CONTACTED: 2023-04-12
</span></span><span class="line"><span class="cl">:END:</span></span></code></pre></div>
<p>There are a few other fields, like birthday and physical address, too.</p>
<p>On its own, it doesn&rsquo;t do a ton. You can add notes to a :NOTES: property if you like, and you can search the entire file with an <code>org-contacts</code> command that lists results instead of just doing a normal text search operation.</p>
<h2 id="tracking-contact-information">Tracking contact information</h2>
<p>There are a few ways I thought of to come at what I wanted to do, which amounted to:</p>
<ul>
<li>
<p>Keeping track of whom I&rsquo;ve had contact with</p>
</li>
<li>
<p>Keeping track of when I last had contact with someone</p>
</li>
<li>
<p>Keeping track of useful details about people</p>
</li>
<li>
<p>Surfacing people I haven&rsquo;t seen in a while</p>
<p>The <code>NOTES</code> property in a vcard record is fine, but org-mode provides a way to add a log to each record in its own drawer, which changes the record to look like this:</p>
</li>
</ul>
<!--listend-->






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-org" data-lang="org"><span class="line"><span class="cl">\* Joe Grudd :social:
</span></span><span class="line"><span class="cl"><span class="c">:PROPERTIES:
</span></span></span><span class="line"><span class="cl"><span class="cs">:EMAIL: joe@grudd.com
</span></span></span><span class="line"><span class="cl"><span class="cs">:WEBSITE: http://joe.grudd.com
</span></span></span><span class="line"><span class="cl"><span class="cs">:CONTACTED: 2023-04-12
</span></span></span><span class="line"><span class="cl"><span class="c">:END:</span>
</span></span><span class="line"><span class="cl"><span class="c">:LOGBOOK:
</span></span></span><span class="line"><span class="cl"><span class="cs">  - Note taken on [2023-04-12 Wed 11:16] \\
</span></span></span><span class="line"><span class="cl"><span class="cs">    Caught up over IM for the first time in a while. He&#39;s moving to California next month.
</span></span></span><span class="line"><span class="cl"><span class="c">  :END:</span></span></span></code></pre></div>
<p>org-mode pretties all this stuff up, so the <code>LOGBOOK</code> and <code>PROPERTIES</code> drawers aren&rsquo;t always visible.</p>
<p>I also added the <code>CONTACTED</code> field to <code>PROPERTIES</code>. It&rsquo;s just an ISO-8601 date meant to reflect the last time I had some kind of contact, even if it&rsquo;s just a ping.</p>
<p>So at this point, I could just use this as is and it&rsquo;d be no worse than a spreadsheet.</p>
<h2 id="automating-updates">Automating updates</h2>
<p>I wanted a way to quickly note a contact &ldquo;touch&rdquo; so I made a few functions for that:</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="nb">defun</span> <span class="nv">org-set-contacted-today</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Set the CONTACTED property of the current item to today&#39;s date.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">org-set-property</span> <span class="s">&#34;CONTACTED&#34;</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;%Y-%m-%d&#34;</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="nb">defun</span> <span class="nv">org-set-contacted-date</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;Set the CONTACTED property of the current item to a chosen date.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">date</span> <span class="p">(</span><span class="nv">org-read-date</span> <span class="no">nil</span> <span class="no">t</span> <span class="no">nil</span> <span class="s">&#34;Enter the date: &#34;</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">org-set-property</span> <span class="s">&#34;CONTACTED&#34;</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;%Y-%m-%d&#34;</span> <span class="nv">date</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">map!</span> <span class="nb">:mode</span> <span class="nv">org-mode</span>
</span></span><span class="line"><span class="cl">      <span class="nb">:localleader</span>
</span></span><span class="line"><span class="cl">      <span class="nb">:desc</span> <span class="s">&#34;Set CONTACTED property to today&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="s">&#34;c t&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-set-contacted-today</span>
</span></span><span class="line"><span class="cl">      <span class="s">&#34;c d&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-set-contacted-date</span>
</span></span><span class="line"><span class="cl">      <span class="s">&#34;c z&#34;</span> <span class="nf">#&#39;</span><span class="nv">my/org-remove-todo</span>
</span></span><span class="line"><span class="cl">                <span class="p">)</span></span></span></code></pre></div>
<p>Those two allow me to set the <code>CONTACTED</code> property either to today&rsquo;s date (<code>spc m c t</code>), or by interactively selecting a date (<code>spc m c d</code>). There&rsquo;s a third mapping that lets me z out the TODO status of a contact (<code>spc m c z</code>), which I will get to.</p>
<h2 id="agenda-customization">Agenda customization</h2>
<p>Next up, I wanted some kind of agenda automation &ndash; custom views that&rsquo;d let me see contacts overdue for some kind of ping. I made a few driven by a combination of tags and age of the <code>CONTACTED</code> field.</p>
<p>Here&rsquo;s one of them, driven by a function that finds aged contacts:</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">add-to-list</span> <span class="ss">&#39;org-agenda-custom-commands</span>
</span></span><span class="line"><span class="cl">             <span class="o">&#39;</span><span class="p">(</span><span class="s">&#34;N&#34;</span> <span class="s">&#34;Professional network last contacted &gt; 90 days ago&#34;</span>
</span></span><span class="line"><span class="cl">               <span class="p">((</span><span class="nv">tags</span> <span class="s">&#34;network&#34;</span>
</span></span><span class="line"><span class="cl">                      <span class="p">((</span><span class="nv">org-agenda-overriding-header</span> <span class="s">&#34;Network contacts, not contacted in the past 90 days&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                       <span class="p">(</span><span class="nv">org-tags-match-list-sublevels</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                       <span class="p">(</span><span class="nv">org-agenda-skip-function</span>
</span></span><span class="line"><span class="cl">                        <span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">                          <span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nv">org-contacted-more-than-days-ago</span> <span class="mi">90</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">(</span><span class="nb">or</span> <span class="p">(</span><span class="nv">outline-next-heading</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                <span class="p">(</span><span class="nf">goto-char</span> <span class="p">(</span><span class="nf">point-max</span><span class="p">))))))))</span>
</span></span><span class="line"><span class="cl">                <span class="p">)))</span></span></span></code></pre></div>
<p>So in Doom, I can tap <code>spc oAN</code> and get a list of contacts tagged with <code>network</code> whom I haven&rsquo;t had any contact with for more than 90 days.</p>
<h2 id="setting-priority-by-touch-date">Setting priority by touch date</h2>
<p>I wanted a way to see which contacts were aging and decided to use plain old priorities for that, so a function looks at the difference between today and <code>CONTACTED</code> and prioritizes more aged contacts higher:</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></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">my/org-update-priorities-based-on-contacted</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">save-excursion</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nf">goto-char</span> <span class="p">(</span><span class="nf">point-min</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nb">while</span> <span class="p">(</span><span class="nf">re-search-forward</span> <span class="s">&#34;^\\*+ &#34;</span> <span class="no">nil</span> <span class="no">t</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">contacted-date</span> <span class="p">(</span><span class="nv">org-entry-get</span> <span class="p">(</span><span class="nf">point</span><span class="p">)</span> <span class="s">&#34;CONTACTED&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">today</span> <span class="p">(</span><span class="nf">format-time-string</span> <span class="s">&#34;%Y-%m-%d&#34;</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nb">when</span> <span class="nv">contacted-date</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nb">let</span> <span class="p">((</span><span class="nv">days-ago</span> <span class="p">(</span><span class="nf">-</span> <span class="p">(</span><span class="nv">time-to-days</span> <span class="p">(</span><span class="nf">current-time</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">                             <span class="p">(</span><span class="nv">time-to-days</span> <span class="p">(</span><span class="nv">org-time-string-to-time</span> <span class="nv">contacted-date</span><span class="p">)))))</span> <span class="c1">; calculate days since CONTACTED date</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">org-set-property</span> <span class="s">&#34;PRIORITY&#34;</span>
</span></span><span class="line"><span class="cl">                               <span class="p">(</span><span class="nb">cond</span>
</span></span><span class="line"><span class="cl">                                <span class="p">((</span><span class="nf">&lt;</span> <span class="nv">days-ago</span> <span class="mi">45</span><span class="p">)</span> <span class="s">&#34;C&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                <span class="p">((</span><span class="nf">&lt;</span> <span class="nv">days-ago</span> <span class="mi">90</span><span class="p">)</span> <span class="s">&#34;B&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                <span class="p">(</span><span class="no">t</span> <span class="s">&#34;A&#34;</span><span class="p">)))))))))</span></span></span></code></pre></div>
<p>It&rsquo;s connected to a save hook, so every contact&rsquo;s priority gets recalculated at save:</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></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">&#39;after-save-hook</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nb">lambda</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nf">string-equal</span> <span class="p">(</span><span class="nf">buffer-file-name</span><span class="p">)</span> <span class="s">&#34;~/org/contacts.org&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">(</span><span class="nv">my/org-update-priorities-based-on-contacted</span> <span class="p">))))</span></span></span></code></pre></div>
<p>That prioritization shows up in the agenda views I set up, with <code>[A]</code> priority contacts getting their own section.</p>
<h2 id="custom-todo-states">Custom TODO states</h2>
<p>Finally, I wanted a way to keep track of where a given contact is, or cue myself on next steps, so I set up custom TODO states just for my <code>contacts.org</code> file:</p>
<p><code>#+TODO: PING(p) PINGED(P!) FOLLOWUP(f) SKED(s) | TIMEOUT(t) OK(o)</code></p>
<p>By putting a <code>!</code> inside the shortcut parens, org-mode will automatically log changes in and out of those states. For now I just have <code>PINGED</code> wired up that way, and <code>TIMEOUT</code> and <code>OK</code>, as <code>DONE</code> equivalents will similarly trigger a log entry.</p>
<p><code>FOLLOWUP</code> and <code>SKED</code> are there as reminders that I need to do something next. <code>TIMEOUT</code> is a way to tell myself I gave it a shot and nothing came of it. <code>OK</code> is just an interim state on the way to no state until the agenda surfaces someone again.</p>
<p>The logging for these state changes looks like this in a given contact entry:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-org" data-lang="org"><span class="line"><span class="cl">\* PINGED Joe Grudd :social:
</span></span><span class="line"><span class="cl"><span class="c">:PROPERTIES:
</span></span></span><span class="line"><span class="cl"><span class="cs">:EMAIL: joe@grudd.com
</span></span></span><span class="line"><span class="cl"><span class="cs">:WEBSITE: http://joe.grudd.com
</span></span></span><span class="line"><span class="cl"><span class="cs">:CONTACTED: 2023-04-12
</span></span></span><span class="line"><span class="cl"><span class="c">:END:</span>
</span></span><span class="line"><span class="cl"><span class="c">:LOGBOOK:
</span></span></span><span class="line"><span class="cl"><span class="cs">- State &#34;PINGED&#34;     from &#34;PING&#34;   [2023-04-11 Tue 20:21]
</span></span></span><span class="line"><span class="cl"><span class="cs">- Note taken on [2023-04-12 Wed 11:16] \\
</span></span></span><span class="line"><span class="cl"><span class="cs">  Caught up over text for the first time in a while. He&#39;s moving to California next month.
</span></span></span><span class="line"><span class="cl"><span class="c">:END:</span></span></span></code></pre></div>
<p>This is also where that last &ldquo;z&rdquo; keybinding comes in:</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="nb">defun</span> <span class="nv">my/org-remove-todo</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nb">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">org-set-property</span> <span class="s">&#34;TODO&#34;</span> <span class="s">&#34;&#34;</span><span class="p">))</span></span></span></code></pre></div>
<p>With <code>spc m c z</code> I can zero out the TODO state of a given contact without triggering a log entry, keeping a little bit of noise down.</p>
<h2 id="what-else">What else?</h2>
<p>That&rsquo;s the system. I guess the summary is:</p>
<p>&ldquo;I&rsquo;ve used org-contacts to keep my contacts in a plaintext file. By using existing data features and agenda customizations, I get prompts that will help me cultivate my <code>Social Maintenance</code> habit when it&rsquo;s due. With a few custom functions and a save hook, I can use light automation to make the text more dynamic without a lot of day-to-day effort.&rdquo;</p>
<p>And I&rsquo;m a little more clear on what &ldquo;social maintenance&rdquo; can mean, now. I think I&rsquo;d created an ill-defined monster the longer I let it sit there with no shape. As I put this together I got to think about what would be meaningful, and I realized it just makes my day when I get a text from someone asking how it&rsquo;s going, so that&rsquo;s a fine standard to apply.</p>
<p>And yes, it was an interesting ChatGPT exercise. It would have taken me days to suss all this out on my own. I just don&rsquo;t have the elisp. It took much less time just dialoging with the bot, and it let me work much more iteratively if an idea didn&rsquo;t test quite right. I wonder how this would have gone if I&rsquo;d thought of trying it when I was using Obsidian a lot, or if I&rsquo;d been in more of a Rails or Sinatra mood.</p>
<p>I think the whole thing will seem like overkill to some, but I am not good at keeping up with people. I am not going to go all autobiographical to explain it, I&rsquo;m just gonna say that there is what I want to do and there is what I do, and they aren&rsquo;t aligned, and I know enough about myself to know that in the absence of a supporting system my good intentions will not mean anything.</p>
<p>And I&rsquo;ve had a few recent interactions with people I haven&rsquo;t spoken to in a long time. It feels really good to reconnect, even if it&rsquo;s just a few lines of &ldquo;what&rsquo;s up with you?&rdquo; So I&rsquo;ve built a system to help me get more of that.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-04-12</title>
      <link>https://mike.puddingtime.org/posts/2023-04-12-daily-notes/</link>
      <pubDate>Wed, 12 Apr 2023 16:01:09 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-12-daily-notes/</guid>
      <description>More ChatGPT and org, using the org agenda, Yellowjackets again, Doom keybindings</description>
      <content:encoded><![CDATA[<h2 id="chatgpt-and-org-configuration">ChatGPT and org configuration</h2>
<p>I tried out <a href="https://github.com/alphapapa/org-super-agenda">org-superagenda</a> a while back. It improves on the vanilla org agenda by creating customizable sections, which help it scan a little better. I bounced off of it because while I wanted the quality of life improvements it offered, I was struggling a little with the syntax, and was caught up in that brainspace you can get into where you just want the thing to work and it&rsquo;s throwing off your sense of time and perception of the required investment to make it work.</p>
<p>This morning I was looking at my agenda and hating it because it was in a &ldquo;mostly correct except where it is glaringly incorrect&rdquo; state, so I figured it&rsquo;d be a good practical task to throw at ChatGPT:</p>
<p><code>Describe an orgmode super agenda configuration that shows habits, important items, overdue items, and items due in the near future</code></p>
<p>I got a copy-pastable example that met the requirements.</p>
<p><code>Could you add items due today to that list</code></p>
<p>Yep. That worked.</p>
<p><code>could you move the today list to second place and add a list at the bottom of unscheduled todo items</code></p>
<p>That response worked well, too. It does a decent job of explaining what each piece of the solution does.</p>
<h2 id="using-the-org-agenda">Using the org agenda</h2>
<p>Figuring out the org agenda has been key to how I use the tool.</p>
<p>With a good agenda setup I can feel pretty on top of things. When it&rsquo;s broken I know there are things out there in my file collection that I&rsquo;m not going to see. As I&rsquo;ve leaned into org capture, that&rsquo;s become even more true, because capture buffers keep you out of the file you&rsquo;re adding something to: You don&rsquo;t see the other things in there because you don&rsquo;t go past them to get to where you&rsquo;re adding new content.</p>
<p>Besides surfacing stuff, the agenda is also the nerve center. You can do basic scheduling and status changes from it, and maybe even more importantly for a sense of organizational calm, you can refile from it. So rather than visiting each file to find stuff and move it around, you can see it all from the agenda overview and refile it from there.</p>
<p>With a restored agenda, I made the connection between my literate Emacs config and all the other stuff flying around in my org mode ecosystem: Links I gathered about configuration tweaks or things I&rsquo;d like to try can more easily go into a literate config file, so I made an &ldquo;Ideas&rdquo; heading at the bottom of the file and started refiling my the Emacs-related things in my agenda&rsquo;s inbox into my <code>config.org</code> file.</p>
<p>People love hooking into org, too, so even things that started life without org mode in mind can pick up org affinities. The pinboard mode I adopted, for instance, doesn&rsquo;t natively use org&rsquo;s link storing function when copying a link, but someone wrote a function to do that.  Now I can retrieve a link and add it to a post without taking my hands off the keyboard or switching contexts.</p>
<h3 id="which-reminds-me-dot-dot-dot">Which reminds  me &hellip;</h3>
<p>I discovered <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Convenience.html">winner-mode</a> today.</p>
<p>It&rsquo;s annoying when an Emacs mode splits the window into frames, then leaves two frames behind when I quit it. <code>winner-mode</code> &ldquo;records the changes in the window configuration (i.e., how the frames are partitioned into windows), so that you can undo them.&rdquo; It&rsquo;s useful to me because I want to use <code>pinboard-mode</code> as a link retrieval tool for blogging. Once I&rsquo;ve grabbed the link, I just want to tap <code>q</code> and get back to my blog buffer, not find myself with a split window. <code>winner-mode</code> closes the pinboard buffer, then removes the frame, and I&rsquo;m back where I left off, able to add my link and keep typing.</p>
<h2 id="custom-doom-keybindings">Custom Doom keybindings</h2>
<p>I&rsquo;ve been digging Doom&rsquo;s modal interface, and waiting around for a reason to extend it. Yesterday&rsquo;s addition of <code>pinboard.el</code> finally gave me an excuse, since Doom was killing its keybindings out of the box.</p>
<p>The <code>p</code> prefix in Doom&rsquo;s menu system is already occupied by <code>projectile</code>, so I used <code>P</code>:</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">map!</span> <span class="nb">:leader</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nb">:prefix-map</span> <span class="p">(</span><span class="s">&#34;P&#34;</span> <span class="o">.</span> <span class="s">&#34;Pinboard&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;open Pinboard&#34;</span> <span class="s">&#34;p&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;open current link&#34;</span> <span class="s">&#34;o&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard-open</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;copy org link&#34;</span> <span class="s">&#34;l&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-store-link</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;edit link&#34;</span> <span class="s">&#34;e&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard-edit</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;copy URL&#34;</span> <span class="s">&#34;c&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard-kill-url</span>
</span></span><span class="line"><span class="cl">        <span class="p">)))</span></span></span></code></pre></div>
<p>So <code>spc Pp</code> will open the pinboard buffer (or switch to it), <code>spc Po</code> will open a given link, <code>spc Pl</code> will store an org link (for retrieval via <code>spc mll</code>), etc. etc.</p>
<p>One thing I&rsquo;m struggling with here is a vagary of Doom as an environment. The logical place for all of that is in the <code>bindings.el</code> file, but the bindings don&rsquo;t &ldquo;take&rdquo; when I put them there.  They do when I put them in <code>config.el</code>. The docs weren&rsquo;t super helpful in debugging that, and the things that look syntactically intuitive didn&rsquo;t seem to solve the problem.</p>
<p>It&rsquo;s no big deal, and I&rsquo;d rather just have all of that stuff travel together with the mode it addresses, anyhow, but it&rsquo;s a thing I Do Not Understand About the Environment except at a very vague &ldquo;well, there&rsquo;s a lot of lazy loading going on to keep things fast&rdquo; level, and it&rsquo;s going to bother me.</p>
<p>I should just add an <code>INSOMNIA</code> state to my TODO lists and save it for the next &ldquo;welp, it&rsquo;s 3 a.m. and I might as well screw around with this problem&rdquo; session.</p>
<h2 id="yellowjackets-again">Yellowjackets again</h2>
<p>Well, we finished the first season last night.</p>
<ul>
<li><strong>Standalone season</strong> score: 8</li>
<li><strong>Prospects for the future</strong> score: 5</li>
</ul>
<p>Basically, my &ldquo;endless puzzlebox&rdquo; antennae are quivering.</p>
<p>The season all on its own was gripping and kept our interest. I felt invested in the characters and whatever they were dealing with. I love the way it walks right up to the <em><a href="https://www.imdb.com/title/tt6998518/">Mandy</a></em> line a few times. It has a dark sense of humor but it&rsquo;s not mean.</p>
<p>The 2 missing points for the standalone season score are because it had some minor pacing/bog-down stuff in the middle, and because some stuff going on just felt like gratuitous puzzlebox misdirection. It felt at times like it was written too self-consciously aware of recap culture and a certain kind of mock-obsessive over-read/over-think that comes along with that.</p>
<p>The &ldquo;prospects for the future&rdquo; score is a function of how I felt as the credits rolled on the season ender, and it honestly wasn&rsquo;t great. The episode didn&rsquo;t feel energetic, it suggested an appetite for &ldquo;surprise reversal&rdquo; that will exceed my patience over the long haul, and it reminded a bit too much of the first couple of seasons of HBO&rsquo;s <em><a href="https://www.imdb.com/title/tt8068860/">Servant</a></em>, which I abandoned with no remorse at the end of the second season.</p>
<p>I feel a little bad about my reaction, because maybe I&rsquo;m suggesting that television productions should simply abandon the only tools they have to get more seasons. In some ways, they <em>have</em> to pander to recap culture. They <em>have</em> to pander to fannish over-analysis. They <em>have</em> to end each season with a hook and a sense of incompleteness. They <em>have</em> to live within a fickle system run by people addicted to the analytics streaming affords, who will happily kill a property and move on to the next with no sense of investment.</p>
<p>But, you know, don&rsquo;t point out a problem without pointing out a solution:</p>
<p><em>For All Mankind</em> (Al prefers to think of it as <em>Space is Trying to Murder You Again This Week</em>) does a nice job with this conundrum: Each season has an arc and a sense of conclusion. There&rsquo;s payoff. Then it does an end-credits thing where it flash-forwards to the next season&rsquo;s era and offers you a look. It doesn&rsquo;t appeal to your thwarted expectations of closure, it appeals to your curiosity.</p>
<p>And to make note of a counterpoint, <em>Succession</em> isn&rsquo;t above leaving things on a hanging note of tension, but I&rsquo;ve stuck with it. It&rsquo;s not terrible to leave things unresolved, or end a season with a directional cue in the form of an unfinished arc. Maybe the thing I&rsquo;m reacting to with the puzzlebox stuff is the garish palette those shows paint with, swinging for the meme fences.</p>
<p>Anyhow, we have a few episodes of <em>Yellowjackets</em> season 2 cued up. The prospect of watching them, having skimmed a few episode descriptions in Plex, is not sparking a &ldquo;full-body yes.&rdquo; There&rsquo;s just so much other stuff out there that I&rsquo;m okay with the thought of letting it have its run then deciding whether it&rsquo;s worth it to watch through the whole thing.</p>
]]></content:encoded>
    </item>
    <item>
      <title>First stab at literate config with Doom Emacs</title>
      <link>https://mike.puddingtime.org/posts/2023-04-05-first-stab-at-literate-config/</link>
      <pubDate>Wed, 05 Apr 2023 08:53:21 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-05-first-stab-at-literate-config/</guid>
      <description>&lt;p&gt;My historic pattern for descending into Emacs hell has always started with the kitchen-sink init, and the path to recovery has always involved a patient refactoring into multiple files: Some kind of &amp;ldquo;the basics,&amp;rdquo; something just for org, something for odd little quality of life things, and a quarantine file where new stuff can enjoy a probation period where I can bisect it first when something goes wrong. If I add a big chunk of functionality from a new mode, that might get its own file, too.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>My historic pattern for descending into Emacs hell has always started with the kitchen-sink init, and the path to recovery has always involved a patient refactoring into multiple files: Some kind of &ldquo;the basics,&rdquo; something just for org, something for odd little quality of life things, and a quarantine file where new stuff can enjoy a probation period where I can bisect it first when something goes wrong. If I add a big chunk of functionality from a new mode, that might get its own file, too.</p>
<p>That has always helped me feel a little in control, at least.</p>
<p>I noticed Doom Emacs has a <code>literate</code> module in its <code>init.el</code>, so I did some reading. The very high level summary is that Doom lets you use <a href="https://en.wikipedia.org/wiki/Literate_programming">literate programming</a> principles via org-mode to build your <code>config.el</code> file from an org file:</p>
<ul>
<li>You enclose your actual configuration code in src blocks:</li>
</ul>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1">#+begin_src emacs-lisp</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">setq</span> <span class="n">doom</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Code Retina&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">14</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="n">doom</span><span class="o">-</span><span class="n">variable</span><span class="o">-</span><span class="n">pitch</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Sans&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">13</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1">#+end_src</span></span></span></code></pre></div>
<p>&hellip; and those blocks are &ldquo;tangled&rdquo; into a <code>config.el</code> file.</p>
<p>You get to use all of org-mode&rsquo;s affordances for document structure, so you can add headings, and your comments can just be prose:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="o">**</span> <span class="n">Base</span> <span class="n">Appearance</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">***</span> <span class="n">Line</span> <span class="n">spacing</span> 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#+begin_src emacs-lisp</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">setq</span><span class="o">-</span><span class="n">default</span> <span class="n">line</span><span class="o">-</span><span class="n">spacing</span> <span class="mf">0.5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#+end_src</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">***</span> <span class="ne">Font</span> <span class="n">Settings</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#+begin_src emacs-lisp</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">setq</span> <span class="n">doom</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Code Retina&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">14</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="n">doom</span><span class="o">-</span><span class="n">variable</span><span class="o">-</span><span class="n">pitch</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Sans&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">13</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1">#+end_src</span></span></span></code></pre></div>
<p>So this morning I moved my still-pretty-simple <code>config.el</code> into <code>config.org</code> to see what I thought.</p>
<p>It&rsquo;s pretty cool!</p>
<p>The traditional ugliness of Emacs configs, for me, has always been the slow drift out of organization. Maybe for a while all the UI stuff, personalization stuff, appearance stuff is traveling together, but something makes its way in at the bottom of the file, then something else, and you&rsquo;re left with a bunch of things that aren&rsquo;t near their logical neighbors. There are the things you comment out that just become a big chunk of &hellip; something &hellip; it&rsquo;s hard to read because they aren&rsquo;t syntax highlighted anymore. There&rsquo;s verbose documentation that makes it hard to scan. etc.</p>
<p>Literate config in Emacs allows you to bring semantically meaningful structure to the configuration file: Broad categories of options can go under headings, commentary is written as prose, and you can use all of org mode&rsquo;s structure editing tools to quickly move chunks of configuration around into a more readable, logical order.</p>
<p>Doom&rsquo;s default <code>config.el</code> comes with a ton of comments. I&rsquo;m glad they&rsquo;re there when I need them, I hate having to scroll through and past them. Moving everything into <code>config.org</code> let me just move the comments into a <code>Docs</code> heading for each section, so they stay folded away unless I need them.</p>
<p>I&rsquo;ve got a few chunks of config that need some work. I can research how to use a given module, toss in reference links and sample snippets, and only allow certain code blocks to be compiled into my final <code>config.el</code>.</p>
<p>And I can also evaluate a src block by hitting <code>enter</code> on the last line of the block, so if you&rsquo;re in an iterative mode, trying things out and testing them, it&rsquo;s a few keystrokes less to make sure something evaluates cleanly, returns the value I was hoping for, etc.</p>
<p>I&rsquo;ve known about literate programming in the context of org for a while. A very long while ago, when I was first playing around with web analytics reporting, I had some simple code blocks embedded in an org file that allowed me to pull basic website numbers into my org file by getting the output of a script. That could all then be exported into a status report.  It was cool but also trivial. It didn&rsquo;t feel like a huge quality of life improvement. This feels like something that, with very little time spent getting it into basic shape, will be more maintainable over time. It&rsquo;s easy to see where to insert something in the document, so things are more likely to stay organized,  and it&rsquo;s easy to test.</p>
<p>It was very little work to set up in the Doom Emacs context:</p>
<ol>
<li>I enabled the functionality in <code>init.el</code> by uncommenting <code>literate</code></li>
<li>I copied my <code>config.el</code> file into <code>config.org</code> wholesale.</li>
<li>I put every config stanza under a level 2 heading to start.</li>
<li>Short (5 lines or fewer) comments became leading prose blocks.</li>
<li>Long comments went into level 3 <code>Docs</code> subheads.</li>
<li>I collapsed my view to headings only and  moved everything related to each other into proximity of each other with org&rsquo;s section up/down keys.</li>
<li>I added top-level headings for basic config, my more extensive org mode stuff, and utility functions.</li>
</ol>
<p>I&rsquo;m still building up my Doom config, so it didn&rsquo;t take long. Maybe 15 minutes to get to something much more easy to scan:</p>
<p><img src="/img/org-config.jpg" alt="Screenshot of an org-based config file&rsquo;s heading hierarchy"></p>
<p>Sitting here thinking about it, I guess it reminds me a little of the first time I sat down and wrote a real Puppet manifest for a real purpose and not a &ldquo;how does this thing work?&rdquo; purpose. It felt like clarity was emerging from the writing process.</p>
<p>Seems like a keeper.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily notes for 2023-03-22</title>
      <link>https://mike.puddingtime.org/posts/2023-03-22-daily-notes-for-2023-03-22/</link>
      <pubDate>Wed, 22 Mar 2023 10:42:33 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-03-22-daily-notes-for-2023-03-22/</guid>
      <description>Succumbing to org-roam, the pleasures of a straight razor competently wielded, Decline of Western Civilization.</description>
      <content:encoded><![CDATA[<h3 id="succumbing-to-org-roam">Succumbing to org-roam</h3>
<p>Well, it took less than 12 hours to go from &ldquo;I&rsquo;m not going to even touch that&rdquo; to &ldquo;huh, I wonder if it&rsquo;s cool?&rdquo;</p>
<p>Yes, <a href="https://www.orgroam.com">org-roam</a> is cool. It&rsquo;s a Zettelkasten implementation built atop org-mode. To make it work in Doom Emacs you just add it to the org-mode line in Doom&rsquo;s <code>init.el</code>:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">(org +roam2) </span></span></code></pre></div>
<p>&hellip; and then run <code>doom sync</code>.</p>
<p>You should add a <code>roam</code> subdir to your standard org files location or it will complain when you try to use it.</p>
<p>You can instantiate a new node with <code>spc n r i</code> (&rsquo;n&rsquo;otes, &lsquo;r&rsquo;oam, &lsquo;i&rsquo;nsert)</p>
<p>That gets you a roam buffer and you can start typing. As with most transient Emacs buffers, <code>C-c</code> will save and exit.</p>
<p>If you want to link to a separate note, you can start typing its name in the body of the current note and get an autocomplete list.</p>
<p>If you link to a note from another note, Roam takes care of adding a backlink at the bottom of the target note.</p>
<p>As with all things Emacs, there are org-roam configs you can go find on the street and stick in your mouth. As with all things Emacs, I didn&rsquo;t describe it that way because I thought that would make such an approach attractive to you. I want you to be repulsed by that approach because it is unclean. One of the advantages of Doom Emacs (or Spacemacs, or Prelude) is that if they include a package, they probably include some basic configuration, so you can kick the tires then start layering on capabilities.</p>
<p>Anyhow, in its basic Doom Emacs config, org-roam is unremarkable. If you want a zettel and don&rsquo;t want Emacs, go get Obsidian or one of its competitors. I&rsquo;m going to stick with it for a while. As I mentioned <a href="/posts/2023-03-21-daily-notes-for-2023-03-21/">yesterday</a>, I like org-mode&rsquo;s intertwingling of tasks/actions/todos and prose, so it suits me.</p>
<h3 id="the-pleasures-of-a-straight-razor-competently-wielded">The pleasures of a straight razor competently wielded</h3>
<p>A brief history of me and professional grooming:</p>
<ul>
<li>My grandmother paid for my first stylist haircut when I was in 7th grade. I had no idea how to maintain it.</li>
<li>I spent a few years just telling barbers to take it all off.</li>
<li>The army taught me the pleasures of walking in, paying your $5, and getting a high-and-tight. Once I&rsquo;d been in a few years, I&rsquo;d modify the request to say &ldquo;leave a little up top.&rdquo;</li>
<li>Over the past 20 years I developed an appreciation for Great Clips because they store your preferences and last cut in the computer under your phone number.</li>
</ul>
<p>Then last year I walked into a barber shop near the office because things were dire and I had a few minutes. The barber handled the basic cut, then offered to do some detail work with a straight razor since he had time. That part was amazing, and it made my day.</p>
<p>I started going back, partially because it was a great first experience and partly because the barber was utterly disinterested in small talk. Just enough to establish we spoke a common tongue, then nothing except the occasional request for a decision.  We did enter into an extended dialog about my beard made up of very sharp exchanges in the ensuing months. He was in favor of taking more of it off, and I would say &ldquo;no, I&rsquo;m not there yet, please just do what you can with it.&rdquo; He&rsquo;d mutter and then cluck when he got to the part where it began to curl at the bottom. &ldquo;I can&rsquo;t do anything with this &hellip; you&rsquo;re sure you&rsquo;re okay?&rdquo;</p>
<p>Then last week I had a video conference and was wearing a shirt with a collar and a jacket and I realized I couldn&rsquo;t see my collar under my beard. I couldn&rsquo;t really see my mouth, either.</p>
<p>I recently read about a study that suggested people with beards will ultimately be perceived as more trustworthy and accessible <em>once they are given an opportunity to smile</em>. Until that point, the unbearded have all the social advantages. So I decided it might be best to make my mouth observable. COVID and masking did reveal me to be a proficient eyebrow flasher, but I don&rsquo;t think you can completely rely on that.</p>
<p>So I booked time with my barber and left out the haircut (I&rsquo;m good for a few more weeks) but did add the razor true-up.</p>
<p>When I sat down he resignedly asked &ldquo;the usual, just fix the scruff?&rdquo; and I said &ldquo;no, I&rsquo;d like to get some of that length and volume out of there.&rdquo; He started to nod vigorously, and we entered into an extended negotiation measured in finger widths (&ldquo;okay, but top of finger or bottom?&rdquo;) and ultimately settled on something that would both reveal my mouth and also let you see my neck and/or collar.</p>
<p>Then it was just closing my eyes and enjoying the hot towel, thick lather, and precision work of a sharp straight razor, including temples and neck.</p>
<p>Restorative.</p>
<p>I go all the way across town &ndash; the barber moved from near the office to even further west &ndash; but it&rsquo;s worth the train ride once a month to have a good barber.</p>
<h3 id="movie-decline-of-western-civilization">Movie: Decline of Western Civilization</h3>
<p>I rewatched Penelope Spheeris&rsquo; <em>Decline of Western Civilization</em> for the umpteenth time. X is one of my top 5 favorite bands of all time, so I love everything with them in it, even if John Doe&rsquo;s trolling over &ldquo;Johnny Hit and Run Pauline&rdquo; makes me cringer harde with every viewing.  The people around the periphery are great, too, including Club 88&rsquo;s owner, who is determined to greet the whole freak show playing out in his venue with a certain patient equanimity I hope I can equal as the world moves on around me. And I&rsquo;m grimly fascinated with Fear, and Lee Ving in particular, and his theatrical hate.</p>
<p>Punk was the first real subgenre I embraced. I was up at 2 in the morning in 10th grade, working on a paper for my journalism class, when the college radio station I&rsquo;d been listening to jazz on hours earlier suddenly crackled back to life from its post-midnight-signoff hiss because someone had snuck into the studio and announced the first (and possibly last) installment of &ldquo;Goshen College&rsquo;s Guts Radio.&rdquo;</p>
<p>Then they peeled my skull back with Fear, Black Flag, Dead Kennedys, and stuff I never heard again.</p>
<p>I mentioned it to the stoner who sat in front of me in American History and he came back the next day with the Dead Boys&rsquo; <em>Young, Loud and Snotty</em> on one side of a cassette tape, and a hastily assembled tour of more vintage punk on the other.</p>
<p>Anyhow, <em>Decline</em>: X are the odd ones out there. A punk act, yes, but with the seeds of their eventual trajectory present if you look for them. The case has been made that they were a case of tragic mistiming and I think it might be true: There they were at the height of their <em>energy</em> in 1980, but the <em>sensibility</em> they anticipated was years away from the eventual saturation it achieved with vintage scavengers and billy boys. My affection for X is undying: They were my bridge from a sullen, resentful anger toward all the normal people to a belief that maybe <em>I</em> was one of the decent people, too.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily notes for 2023-03-21</title>
      <link>https://mike.puddingtime.org/posts/2023-03-21-daily-notes-for-2023-03-21/</link>
      <pubDate>Tue, 21 Mar 2023 11:03:54 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-03-21-daily-notes-for-2023-03-21/</guid>
      <description>Back to org-mode, a decent C25K Apple Watch app, custom Hugo RSS.</description>
      <content:encoded><![CDATA[<h3 id="back-to-org-mode">Back to org-mode</h3>
<p>Reasonable default configurations have been a pleasure of [Doom Emacs][]. Even org-mode, which I had somewhat dialed in on my own, works well enough, and maybe better, under Doom. When I took my <code>org-conf.el</code> apart I realized how many geological layers of features that sounded interesting but never made their way into regular use were sitting there, gumming things up and slowing things down.</p>
<p>I posted last night about a nicely wired up Projectile/org-mode pairing:</p>
<iframe src="https://social.lol/@mph/110059541236136990/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe><script src="https://social.lol/embed.js" async="async"></script>
<p>Whenever I get bit by the org-mode bug, the first thing I notice and remember loving is the intertwining of text and tasks. Sitting down and making lists in an app has never felt completely comfortable to me, and the notes capabilities of a lot of task apps leave me cold. They look and feel like afterthoughts, and the text is dead and inert inside them. Once the task is done, the text is effectively gone unless you take time to pull it out and put it somewhere.</p>
<p>When your todos and text are happening on equal footing with each other, your &ldquo;todo list&rdquo; stops being a todo list and starts being a sort of log or journal. Structure your notes correctly within todos, and org-mode makes it easy to copy them into another file or hierarchy, or you can just leave them in place and keep moving.</p>
<p>Preparing for a meeting this week, I loved sketching in the things I needed to cover as headings that happened to be todos, then launching straight into notes underneath those headings, roughing in initial thoughts or leaving myself prompts without clicking into a cramped little box.</p>
<p>I loved org-mode when I worked in a status report work culture because my weekly report was also my todo list. I wrote an exporter that kept out the stuff nobody else cared about, but showed the most recent log entry in each item. As priorities shifted, my status report was always up to date. As I wrote each week&rsquo;s update, I could see the previous week&rsquo;s just below it in the item drawer. Items that were delegated, on hold, or dropped, reflected reality at the moment of export. Attempts to do similar with other tools never came close, no matter how robust their scripting libraries.</p>
<p>So, having an Emacs distro that feels very solid underfoot and presents a clean, useful, uncluttered org configuration is a real joy.</p>
<p>I am also enjoying <a href="https://beorgapp.com">Beorg</a>, an iOS/iPadOS app that works well with org-mode, syncing via iCloud, Dropbox, WebDAV, or Box. It tilts toward the todo/agenda-oriented parts of the org-mode experience, but you can edit your prose notes with it in a pinch. It can also integrate with iOS Reminders and Calendar apps, so your agenda view can reflect your org stuff and your phone stuff if you have to live in a split ecosystem for things like shopping lists. It&rsquo;s not a completely seamless experience, but it is smooth and works well.</p>
<p>And the whole experience reminds me that, speaking only for myself, as much as I think it&rsquo;s possible to get work done on an iPad, I can&rsquo;t get it done as well as I can on a laptop or desktop machine.</p>
<h3 id="c25k-phone-app">C25K phone app</h3>
<p>&ldquo;Try to get more exercise&rdquo; has found its way onto the medical agenda, so I am trying to get more exercise.  My routine over the past couple of years has involved 3 or 4 miles of walking most weekdays, and upwards of 6 or 8 on weekends. That has served me pretty well, but after a few experiments and some measuring, it&rsquo;s pretty clear that 30 minutes of running every other day is helping even more.</p>
<p><a href="http://www.c25k.com">Couch to 5k</a> has been my go-to &ldquo;get back into running&rdquo; program over the years. It&rsquo;s a slow ramp &ndash; slower than I&rsquo;d like some days. When I compare how well I&rsquo;ve kept up a running habit (and kept feeling healthy) ramping myself up vs. sticking to C25K, it&rsquo;s clear I do better letting myself be held back a little.</p>
<p>When I first did C25K I did it using a Timex Ironman and watching the stopwatch. That wasn&rsquo;t great because it kept me from just going to my running place. In early smartphone days I was happy to use an app, but wow was iOS terrible for that kind of thing back then: Music never coming back after a voice prompt, bad UI ideas, etc.</p>
<p>I&rsquo;d always hoped Apple Watch would address it, but for a few years it was even worse, and I went through a series of hacks and workarounds, but was resigned to just keeping my phone on me for runs.</p>
<p>This time around it seems Apple Watch is finally mature enough to support a standalone C25K app in the form of <a href="https://apps.apple.com/us/app/watchto5k-couch-to-5k-watch/id1517914828">WatchTo5K</a>. It&rsquo;s part of a crowded field, and there may be others that work just fine, but WatchTo5K had decent reviews and has gotten me through three weeks so far with no complaints. It just works, it&rsquo;s simple, and it talks to Apple Health so I can correlate runs with a few other biometrics.</p>
<p>The only other wrinkle isn&rsquo;t a big deal: I run in a park across the street from my house, so the watch is constantly picking up then dropping my Wi-Fi network. Even though my running playlist is downloaded to the watch, it causes the music to stutter every time I run back out of range. Putting the watch in airplane mode addresses that.</p>
<p>It&rsquo;s pretty nice to just put on my watch and Beats Fit Pros, start my playlist, start the app, and start running, with nothing else to think about or fiddle with for the next 30 minutes.</p>
<h3 id="custom-hugo-rss">Custom Hugo RSS</h3>
<p>I made a small tweak to my site&rsquo;s RSS feed, adding a shortcode to list the tags for each post and adding it to each entry&rsquo;s description. It&rsquo;s a small adaptation to reflect the ways I use my feed to cross-post to Mastodon and Twitter. Mastodon is especially on my mind, given that tags are what drives discovery. For my daily posts it&rsquo;ll be a little redundant and I guess I could build some logic in to handle that, but not today.</p>
<p>Here&rsquo;s the shortcode (<code>rss_tags.html</code>):</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">{{- $tags := .Language.Params.Taxonomies.tag | default &#34;tags&#34; }}
</span></span><span class="line"><span class="cl">{{- range ($.GetTerms $tags) }}
</span></span><span class="line"><span class="cl">  #{{ .LinkTitle }}
</span></span><span class="line"><span class="cl">{- end }}</span></span></code></pre></div>
<p>&hellip; and <a href="https://codingnconcepts.com/hugo/custom-rss-feed-hugo/#customize-rss-feed">here&rsquo;s the tutorial I used</a> to figure out how to customize the feed. It just involved changing the description element:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&lt;description&gt;{{ .Summary | html }} &lt;br /&gt;
</span></span><span class="line"><span class="cl">  {{ partial &#34;rss_tags.html&#34; . }}
</span></span><span class="line"><span class="cl">&lt;/description&gt;</span></span></code></pre></div>
]]></content:encoded>
    </item>
    <item>
      <title>org-mode In Your Pocket Is a GNU-Shaped Devil</title>
      <link>https://mike.puddingtime.org/posts/2010-02-03-orgmode-in-your/</link>
      <pubDate>Wed, 03 Feb 2010 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2010-02-03-orgmode-in-your/</guid>
      <description>&lt;p&gt;If the iPhone has helped me accomplish one thing, it has probably been
to make it easier for me to stay away from Emacs.&lt;/p&gt;
&lt;p&gt;It works like this:&lt;/p&gt;
&lt;p&gt;It is not controversial to assert that Emacs is an environment all its
own. You can find libraries and packages that allow Emacs to acknowledge
and talk to outside environments, so it&amp;rsquo;s not a &lt;em&gt;closed&lt;/em&gt; environment,
but it&amp;rsquo;s different enough that there&amp;rsquo;s some fiddling involved to get it
chatting with the outside world.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>If the iPhone has helped me accomplish one thing, it has probably been
to make it easier for me to stay away from Emacs.</p>
<p>It works like this:</p>
<p>It is not controversial to assert that Emacs is an environment all its
own. You can find libraries and packages that allow Emacs to acknowledge
and talk to outside environments, so it&rsquo;s not a <em>closed</em> environment,
but it&rsquo;s different enough that there&rsquo;s some fiddling involved to get it
chatting with the outside world.</p>
<p>The iPhone could also be considered an environment all its own, but it&rsquo;s
an environment built with an eye on a broader context. iPhones have a
pretty easy time doing things like talking to iCal or Outlook with a few
button clicks, for instance. Now, unlike Emacs, there&rsquo;s a point with the
iPhone where no amount of grunting or straining will matter, and if you
want it to talk to something else nobody else has bothered to make it
talk to, there&rsquo;s an SDK you can download.</p>
<p>All that said, when Emacs and iPhone can both respond to a particular requirement with &ldquo;there&rsquo;s an [app | elisp package] for that,&rdquo; the iPhone variation will usually involve a quick download and three or four fields in a configuration screen, tops.</p>
<p>When I got an iPhone, I was a pretty heavy Emacs <a href="http://orgmode.org/">org mode</a> user. The
smartphone I had prior to the iPhone was a BlackBerry, and the
BlackBerry never really talked to my Mac on any useful level: lost
contacts, extra contacts, a new contact for every phone number I had
listed for what had once been a single contact, crummy calendar syncing,
forget about bookmarks syncing, etc. etc. etc. Because the BlackBerry
sucked for me as a Mac user, and because iCal was anemic when it came to
todos, org mode was able to fend off everything.</p>
<p>I won&rsquo;t go into a lot of detail about org mode except to say that it&rsquo;s
neat. You just open a &ldquo;.org&rdquo; file in Emacs and start typing using a
pretty simple notation. For instance &hellip;</p>
<pre><code>* PracNet

** TODO Look at reviews: can we get user information to the front page? (ASP)

   DEADLINE:

** TODO Look at inside pages: make a toolkit for callouts that can fit into the CSS

   DEADLINE:
</code></pre>
<p>When that text appears in an Emacs buffer in org mode, it&rsquo;s nicely color
coded. A few keystrokes make it easy to cycle between &ldquo;TODO&rdquo; and &ldquo;DONE&rdquo;
or some other status.</p>
<p>As with all things Emacs, it&rsquo;s very customizable.</p>
<p>Then the iPhone came along and promised me that if I would accept a few
small tradeoffs, it would sync up with a lot more of my stuff:
bookmarks, addresses, e-mail, etc. etc. etc. I&rsquo;d have all that stuff in
my pocket, and when I returned home my Mac would automagically commune
with it to learn what had changed in my absence.</p>
<p>org mode fell by the wayside, and the little ecosystem I&rsquo;d created
within Emacs crumbled because it was no longer a place to live &hellip; just
a place to visit when I needed to push text around.</p>
<p>So <a href="http://mobileorg.ncogni.to/">MobileOrg</a> strikes me as fascinating and horrifying at the same
time. All it does is this:</p>
<p>You save your Emacs org mode files on a WebDAV server, load MobileOrg
onto your iPhone, and you&rsquo;ll have org mode on your iPhone and it&rsquo;ll all
sync up, just like Remember the Milk or ToodleDo or any of the other
todo services that have &ldquo;an app for that.&rdquo;</p>
<p>&ldquo;If you are a MobileMe user, you already have access to a WebDAV server:
iDisk,&rdquo; says the MobileOrg site in a manner I cannot help but read as
<em>insinuating.</em></p>
<p>&ldquo;Sucker &hellip; walked away from Emacs and even took the extra step of
slurping the MobileMe kool-aid thinking it&rsquo;d harden your resolve against
ever returning. Well &hellip; fine &hellip; <em>keep</em> your precious iDisk &hellip; it will
become the tool of your re-liberation.&rdquo;</p>
<p>Less than two years ago, when I was venturing forth from org mode and
getting to know the iPhone as a way to keep all my Stuff in sync,
MobileOrg would have had me at hello. Now it just gives me the shaking
fits.</p>
<p>With Emacs, you don&rsquo;t just go &ldquo;la la la &hellip; I&rsquo;m gonna add org mode back
and call it a day!&rdquo; You think to yourself, &ldquo;I love org mode. I wish
there was an easy way to turn an e-mail message into a todo &hellip;&rdquo; and the
next thing you know you&rsquo;re dealing with how to configure <a href="http://gnus.org/">GNUS</a>.</p>
<p>Then you think &ldquo;All my calendar stuff is in Google calendar &hellip; how can
I get it into my org mode agenda?&rdquo; and that means you&rsquo;re off reading
<a href="http://bc.tech.coop/blog/070306.html">this guy&rsquo;s page</a> and just getting angrier and angrier.</p>
<p>Then you go in the kitchen and make a drink, and while you&rsquo;re making it
and calming down you think to yourself, if I&rsquo;m doing all this stuff in
Emacs anyhow, what would it hurt to <a href="http://www.instantmessagingplanet.com/public/article.php/3742411">follow Twitter in Emacs</a>?</p>
<p>Now you&rsquo;re not drinking because you&rsquo;re angry &hellip; you&rsquo;re drinking because
you wonder what happened to you and it makes you sad. But you&rsquo;re drunk,
so it seems like a perfectly good idea to <a href="http://mwolson.org/projects/EmacsMuse.html">build an entire Web site
using nothing but Emacs because then you can get a LaTeX version of it
for if the asteroids hit and their radiation destroys all HTML</a>. And
having decided to do that, part of you thinks about how glad you are you
have org mode, so you can organize the lengthy process of making sure
you never have to leave Emacs again.</p>
<p>It&rsquo;s knowing what&rsquo;s in store for me as I sit here with MobileOrg on my
iPhone and the necessary WebDAV share all set up that makes me read this
and just want to spit nails:</p>
<blockquote>
<p>At its core, Org-mode is a simple outliner for note-taking and list
management. You can learn the basics for using it in five minutes. This
may be all you need, and Org-mode will not impose more complex features
on you.</p>
</blockquote>
<p>That&rsquo;s right &hellip; because org-mode is just a collection of lisp running
in an editor. It <em>cannot</em> impose more complex features on you. The
genius of org-mode is that you will eventually impose more complex
features on yourself.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
