<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://blog.davep.org</id>
  <title>davep</title>
  <updated>2026-05-20T18:37:01.922399+00:00</updated>
  <link href="https://blog.davep.org/feeds/emacs.atom.xml" rel="self"/>
  <link href="https://blog.davep.org" rel="alternate"/>
  <generator uri="https://lkiesow.github.io/python-feedgen" version="1.0.0">python-feedgen</generator>
  <subtitle>Posts in category "Emacs" from davep</subtitle>
  <entry>
    <id>https://blog.davep.org/2026/05/19/next-gh-pr-el-v1-0-0.html</id>
    <title>next-gh-pr.el v1.0.0</title>
    <updated>2026-05-19T16:43:33+01:00</updated>
    <content type="html">&lt;p&gt;Pretty much every project that I actively maintain on my &lt;a href="https://github.com/davep" rel="noopener noreferrer" target="_blank"&gt;GitHub
account&lt;/a&gt; has a change log of some description. For
a long time now, whenever I add a new entry to the log, I'll include a link
to the PR that implements that change. Inevitably, this results in me adding
the ChangeLog entry, creating the PR, then doing a follow-up change and
commit now that I know the PR number, which allows me to add the link.&lt;/p&gt;
&lt;p&gt;So I've created &lt;a href="https://github.com/davep/next-gh-pr.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;next-gh-pr.el&lt;/code&gt;&lt;/a&gt; to
save me just a little time and let me be just a little more lazy. Inside it
I've currently got a &lt;code&gt;next-gh-pr-insert-markdown-link&lt;/code&gt; command which, when
run, as you might imagine, inserts a link to the next likely PR URL as
Markdown.&lt;/p&gt;
&lt;p&gt;Working out the next URL is simple enough: get the latest issue and PR
number, take whichever is the highest, and add 1. There is the wrinkle that
discussions also cause this number to bump, and getting the latest
discussion number is a little extra faff that I can't be bothered with right
now, but my projects very seldom have discussions taking place anyway.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/05/19/next-gh-pr-el-v1-0-0.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="GitHub"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="git"/>
    <category term="next-gh-pr.el"/>
    <published>2026-05-19T16:43:33+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/05/13/stopping-an-accidental-push.html</id>
    <title>Stopping an accidental push</title>
    <updated>2026-05-13T19:04:49+01:00</updated>
    <content type="html">&lt;p&gt;After starting to make use of &lt;a href="https://blog.davep.org/2026/05/10/more-syncing-github-to-gitlab-and-codeberg.html"&gt;the GitLab/Codeberg sync
approach&lt;/a&gt; for
various repositories, I found that my muscle memory in
&lt;a href="https://magit.vc/" rel="noopener noreferrer" target="_blank"&gt;Magit&lt;/a&gt; was getting the better of me and, on occasion,
I'd push a new branch to &lt;code&gt;backups&lt;/code&gt; when I wanted &lt;code&gt;origin&lt;/code&gt;. I sensed there
had to be a way round that.&lt;/p&gt;
&lt;p&gt;Here's what I settled on:&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;advice-add&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;magit-list-remotes&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;:filter-return&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;remotes&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;delete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;backups&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;remotes&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now I never see &lt;code&gt;backups&lt;/code&gt; in Magit and now I can keep using my muscle memory
(rather than actually reading what is in front of me, it seems).&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/05/13/stopping-an-accidental-push.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Magit"/>
    <category term="backups"/>
    <category term="git"/>
    <published>2026-05-13T19:04:49+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/05/09/make-phony-el-v1-4-0.html</id>
    <title>make-phony.el v1.4.0</title>
    <updated>2026-05-09T08:36:11+01:00</updated>
    <content type="html">&lt;p&gt;I've done a small update to
&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;, my little
&lt;a href="https://blog.davep.org/tag/emacs/"&gt;Emacs&lt;/a&gt; package that lets me be lazy when adding &lt;code&gt;.PHONY&lt;/code&gt; to
mark a target as a &lt;a href="https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html" rel="noopener noreferrer" target="_blank"&gt;phony
target&lt;/a&gt;
in a Makefile.&lt;/p&gt;
&lt;p&gt;The only change is a tweak to the regular expression, to tighten up the
check for a target that can be marked.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/05/09/make-phony-el-v1-4-0.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="make-phony.el"/>
    <published>2026-05-09T08:36:11+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/05/08/blogmore-el-v4-5-0.html</id>
    <title>blogmore.el v4.5.0</title>
    <updated>2026-05-08T19:27:54+01:00</updated>
    <content type="html">&lt;p&gt;Carrying on with &lt;a href="https://blog.davep.org/2026/05/07/blogmore-el-v4-4-0.html"&gt;the theme of being lazy while editing
posts&lt;/a&gt;, I've released
&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; v4.5.0. This version
adds &lt;code&gt;blogmore-set-as-cover&lt;/code&gt;. With this, if you place &lt;code&gt;point&lt;/code&gt; on a line that
is an image and run the command, it is set as the &lt;code&gt;cover&lt;/code&gt; for the post.&lt;/p&gt;
&lt;p&gt;Sure, it's not like it's hard to copy, move, insert a new line, type
&lt;code&gt;cover:&lt;/code&gt; and then paste the text, but this is faster and more accurate.&lt;/p&gt;
&lt;p&gt;And I'm lazy.&lt;/p&gt;
&lt;p&gt;And I like hacking on &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; that makes my workflow
flow faster.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/05/08/blogmore-el-v4-5-0.html"/>
    <category term="Emacs"/>
    <category term="BlogMore"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="blogmore.el"/>
    <category term="coding"/>
    <published>2026-05-08T19:27:54+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/05/07/blogmore-el-v4-4-0.html</id>
    <title>blogmore.el v4.4.0</title>
    <updated>2026-05-07T09:05:10+01:00</updated>
    <content type="html">&lt;p&gt;I've released an 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;, my
&lt;a href="https://blog.davep.org/tag/emacs/"&gt;Emacs&lt;/a&gt; package that helps me out when writing this blog. I've
added two commands to this version which help me be lazier than ever.&lt;/p&gt;
&lt;p&gt;The first is &lt;code&gt;blogmore-become-like&lt;/code&gt;. When run, this prompts for another post
and, once selected, it sets &lt;em&gt;this&lt;/em&gt; post's category and tags to be the same
as the other one. I added this because I'm often writing an occasional
series of posts that are all about the same project, and so I always find
myself copying and pasting those frontmatter properties from another post.&lt;/p&gt;
&lt;p&gt;The second command I've added is &lt;code&gt;blogmore-toggle-image-centre&lt;/code&gt;. Built into
&lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt; is a little bit of styling that will
ensure an image is placed in the centre of the page, if the URL for the
image has &lt;code&gt;#centre&lt;/code&gt; on the end. This means that, for most images I add, I
have to go and edit the URL to add that. Now I can just run a single command
when the cursor is on an image and it'll add (or remove, if it's already
there) that styling hint.&lt;/p&gt;
&lt;p&gt;In both cases, I've added the commands to the transient menu too.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/05/07/blogmore-el-v4-4-0.html"/>
    <category term="Emacs"/>
    <category term="BlogMore"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="blogmore.el"/>
    <category term="coding"/>
    <published>2026-05-07T09:05:10+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/28/blogmore-el-v4-3-0.html</id>
    <title>blogmore.el v4.3.0</title>
    <updated>2026-04-28T08:30:43+01:00</updated>
    <content type="html">&lt;p&gt;After adding the &lt;a href="https://blog.davep.org/2026/04/27/blogmore-v2-17-0.html"&gt;email comment invite facility to
BlogMore&lt;/a&gt; it only made sense that I add
some commands 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; to
make it easier to edit the front matter that can help drive that feature.&lt;/p&gt;
&lt;p&gt;So... I've released v4.3.0 of &lt;code&gt;blogmore.el&lt;/code&gt; that adds two new commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blogmore-toggle-invite-comments&lt;/code&gt; -- toggles the comment invitation
  property&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blogmore-invite-comments-to&lt;/code&gt; -- makes it easy to set, edit or remove the
  email address to use when making the invite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I've also added the two commands to the transient menu, using
&lt;kbd&gt;C&lt;/kbd&gt;-&lt;kbd&gt;t&lt;/kbd&gt; for the former and &lt;kbd&gt;C&lt;/kbd&gt;-&lt;kbd&gt;a&lt;/kbd&gt; for
the latter.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/28/blogmore-el-v4-3-0.html"/>
    <category term="Emacs"/>
    <category term="BlogMore"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="blogmore.el"/>
    <category term="coding"/>
    <published>2026-04-28T08:30:43+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/24/kbdify-el-v1-0-0.html</id>
    <title>kbdify.el v1.0.0</title>
    <updated>2026-04-24T17:04:37+01:00</updated>
    <content type="html">&lt;p&gt;When I'm writing documentation in &lt;a href="https://blog.davep.org/tag/markdown/"&gt;Markdown&lt;/a&gt; I like, where
possible, to mark up keys with the &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt; tag. This was the reason for &lt;a href="https://blog.davep.org/2026/04/04/blogmore-v2-9-0.html"&gt;one
of the updates to BlogMore&lt;/a&gt;: I'd not done
any good default markup for &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt; and the moment I realised, I knew I had
to fix it.&lt;/p&gt;
&lt;p&gt;Now that I'm writing more on this blog, and especially about
&lt;a href="https://blog.davep.org/tag/coding/"&gt;coding&lt;/a&gt;, I'm mentioning keys pretty often (even more so given
I'm doing a lot of tidying up of my &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt;
packages). The thing is though: I find having to type out &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt; and
&lt;code&gt;&amp;lt;/kbd&amp;gt;&lt;/code&gt; kind of tedious, and it's something I mistype from time to time. I
guess I could use some sort of HTML tag inserting tool or whatever, but I
got to thinking that it would be handy if I could point an Emacs command at
a particular sequence in a buffer and have it mark up the whole thing.&lt;/p&gt;
&lt;p&gt;This resulted in a small bit of code I'm calling
&lt;a href="https://github.com/davep/kbdify.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;kbdify.el&lt;/code&gt;&lt;/a&gt;. It's pretty simple, if
&lt;code&gt;point&lt;/code&gt; is sat on some text that looks like this:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;C-M-S-s-&amp;lt;up&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and I run &lt;code&gt;kbdify&lt;/code&gt; I get this:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;lt;kbd&amp;gt;C&amp;lt;/kbd&amp;gt;-&amp;lt;kbd&amp;gt;M&amp;lt;/kbd&amp;gt;-&amp;lt;kbd&amp;gt;S&amp;lt;/kbd&amp;gt;-&amp;lt;kbd&amp;gt;s&amp;lt;/kbd&amp;gt;-&amp;lt;kbd&amp;gt;&amp;amp;lt;up&amp;amp;gt;&amp;lt;/kbd&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result rendering as
&lt;kbd&gt;C&lt;/kbd&gt;-&lt;kbd&gt;M&lt;/kbd&gt;-&lt;kbd&gt;S&lt;/kbd&gt;-&lt;kbd&gt;s&lt;/kbd&gt;-&lt;kbd&gt;&amp;lt;up&amp;gt;&lt;/kbd&gt;.&lt;/p&gt;
&lt;p&gt;I could probably take it a bit further, have it optionally work on a region
and stuff like that, but even in its current simplistic form it's going to
be loads quicker and a lot more accurate and will probably perfectly cover
99% of the times I need it. There is the issue that it's not going to handle
something like &lt;code&gt;M-x some-command RET&lt;/code&gt; in the way I might like, but then
again &lt;code&gt;some-command&lt;/code&gt; isn't a key. Like, does it make more sense to have:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;kbd&gt;M&lt;/kbd&gt;-&lt;kbd&gt;x&lt;/kbd&gt; &lt;kbd&gt;some-command&lt;/kbd&gt; &lt;kbd&gt;RET&lt;/kbd&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;anyway? Personally I think this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;kbd&gt;M&lt;/kbd&gt;-&lt;kbd&gt;x&lt;/kbd&gt; &lt;code&gt;some-command&lt;/code&gt; &lt;kbd&gt;RET&lt;/kbd&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;probably makes more sense.&lt;/p&gt;
&lt;p&gt;I think I'm good for now.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/24/kbdify-el-v1-0-0.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="kbdify.el"/>
    <category term="Markdown"/>
    <published>2026-04-24T17:04:37+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/24/itch-el-v1-3-0.html</id>
    <title>itch.el v1.3.0</title>
    <updated>2026-04-24T08:21:24+01:00</updated>
    <content type="html">&lt;p&gt;When I'm working in &lt;a href="https://blog.davep.org/category/emacs/"&gt;Emacs&lt;/a&gt; I use the &lt;code&gt;*scratch*&lt;/code&gt; buffer
quite a bit. I find it especially useful if I'm working on some &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs
Lisp&lt;/a&gt; code, but I also find it handy as a place to drop
something I want to retrieve soon, or a quick note that I want to refer back
to soon; sometimes I even paste some text there and copy it back just to
strip the formatting from it before using it elsewhere&lt;sup id="fnref:259-1"&gt;&lt;a class="footnote-ref" href="#fn:259-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Because of this, for a long time, I carried a little function around that I
had bound to &lt;kbd&gt;M&lt;/kbd&gt;-&lt;kbd&gt;s&lt;/kbd&gt; to quickly take me to the &lt;code&gt;*scratch*&lt;/code&gt;
buffer. Then, I think &lt;a href="https://blog.davep.org/2017/04/01/another_revamp_of_my_emacs_config.html"&gt;around the time I did the follow-up revamp of my Emacs
configuration&lt;/a&gt;, I turned
it into a little package for my own use called
&lt;a href="https://github.com/davep/itch.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;itch.el&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The command (&lt;code&gt;itch-scratch-buffer&lt;/code&gt;) is simple enough: run it and I get
switched to my &lt;code&gt;*scratch*&lt;/code&gt; buffer. If I run it with a prefix argument it
switches to &lt;code&gt;*scratch*&lt;/code&gt; and resets the content back to the
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Interaction.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;initial-scratch-message&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;More recently I've found that I'm wanting a scratch buffer that is for
writing Markdown. Like many folk I use it a lot for documentation, and of
course I also use it for this blog. I also use it heavily for keeping notes
in Obsidian&lt;sup id="fnref:259-2"&gt;&lt;a class="footnote-ref" href="#fn:259-2"&gt;2&lt;/a&gt;&lt;/sup&gt;. So, often, I find myself switching to a temporary buffer
(&lt;code&gt;*foo*&lt;/code&gt; or something), setting it to &lt;code&gt;markdown-mode&lt;/code&gt;, and then writing what
I need.&lt;/p&gt;
&lt;p&gt;So yesterday I finally cracked and added &lt;code&gt;itch-markdown-scratch-buffer&lt;/code&gt;.
It's just like &lt;code&gt;itch-scratch-buffer&lt;/code&gt;, only it creates a &lt;code&gt;*scratch:
Markdown*&lt;/code&gt; buffer, using the same clear-if-prefix rule.&lt;/p&gt;
&lt;p&gt;So now I've got this bound to &lt;kbd&gt;M&lt;/kbd&gt;-&lt;kbd&gt;S&lt;/kbd&gt;-&lt;kbd&gt;s&lt;/kbd&gt; and I
can faff around just a little less when I want a Markdown scratchpad.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:259-1"&gt;
&lt;p&gt;On macOS at least, I find the "paste without formatting" support of
some applications to be really inconsistent; a quick layover in the
&lt;code&gt;*scratch*&lt;/code&gt; buffer does the trick every time.&amp;#160;&lt;a class="footnote-backref" href="#fnref:259-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:259-2"&gt;
&lt;p&gt;Yes, I know, I should be using Org, but sadly it's just never clicked
for me, and I also find good syncing and having a consistent application
on mobile and desktop are important.&amp;#160;&lt;a class="footnote-backref" href="#fnref:259-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;</content>
    <link href="https://blog.davep.org/2026/04/24/itch-el-v1-3-0.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="itch.el"/>
    <published>2026-04-24T08:21:24+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/23/unabbrev-el-v1-0-0.html</id>
    <title>unabbrev.el v1.0.0</title>
    <updated>2026-04-23T08:25:57+01:00</updated>
    <content type="html">&lt;p&gt;Back in the late 1990s, like plenty of people who were very online, I was a
very avid user of Usenet. There were a few groups I was very active in, even
a couple that I maintained a FAQ for. Being that active and wanting to help
and answer questions, I was forever posting and pasting links to various
resources. Given that I used &lt;a href="https://blog.davep.org/category/emacs/"&gt;Emacs&lt;/a&gt; to edit my posts&lt;sup id="fnref:255-1"&gt;&lt;a class="footnote-ref" href="#fn:255-1"&gt;1&lt;/a&gt;&lt;/sup&gt;,
I eventually realised that I should come up with a tool that let me call on
common URLs quickly.&lt;/p&gt;
&lt;p&gt;So back in 1998 &lt;a href="https://github.com/davep/handyurl.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;handyurl.el&lt;/code&gt;&lt;/a&gt; was
born. It was a simple idea: have a file of URLs that I commonly refer to and
let me quickly pick from one and paste it. This made for a useful tool and
also gave me something to build given I was learning &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs
Lisp&lt;/a&gt; at the time.&lt;/p&gt;
&lt;p&gt;For reasons I can't quite recall, some time later (the next year, by the
looks of things), I wrote
&lt;a href="https://github.com/davep/quickurl.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;quickurl.el&lt;/code&gt;&lt;/a&gt; as a successor to
&lt;code&gt;handyurl.el&lt;/code&gt;. I honestly can't remember &lt;em&gt;why&lt;/em&gt; this happened, I can't
remember why I didn't just keep extending &lt;code&gt;handyurl.el&lt;/code&gt;. But, anyway,
&lt;code&gt;quickurl.el&lt;/code&gt; did more and was more flexible, with built-in URL-grabbing and
editing and so on.&lt;/p&gt;
&lt;p&gt;Not that long later I got an email from the FSF asking if I might be willing
to hand over copyright so that &lt;code&gt;quickurl.el&lt;/code&gt; could become part of Emacs
itself. I was, of course, delighted to do so.&lt;/p&gt;
&lt;p&gt;Eventually &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;&lt;code&gt;quickurl.el&lt;/code&gt; was declared
obsolete&lt;/a&gt; and, while it seems to
still be shipped with Emacs, it's not documented or easy to discover.&lt;/p&gt;
&lt;p&gt;In the deprecation notice in &lt;code&gt;NEWS&lt;/code&gt; the suggestion is that the user should
switch to one or more of 3 alternatives:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;** The quickurl.el library is now obsolete.
Use &amp;#39;abbrev&amp;#39;, &amp;#39;skeleton&amp;#39; or &amp;#39;tempo&amp;#39; instead.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;abbrev&lt;/code&gt; I know, the other two I've never noticed and don't know anything
about.&lt;/p&gt;
&lt;p&gt;Obviously, between &lt;code&gt;quickurl.el&lt;/code&gt; being pulled into Emacs, and it being made
obsolete, my use of it fell right off. I eventually stopped posting to and
reading Usenet, I also stopped using &lt;a href="http://www.mutt.org/" rel="noopener noreferrer" target="_blank"&gt;mutt&lt;/a&gt;+Emacs as
my mail client of choice, and so found myself seldom writing things that
needed lots of links, in Emacs.&lt;/p&gt;
&lt;p&gt;Until recently.&lt;/p&gt;
&lt;p&gt;At the moment I'm finding that I'm wanting to write on my blog more and
more, and doing that means I often want to include some common links, and I
write my posts in Emacs using &lt;code&gt;markdown-mode&lt;/code&gt; and with a little help from
&lt;a href="https://blog.davep.org/tag/blogmore-el/"&gt;&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;; the need to have an easy-to-pick-from
common menu of URLs is back.&lt;/p&gt;
&lt;p&gt;Driven by this I've &lt;a href="https://github.com/davep/.emacs.d/blob/4d4a7b5da662b28764e779aba2700d451f5221a5/init.d/packages.d/personal/blogmore.el#L14-L17" rel="noopener noreferrer" target="_blank"&gt;made a point of using &lt;code&gt;abbrev&lt;/code&gt; to initially solve this
problem&lt;/a&gt;.
This works, but I do have a problem: I keep forgetting what the
abbreviations are. I find myself wanting to have a key binding that lets me
at the very least
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Completion.html" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;completing-read&lt;/code&gt;&lt;/a&gt;
the desired abbrev. So yesterday I quickly knocked up
&lt;a href="https://github.com/davep/unabbrev.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;unabbrev.el&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's simple, straightforward, small and does the job I needed. Doubtless
there's something else out there that can do this sort of thing too, but
part of the fun of Emacs (for me) is that I find I have a need and I can
hack together some Lisp and get that problem solved.&lt;/p&gt;
&lt;p&gt;&lt;img alt="unabbrev in action" height="676" loading="lazy" src="https://blog.davep.org/attachments/2026/04/23/unabbrev.webp#centre" width="734" /&gt;&lt;/p&gt;
&lt;p&gt;I suppose what I &lt;em&gt;should&lt;/em&gt; do is revive either &lt;code&gt;handyurl.el&lt;/code&gt; or &lt;code&gt;quickurl.el&lt;/code&gt;
and tweak and update whichever, at the very least adding some sort of insert
formatting facility that is sensitive to the underlying mode (because links
in Markdown need a format different from links in HTML, etc).&lt;/p&gt;
&lt;p&gt;For now though &lt;code&gt;unabbrev.el&lt;/code&gt; is going to help my failing memory when I want
to link a common resource.&lt;/p&gt;
&lt;p&gt;As an aside, all of this does have me wonder about one thing: is the Free
Software Foundation the place that code goes to die? Like, sure, of course I
&lt;em&gt;can&lt;/em&gt; make changes to &lt;code&gt;quickurl.el&lt;/code&gt; and do my own thing with it, as long as
I don't misrepresent the copyright status and maintain a compatible licence,
etc; but there is this thing where, if Emacs doesn't want that code any
more, if the FSF don't want that code any more, wouldn't it be nice if
they'd sign it back over again?&lt;/p&gt;
&lt;p&gt;I am tempted to drop them a line and see what the deal is. I did &lt;a href="https://fosstodon.org/@davep/116376633686272162" rel="noopener noreferrer" target="_blank"&gt;tag-ask on
Mastodon&lt;/a&gt; but got no reply.
Unfortunately though that account looks like the FSF treat Mastodon as a
write-only resource.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:255-1"&gt;
&lt;p&gt;But curiously never got into
&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Gnus.html" rel="noopener noreferrer" target="_blank"&gt;Gnus&lt;/a&gt;,
my news client of choice was &lt;a href="https://www.slrn.org/" rel="noopener noreferrer" target="_blank"&gt;slrn&lt;/a&gt; and I
composed posts in Emacs.&amp;#160;&lt;a class="footnote-backref" href="#fnref:255-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;</content>
    <link href="https://blog.davep.org/2026/04/23/unabbrev-el-v1-0-0.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="FOSS"/>
    <category term="FSF"/>
    <category term="Free Software"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="handyurl.el"/>
    <category term="quickurl.el"/>
    <category term="unabbrev.el"/>
    <published>2026-04-23T08:25:57+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/22/expando-el-v1-6.html</id>
    <title>expando.el v1.6</title>
    <updated>2026-04-22T19:21:40+01:00</updated>
    <content type="html">&lt;p&gt;Recently I've had an odd problem with &lt;a href="https://blog.davep.org/category/emacs/"&gt;Emacs&lt;/a&gt;:
occasionally, and somewhat randomly, as I wrote code, and only when I wrote
&lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; code, and only when working in
&lt;code&gt;emacs-lisp-mode&lt;/code&gt;, I'd find that the buffer I was working in would
disappear. Not just fully disappear, but more like if I'd used
&lt;code&gt;quit-window&lt;/code&gt;. Worse still, once this started happening, it wouldn't go away
unless I turned Emacs off and on again.&lt;/p&gt;
&lt;p&gt;Very un-Emacs!&lt;/p&gt;
&lt;p&gt;Normally this would happen when I'm in full flow on something, so I'd just
restart Emacs and crack on with the thing I was writing; because of this I
wasn't diagnosing what was actually going on.&lt;/p&gt;
&lt;p&gt;Then, today, as I was writing &lt;code&gt;require&lt;/code&gt; in some code, and kept seeing the
buffer go away when I hit &lt;kbd&gt;q&lt;/kbd&gt;, it dawned on me.&lt;/p&gt;
&lt;p&gt;Recently, when &lt;a href="https://blog.davep.org/2026/04/06/expando-el-v1-5.html"&gt;I cleaned up
&lt;code&gt;expando.el&lt;/code&gt;&lt;/a&gt;, I added the ability to
close the window with &lt;kbd&gt;q&lt;/kbd&gt;.&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="gd"&gt;--- a/expando.el&lt;/span&gt;
&lt;span class="gi"&gt;+++ b/expando.el&lt;/span&gt;
&lt;span class="gu"&gt;@@ -58,7 +58,8 @@ Pass LEVEL as 2 (or prefix a call with \\[universal-argument] and&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;  (let ((form (preceding-sexp)))
&lt;span class="w"&gt; &lt;/span&gt;    (with-current-buffer-window &amp;quot;*Expando Macro*&amp;quot; nil nil
&lt;span class="w"&gt; &lt;/span&gt;      (emacs-lisp-mode)
&lt;span class="gd"&gt;-      (pp (funcall (expando--expander level) form)))))&lt;/span&gt;
&lt;span class="gi"&gt;+      (local-set-key (kbd &amp;quot;q&amp;quot;) #&amp;#39;quit-window)&lt;/span&gt;
&lt;span class="gi"&gt;+      (pp (funcall (expando--expander level) form)))))&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;(provide &amp;#39;expando)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, after opening a window for the purposes of displaying the expanded
macro, switch to &lt;code&gt;emacs-lisp-mode&lt;/code&gt;, locally set the binding so &lt;kbd&gt;q&lt;/kbd&gt;
will call on &lt;code&gt;quit-window&lt;/code&gt;, and I'm all good.&lt;/p&gt;
&lt;p&gt;Except... not, as it turns out.&lt;/p&gt;
&lt;p&gt;To quote from the documentation for &lt;code&gt;local-set-key&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The binding goes in the current buffer’s local map, which in most cases is
shared with all other buffers in the same major mode.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;D'oh!&lt;/p&gt;
&lt;p&gt;Point being, any time I used &lt;code&gt;expando-macro&lt;/code&gt;, I was changing the meaning of
&lt;kbd&gt;q&lt;/kbd&gt; in the keyboard map for &lt;code&gt;emacs-lisp-mode&lt;/code&gt;. :-/&lt;/p&gt;
&lt;p&gt;And so v1.6 of &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; is now a
thing, in which I introduce a derived mode of &lt;code&gt;emacs-lisp-mode&lt;/code&gt; and set
&lt;kbd&gt;q&lt;/kbd&gt; in its keyboard map. In fact, I keep the keyboard map nice and
simple.&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;defvar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;expando-view-mode-map&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;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;make-sparse-keymap&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;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;q&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&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;quit-window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;map&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;Mode map for &lt;/span&gt;&lt;span class="ss"&gt;`expando-view-mode&amp;#39;&lt;/span&gt;&lt;span class="s"&gt;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;define-derived-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;expando-view-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;emacs-lisp-mode&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="s"&gt;&amp;quot;Major mode for viewing expanded macros.&lt;/span&gt;

&lt;span class="s"&gt;The key bindings for &lt;/span&gt;&lt;span class="ss"&gt;`expando-view-mode&amp;#39;&lt;/span&gt;&lt;span class="s"&gt; are:&lt;/span&gt;

&lt;span class="s"&gt;\\{expando-view-mode-map}&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;From now on I should be able to code in full flow state without the worry
that my window will disappear at any given moment...&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/22/expando-el-v1-6.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="expando.el"/>
    <category term="local-set-key"/>
    <published>2026-04-22T19:21:40+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/21/blogmore-el-v4-2.html</id>
    <title>blogmore.el v4.2</title>
    <updated>2026-04-21T19:27:26+01:00</updated>
    <content type="html">&lt;p&gt;Another wee 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;,
with a bump to v4.2.&lt;/p&gt;
&lt;p&gt;After &lt;a href="https://blog.davep.org/2026/04/17/blogmore-el-v4-1.html"&gt;adding the webp helper command&lt;/a&gt;
the other day, something about it has been bothering me. While the command
is there as a simple helper if I want to &lt;a href="https://blog.davep.org/2026/04/16/i-should-use-webp.html"&gt;change an individual image to
webp&lt;/a&gt; -- so it's not intended to be a
general-purpose tool -- it felt "wrong" that it did this one specific thing.&lt;/p&gt;
&lt;p&gt;So I've changed it up and now, rather than being a command that changes an
image's filename so that it has a &lt;code&gt;webp&lt;/code&gt; extension, it now cycles through a
small range of different image formats. Specifically it goes &lt;code&gt;jpeg&lt;/code&gt; to &lt;code&gt;png&lt;/code&gt;
to &lt;code&gt;gif&lt;/code&gt; to &lt;code&gt;webp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With this change in place I can position &lt;code&gt;point&lt;/code&gt; on an image in the Markdown
of a post and keep running the command to cycle the extension through the
different options. I suppose at some point it might make sense to turn this
into something that &lt;em&gt;actually&lt;/em&gt; converts the image itself, but this is about
going back and editing key posts when I change their image formats.&lt;/p&gt;
&lt;p&gt;Another change is to the code that slugs the title of a post to make the
Markdown file name. I ran into the motivating issue yesterday when posting
some images on &lt;a href="https://seen-by.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;my photoblog&lt;/a&gt;. I had a title
with an apostrophe in it, which meant that it went from something like
&lt;code&gt;Dave's Test&lt;/code&gt; (as the title) to &lt;code&gt;dave-s-test&lt;/code&gt; (as the slug). While the slug
doesn't really matter, this felt sort of messy; I would prefer that it came
out as &lt;code&gt;daves-test&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Given that wish, I modified &lt;code&gt;blogmore-slug&lt;/code&gt; so that it strips &lt;code&gt;'&lt;/code&gt; and &lt;code&gt;"&lt;/code&gt;
before doing the conversion of non-alphanumeric characters to &lt;code&gt;-&lt;/code&gt;. While
doing this, for the sake of completeness, I did a simple attempt at removing
accents from some characters too. So now the slugs come out a little tidier
still.&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-slug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;That&amp;#39;s Café Ëmacs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s"&gt;&amp;quot;thats-cafe-emacs&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The slug function has been the perfect use for an &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs
Lisp&lt;/a&gt; function I've never used before: &lt;code&gt;thread-last&lt;/code&gt;. It's
not like I've been avoiding it, it's just more a case of I've never quite
felt it was worthwhile using until now. Thanks to it the body of
&lt;code&gt;blogmore-slug&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="nv"&gt;thread-last&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;ucs-normalize-NFKD-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;seq-filter&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;char&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="nf"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;#x300&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;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;#x36F&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;concat&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="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;#39;\&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="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="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;0-9a-z&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="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="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;seq&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="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="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;seq&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="nv"&gt;eol&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;rather than 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;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="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;seq&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="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="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;seq&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="nv"&gt;eol&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;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="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;0-9a-z&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;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="p"&gt;(&lt;/span&gt;&lt;span class="nf"&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;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;#39;\&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="nf"&gt;concat&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;seq-filter&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;char&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="nf"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;#x300&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;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;#x36F&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;ucs-normalize-NFKD-string&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)))))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Given that making the slug is very much a "pipeline" of functions, the
former looks far more readable and feels more maintainable than the latter.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/21/blogmore-el-v4-2.html"/>
    <category term="Emacs"/>
    <category term="BlogMore"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="blogmore.el"/>
    <category term="coding"/>
    <published>2026-04-21T19:27:26+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/17/blogmore-el-v4-1.html</id>
    <title>blogmore.el v4.1</title>
    <updated>2026-04-17T10:25:37+01:00</updated>
    <content type="html">&lt;p&gt;Following on from &lt;a href="https://blog.davep.org/2026/04/16/i-should-use-webp.html"&gt;yesterday's experiment with
webp&lt;/a&gt; I got to thinking that it might be
handy to add a wee command 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; that can quickly swap
an image's extension from whatever it is to &lt;code&gt;webp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So &lt;a href="https://github.com/davep/blogmore.el/releases/tag/v4.1" rel="noopener noreferrer" target="_blank"&gt;v4.1&lt;/a&gt; has
happened. The new command is simple enough, called
&lt;code&gt;blogmore-webpify-image-at-point&lt;/code&gt;; it just looks to see if there's a
Markdown image on the current line and, if there is, replaces the file's
extension with &lt;code&gt;webp&lt;/code&gt; no matter what it was before.&lt;/p&gt;
&lt;p&gt;If/when I decide to convert all the &lt;code&gt;png&lt;/code&gt; files in the blog to &lt;code&gt;webp&lt;/code&gt; I'll
obviously use something very batch-oriented, but for now I'm still
experimenting, so going back and quickly changing the odd image here and
there is a nicely cautious approach.&lt;/p&gt;
&lt;p&gt;I have, of course, added the command to the transient menu that is brought
up by the &lt;code&gt;blogmore&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;One other small change in v4.1 is that a newly created post is saved right
away. This doesn't make a huge difference, but it does mean I start out with
a saved post that will be seen by &lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt;
when generating the site.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/17/blogmore-el-v4-1.html"/>
    <category term="Emacs"/>
    <category term="BlogMore"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="blogmore.el"/>
    <category term="coding"/>
    <category term="web"/>
    <category term="webp"/>
    <published>2026-04-17T10:25:37+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/16/boxquote-el-v2-4.html</id>
    <title>boxquote.el v2.4</title>
    <updated>2026-04-16T08:29:35+01:00</updated>
    <content type="html">&lt;p&gt;&lt;a href="https://github.com/davep/boxquote.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;boxquote.el&lt;/code&gt;&lt;/a&gt; is another of my
oldest &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; packages. The original code itself was
inspired by something I saw on Usenet, and writing my own version of it
seemed like a great learning exercise; as noted in the thanks section in the
commentary in the source:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kai Grossjohann for inspiring the idea of boxquote. I wrote this code to
mimic the "inclusion quoting" style in his Usenet posts. I could have
hassled him for his code but it was far more fun to write it myself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While I never used this package to quote text I was replying to in Usenet
posts, I did use it a &lt;em&gt;lot&lt;/em&gt; on Usenet, and in mailing lists, and similar
places, to quote &lt;em&gt;stuff&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The default use is to quote a body of text; often a paragraph, or a region,
or perhaps even Emacs' idea of a &lt;code&gt;defun&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;,----
| `boxquote.el` provides a set of functions for using a text quoting style
| that partially boxes in the left hand side of an area of text, such a
| marking style might be used to show externally included text or example
| code.
`----
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where the package really turned into something fun and enduring, for me, was
when I started to add the commands that grabbed information from elsewhere
in Emacs and added a title to explain the content of the quote. For example,
using &lt;code&gt;boxquote-describe-function&lt;/code&gt; to quote the documentation for a function
at someone, while also showing them how to get at that documentation:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;,----[ C-h f boxquote-text RET ]
| boxquote-text is an autoloaded interactive native-comp-function in
| ‘boxquote.el’.
|
| (boxquote-text TEXT)
|
| Insert TEXT, boxquoted.
`----
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or perhaps getting help with a particular key combination:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;,----[ C-h k C-c b ]
| C-c b runs the command boxquote (found in global-map), which is an
| interactive native-comp-function in ‘boxquote.el’.
|
| It is bound to C-c b.
|
| (boxquote)
|
| Show a transient for boxquote commands.
|
|   This function is for interactive use only.
|
| [back]
`----
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or figuring out where a particular command is and how to get at it:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;,----[ C-h w fill-paragraph RET ]
| fill-paragraph is on fill-paragraph (M-q)
`----
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While I seldom have use for this package these days (mainly because I don't
write on Usenet or in mailing lists any more) I did keep carrying it around
(always pulling it down &lt;a href="https://melpa.org/#/boxquote" rel="noopener noreferrer" target="_blank"&gt;from melpa&lt;/a&gt;) and had
all the various commands bound to some key combination.&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;boxquote&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;: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 i&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;boxquote-insert-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="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b M-w&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;boxquote-kill-ring-save&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 y&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;boxquote-yank&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 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;boxquote-region&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 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;boxquote-title&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 h f&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;boxquote-describe-function&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 h v&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;boxquote-describe-variable&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 h k&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;boxquote-describe-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="s"&gt;&amp;quot;&amp;lt;f12&amp;gt; b h w&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;boxquote-where-is&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 !&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;boxquote-shell-command&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Recently, with the &lt;a href="https://blog.davep.org/tag/blogmore-el/"&gt;creation of &lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;, I moved
the boxquote commands off the &lt;kbd&gt;b&lt;/kbd&gt; prefix (because I wanted that for
blogging) and onto an &lt;kbd&gt;x&lt;/kbd&gt; prefix. Even then... that's a lot of
commands bound to a lot of keys that I almost never use but still can't let
go of.&lt;/p&gt;
&lt;p&gt;Then I got to thinking: &lt;a href="https://blog.davep.org/2026/04/04/blogmore-el-v2-6.html"&gt;I'd made good use of transient in
&lt;code&gt;blogmore.el&lt;/code&gt;&lt;/a&gt;, why not use it here too?
So now &lt;code&gt;boxquote.el&lt;/code&gt; has acquired a &lt;code&gt;boxquote&lt;/code&gt; command which uses transient.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The boxquote transient in action" height="204" loading="lazy" src="https://blog.davep.org/attachments/2026/04/16/boxquote.webp#centre" width="620" /&gt;&lt;/p&gt;
&lt;p&gt;Now I can have:&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;boxquote&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;: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 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;boxquote&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and all the commands are still easy to get to and easy to (re)discover. I've
also done my best to make them context-sensitive too, so only applicable
commands should be usable at any given time.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/16/boxquote-el-v2-4.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="boxquote.el"/>
    <published>2026-04-16T08:29:35+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/15/slstats-el-v1-11.html</id>
    <title>slstats.el v1.11</title>
    <updated>2026-04-15T15:52:55+01:00</updated>
    <content type="html">&lt;p&gt;Yet another older &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs Lisp&lt;/a&gt; package that has had a tidy
up. This one is &lt;a href="https://github.com/davep/slstats.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;slstats.el&lt;/code&gt;&lt;/a&gt;, a wee
package that can be used to look up various statistics about the Second Life
grid. It's mainly a wrapper around the API provided by &lt;a href="https://gridsurvey.com/" rel="noopener noreferrer" target="_blank"&gt;the Second Life grid
survey&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;slstats&lt;/code&gt; is run, you get an overview of all of the information
available.&lt;/p&gt;
&lt;p&gt;&lt;img alt="An overview of the grid" height="620" loading="lazy" src="https://blog.davep.org/attachments/2026/04/15/sl-overview.webp#centre" width="692" /&gt;&lt;/p&gt;
&lt;p&gt;There are also various commands for viewing individual details about the
grid in the echo area:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;slstats-signups&lt;/code&gt; - Display the Second Life sign-up count&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slstats-exchange-rate&lt;/code&gt; - Display the L$ -&amp;gt; $ exchange rate&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slstats-inworld&lt;/code&gt; - Display how many avatars are in-world in Second Life&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slstats-concurrency&lt;/code&gt; - Display the latest-known concurrency stats for
  Second Life&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slstats-grid-size&lt;/code&gt; - Display the grid size data for Second Life&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is also &lt;code&gt;slstats-region-info&lt;/code&gt; which will show information and the
object and terrain maps for a specific region.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Region information for Da Boom" height="844" loading="lazy" src="https://blog.davep.org/attachments/2026/04/15/slstats-region-info.webp#centre" width="692" /&gt;&lt;/p&gt;
&lt;p&gt;As with a good few of my older packages: it's probably not &lt;em&gt;that&lt;/em&gt; useful,
but at the same time it was educational to write it to start with, and it
can be an amusement from time to time.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/15/slstats-el-v1-11.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="Second Life"/>
    <category term="coding"/>
    <category term="slstats.el"/>
    <published>2026-04-15T15:52:55+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/14/wordcloud-el-v1-4.html</id>
    <title>wordcloud.el v1.4</title>
    <updated>2026-04-14T08:47:39+01:00</updated>
    <content type="html">&lt;p&gt;I &lt;em&gt;think&lt;/em&gt; I'm mostly caught up with the collection of &lt;a href="https://blog.davep.org/tag/emacs-lisp/"&gt;Emacs
Lisp&lt;/a&gt; packages &lt;a href="https://blog.davep.org/2022/08/23/i-must-be-getting-old.html"&gt;that need updating and
tidying&lt;/a&gt;, which means yesterday
evening's clean-up should be one of the last (although I would like to
revisit a couple and actually improve and extend them at some point).&lt;/p&gt;
&lt;p&gt;As for what I cleaned up yesterday:
&lt;a href="https://github.com/davep/wordcloud.el" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;wordcloud.el&lt;/code&gt;&lt;/a&gt;. This is a package
that, when run in a buffer, will count the frequency of words in that buffer
and show the results in a fresh window, complete with the "word cloud"
differing-font-size effect.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Word cloud in action" height="704" loading="lazy" src="https://blog.davep.org/attachments/2026/04/14/wordcloud.webp#centre" width="818" /&gt;&lt;/p&gt;
&lt;p&gt;This package is about 10 years old at this point, and I'm struggling to
remember &lt;em&gt;why&lt;/em&gt; I wrote it now. I know I was doing something -- either
writing something or reviewing it -- and the frequency of some words was
important. I also remember this doing the job just fine and solving the
problem I needed to solve.&lt;/p&gt;
&lt;p&gt;Since then it's just sat around in my personal library of stuff I've written
in Emacs Lisp, not really used. I imagine that's where it's going back to,
but at least it's cleaned up and should be functional for a long time to
come.&lt;/p&gt;</content>
    <link href="https://blog.davep.org/2026/04/14/wordcloud-el-v1-4.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="wordcloud.el"/>
    <published>2026-04-14T08:47:39+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/08/quiz-el-v1-7.html</id>
    <title>quiz.el v1.7</title>
    <updated>2026-04-08T16:54:38+01:00</updated>
    <content type="html">&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" height="746" loading="lazy" src="https://blog.davep.org/attachments/2026/04/08/updated-quiz.webp#centre" width="923" /&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;</content>
    <link href="https://blog.davep.org/2026/04/08/quiz-el-v1-7.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="quiz.el"/>
    <published>2026-04-08T16:54:38+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/08/fasta-el-v1-1.html</id>
    <title>fasta.el v1.1</title>
    <updated>2026-04-08T11:25:43+01:00</updated>
    <content type="html">&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" height="662" loading="lazy" src="https://blog.davep.org/attachments/2026/04/08/fasta.webp#centre" width="678" /&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;</content>
    <link href="https://blog.davep.org/2026/04/08/fasta-el-v1-1.html"/>
    <category term="Emacs"/>
    <category term="Bioinformatics"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="biology"/>
    <category term="coding"/>
    <category term="fasta.el"/>
    <published>2026-04-08T11:25:43+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/07/quiz-el-v1-6.html</id>
    <title>quiz.el v1.6</title>
    <updated>2026-04-07T09:18:23+01:00</updated>
    <content type="html">&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" height="774" loading="lazy" src="https://blog.davep.org/attachments/2026/04/07/quiz.webp#centre" width="720" /&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" height="838" loading="lazy" src="https://blog.davep.org/attachments/2026/04/07/original-quiz.webp#centre" width="777" /&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;</content>
    <link href="https://blog.davep.org/2026/04/07/quiz-el-v1-6.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="quiz.el"/>
    <published>2026-04-07T09:18:23+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/06/expando-el-v1-5.html</id>
    <title>expando.el v1.5</title>
    <updated>2026-04-06T20:43:29+01:00</updated>
    <content type="html">&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" height="1061" loading="lazy" src="https://blog.davep.org/attachments/2026/04/06/expando.webp#centre" width="1024" /&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;</content>
    <link href="https://blog.davep.org/2026/04/06/expando-el-v1-5.html"/>
    <category term="Emacs"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="coding"/>
    <category term="expando.el"/>
    <category term="defmacro"/>
    <published>2026-04-06T20:43:29+01:00</published>
  </entry>
  <entry>
    <id>https://blog.davep.org/2026/04/06/blogmore-el-v4-0.html</id>
    <title>blogmore.el v4.0</title>
    <updated>2026-04-06T17:04:16+01:00</updated>
    <content type="html">&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:273-1"&gt;&lt;a class="footnote-ref" href="#fn:273-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" height="970" loading="lazy" src="https://blog.davep.org/attachments/2026/04/06/remove-tag.webp#centre" width="1000" /&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:273-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:273-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;</content>
    <link href="https://blog.davep.org/2026/04/06/blogmore-el-v4-0.html"/>
    <category term="Emacs"/>
    <category term="BlogMore"/>
    <category term="Emacs"/>
    <category term="Emacs Lisp"/>
    <category term="Lisp"/>
    <category term="blogmore.el"/>
    <category term="coding"/>
    <published>2026-04-06T17:04:16+01:00</published>
  </entry>
</feed>
