Blog

For the English part of the blog, see Content AND Presentation.

2025-01-13 A minor Org Clive improvement

It’s been a while since I touched Org Clive, but I’m still using it. (Side note: after writing about a dozen articles on my Doctor Who weblog it went a bit dormant. I’m still thinking about it – in fact, even more than thinking, I’m slowly writing it – and I really do hope to come back to publishing there with some regularity. Stay tuned, and if you are interested, keep its RSS feed in your RSS reader.) One gripe I had with it is that the org-clive-generate-subtree command is a bit stupid. If I’m in the middle of writing a long article (and articles on that weblog tend to be long enough to warrant sections), and I’m in the middle of a section of an article, M-x org-clive-generate-subtree tries to export the current subtree (that is, the section), and complains.
Entry ‘…’ does not have the ‘CUSTOM’ property

The solution is obvious – that command should go up the Org hierarchy until it gets to a headline with the CUSTOM_ID property and export it, or signal an error when it doesn’t find any.

Quite fortunately, I have already solved a very similar problem, so I know about the org-up-heading-safe function. The solution turned out to be (expectedly) short, although slightly tricky because of the use of not and unless (and as we all know, negations are a bit less intuitive for our brains).

That’s it for today – stay tuned for more Emacs and programming stuff in the future, and if there is no article here some day, it will most probably mean that a new post appeared on Crimson Eleven Delight Petrichor!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode

Comments on this page

2025-01-05 Killing all buffers visiting files in a certain directory

When I leave the office, I generally close all work-related things – I sign out of Slack, shut down the virtual machine, and unmount the encrypted filesystem with work data. Obviously, I also want to kill all buffers “related to” that filesystem, for example all buffers visiting files there.

This is similar but different from project-kill-buffers – that command kills the buffers belonging to the current project (for example, the current Git repository), and I usually have more than one Git repo in the encrypted filesystem.

There seems to be a few ways of doing this. Probably the simplest one uses Ibuffer. You can just press * e to mark all buffers whose associated file doesn’t exists and then D to kill the marked buffers. This is a clever thing (since the filesystem is unmounted, all buffers visiting files there will get marked), but sadly is not enough. For example, Magit buffers are not associated with files, so they won’t be selected.

Another idea is to use % f to mark buffers by their filename, and enter a regex matching the directory name you need. For some reason, the Magit buffers are also selected with this approach, although I’m not sure why. I think the magic happens in the ibuffer-buffer-file-name function, but I’m not really sure if I want to dig into how exactly this works, since this solution is not complete, either. For example, *Diff* buffers are not marked with this approach, and I often diff similar fragments of code.

It turns out that Ibuffer has yet another facility which can help here. / F can filter the buffers by their directory; once I only have buffers in a given directory, I can press t to mark all of them (actually, toggle all the marks, but if nothing is marked, this does what I need) and then D to kill them.

This, of course, is just a workaround – what I’d really need is a simple command, let’s call it kill-all-buffers-in-directory, which would do exactly this, but automatically. It is still just a proxy – I could open a file in my encrypted directory and M-x cd to another directory in it – but as this is something I never do, closing all buffers whose “default directory” is a subdirectory of the mount point of my filesystem is enough for me.

As usual, the hard thing is to create a reasonable UI. In this case, this means notifying the user about the result of the buffer killing spree. The user must know if not all buffers were killed (this may happen if for example a buffer was visiting a file modified since the last save, and the user answered “no” when asked whether to save that buffer). I decided that just showing how many buffers were killed out of how many found is fine; as an added bonus, I used error if at least one buffer was not killed.

(defun kill-all-buffers-in-directory (directory)
  "Kill all buffers whose current directory is DIRECTORY."
  (interactive "D")
  (let* ((buffers (seq-filter
                   (lambda (buffer)
                     (string-prefix-p
                      directory
                      (expand-file-name (with-current-buffer buffer default-directory)))
                     )
                   (buffer-list)))
         (killed-status (mapcar #'kill-buffer buffers))
         (buffer-count (length killed-status))
         (not-killed-count (seq-count #'null killed-status))
         (killed-count (- buffer-count not-killed-count))
         (message (format "%s/%s buffer(s) killed" killed-count buffer-count)))
    (if (zerop not-killed-count)
        (message message)
      (error message))))

Note that I used the built-in seq-filter to avoid depending on cl. (I could have used seq-map too, but there is nothing wrong with mapcar.)

Also, I had to use expand-file-name. The docstring for default-directory says:
It should be an absolute directory name; on GNU and Unix systems, these names start with “” or “" and end with “”.
It turns out that for buffers visiting files, default-directory starts with / (at least this is what I have observed), but for Dired buffers under my home directory it starts with ~. Go figure.

That’s it for today. As usual, Emacs proves to be a great environment for tinkering and molding your tools into exactly what you need – even if sometimes an unexpected quirk pops up. Of course, I cannot not mention here the late Robert J. Chassell’s excellent Introduction to Programming in Emacs Lisp – and also my book about Emacs Lisp, designed as a “next step” after that. That book shows how to build three utilities in Emacs Lisp, starting from a very simple prototype and arriving at a useful tool for editing prose (reorder-sentence), complete with a pretty polished UI.

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2024-12-25 Merry Christmas 2024

And yet again, Christmas came! Every year, this is a powerful reminder that one day, we may live with God in Heaven. And much more than a reminder – Jesus lives and is truly present in the Eucharist, and like usual food and drink enables us to live here on Earth, Holy Communion enables us to live eternally. We just need to follow Him, and seriously! And Christmas is one of quite a few festivals where we have the opportunity to thank God for that and participate in the events that happened two thousand years ago. All this is of course only possible because of God’s mercy, since we are all sinners, but as St. Paul writes (paraphrasing Isaiah):
What eye has not seen, and ear has not heard, and what has not entered the human heart, what God has prepared for those who love him.
Let us rejoice, because Christ is born today to save us from the devil and the consequences of our own evil deeds! And let us rejoice because the Holy Spirit guides us every day so that we may do good, too!

And according to the little tradition of mine, I will of course say a decade of Rosary for all of you, my dear readers.

Happy Christmas!

CategoryEnglish, CategoryBlog, CategoryFaith

Comments on this page

More...