Posts from 2026

blogmore.el v2.4

1 min read

I've just released a little update to blogmore.el, adding blogmore-toggle-draft as a command. This came about in connection with the feature request that resulted in BlogMore v2.7.0 being released.

While I don't personally use draft for my posts, I can see the utility of it and if someone were to happen to use blogmore.el, it could be useful to have this bound to a handy key combination.

As for how it works: that's simple. When run, if there is no draft: frontmatter property, then draft: true is added. If draft: is there it is removed. Yes, it does mean that it will also remove draft: false too but... eh. Okay, fine, I might handle that case as a followup but I couldn't really imagine someone wanting to keep draft: false in the frontmatter.

If a post is ready to go, why bother with a header that means the same thing when it's not there?

BlogMore v2.7.0

1 min read

Given I've been on a little bit of an Emacs Lisp side quest, it's been a couple or so days since I made a release of BlogMore. Today's release comes after a feature request about draft posts.

While support for marking posts as drafts, and including or excluding them from a build, is something that's been in BlogMore from the start, it's not something I've ever used. These days, when I'm writing a post, especially if it's one that's taking a while to write, I'll do it in a branch and eventually PR into main before publishing. Given this it was useful to get a request relating to the feature as it helps me understand how someone else might use it.

So as of v2.7.0, if a post is marked as a draft, and if drafts are included in the build, it will be pretty obvious:

A draft post

When the post's title appears in the archive it will also appear obvious that it's still a draft too:

A draft post in the archive

All of this is, of course, modifiable via the template API and via styling, so if the choice of colour or icon doesn't suit it can be modified to taste.

binclock.el v1.12

2 min read

Some time in the late 1990s, after I'd been using GNU Emacs for a few years1, I grabbed a copy of Writing GNU Emacs Extensions. While I'd obviously created and added to and tinkered with my ~/.emacs some, I'd never written any non-trivial code. I feel it was around 1998 or 1999 that I really started to get into trying to write actual extensions, thanks to that book.

I can't remember what the first complete package was. I think it was actually 5x5.el2 but it might also have been binclock.el. Honestly, it's so long ago now that I don't have any good recollection and I don't have any record3. All of which is to say, binclock.el is one of my oldest bits of Emacs Lisp code, so it seemed fair that while I'm cleaning things up, I should give it a tidy too.

For anyone curious: it's a very simple binary clock type of thing. It opens a very small window and, depending on your settings, shows the time in various ways, all of which are in some way a binary display.

I can't say I've honestly ever had it running for more than a few moments, as an amusement, but I do remember it being a really helpful body of code to work on to help get familiar with Elisp. So, 27 years on from when I first opened the buffer to create it, it's tweaked and tidied and hopefully ready for another 27.

Would be cool if I'm around long enough to give it yet another tweak then.


  1. I first met it on OS/2 of all places, in 1994, or thereabouts. 

  2. Yes, the one that became Tools > Games > 5x5

  3. If I was using version control at all then, it was probably just rcs

obfusurl.el v2.2

1 min read

This bit of Emacs Lisp absolutely comes from a more innocent time on the Internet. Looking at it, it seems I wrote the first version, at least as a proper package, back in 2001. It's very possible that I carried a non-package version of it around as part of dp-lib.el1 for some time before, so it might date from the late 1990s. While we weren't absolutely innocent back then, the idea of a slightly-risky-looking URL wasn't quite so bad as it is now.

So obfusurl.el came about from my time on Usenet, where sometimes you'd want to post a URL that would otherwise be a spoiler. This package was my solution to that. It's a simple idea: keep the protocol and domain and so on visible, just hide the remaining part. So rather than post:

https://blog.davep.org/about/

You'd post:

https://blog.davep.org/%61%62%6f%75%74/

I suppose this is still useful today, although I would expect a lot of people to be way less likely to want to attempt that click -- readable domain or not.

But, anyway, the code needed a tidy and cleanup for today's Emacs and Emacs Lisp. So obfusurl.el v2.2 now exists.


  1. For a good chunk of my first decade of using Emacs, I carried a lot of personal code around in a rather large "library" file. 

eg.el v1.2

1 min read

Okay, that's it then; this is turning into a thing I think. Second in an occasional series of posts where I tidy up some of my old Emacs packages. This time I dug out eg.el and cleaned up some of the frowned-upon behaviour.

For anyone who doesn't know it: eg.el is one of many Norton Guide readers I've written over the years. This particular one was possibly the most fun as it was the most unlikely one to write and also, I think it's fair to say, my most ambitious one as well. It also holds a special place for me in that the bulk of it was written on trains during multiple trips up to Scotland, before I finally moved here (on the MacBook Air I mentioned the other day).

As I look at it now, I sort of want to give it a proper revisit. I've written more Norton Guide code since (see AgiNG for example) and have learnt better ways to handle certain things, and I also have an even bigger Norton Guide collection to test against. All of this could make for an even better Emacs implementation.

I also suspect that, this time around, I can do a better job of handling the colour and retaining the original Norton Guide reader look and feel. But, for now, the code has been tidied up and should keep working for some time yet.

thinks.el v1.13

1 min read

Given the recent spate of hacking on some Emacs Lisp, I've got a real taste for hacking on some more. Or, more to the point, revisiting some of the packages I have in Melpa and tidying them up where necessary.

The main thing I'll need to address is cutting back on all my old setf ways. I liked that approach to doing things, it made lots of sense and felt elegant; sadly the Emacs maintainers didn't seem to agree.

So... kicking this off I've released v1.13 of thinks.el. This is a bit of nonsense I wrote back in the days when Usenet was still pretty busy and the place to be (well, okay, back in 2000 when I was still hanging out on Usenet). The package itself lets you quickly and easily...

. o O ( ...write some text and then mark it all and then run a command and )
      ( have it turned into something that looks a little like a thought   )
      ( bubble.                                                            )

It has some variations on how the bubble looks, and also lets you use customize to tweak the characters to use, and also has an "extra silly" mode too.

Updating this wasn't too bad. Mostly just a case of turning some instances of (setf (point) ...) into (goto-char ...), and also modifying one instance of incf to be cl-incf.

Honestly, I don't know how useful this package is to anyone anymore. Most folk don't even know what Usenet is these days, and all the "social" places seem to favour non-monospaced fonts, meaning the bubbles would look pretty terrible anyway.

On the other hand, it seems a shame to not update it, and perhaps someone somewhere still uses it to make some pithy parenthetical remark, possibly about September never ending.

blogmore.el v2.3

1 min read

I've bumped blogmore.el to v2.3. The main change in this release, which I've had on my mental to-do list for a couple of days now, revolves around categories, tags and case.

I've got BlogMore set up so that it's pretty relaxed about case when it comes to categories and tags; so when it comes to generated files and URLs everything collapses to lowercase. However, blogmore.el wasn't taking this into account.

While it wasn't a serious issue, it did have the side-effect that, if you had a tag of lisp and a tag of Lisp, both would appear in the list of tags you could complete from. Also, when you went to add a tag to the tags frontmatter (via the blogmore-add-tag command), if you selected Lisp and lisp was already there, you'd end up with both versions after the command finished.

ℹ️ Note

As mentioned earlier: BlogMore itself would collapse Lisp and lisp to the same tag; the downside here is you'd see both tags shown in the post itself. Not a real problem, just not very tidy.

So earlier I changed things up a little; first cleaning up when loading pre-existing values and then ensuring the newly-set tags are deduplicated.

This now means I can edit and update a post even faster, without needing to worry about accidentally duplicating tags. This in turn reduces the friction to writing a post for my blog. That is, after all, the whole point of the name of the package and the blogging tool it's connected to!

OldNews v1.3.0

1 min read

OldNews

Yesterday evening I released v1.3.0 of OldNews, my terminal-based client for TheOldReader.

The main reason for this release is that html_to_markdown had a major release and the one function I use from it fundamentally changed the return type, causing OldNews to crash any time you tried to read an article.

It was a quick enough fix, although it's one I want to go back and review and perhaps see if there's a better approach, or see if this new return type offers something I could be making better use of.

The one other change, which I made a wee while ago but hadn't got round to releasing yet (I've been kind of distracted recently), is that OldNews now only makes a call out to the API to mark an article as read when you read it, but only if it was previously unread. A small internal change nobody should really notice, but it saves on work.

If you're a user of TheOldReader and fancy interacting with it from the terminal too then it's out there to try out. It's licensed GPL-3.0 and available via GitHub and also via PyPI. If you have an environment that has pipx installed you should be able to get up and running with:

pipx install oldnews

It can also be installed using uv:

uv tool install oldnews

If you don't have uv installed you can use uvx.sh to perform the installation. For GNU/Linux or macOS or similar:

curl -LsSf uvx.sh/oldnews/install.sh | sh

or on Windows:

powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/oldnews/install.ps1 | iex"

Once installed, run the oldnews command.

blogmore.el v2.2

3 min read

It really feels like BlogMore has kicked off a whole new thing when it comes to personal hacking. During the past few years I've developed a lot of Python applications and libraries, and have had a ton of fun doing so, but during that time I've not really done anything with writing stuff for Emacs.

To a large degree I think this says something about how stable Emacs is for me (I've been using it for a touch over 30 years at this point, you'd think I'd be kind of settled with it), but it's still always fun to have a reason to hack on some Lisp code. There's little doubt my Lisp -- especially Emacs Lisp -- has got a wee bit rusty.

So I'm having a lot of fun at the moment falling into the rabbit hole of expanding on and tinkering with blogmore.el. The reason I've just made v2.2 is a good example of exactly this. There are no real user-facing changes in the code, it was all things I just wanted to tidy up.

The main thing that has been bugging me for the past day is the repeating boilerplate that resulted from adding all the different current-blog-aware setting getter functions. There were 7 different functions, all looking like this:

(defun blogmore--post-maker-function ()
  "Get the post maker function for the current blog."
  (or
   (blogmore--blog-post-maker-function (blogmore--chosen-blog))
   blogmore-default-post-maker-function))

Exact same pattern, the only thing different being the name of the getter function being called on, and the name of the variable that contained the global default value.

So just a little earlier I cleaned this up using one of my favourite things about Lisp: defmacro. There's something about macros that makes me really like coding in Lisp, and which I cite as a really good thing when asked why I like Lisp, but which I always seem to utterly fail to explain well. Macros feel like one of those things you just have to experience for yourself to really get1.

Now, thanks to this:

(defmacro blogmore--setting (setting)
  "Generate a function to get the value of SETTING for the current blog."
  `(defun ,(intern (format "blogmore--%s" setting)) ()
     ,(format "Get the %s for the current blog." setting)
     (or (,(intern (format "blogmore--blog-%s" setting)) (blogmore--chosen-blog))
         ,(intern (format "blogmore-default-%s" setting)))))

all those 7 functions can collapse to this2:

(blogmore--setting post-template)
(blogmore--setting post-maker-function)
(blogmore--setting category-maker-function)
(blogmore--setting tag-maker-function)
(blogmore--setting post-link-format)
(blogmore--setting category-link-format)
(blogmore--setting tag-link-format)

Now the code is shorter, cleaner, and if I need to change anything I only need to change it in one place. Sure, the latter part especially is one of those "you could do that with a function too" things (have the work in one place), but here I can get the language to write me a whole load of functions, all of which refer to different functions and variables, each one based off just the one symbol.

The point of all of this being: v2.2 of blogmore.el is now out, it adds nothing for the user (who I suspect is only me anyway), but I had an absolute blast dusting off more of my Emacs Lisp knowledge and getting back the urge to code even more Emacs Lisp.

All of this has even got me tidying up my ~/.emacs.d/ and has me thinking I should go back through some of my older code and clean up all that legacy nonsense.


  1. There was a time I would have said "grok" here but... well that's spoiled now. 

  2. I suppose I could reduce that to one "call" with a loop over a list of symbols, but that feels unnecessary here. 

blogmore.el v2.1

1 min read

I've given blogmore.el a wee bump to v2.1. This release fixes a small problem I noticed today when I tried to use it to edit the tags for a post on my photoblog: the code to find and gather properties from posts didn't handle deeply-nested directory hierarchies for the post markdown files. I should have noticed this when I first wrote the code, but of course I was so busy testing against my primary blog, which only goes one sub-level deep, that I never noticed it wasn't going to work deeper.

So rather than using grep to look for things like foo/**/*.md I swapped to a combination of find and grep. Which works, but is slightly (but noticeably) slower.

Then I got to thinking that if I was doing this by hand, on the command line, I'd be using ripgrep anyway. Given this I might as well use it here. Of course, not everyone who might use blogmore.el will have rg installed so it makes sense to look for that and use it if it's available, otherwise fall back on find/grep.

There's still some low-priority cleaning up I want to do around this; an obvious change I want to make being one where I want to collapse all cases of the same word (Tree vs tree, etc) into one "hit"1. For now though, as always, it's working well enough for my needs and this change fixed an obvious issue I ran into.


  1. BlogMore itself takes care of this, but it would be nice to have the prompt in blogmore.el also take this into account.