<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>davep</title>
    <link>https://blog.davep.org</link>
    <description>Posts in category "Emacs" from davep</description>
    <atom:link href="https://blog.davep.org/feeds/emacs.rss.xml" rel="self"/>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Sun, 12 Apr 2026 20:39:10 +0000</lastBuildDate>
    <item>
      <title>quiz.el v1.7</title>
      <link>https://blog.davep.org/2026/04/08/quiz-el-v1-7.html</link>
      <description>&lt;p&gt;I &lt;a href="https://blog.davep.org/2026/04/07/quiz-el-v1-6.html"&gt;wondered yesterday&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;...those question headers are displaying differently, with the background
colour no longer spanning the width of the window. I'd like to understand
why.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Turns out it was pretty straightforward:&lt;/p&gt;
&lt;div class="highlight" data-lang="diff"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;diff --git a/quiz.el b/quiz.el&lt;/span&gt;
&lt;span class="gh"&gt;index 2dbe45d..c1ba255 100644&lt;/span&gt;
&lt;span class="gd"&gt;--- a/quiz.el&lt;/span&gt;
&lt;span class="gi"&gt;+++ b/quiz.el&lt;/span&gt;
&lt;span class="gu"&gt;@@ -40,7 +40,8 @@&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;(defface quiz-question-number-face
&lt;span class="w"&gt; &lt;/span&gt;  &amp;#39;((t :height 1.3
&lt;span class="w"&gt; &lt;/span&gt;       :background &amp;quot;black&amp;quot;
&lt;span class="gd"&gt;-       :foreground &amp;quot;white&amp;quot;))&lt;/span&gt;
&lt;span class="gi"&gt;+       :foreground &amp;quot;white&amp;quot;&lt;/span&gt;
&lt;span class="gi"&gt;+       :extend t))&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;  &amp;quot;Face for the question number.&amp;quot;
&lt;span class="w"&gt; &lt;/span&gt;  :group &amp;#39;quiz)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and so v1.7 has happened.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Quiz with reinstated header look" src="https://blog.davep.org/attachments/2026/04/08/updated-quiz.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;It looks like, perhaps, at some point in the past, &lt;code&gt;:extend&lt;/code&gt; was &lt;code&gt;t&lt;/code&gt; by
default, but it no longer is? Either way, explicitly setting it to &lt;code&gt;t&lt;/code&gt; has
done the trick.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/08/quiz-el-v1-7.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>quiz.el</category>
      <pubDate>Wed, 08 Apr 2026 16:54:38 +0100</pubDate>
    </item>
    <item>
      <title>fasta.el v1.1</title>
      <link>https://blog.davep.org/2026/04/08/fasta-el-v1-1.html</link>
      <description>&lt;p&gt;Today's &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; package tidy-up is of a package I
first wrote &lt;a href="https://blog.davep.org/2017/12/12/on_to_something_new.html"&gt;a couple of employers
ago&lt;/a&gt;. While working on code I often
found myself viewing &lt;a href="https://en.wikipedia.org/wiki/FASTA_format" rel="noopener noreferrer" target="_blank"&gt;FASTA
files&lt;/a&gt; in an Emacs buffer and so
I thought it would be fun to use this as a reason to knock up a simple mode
for highlighting them.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/davep/fasta.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;fasta.el&lt;/code&gt;&lt;/a&gt; was the result.&lt;/p&gt;
&lt;p&gt;&lt;img alt="An example FASTA file" src="https://blog.davep.org/attachments/2026/04/08/fasta.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;While I doubt it was or is of much use to others, it helped me better
understand simple font-locking in Emacs Lisp, and also made some buffers
look a little less boring when I was messing with test data.&lt;/p&gt;
&lt;p&gt;As for this update: it's the usual stuff of cleaning up &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;deprecated uses of
&lt;code&gt;setf&lt;/code&gt;&lt;/a&gt;, mostly.&lt;/p&gt;
&lt;p&gt;If &lt;a href="https://blog.davep.org/tag/bioinformatics/"&gt;bioinformatics&lt;/a&gt;-related Emacs Lisp code written by
a non-bioinformatician is your thing, you might also find
&lt;a href="https://github.com/davep/2bit.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;2bit.el&lt;/code&gt;&lt;/a&gt; of interest too. Much like
&lt;code&gt;fasta.el&lt;/code&gt; it too probably doesn't have a practical use, but it sure was fun
to write and taught me a few things along the way; it also &lt;a href="https://www.youtube.com/watch?v=OimlNumAKWo" rel="noopener noreferrer" target="_blank"&gt;sort of goes
hand-in-hand with &lt;code&gt;fasta.el&lt;/code&gt;
too&lt;/a&gt;.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/08/fasta-el-v1-1.html</guid>
      <category>Emacs</category>
      <category>Bioinformatics</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>biology</category>
      <category>coding</category>
      <category>fasta.el</category>
      <pubDate>Wed, 08 Apr 2026 11:25:43 +0100</pubDate>
    </item>
    <item>
      <title>quiz.el v1.6</title>
      <link>https://blog.davep.org/2026/04/07/quiz-el-v1-6.html</link>
      <description>&lt;p&gt;A quick little refresh of one of my old packages, this time
&lt;a href="https://github.com/davep/quiz.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;quiz.el&lt;/code&gt;&lt;/a&gt;. This is a nice little
distraction when you're working in &lt;a href="https://blog.davep.org/category/emacs/"&gt;Emacs&lt;/a&gt;, letting you
spin up a quick trivia quiz in a buffer.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Quiz in action" src="https://blog.davep.org/attachments/2026/04/07/quiz.png" /&gt;&lt;/p&gt;
&lt;p&gt;It's backed by the &lt;a href="https://opentdb.com/" rel="noopener noreferrer" target="_blank"&gt;Open Trivia Database&lt;/a&gt;, so there's
a good few subjects, questions, and levels of difficulty to play with.&lt;/p&gt;
&lt;p&gt;The only changes I've made to it in this release are the usual clean-ups of
the &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;deprecated uses of &lt;code&gt;setf&lt;/code&gt;&lt;/a&gt;,
plus I've added &lt;kbd&gt;q&lt;/kbd&gt; as a binding to the quiz window to quickly quit
the quiz.&lt;/p&gt;
&lt;p&gt;I might have to come back and revisit it soon, as it looks like the default
face choices could probably do with a rethink, and I can see at the moment
that the attempt at a window-wide "header" for each question isn't working
any longer. For comparison, here's how the package looked when running back
when I first wrote it back in 2017:&lt;/p&gt;
&lt;p&gt;&lt;img alt="How it originally looked" src="https://blog.davep.org/attachments/2026/04/07/original-quiz.png" /&gt;&lt;/p&gt;
&lt;p&gt;Leaving aside the fact that I was &lt;a href="https://blog.davep.org/2020/06/14/my-journey-to-the-dark-side-is-complete.html"&gt;still running a very light Emacs
then&lt;/a&gt;, those
question headers are displaying differently, with the background colour no
longer spanning the width of the window. I'd like to understand why.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/07/quiz-el-v1-6.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>quiz.el</category>
      <pubDate>Tue, 07 Apr 2026 09:18:23 +0100</pubDate>
    </item>
    <item>
      <title>expando.el v1.5</title>
      <link>https://blog.davep.org/2026/04/06/expando-el-v1-5.html</link>
      <description>&lt;p&gt;While I have been doing a &lt;em&gt;lot&lt;/em&gt; of hacking on
&lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;, I haven't forgotten
my plan to revisit and refresh some of my older personal packages. This
evening I've paid some attention to
&lt;a href="https://github.com/davep/expando.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;expando.el&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This started life a &lt;em&gt;long&lt;/em&gt; time ago, as part of my grab-bag of handy
functions that got carried around and copied from machine to machine, until
I did a big tidy-up of everything back in 2017 and turned various things
into packages that I managed via a self-hosted (well, GitHub pages hosted)
package index.&lt;/p&gt;
&lt;p&gt;It's a pretty simple but very useful bit of code that lets me quickly
macroexpand a sexp at &lt;code&gt;point&lt;/code&gt; and pretty print it into a display window.
I've often found it indispensable when it came to writing my own macros.&lt;/p&gt;
&lt;p&gt;&lt;img alt="expando in action" src="https://blog.davep.org/attachments/2026/04/06/expando.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;This release simply adds a &lt;code&gt;lexical-binding&lt;/code&gt; header to the file, and also
adds a &lt;kbd&gt;q&lt;/kbd&gt; key binding to the resulting view window so that it can
be quickly and easily closed.&lt;/p&gt;
&lt;p&gt;Also, as with all my other personal packages, I've swapped away from using
&lt;a href="https://blog.davep.org/delpa/"&gt;delpa&lt;/a&gt; to simply using &lt;code&gt;:vc&lt;/code&gt; to pull it in.&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;expando&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:vc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/expando.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:rev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:newest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:bind&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-c e&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;expando-macro&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or perhaps I should say...&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;use-package-vc-install&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;expando&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/expando.el&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defvar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;use-package--warning69&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keyword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;msg&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%s/%s: %s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;expando&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;keyword&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;error-message-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;display-warning&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;condition-case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fboundp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;expando-macro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;autoload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;expando-macro&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;expando&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-c e&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kmap&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;symbolp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;symbol-value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="nv"&gt;global-map&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kdesc&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stringp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;key-description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;symbolp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;nil&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;binding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lookup-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kmap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;bind-key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;assoc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kdesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;personal-keybindings&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;details&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;expando-macro&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;numberp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setcdr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;details&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;personal-keybindings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kdesc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;details&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kmap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;expando-macro&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;debug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ne"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;funcall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;use-package--warning69&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/06/expando-el-v1-5.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>expando.el</category>
      <category>defmacro</category>
      <pubDate>Mon, 06 Apr 2026 20:43:29 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v4.0</title>
      <link>https://blog.davep.org/2026/04/06/blogmore-el-v4-0.html</link>
      <description>&lt;p&gt;Despite having bumped it from 2.x to 3.x
&lt;a href="https://blog.davep.org/2026/04/05/blogmore-el-v3-1.html"&gt;yesterday&lt;/a&gt;, I'm calling
&lt;a href="https://github.com/davep/blogmore.el/releases/tag/v4.0" rel="noopener noreferrer" target="_blank"&gt;v4.0&lt;/a&gt; on
&lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; today. There's a good
reason for this though. While tinkering with some of the configuration
yesterday, and also answering a configuration question last night, I
realised that it made sense to make some of the internals into public
utility functions.&lt;/p&gt;
&lt;p&gt;Now, sure, &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; doesn't really have &lt;em&gt;internals&lt;/em&gt; in
the private function sense, but I've always liked the approach that a
&lt;code&gt;package--&lt;/code&gt; prefix communicates &lt;em&gt;"internal, might go away"&lt;/em&gt; vs &lt;code&gt;package-&lt;/code&gt;
which tells me &lt;em&gt;"this is a stable part of the API of this package"&lt;/em&gt;. With
this in mind I've always tried to write my code using this convention. I did
this with &lt;code&gt;blogmore.el&lt;/code&gt; too and a &lt;em&gt;lot&lt;/em&gt; of the code had the &lt;code&gt;blogmore--&lt;/code&gt;
prefix.&lt;/p&gt;
&lt;p&gt;There's plenty of code in there that someone might want to make use of, if
they wanted to add their own commands, or do fun things with the
configuration. So with this in mind I've "promoted" a bunch of code to being
"public" and, in that case, I feel this deserves another major version
bump&lt;sup id="fnref:254-1"&gt;&lt;a class="footnote-ref" href="#fn:254-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Things that are now part of the "public" interface include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blogmore-clean-time-string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-get-frontmatter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-remove-frontmatter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-set-frontmatter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-slug&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-toggle-frontmatter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-with-post&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each one is documented via its docstring (just a quick
&lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;h&lt;/kbd&gt; &lt;kbd&gt;f&lt;/kbd&gt; &lt;code&gt;function-name&lt;/code&gt; &lt;kbd&gt;RET&lt;/kbd&gt;
away) and hopefully is pretty self-explanatory.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;blogmore-with-post&lt;/code&gt; is especially handy as it provides a quick and easy way
of pulling information from a post file. So something like this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-with-post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/davep.github.com/content/posts/2026/04/2026-04-05-blogmore-el-v3-1.md&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-get-frontmatter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-get-frontmatter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;resulting in:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blogmore.el v3.1&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2026-04-05 20:04:44+0100&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Meaning that this snippet from &lt;a href="https://blog.davep.org/2026/04/05/blogmore-el-v3-1.html"&gt;yesterday's
post&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;with-temp-buffer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;insert-file-contents-literally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;parse-iso8601-time-string&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--clean-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--get-frontmatter-property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;becomes:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-with-post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;parse-iso8601-time-string&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-clean-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-get-frontmatter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Not massively different, but it reads better and now all the calls are to
the "public API" of the package.&lt;/p&gt;
&lt;p&gt;Not all the changes are "promoted internals". I've also added a
&lt;code&gt;blogmore-remove-tag&lt;/code&gt; command (and also added it to the transient menu).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Removing a tag" src="https://blog.davep.org/attachments/2026/04/06/remove-tag.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;I've also changed the way that &lt;code&gt;blogmore-add-tag&lt;/code&gt; works so that, now, if
it's called from the transient, it immediately goes back to the tag input
prompt, allowing for another tag to be immediately selected (you can quit
out of this with &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;g&lt;/kbd&gt;). Removal of a tag works in a
similar way, making things a lot quicker.&lt;/p&gt;
&lt;p&gt;I've also added some extra tests too, which makes it even easier for me to
make future changes with confidence. The more I work with it the more I
appreciate that
&lt;a href="https://www.gnu.org/software/emacs/manual/html_mono/ert.html" rel="noopener noreferrer" target="_blank"&gt;ERT&lt;/a&gt; is
available.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:254-1"&gt;
&lt;p&gt;Ordinarily it shouldn't matter as the public interface isn't changing,
but some of the "internal" functions had been mentioned as options for
configuration.&amp;#160;&lt;a class="footnote-backref" href="#fnref:254-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/06/blogmore-el-v4-0.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <category>coding</category>
      <pubDate>Mon, 06 Apr 2026 17:04:16 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v3.1</title>
      <link>https://blog.davep.org/2026/04/05/blogmore-el-v3-1.html</link>
      <description>&lt;p&gt;When &lt;a href="https://blog.davep.org/2026/03/19/some-blogmore-elisp.html"&gt;I first started writing
&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; it was just going to be
a handful of commands that let me spin up a new blog post, and insert the
odd link here and there when needed. Initially it only handled a single
blog, and everything it did was based around how I lay my personal blog out,
and was also very much geared to how I'd made
&lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; work.&lt;/p&gt;
&lt;p&gt;But then I wanted to use it to edit both my personal blog &lt;em&gt;and&lt;/em&gt; my
&lt;a href="https://seen-by.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;photoblog&lt;/a&gt;. So then I had to add support for
configuring different ways of laying out posts for different blogs, etc.&lt;/p&gt;
&lt;p&gt;Still, it was mostly written as a personal tool that worked for my stuff. I
&lt;em&gt;tried&lt;/em&gt; to make it so that it was easy enough to configure (and let's be
fair: it's for Emacs and written in &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt;, it's
kind of hard to not be very configurable if you're happy to get your hands
dirty with some coding), but there were still some parts of it that weren't
as easy to change as I'd have liked.&lt;/p&gt;
&lt;p&gt;Also, when I'd originally added the multi-blog configuration, I'd chosen a
format for the list of blogs that was an assoc-list of pure lists wrapped by
a &lt;code&gt;cl-defstruct&lt;/code&gt; to make for easier access. It worked well but was very
positional in its nature.&lt;/p&gt;
&lt;p&gt;So when &lt;a href="https://mastodon.me.uk/@andyc/116348654225582976" rel="noopener noreferrer" target="_blank"&gt;the request came
in&lt;/a&gt; to be able to have
better control over the name of the file when starting a new post, which
meant I was going to need to rearrange the structure again, it was time to
try and do something about it.&lt;/p&gt;
&lt;p&gt;Which is how I'm now on v3.1 (yes, there was a
&lt;a href="https://github.com/davep/blogmore.el/releases/tag/v3.0" rel="noopener noreferrer" target="_blank"&gt;v3.0&lt;/a&gt; but I quickly
found something in that that needed fixing&lt;sup id="fnref:261-1"&gt;&lt;a class="footnote-ref" href="#fn:261-1"&gt;1&lt;/a&gt;&lt;/sup&gt;). It's a major version bump
because I've totally changed how the &lt;code&gt;blogmore-blogs&lt;/code&gt; variable holds the
data.&lt;/p&gt;
&lt;p&gt;From now on I'm using
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eieio/" rel="noopener noreferrer" target="_blank"&gt;EIEIO&lt;/a&gt; to
create a class that holds all of the data for a given blog. This, I believe,
makes the code easier to read and should also make it more resilient to the
addition of any new properties. Also thanks to &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eieio/Customizing.html" rel="noopener noreferrer" target="_blank"&gt;how such classes can work
with the customize
system&lt;/a&gt;
the &lt;code&gt;customize&lt;/code&gt; experience remains pretty much the same too.&lt;/p&gt;
&lt;p&gt;Personally I don't use the &lt;code&gt;customize&lt;/code&gt; UI, instead I declare everything
via &lt;code&gt;use-package&lt;/code&gt;. As of the time of writing my declaration for &lt;code&gt;blogmore&lt;/code&gt;
looks like this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:vc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/blogmore.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:rev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:newest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:init&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore-new-post-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;end-it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:custom&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blogs&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blog&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;:title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;:posts-directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/davep.github.com/content/posts/&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;:post-subdirectory-function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%Y/%m/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blog&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;:title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;seen-by.davep.dev&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;:posts-directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/seen-by/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:bind&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There's a bunch of other changes and tweaks under the hood in this release
too. All of these should come together to make &lt;code&gt;blogmore.el&lt;/code&gt; a little more
configurable than it was before. I think, to get the best out of it, anyone
wanting to configure it "just so" for their purposes will still have to do a
little bit of work, which makes me want to spend some time soon writing some
proper documentation, complete with examples of how you might achieve
different things.&lt;/p&gt;
&lt;p&gt;One big change I've made under the hood is to the code that is used when you
insert a link to a post (&lt;code&gt;blogmore-link-post&lt;/code&gt;). When this runs it lets me
pick a file in your filesystem that is a post from my currently-active blog.
Once it has the filename it needs to turn it into a root-relative link. So
this:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~/write/davep.github.com/content/posts/2026/04/01/2026-04-01-foo.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;needs to become:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/2026/04/01/foo.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Until now I just did some regexp faffing that took the &lt;code&gt;2026-04-01-&lt;/code&gt; at the
start of the filename and swapped each &lt;code&gt;-&lt;/code&gt; for &lt;code&gt;/&lt;/code&gt;. Nice and easy. Simple
enough to code up and get things working a few weeks back. Not at all
flexible.&lt;/p&gt;
&lt;p&gt;So as a proof-of-concept of how sophisticated someone could get with
configuring this I've changed &lt;code&gt;blogmore-default-post-maker-function&lt;/code&gt; from
this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defcustom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-default-post-maker-function&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;replace-regexp-in-string&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\\1/\\2/\\3/&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-sans-extension&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Default function to generate a link for a blog post from its filename.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;function&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and turned it into this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defcustom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-default-post-maker-function&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%s/%s&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format-time-string&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%Y/%m/%d&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;with-temp-buffer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;insert-file-contents-literally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;parse-iso8601-time-string&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--clean-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--get-frontmatter-property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;replace-regexp-in-string&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bol&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Default function to generate a link for a blog post from its filename.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;function&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So whereas before I was simply messing with the file's name, now I'm loading
the &lt;code&gt;date&lt;/code&gt; frontmatter from the chosen file and using &lt;em&gt;that&lt;/em&gt; to create the
date portion of the path in the URL that I use on my blog. The benefit here
is that someone might want to keep the date portion of the path in the URL,
but never want it as part of the Markdown source file's name, and so this
change means they can call the file anything they want; it doesn't look at
that but instead uses the actual date from the post's frontmatter.&lt;/p&gt;
&lt;p&gt;I think this nicely demonstrates that, especially thanks to how powerful
Emacs and Emacs Lisp are, it's fairly easy to make &lt;code&gt;blogmore.el&lt;/code&gt; work just
the way you want. I &lt;em&gt;think&lt;/em&gt; I've provided almost all the hooks necessary to
configure it all sorts of ways, but if you do happen to use it and run into
something I might have missed, &lt;a href="https://github.com/davep/blogmore.el/issues" rel="noopener noreferrer" target="_blank"&gt;let me
know&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:261-1"&gt;
&lt;p&gt;I have at least two slightly different &lt;code&gt;date&lt;/code&gt; formats going on in my
Markdown and Emacs' &lt;code&gt;parse-iso8601-time-string&lt;/code&gt; is kind of picky. So I
&lt;a href="https://github.com/davep/blogmore.el/pull/57/changes" rel="noopener noreferrer" target="_blank"&gt;added a function to try and clean that
up&lt;/a&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:261-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/05/blogmore-el-v3-1.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <category>coding</category>
      <category>EIEIO</category>
      <pubDate>Sun, 05 Apr 2026 20:04:44 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.7</title>
      <link>https://blog.davep.org/2026/04/04/blogmore-el-v2-7.html</link>
      <description>&lt;p&gt;There's no question that the
&lt;a href="https://blog.davep.org/2026/02/20/five-days-with-copilot.html"&gt;experiment&lt;/a&gt; that is
&lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; has resulted in me blogging more.
Although my previous setup wasn't exactly all friction, there's something
about "owning" most of the tools and really knowing how they work, and being
able to quickly modify them so they work "just so", that makes me more
inclined to quickly write something up.&lt;/p&gt;
&lt;p&gt;I can see this if I look at the &lt;a href="https://blog.davep.org/archive/"&gt;numbers in the archive for this
blog&lt;/a&gt;. In &lt;a href="https://blog.davep.org/2026/03/"&gt;March alone&lt;/a&gt; I wrote 43 posts; that's more
than I wrote in any whole year, other than &lt;a href="https://blog.davep.org/2023/"&gt;2023&lt;/a&gt;. While I suspect
this will start to calm down as work on BlogMore and
&lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; settles down, I sense
I'll be writing a bit more often for some time to come.&lt;/p&gt;
&lt;p&gt;Because of this I decided to do a little bit of housekeeping on the &lt;a href="https://github.com/davep/davep.github.com/tree/main/content/posts" rel="noopener noreferrer" target="_blank"&gt;posts
directory&lt;/a&gt;
in the blog's &lt;a href="https://github.com/davep/davep.github.com" rel="noopener noreferrer" target="_blank"&gt;source
repository&lt;/a&gt;. Originally I had the
Markdown source for every post all in one directory. Then last month &lt;a href="https://github.com/davep/davep.github.com/pull/59" rel="noopener noreferrer" target="_blank"&gt;I
broke those down by
year&lt;/a&gt;. Then earlier
today, seeing how this year is going, &lt;a href="https://github.com/davep/davep.github.com/pull/137" rel="noopener noreferrer" target="_blank"&gt;I decided to break 2026 down by
month&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then I realised I had a problem in &lt;code&gt;blogmore.el&lt;/code&gt;. It assumed that the
Markdown file for a new post (&lt;code&gt;blogmore-new&lt;/code&gt;) would always be created in a
subdirectory named after the year, underneath the defined posts directory.
Until today that was the case&lt;sup id="fnref:248-1"&gt;&lt;a class="footnote-ref" href="#fn:248-1"&gt;1&lt;/a&gt;&lt;/sup&gt;, but now &lt;em&gt;I&lt;/em&gt; wanted it to work
differently.&lt;/p&gt;
&lt;p&gt;So this is why I'm making a second release in one day: &lt;a href="https://github.com/davep/blogmore.el/pull/45" rel="noopener noreferrer" target="_blank"&gt;I added the ability
to configure the subdirectory where a new post is
created&lt;/a&gt;. I've changed the
default now so that it assumes the user wants the subdirectory to be
&lt;code&gt;YYYY/MM/DD&lt;/code&gt; (because more granular feels like the right default). In my
case I don't want that, I just want &lt;code&gt;YYYY/MM&lt;/code&gt;, but now I can configure that.
The value that is set is a function that returns the name of the
subdirectory, so in the case of my blog I have it as:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%Y/%m/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the other hand, for my &lt;a href="https://seen-by.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;photoblog&lt;/a&gt; I want the
full date as a subdirectory so I can leave it as the default. The whole
&lt;code&gt;use-package&lt;/code&gt; for &lt;code&gt;blogmore&lt;/code&gt; now looks like:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:vc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/blogmore.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:rev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:newest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:init&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore-new-post-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;end-it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:custom&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blogs&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;;; Root directory for posts.&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/davep.github.com/content/posts/&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;;; Subdirectory for new posts, relative to the root.&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%Y/%m/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;seen-by.davep.dev&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;;; Root directory for posts.&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/seen-by/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:bind&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Technically this is a breaking change because it bumps &lt;a href="https://github.com/davep/blogmore.el/blob/b80743391eedeb507c5b743c1af531701a2f858a/blogmore.el#L48-L86" rel="noopener noreferrer" target="_blank"&gt;the meaning of each
"position" in the values within
&lt;code&gt;blogmore-blogs&lt;/code&gt;&lt;/a&gt;.
However, in my case, because I was only ever defining the blog name and the
top-level directory for the posts (both mandatory), this didn't break
anything; I also strongly suspect nobody else is using this so I very much
doubt I'm messing with someone else's setup&lt;sup id="fnref:248-2"&gt;&lt;a class="footnote-ref" href="#fn:248-2"&gt;2&lt;/a&gt;&lt;/sup&gt;. If I have I apologise; do
let me know.&lt;/p&gt;
&lt;p&gt;Anyway, all of this goes to explain why the heck I made two releases of the
same package back to back in the same day. This is what happens when &lt;a href="https://www.metoffice.gov.uk/about-us/news-and-media/media-centre/weather-and-climate-news/2026/amber-wind-warning-for-easter" rel="noopener noreferrer" target="_blank"&gt;my
namesake is having fun
outside&lt;/a&gt;
and so I just want to sit on the sofa, hack on some code, and watch the
chaos in the garden.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:248-1"&gt;
&lt;p&gt;For my blog, which again shows that &lt;code&gt;blogmore.el&lt;/code&gt; started as a quick
hack for getting work done on my blog, but I also want to make it as
configurable as possible.&amp;#160;&lt;a class="footnote-backref" href="#fnref:248-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:248-2"&gt;
&lt;p&gt;Even if someone else &lt;em&gt;is&lt;/em&gt; using this I would suspect they hadn't
configured anything more than I have.&amp;#160;&lt;a class="footnote-backref" href="#fnref:248-2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/04/blogmore-el-v2-7.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <category>coding</category>
      <category>transient</category>
      <pubDate>Sat, 04 Apr 2026 19:24:39 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.6</title>
      <link>https://blog.davep.org/2026/04/04/blogmore-el-v2-6.html</link>
      <description>&lt;p&gt;Like most people, I imagine, I first ran into
&lt;a href="https://www.gnu.org/software/emacs/manual/html_mono/transient.html" rel="noopener noreferrer" target="_blank"&gt;transient&lt;/a&gt;
when first using &lt;a href="https://magit.vc/" rel="noopener noreferrer" target="_blank"&gt;magit&lt;/a&gt;. I took to it pretty quickly and
it's always made sense to me as a user interface. But... I've never used it
for any code I've ever written.&lt;/p&gt;
&lt;p&gt;I think, incorrectly, I'd half assumed it was going to be some faff to set
up, and of course for a good while it wasn't part of Emacs anyway. Given
this, I'd always had it filed under the heading &lt;em&gt;"that's so neat I'll give
it a go one day but not at the moment"&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Meanwhile... ever since I did the last big revamp of my &lt;a href="https://github.com/davep/.emacs.d" rel="noopener noreferrer" target="_blank"&gt;Emacs
configuration&lt;/a&gt;, I found myself leaning
into a command binding approach that does the whole &lt;em&gt;prefix-letter-letter&lt;/em&gt;
thing. For reasons I can't actually remember I fell into the habit of using
&lt;kbd&gt;F12&lt;/kbd&gt;&lt;sup id="fnref:244-1"&gt;&lt;a class="footnote-ref" href="#fn:244-1"&gt;1&lt;/a&gt;&lt;/sup&gt; as my chosen prefix key. As such, over the past 10 or so
years (since I greatly overhauled my Emacs setup), I've got into setting up
bindings for commands that follow this prefix convention.&lt;/p&gt;
&lt;p&gt;So when I created &lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; I
set up the commands following this pattern.&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:vc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/blogmore.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:rev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:newest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:init&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore-new-post-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;end-it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:custom&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blogs&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/davep.github.com/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;seen-by.davep.dev&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/seen-by/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:bind&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b n&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b e&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-edit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b d&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-toggle-draft&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b s c&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-set-category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b a t&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-add-tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b u d&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-update-date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b u m&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-update-modified&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b l p&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b l c&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b l t&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-tag&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It works well, it makes it nice and easy to remember the bindings, etc.
Nobody needs me to sell them on the merits of this approach.&lt;/p&gt;
&lt;p&gt;Then I got to thinking last night: why am I setting up all those bindings
when I could probably do it all via a transient? So that was the moment to
actually RTFM and get it going. The first version was incredibly quick to
get up and running and I was kicking myself that I'd taken so long to
actually look at the package properly.&lt;/p&gt;
&lt;p&gt;This morning I've worked on it a little more and the final form is still
pretty straightforward.&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;transient-define-prefix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Show a transient for BlogMore commands.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;:description&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;BlogMore: %s\n&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--chosen-blog-sans-error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;No blog selected&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Blog&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Select blog&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Post&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;n&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;New post&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--chosen-blog-sans-error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;e&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Edit post&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-edit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--chosen-blog-sans-error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Toggle draft status&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-toggle-draft&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Set post category&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-set-category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;t&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Add tag&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-add-tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;u d&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Update date&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-update-date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;u m&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Update modified date&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-update-modified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Links&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;l c&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Link to a category&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-category&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;l p&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Link to a post&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;l t&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Link to a tag&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:inapt-if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-p&lt;/span&gt;&lt;span class="p"&gt;)]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With this in place I can simplify my &lt;code&gt;use-package&lt;/code&gt; quite a bit, just binding
a single key to run &lt;code&gt;blogmore&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:vc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/blogmore.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:rev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:newest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:init&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore-new-post-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;end-it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:custom&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blogs&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/davep.github.com/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;seen-by.davep.dev&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/seen-by/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:bind&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, when I'm working on a blog post, I can just hit &lt;kbd&gt;F12&lt;/kbd&gt;
&lt;kbd&gt;b&lt;/kbd&gt; and I get a neat menu:&lt;/p&gt;
&lt;p&gt;&lt;img alt="BlogMore with all commands available" src="https://blog.davep.org/attachments/2026/04/04/transient-all.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;Better still, because of how &lt;code&gt;transient&lt;/code&gt; works, I can ensure that only
applicable commands are available, while still showing them all. So if I've
not even got a blog selected yet:&lt;/p&gt;
&lt;p&gt;&lt;img alt="With no commands available" src="https://blog.davep.org/attachments/2026/04/04/transient-none.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;Or with a blog selected but not actually working on a post yet:&lt;/p&gt;
&lt;p&gt;&lt;img alt="With some commands available" src="https://blog.davep.org/attachments/2026/04/04/transient-some.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;So far I'm really liking this approach, and I'm tempted to lean into
transient more with some of my packages now. While on the surface it does
seem that it has the downside of the binding choices being dictated by me,
the fact is that the commands are all still there and anyone can use their
own bindings, or I guess override the transient itself and do their own
thing.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:244-1"&gt;
&lt;p&gt;Yes, it is a bit out of the way on the keyboard, but so is
&lt;kbd&gt;Esc&lt;/kbd&gt;. I find my muscle memory has no problem with it.&amp;#160;&lt;a class="footnote-backref" href="#fnref:244-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/04/blogmore-el-v2-6.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <category>coding</category>
      <category>transient</category>
      <pubDate>Sat, 04 Apr 2026 11:48:21 +0100</pubDate>
    </item>
    <item>
      <title>nukneval.el v1.3</title>
      <link>https://blog.davep.org/2026/04/03/nukneval-el-v1-3.html</link>
      <description>&lt;p&gt;Back when I first really got into writing &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt;
code, one of the first things I got &lt;em&gt;very&lt;/em&gt; used to and really fell in love
with was being able to
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Eval.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;eval-last-sexp&lt;/code&gt;&lt;/a&gt;
(&lt;kbd&gt;C-x&lt;/kbd&gt; &lt;kbd&gt;C-e&lt;/kbd&gt;) the code I was writing, either to test it
right there in the buffer, or to cause it to be bound so I could use it
elsewhere. It was so different from any other mode of working I'd used
before and it was really addictive as a way of hacking on code.&lt;/p&gt;
&lt;p&gt;Also quite quickly I got used to the fact that &lt;code&gt;eval-last-sexp&lt;/code&gt; wasn't so
helpful with things like a &lt;code&gt;defvar&lt;/code&gt; or a &lt;code&gt;defconst&lt;/code&gt;, if I was changing them
up to try out new ways of doing things with the code I was working on; there
I had to remember to get used to using &lt;code&gt;eval-defun&lt;/code&gt; (&lt;kbd&gt;C-M-x&lt;/kbd&gt;).
Hardly a great problem, but something to keep in mind&lt;sup id="fnref:246-1"&gt;&lt;a class="footnote-ref" href="#fn:246-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Pretty quickly, as I worked on longer packages, I found myself wanting to,
in effect, unload a whole buffer of code and evaluate it again. From this
desire came &lt;a href="https://github.com/davep/nukneval.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;nukneval.el&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The original version of this has been sat around since 2002 or so, perhaps a
little earlier, and has served me well every time I've been messing with a
new package. While I suspect there is (now, perhaps was then too?) a better
way of doing things, the approach used in nukneval helped me learn some
things and served me well (and still does). Now it's muscle-memory to run
it.&lt;/p&gt;
&lt;p&gt;The way it works is quite simple: go to the start of a buffer, &lt;code&gt;read&lt;/code&gt; each
form, check if the &lt;code&gt;car&lt;/code&gt; is of a given list of symbols, decide if it's
something I want to unbind, and then pick either &lt;code&gt;makunbound&lt;/code&gt; or
&lt;code&gt;fmakunbound&lt;/code&gt; and use that on the symbol. Finally, once the end of the
buffer has been hit: &lt;code&gt;eval-buffer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I've just released v1.3 as part of my slow wander through my old Emacs Lisp
packages, with this release cleaning up a deprecated use of &lt;code&gt;setf&lt;/code&gt; to move
&lt;code&gt;point&lt;/code&gt;, and also rewriting the code so it's a bit cleaner and also gives
better feedback.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:246-1"&gt;
&lt;p&gt;&lt;a href="https://emacsredux.com/about/" rel="noopener noreferrer" target="_blank"&gt;Bozhidar Batsov&lt;/a&gt; recently wrote a good
post &lt;a href="https://emacsredux.com/blog/2026/03/25/reloading-emacs-lisp-code/" rel="noopener noreferrer" target="_blank"&gt;covering these sorts of
issues&lt;/a&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:246-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/03/nukneval-el-v1-3.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>nukneval.el</category>
      <pubDate>Fri, 03 Apr 2026 15:09:19 +0100</pubDate>
    </item>
    <item>
      <title>make-phony.el v1.3</title>
      <link>https://blog.davep.org/2026/04/03/make-phony-el-v1-3.html</link>
      <description>&lt;p&gt;A wee bit over 5 years back &lt;a href="https://blog.davep.org/2019/12/01/being-phony-and-lispy-regular-expressions.html"&gt;I wrote a tiny package to quickly insert PHONY
target markers into a
&lt;code&gt;Makefile&lt;/code&gt;&lt;/a&gt;.
While it's far from my most-used package, it's one that gets a call on
occasion, so it's one I still carry around in my &lt;a href="https://github.com/davep/.emacs.d" rel="noopener noreferrer" target="_blank"&gt;Emacs
configuration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Given I'm currently engaging in a slow background process of cleaning up
some of my &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; packages, removing some &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;obsoleted
practices&lt;/a&gt;, I've given
&lt;a href="https://github.com/davep/make-phony.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;make-phony.el&lt;/code&gt;&lt;/a&gt; a little bit of
attention.&lt;/p&gt;
&lt;p&gt;As well as &lt;a href="https://github.com/davep/make-phony.el/pull/1/changes" rel="noopener noreferrer" target="_blank"&gt;dropping the use of &lt;code&gt;setf&lt;/code&gt; to set &lt;code&gt;point&lt;/code&gt; to the start of a
line&lt;/a&gt;, I also tweaked
the code a little &lt;a href="https://github.com/davep/make-phony.el/pull/2/changes" rel="noopener noreferrer" target="_blank"&gt;so that it only inserts a &lt;code&gt;PHONY&lt;/code&gt; if there isn't already
one there&lt;/a&gt;. While
that's hardly been a problem for me, it just felt like a neat bit of
cleaning up to how it works.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/03/make-phony-el-v1-3.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>make-phony.el</category>
      <pubDate>Fri, 03 Apr 2026 10:23:40 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.5</title>
      <link>https://blog.davep.org/2026/04/02/blogmore-el-v2-5.html</link>
      <description>&lt;p&gt;Following on from &lt;a href="https://blog.davep.org/2026/04/01/blogmore-el-v2-4.html"&gt;yesterday's release&lt;/a&gt;,
I've bumped &lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; to v2.5.
The main change to the package is the thing I mentioned yesterday about the
toggle of the &lt;code&gt;draft&lt;/code&gt; status. The &lt;code&gt;draft&lt;/code&gt; toggle yesterday was pretty
simple, with it working like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If there is no &lt;code&gt;draft&lt;/code&gt; frontmatter, &lt;code&gt;draft: true&lt;/code&gt; is added&lt;/li&gt;
&lt;li&gt;If there is any &lt;code&gt;draft&lt;/code&gt; frontmatter, it is removed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This meant that if you had &lt;code&gt;draft: false&lt;/code&gt; set and you went to toggle, it
would be removed, which is the same as setting it to &lt;code&gt;draft: false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unlikely to generally be an issue, but I also couldn't let that stay like
that. It bothered me.&lt;/p&gt;
&lt;p&gt;So now it works as you'd expect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If there is no &lt;code&gt;draft&lt;/code&gt; frontmatter, &lt;code&gt;draft: true&lt;/code&gt; is added&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;draft: true&lt;/code&gt; is there, it is removed&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;draft: false&lt;/code&gt; is there, it is set to &lt;code&gt;draft: true&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Much better.&lt;/p&gt;
&lt;p&gt;Another change is that I fixed a problem with older supported versions of
Emacs. I didn't know this was a problem because I'm running 30.2 everywhere.
Meanwhile, thanks to &lt;code&gt;package-lint-current-buffer&lt;/code&gt; from
&lt;a href="https://github.com/purcell/package-lint" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;package-lint.el&lt;/code&gt;&lt;/a&gt;, I have:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Package-Requires: ((emacs &amp;quot;29.1&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;in the metadata for the package. Turns out though that
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eintr/Sorting.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/a&gt;
used to require two parameters (the sequence and the predicate), whereas now
it's fine with just one (it will accept just the sequence and will default
the predicate). So of course &lt;code&gt;blogmore.el&lt;/code&gt; was working fine for me, but
would have crashed for someone with an earlier Emacs.&lt;/p&gt;
&lt;p&gt;As for how I found this out... well I finally, for the first time ever,
dived into using
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/ert/index.html" rel="noopener noreferrer" target="_blank"&gt;ERT&lt;/a&gt; to
write &lt;a href="https://github.com/davep/blogmore.el/blob/34ed59bbe11d31b10382c244188bc3afb7c2f8d8/blogmore-tests.el" rel="noopener noreferrer" target="_blank"&gt;some
tests&lt;/a&gt;.
While I've used testing frameworks in other languages, I'd never looked at
this with &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt;. It works a treat and is great to
work with; I think I'll be using this a lot more from now on.&lt;/p&gt;
&lt;p&gt;Having got tests going I realised I should run them with GitHub actions,
which then meant I managed to discover
&lt;a href="https://github.com/marketplace/actions/set-up-emacs" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;setup-emacs&lt;/code&gt;&lt;/a&gt;. Having
found this the next logical step was to &lt;a href="https://github.com/davep/blogmore.el/blob/34ed59bbe11d31b10382c244188bc3afb7c2f8d8/.github/workflows/tests.yml" rel="noopener noreferrer" target="_blank"&gt;set up a matrix test for all the
versions of Emacs I expect &lt;code&gt;blogmore.el&lt;/code&gt; to work
on&lt;/a&gt;.
This worked fine, except... it didn't. While the tests worked locally, they
were failing for some Emacsen over on GitHub.&lt;/p&gt;
&lt;p&gt;And that's how I discovered the issue with &lt;code&gt;sort&lt;/code&gt; on versions earlier than
the one I'm using locally.&lt;/p&gt;
&lt;p&gt;All in all, that was a good little period of hacking. New things discovered,
the package improved, and a wider range of support for different versions of
Emacs.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/02/blogmore-el-v2-5.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <category>coding</category>
      <category>testing</category>
      <pubDate>Thu, 02 Apr 2026 20:53:09 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.4</title>
      <link>https://blog.davep.org/2026/04/01/blogmore-el-v2-4.html</link>
      <description>&lt;p&gt;I've just released a little update to
&lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;, adding
&lt;code&gt;blogmore-toggle-draft&lt;/code&gt; as a command. This came about in connection with the
feature request that resulted in &lt;a href="https://blog.davep.org/2026/04/01/blogmore-v2-7-0.html"&gt;BlogMore v2.7.0 being
released&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While I don't personally use &lt;code&gt;draft&lt;/code&gt; for my posts, I can see the utility of
it and if someone were to happen to use &lt;code&gt;blogmore.el&lt;/code&gt;, it could be useful to
have this bound to a handy key combination.&lt;/p&gt;
&lt;p&gt;As for how it works: that's simple. When run, if there is no &lt;code&gt;draft:&lt;/code&gt;
frontmatter property, then &lt;code&gt;draft: true&lt;/code&gt; is added. If &lt;code&gt;draft:&lt;/code&gt; is there it
is removed. Yes, it does mean that it will also remove &lt;code&gt;draft: false&lt;/code&gt; too
but... eh. Okay, fine, I &lt;em&gt;might&lt;/em&gt; handle that case as a followup but I
couldn't really imagine someone wanting to keep &lt;code&gt;draft: false&lt;/code&gt; in the
frontmatter.&lt;/p&gt;
&lt;p&gt;If a post is ready to go, why bother with a header that means the same thing
when it's not there?&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/01/blogmore-el-v2-4.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>blogmore.el</category>
      <pubDate>Wed, 01 Apr 2026 20:00:44 +0100</pubDate>
    </item>
    <item>
      <title>binclock.el v1.12</title>
      <link>https://blog.davep.org/2026/04/01/binclock-el-v1-12.html</link>
      <description>&lt;p&gt;Some time in the late 1990s, after I'd been using GNU Emacs for a few
years&lt;sup id="fnref:249-1"&gt;&lt;a class="footnote-ref" href="#fn:249-1"&gt;1&lt;/a&gt;&lt;/sup&gt;, I grabbed a copy of &lt;a href="https://www.oreilly.com/library/view/writing-gnu-emacs/9781449395056/" rel="noopener noreferrer" target="_blank"&gt;Writing GNU Emacs
Extensions&lt;/a&gt;.
While I'd obviously created and added to and tinkered with my &lt;code&gt;~/.emacs&lt;/code&gt;
some, I'd never written any non-trivial code. I feel it was around 1998 or
1999 that I really started to get into trying to write actual extensions,
thanks to that book.&lt;/p&gt;
&lt;p&gt;I can't remember what the first complete package was. I &lt;em&gt;think&lt;/em&gt; it was
actually &lt;code&gt;5x5.el&lt;/code&gt;&lt;sup id="fnref:249-2"&gt;&lt;a class="footnote-ref" href="#fn:249-2"&gt;2&lt;/a&gt;&lt;/sup&gt; but it might also have been
&lt;a href="https://github.com/davep/binclock.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;binclock.el&lt;/code&gt;&lt;/a&gt;. Honestly, it's so
long ago now that I don't have any good recollection and I don't have any
record&lt;sup id="fnref:249-3"&gt;&lt;a class="footnote-ref" href="#fn:249-3"&gt;3&lt;/a&gt;&lt;/sup&gt;. All of which is to say, &lt;code&gt;binclock.el&lt;/code&gt; is one of my oldest bits
of &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; code, so it seemed fair that while I'm
cleaning things up, I should give it a tidy too.&lt;/p&gt;
&lt;p&gt;For anyone curious: it's a very simple binary clock type of thing. It opens
a very small window and, depending on your settings, shows the time in
various ways, all of which are in some way a binary display.&lt;/p&gt;
&lt;p&gt;I can't say I've honestly ever had it running for more than a few moments,
as an amusement, but I do remember it being a really helpful body of code to
work on to help get familiar with Elisp. So, 27 years on from when I first
opened the buffer to create it, it's tweaked and tidied and hopefully ready
for another 27.&lt;/p&gt;
&lt;p&gt;Would be cool if I'm around long enough to give it yet another tweak then.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:249-1"&gt;
&lt;p&gt;I first met it on OS/2 of all places, in 1994, or thereabouts.&amp;#160;&lt;a class="footnote-backref" href="#fnref:249-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:249-2"&gt;
&lt;p&gt;Yes, the one that became &lt;code&gt;Tools &amp;gt; Games &amp;gt; 5x5&lt;/code&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:249-2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:249-3"&gt;
&lt;p&gt;If I was using version control at all then, it was probably just
&lt;code&gt;rcs&lt;/code&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:249-3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/01/binclock-el-v1-12.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>binclock.el</category>
      <pubDate>Wed, 01 Apr 2026 14:30:18 +0100</pubDate>
    </item>
    <item>
      <title>obfusurl.el v2.2</title>
      <link>https://blog.davep.org/2026/04/01/obfusurl-el-v2-2.html</link>
      <description>&lt;p&gt;This bit of &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; absolutely comes from a more
innocent time on the Internet. Looking at it, it seems I wrote the first
version, at least as a proper package, back in 2001. It's very possible that
I carried a non-package version of it around as part of &lt;code&gt;dp-lib.el&lt;/code&gt;&lt;sup id="fnref:265-1"&gt;&lt;a class="footnote-ref" href="#fn:265-1"&gt;1&lt;/a&gt;&lt;/sup&gt; for
some time before, so it might date from the late 1990s. While we weren't
absolutely &lt;em&gt;innocent&lt;/em&gt; back then, the idea of a slightly-risky-looking URL
wasn't quite so bad as it is now.&lt;/p&gt;
&lt;p&gt;So &lt;code&gt;obfusurl.el&lt;/code&gt; came about from my time on Usenet, where sometimes you'd
want to post a URL that would otherwise be a spoiler. This package was my
solution to that. It's a simple idea: keep the protocol and domain and so on
visible, just hide the remaining part. So rather than post:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://blog.davep.org/about/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You'd post:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://blog.davep.org/%61%62%6f%75%74/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I &lt;em&gt;suppose&lt;/em&gt; this is still useful today, although I would expect a lot of
people to be way less likely to want to attempt that click -- readable
domain or not.&lt;/p&gt;
&lt;p&gt;But, anyway, the code needed a tidy and cleanup for today's Emacs and Emacs
Lisp. So &lt;a href="https://github.com/davep/obfusurl.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;obfusurl.el&lt;/code&gt; v2.2&lt;/a&gt; now
exists.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:265-1"&gt;
&lt;p&gt;For a good chunk of my first decade of using Emacs, I carried a lot of
personal code around in a rather large "library" file.&amp;#160;&lt;a class="footnote-backref" href="#fnref:265-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/01/obfusurl-el-v2-2.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>obfusurl.el</category>
      <pubDate>Wed, 01 Apr 2026 10:13:57 +0100</pubDate>
    </item>
    <item>
      <title>eg.el v1.2</title>
      <link>https://blog.davep.org/2026/03/31/eg-el-v1-2.html</link>
      <description>&lt;p&gt;Okay, that's it then; this is &lt;a href="https://blog.davep.org/2026/03/31/thinks-el-v1-13.html"&gt;turning into a thing I
think&lt;/a&gt;. Second in an occasional series of
posts where I tidy up some of my old &lt;a href="https://elisp.dev/" rel="noopener noreferrer" target="_blank"&gt;Emacs packages&lt;/a&gt;.
This time I dug out &lt;a href="https://github.com/davep/eg.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;eg.el&lt;/code&gt;&lt;/a&gt; and cleaned up
some of the &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;frowned-upon
behaviour&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For anyone who doesn't know it: &lt;code&gt;eg.el&lt;/code&gt; is one of &lt;em&gt;many&lt;/em&gt; &lt;a href="https://blog.davep.org/tag/norton-guide/"&gt;Norton
Guide&lt;/a&gt; readers &lt;a href="https://www.davep.org/norton-guides/" rel="noopener noreferrer" target="_blank"&gt;I've written over the
years&lt;/a&gt;. This particular one was
possibly the most fun as it was the most unlikely one to write and also, I
think it's fair to say, my most ambitious one as well. It also holds a
special place for me in that the bulk of it was written &lt;a href="https://blog.davep.org/tag/virgin/"&gt;on
trains&lt;/a&gt; during multiple trips up to Scotland, before I finally
moved here (on the &lt;a href="https://blog.davep.org/2016/04/28/i-now-own-a-macbook.html"&gt;MacBook Air&lt;/a&gt; I
&lt;a href="https://blog.davep.org/2026/03/27/macbook-air-m5.html"&gt;mentioned the other day&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;As I look at it now, I sort of want to give it a proper revisit. I've
written more Norton Guide code since (see &lt;a href="https://blog.davep.org/2025/03/12/aging.html"&gt;AgiNG&lt;/a&gt;
for example) and have learnt better ways to handle certain things, and I
also have an even bigger &lt;a href="https://blog.davep.org/2025/12/12/norton-guide-collection.html"&gt;Norton Guide
collection&lt;/a&gt; to test against. All
of this could make for an even better Emacs implementation.&lt;/p&gt;
&lt;p&gt;I also suspect that, this time around, I can do a better job of handling the
colour and retaining the original Norton Guide reader look and feel. But,
for now, the code has been tidied up and should keep working for some time
yet.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/31/eg-el-v1-2.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>Norton Guide</category>
      <category>coding</category>
      <category>eg.el</category>
      <pubDate>Tue, 31 Mar 2026 21:10:58 +0100</pubDate>
    </item>
    <item>
      <title>thinks.el v1.13</title>
      <link>https://blog.davep.org/2026/03/31/thinks-el-v1-13.html</link>
      <description>&lt;p&gt;Given the recent spate of &lt;a href="https://blog.davep.org/tag/blogmore-el/"&gt;hacking on some Emacs Lisp&lt;/a&gt;,
I've got a real taste for hacking on some more. Or, more to the point,
revisiting some of the packages I have in &lt;a href="https://melpa.org/#/" rel="noopener noreferrer" target="_blank"&gt;Melpa&lt;/a&gt; and
tidying them up where necessary.&lt;/p&gt;
&lt;p&gt;The main thing I'll need to address is cutting back on &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;all my old &lt;code&gt;setf&lt;/code&gt;
ways&lt;/a&gt;. I liked that approach to
doing things, it made lots of sense and felt elegant; sadly the Emacs
maintainers didn't seem to agree.&lt;/p&gt;
&lt;p&gt;So... kicking this off I've released v1.13 of
&lt;a href="https://github.com/davep/thinks.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;thinks.el&lt;/code&gt;&lt;/a&gt;. This is a bit of nonsense
I wrote back in the days when Usenet was still pretty busy and &lt;em&gt;the&lt;/em&gt; place
to be (well, okay, back in 2000 when I was still hanging out on Usenet). The
package itself lets you quickly and easily...&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;. o O ( ...write some text and then mark it all and then run a command and )
      ( have it turned into something that looks a little like a thought   )
      ( bubble.                                                            )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It has some variations on how the bubble looks, and also lets you use
&lt;code&gt;customize&lt;/code&gt; to tweak the characters to use, and also has an "extra silly"
mode too.&lt;/p&gt;
&lt;p&gt;Updating this wasn't too bad. Mostly just a case of turning some instances
of &lt;code&gt;(setf (point) ...)&lt;/code&gt; into &lt;code&gt;(goto-char ...)&lt;/code&gt;, and also modifying one
instance of &lt;code&gt;incf&lt;/code&gt; to be &lt;code&gt;cl-incf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Honestly, I don't know how useful this package is to anyone anymore. Most
folk don't even know what Usenet is these days, and all the "social" places
seem to favour non-monospaced fonts, meaning the bubbles would look pretty
terrible anyway.&lt;/p&gt;
&lt;p&gt;On the other hand, it seems a shame to not update it, and perhaps someone
somewhere still uses it to make some pithy parenthetical remark, possibly
about &lt;a href="https://en.wikipedia.org/wiki/Eternal_September" rel="noopener noreferrer" target="_blank"&gt;September never
ending&lt;/a&gt;.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/31/thinks-el-v1-13.html</guid>
      <category>Emacs</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>coding</category>
      <category>thinks.el</category>
      <pubDate>Tue, 31 Mar 2026 19:35:16 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.3</title>
      <link>https://blog.davep.org/2026/03/31/blogmore-el-v2-3.html</link>
      <description>&lt;p&gt;I've bumped &lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; to v2.3.
The main change in this release, which I've had on my mental to-do list for
a couple of days now, revolves around categories, tags and case.&lt;/p&gt;
&lt;p&gt;I've got &lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; set up so that it's pretty
relaxed about case when it comes to categories and tags; so when it comes to
generated files and URLs everything collapses to lowercase. However,
&lt;code&gt;blogmore.el&lt;/code&gt; wasn't taking this into account.&lt;/p&gt;
&lt;p&gt;While it wasn't a serious issue, it did have the side-effect that, if you
had a tag of &lt;code&gt;lisp&lt;/code&gt; and a tag of &lt;code&gt;Lisp&lt;/code&gt;, both would appear in the list of
tags you could complete from. Also, when you went to add a tag to the tags
frontmatter (via the &lt;code&gt;blogmore-add-tag&lt;/code&gt; command), if you selected &lt;code&gt;Lisp&lt;/code&gt; and
&lt;code&gt;lisp&lt;/code&gt; was already there, you'd end up with both versions after the command
finished.&lt;/p&gt;
&lt;div class="admonition admonition-note"&gt;
&lt;div class="admonition-title"&gt;ℹ️ Note&lt;/div&gt;
&lt;div class="admonition-content"&gt;
&lt;p&gt;As mentioned earlier: BlogMore itself would collapse &lt;code&gt;Lisp&lt;/code&gt; and &lt;code&gt;lisp&lt;/code&gt; to
the same tag; the downside here is you'd see both tags shown in the post
itself. Not a real problem, just not very tidy.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So earlier I changed things up a little; first &lt;a href="https://github.com/davep/blogmore.el/pull/30/changes" rel="noopener noreferrer" target="_blank"&gt;cleaning up when loading
pre-existing values&lt;/a&gt;
and then &lt;a href="https://github.com/davep/blogmore.el/pull/31/changes" rel="noopener noreferrer" target="_blank"&gt;ensuring the newly-set tags are
deduplicated&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This now means I can edit and update a post even faster, without needing to
worry about accidentally duplicating tags. This in turn reduces the friction
to writing a post for my blog. That is, after all, the whole point of the
name of the package and the blogging tool it's connected to!&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/31/blogmore-el-v2-3.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Coding</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <pubDate>Tue, 31 Mar 2026 15:31:41 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.2</title>
      <link>https://blog.davep.org/2026/03/30/blogmore-el-v2-2.html</link>
      <description>&lt;p&gt;It really feels like &lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; has kicked off
a whole new thing when it comes to personal hacking. During the past few
years I've developed a &lt;em&gt;lot&lt;/em&gt; of &lt;a href="https://blog.davep.org/tag/python/"&gt;Python&lt;/a&gt; applications and
libraries, and have had a ton of fun doing so, but during that time I've not
really done anything with writing stuff for &lt;a href="https://blog.davep.org/tag/emacs/"&gt;Emacs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To a large degree I think this says something about how stable Emacs is for
me (I've been using it for a touch over 30 years at this point, you'd think
I'd be kind of settled with it), but it's still always fun to have a reason
to hack on some &lt;a href="https://blog.davep.org/tag/lisp/"&gt;Lisp&lt;/a&gt; code. There's little doubt my Lisp --
especially Emacs Lisp -- has got a wee bit rusty.&lt;/p&gt;
&lt;p&gt;So I'm having a lot of fun at the moment falling into the rabbit hole of
expanding on and tinkering with
&lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;. The reason I've just
made v2.2 is a good example of exactly this. There are no real user-facing
changes in the code, it was all things I just wanted to tidy up.&lt;/p&gt;
&lt;p&gt;The main thing that has been bugging me for the past day is the repeating
boilerplate that resulted from adding all the different current-blog-aware
setting getter functions. There were 7 different functions, all looking like
this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--post-maker-function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Get the post maker function for the current blog.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--blog-post-maker-function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--chosen-blog&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;blogmore-default-post-maker-function&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Exact same pattern, the only thing different being the name of the getter
function being called on, and the name of the variable that contained the
global default value.&lt;/p&gt;
&lt;p&gt;So just a little earlier I cleaned this up using one of my favourite things
about Lisp: &lt;code&gt;defmacro&lt;/code&gt;. There's something about macros that makes me really
like coding in Lisp, and which I cite as a &lt;em&gt;really good thing&lt;/em&gt; when asked
why I like Lisp, but which I always seem to utterly fail to explain well.
Macros feel like one of those things you just have to experience for
yourself to really get&lt;sup id="fnref:232-1"&gt;&lt;a class="footnote-ref" href="#fn:232-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Now, thanks to this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Generate a function to get the value of SETTING for the current blog.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;intern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blogmore--%s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Get the %s for the current blog.&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;intern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blogmore--blog-%s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--chosen-blog&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;intern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blogmore-default-%s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;all those 7 functions can collapse to this&lt;sup id="fnref:232-2"&gt;&lt;a class="footnote-ref" href="#fn:232-2"&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;post-template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;post-maker-function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;category-maker-function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tag-maker-function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;post-link-format&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;category-link-format&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore--setting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tag-link-format&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now the code is shorter, cleaner, and if I need to change anything I only
need to change it in one place. Sure, the latter part especially is one of
those &lt;em&gt;"you could do that with a function too"&lt;/em&gt; things (have the work in one
place), but here I can get the language to write me a whole load of
functions, all of which refer to different functions and variables, each one
based off just the one symbol.&lt;/p&gt;
&lt;p&gt;The point of all of this being: v2.2 of &lt;code&gt;blogmore.el&lt;/code&gt; is now out, it adds
nothing for the user (who I suspect is only me anyway), but I had an
absolute blast dusting off more of my Emacs Lisp knowledge and getting back
the urge to code &lt;a href="https://elisp.dev/" rel="noopener noreferrer" target="_blank"&gt;even more Emacs Lisp&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All of this has even got me tidying up my &lt;code&gt;~/.emacs.d/&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; has me
thinking I should go back through some of my older code and &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;clean up all
that legacy nonsense&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:232-1"&gt;
&lt;p&gt;There was a time I would have said "grok" here but... well that's
spoiled now.&amp;#160;&lt;a class="footnote-backref" href="#fnref:232-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:232-2"&gt;
&lt;p&gt;I suppose I could reduce that to one "call" with a loop over a list of
symbols, but that feels unnecessary here.&amp;#160;&lt;a class="footnote-backref" href="#fnref:232-2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/30/blogmore-el-v2-2.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <category>coding</category>
      <category>defmacro</category>
      <pubDate>Mon, 30 Mar 2026 20:31:03 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.1</title>
      <link>https://blog.davep.org/2026/03/30/blogmore-el-v2-1.html</link>
      <description>&lt;p&gt;I've given &lt;a href="https://github.com/davep/blogmore.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt; a wee bump
to v2.1. This release fixes a small problem I noticed today when I tried to
use it to edit the tags for &lt;a href="https://seen-by.davep.dev/2026/03/30/refactored.html" rel="noopener noreferrer" target="_blank"&gt;a post on my
photoblog&lt;/a&gt;: the code
to find and gather properties from posts didn't handle deeply-nested
directory hierarchies for the post markdown files. I should have noticed
this when I first wrote the code, but of course I was so busy testing
against my primary blog, which only goes one sub-level deep, that I never
noticed it wasn't going to work deeper.&lt;/p&gt;
&lt;p&gt;So rather than using &lt;code&gt;grep&lt;/code&gt; to look for things like &lt;code&gt;foo/**/*.md&lt;/code&gt; I swapped
to a combination of &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt;. Which works, but is slightly (but
noticeably) slower.&lt;/p&gt;
&lt;p&gt;Then I got to thinking that if I was doing this by hand, on the command
line, I'd be using &lt;a href="https://github.com/burntsushi/ripgrep" rel="noopener noreferrer" target="_blank"&gt;ripgrep&lt;/a&gt; anyway.
Given this I might as well use it here. Of course, not everyone who might
use &lt;code&gt;blogmore.el&lt;/code&gt; will have &lt;code&gt;rg&lt;/code&gt; installed so it makes sense to look for
that and use it if it's available, otherwise fall back on &lt;code&gt;find&lt;/code&gt;/&lt;code&gt;grep&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There's still some low-priority cleaning up I want to do around this; an
obvious change I want to make being one where I want to collapse all cases
of the same word (Tree vs tree, etc) into one "hit"&lt;sup id="fnref:201-1"&gt;&lt;a class="footnote-ref" href="#fn:201-1"&gt;1&lt;/a&gt;&lt;/sup&gt;. For now though, as
always, it's working well enough for &lt;em&gt;my&lt;/em&gt; needs and this change fixed an
obvious issue I ran into.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:201-1"&gt;
&lt;p&gt;&lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; itself takes care of this, but
it would be nice to have the prompt in &lt;code&gt;blogmore.el&lt;/code&gt; also take this into
account.&amp;#160;&lt;a class="footnote-backref" href="#fnref:201-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/30/blogmore-el-v2-1.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Coding</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>Unix</category>
      <category>blogmore.el</category>
      <pubDate>Mon, 30 Mar 2026 16:20:22 +0100</pubDate>
    </item>
    <item>
      <title>blogmore.el v2.0</title>
      <link>https://blog.davep.org/2026/03/29/blogmore-el-v2-0.html</link>
      <description>&lt;p&gt;After &lt;a href="https://blog.davep.org/2026/03/19/some-blogmore-elisp.html"&gt;kicking off &lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;, and
then tinkering with it &lt;a href="https://blog.davep.org/2026/03/20/blogmore-el-v1-4.html"&gt;more&lt;/a&gt; and
&lt;a href="https://blog.davep.org/2026/03/21/blogmore-el-v1-7.html"&gt;more&lt;/a&gt;, I've found it really quite
helpful while writing posts. One thing I have noticed though -- given I use
&lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; for this blog and &lt;a href="https://seen-by.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;my
photoblog&lt;/a&gt; -- is that I wanted to be able to use
the package for working with more than one blog.&lt;/p&gt;
&lt;p&gt;So today I found myself with some time to kill and the result is that
&lt;code&gt;blogmore.el&lt;/code&gt; v2.0 has now been released. This version allows for setting up
multiple blogs, each with their own settings for where posts live, how their
paths are formatted, and so on.&lt;/p&gt;
&lt;p&gt;To handle this I've also added the &lt;code&gt;blogmore-work-on&lt;/code&gt; command so that the
active blog can be quickly changed.&lt;/p&gt;
&lt;p&gt;All of this can be configured using Emacs' customize feature.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Customize blogmore" src="https://blog.davep.org/attachments/2026/03/29/customize-blogmore.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;This has all changed since v1.x, where most of the customize options have
now been renamed to include &lt;code&gt;-default-&lt;/code&gt; in their name. The idea here is that
what was &lt;em&gt;the&lt;/em&gt; value for a setting previously is now the default value if a
given blog hasn't had that setting defined.&lt;/p&gt;
&lt;p&gt;For any given blog you wish to work with, you configure a name (for your own
reference) and the path to the posts. Optionally you can also set lots of
other values too.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Customize the blog" src="https://blog.davep.org/attachments/2026/03/29/customize-blogs.png#centre" /&gt;&lt;/p&gt;
&lt;p&gt;If a value is left on &lt;code&gt;Default&lt;/code&gt;, then the corresponding default setting will
be used; if it's set, then that value is used for that specific blog.&lt;/p&gt;
&lt;p&gt;The defaults out of the box match how I do things with my blogs, of course,
so the configuration is pretty straightforward. As of the time of writing my
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/use-package/" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;use-package&lt;/code&gt;&lt;/a&gt;
for &lt;code&gt;blogmore.el&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:vc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;:url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/davep/blogmore.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:rev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:newest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:init&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;blogmore-new-post-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;end-it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:custom&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;blogmore-blogs&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;blog.davep.org&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/davep.github.com/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;seen-by.davep.dev&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/write/seen-by/content/posts/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;:bind&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m b&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-work-on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m p n&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m p e&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-edit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m s c&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-set-category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m a t&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-add-tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m u d&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-update-date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m u m&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-update-modified&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m l p&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m l c&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; m l t&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blogmore-link-tag&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above you can see that I've set only the blog title and posts path
for each blog in &lt;code&gt;blogmore-blogs&lt;/code&gt;; the remaining values are all implied
&lt;code&gt;nil&lt;/code&gt; and so will be defaulted. The full list of values for any given blog
are:&lt;/p&gt;
&lt;div class="highlight" data-lang="elisp"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;BLOG-NAME&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;POSTS-DIRECTORY&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;POST-TEMPLATE&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;POST-MAKER-FUNCTION&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;CATEGORY-MAKER-FUNCTION&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;TAG-MAKER-FUNCTION&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;POST-LINK-FORMAT&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;CATEGORY-LINK-FORMAT&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;TAG-LINK-FORMAT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BLOG-NAME&lt;/code&gt; is the descriptive name to use for the blog.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POSTS-DIRECTORY&lt;/code&gt; is the directory where the blog's posts are stored.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST-TEMPLATE&lt;/code&gt; is a template for new posts. If &lt;code&gt;nil&lt;/code&gt;,
  &lt;code&gt;blogmore-default-template&lt;/code&gt; is used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST-MAKER-FUNCTION&lt;/code&gt; is a function that takes a filename and returns a
  string to be used in the post's URL. If &lt;code&gt;nil&lt;/code&gt;,
  &lt;code&gt;blogmore-default-post-maker-function&lt;/code&gt; is used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CATEGORY-MAKER-FUNCTION&lt;/code&gt; is a function that takes a category name and
  returns a string to be used in the category's URL. If &lt;code&gt;nil&lt;/code&gt;,
  &lt;code&gt;blogmore-default-category-maker-function&lt;/code&gt; is used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TAG-MAKER-FUNCTION&lt;/code&gt; is a function that takes a tag name and returns a
  string to be used in the tag's URL. If &lt;code&gt;nil&lt;/code&gt;,
  &lt;code&gt;blogmore-default-tag-maker-function&lt;/code&gt; is used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST-LINK-FORMAT&lt;/code&gt; is a format string for the post's URL, where &lt;code&gt;%s&lt;/code&gt; is
  replaced with the value returned by the post maker function. If &lt;code&gt;nil&lt;/code&gt;,
  &lt;code&gt;blogmore-default-post-link-format&lt;/code&gt; is used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CATEGORY-LINK-FORMAT&lt;/code&gt; is a format string for the category's URL, where
  &lt;code&gt;%s&lt;/code&gt; is replaced with the value returned by the category maker function. If
  &lt;code&gt;nil&lt;/code&gt;, &lt;code&gt;blogmore-default-category-link-format&lt;/code&gt; is used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TAG-LINK-FORMAT&lt;/code&gt; is a format string for the tag's URL, where &lt;code&gt;%s&lt;/code&gt; is
  replaced with the value returned by the tag maker function. If &lt;code&gt;nil&lt;/code&gt;,
  &lt;code&gt;blogmore-default-tag-link-format&lt;/code&gt; is used.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While I very much doubt any of this is useful to anyone else, it's at least
flexible for my purposes and can probably be configured to someone else's
purpose should they happen to be using BlogMore and Emacs.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/29/blogmore-el-v2-0.html</guid>
      <category>Emacs</category>
      <category>BlogMore</category>
      <category>Coding</category>
      <category>Emacs</category>
      <category>Emacs Lisp</category>
      <category>Lisp</category>
      <category>blogmore.el</category>
      <pubDate>Sun, 29 Mar 2026 20:50:41 +0100</pubDate>
    </item>
  </channel>
</rss>
