Emacs title

Updated Friday, Oct 2, 2026

Here is my current title bar. Emacs users call it a frame title:

Emacs! ~/.emacs.d/configuration.org [Org] *DIRTY*

  • The Emacs! helps me distinguish this application from others, plus conveys my appreciation for Emacs.
  • The full filename is visible, falling back to buffer name when not backed by a file.
  • The major mode is sandwiched between square brackets to remind myself of current buffer’s behaviors.
  • *DIRTY* appears when any buffer is dirty and needs saving. (Try M-x save-some-buffers or C-x s .)

frame-title-format examined

Here is the code from my configuration.org:

(setq-default frame-title-format
              '("Emacs! "
                (:eval
                 (if buffer-file-name
                   (replace-regexp-in-string
                    (regexp-quote (or (getenv "HOME") ""))
                    "~"
                    buffer-file-name)
                   (buffer-name)))
                " [%m]"
                (:eval
                 (if (files--buffers-needing-to-be-saved nil)
                   " *DIRTY*"))))

Read more on the frame-title-format documentation here or type C-h v frame-title-format RET. Strings are shown after expanding percent variables like %m for major mode. Sublists that have their first element set to :eval are evaluated and the computed value is used.

Showing the filename

The following snippet checks if the current buffer has a backing file (is the buffer-file-name variable non-nil?). When It has buffer-file-name set, the buffer-file-name is used after shortening the user’s homedir prefix to ~ like in sh or Bash.

(if buffer-file-name
  (replace-regexp-in-string
   (regexp-quote (or (getenv "HOME") ""))
   "~"
   buffer-file-name)
  (buffer-name))

Unsaved work (DIRTY flag)

The last bit of :eval code accesses a “private function” declared in files.el. (Emacs doesn’t have encapsulation so it is by convention to prefix private variables and functions with some-name--, in this case files--). Possibly, it’ll break because files--buffers-needing-to-be-saved is a private function. It works 🤷. And yup, (if ...) in elisp/common lisp is fun like that, can take one branch (or return nil, if the ELSE is missing).

(if (files--buffers-needing-to-be-saved nil)
  " *DIRTY*")

Why not default?

In contrast, default title string is okay. emacs -q then opening a sample document yields this mediocre title string: configuration.org - GNU Emacs at icarus on my laptop.

  • I don’t need to know it’s GNU Emacs.
  • I don’t need to know the hostname because I don’t regularly use X11 forwarding or some other form of running a remote Emacs frame as a native-looking local window, so the hostname is not relevant to me, as the hostname remains the same on each computer.

Unrelatedly- X11 forwarding is/was pretty cool for Emacs use

Convergent computing vibes in Emacs style.

When I use low-specced devices, it can help to move applications/compute between hosts. This is how I wrote tinybasic.rkt: Used a Pentium M laptop with a couple hundred megs of ram. Instead of running Emacs and my development environment locally, I ssh -Y‘ed into my workstation, opened a new emacsclient frame, and got to work. Everything I needed lived in Emacs, even terminals, since vterm exists. Once I was done, just closed out the frame, and could continue the work on my desktop with the same open buffers, in another emacsclient frame.

Additionally Emacs X11 forwarding works really well on certain WSL setups. (By the way, you can detect WSL in Emacs. Here is how I do it.)

What doesn’t work as well

Anything wrapped in (:eval ...) taking awhile to execute slows down Emacs. Use a profiler such as the built-in one to check. (profiler-start, then profiler-stop, then profiler-report to review.)

I used to include a list of visible windows in the titlebar but it got too slow or busy. Pretty sure it was a bit sluggy as this code runs often. This was the code that I found in my git history. I don’t miss knowing what windows are visible.

(string-join (mapcar #'(lambda (w)
                         (buffer-name (window-buffer w)))
                     (window-list))
             ", ")

That’s all that I have up in the braincase regarding Emacs titlebars.â–©

Offline Wikipedia is based

Updated Saturday, Sep 5, 2026

Caught myself browsing my offline Wikipedia today. I learned about pig animal behaviors, the genesis of PowerPC and Motorola’s role in it, the difference between Prairies and Savannas, that Acorns are produced by Oak trees, and that there are a bunch of minature pig breeds some which make for great pets.

It’s pretty easy to set up your very own offline Wikipedia. First grab a your languauge Wikipedia’s ZIM archive from the Kiwix Library. Search for Wikipedia find and download the entry with the largest file size. The English Wikipedia is about 115GB, other language Wikipedias have less entries with a smaller total file size.

(Don’t forget to browse for other useful zims, there are lots!)

Next grab the Kiwix Reader app. There is a native app for most platforms (Kiwix), a next-gen progressive web app which works much in the same way (Kiwix JS), and a web service (Kiwix Server).

I use a local Kiwix Server reverse proxied through Apache (or whatever httpd I got). Behind the scenes this setup employs a systemd unit to launch kiwix-serve and a rudimentary Python script to streamline kiwix-manage incantations.

But you don’t have to be clever. The PWA or Native app works well too. You’ll still need Kiwix Server for networked or multi-user ZIM collections.

Smart Watch isn't very Smart

Updated Thursday, Aug 20, 2026

Got heat exhaustion / heat stroke a few times in 2025. One way to mitigate further heat damage is to keep track of early heat exhaustion symptoms. In my own personal experience, one reliable indicator is an elevated pulse.

For awhile I measured my pulse manually and got really good at it. The problem was by the time I thought to check my pulse, heat exhaustion was already setting in. So I bought a smart watch, the least obtrusive one that I could find. Happened to be a $150 Vivosmart 5 which looks sort of like a Fitbit clone.

(I’d include a photo here and a few later in the post, but my best camera is my laptop’s grainy 720p camera as my glass sandwich phone ceased being useful as a phone or coaster.)

But for a smart watch it isn’t very smart.

I spend time out in the field doing random stuff, under cars, up trees, biking, whatever. Often my hands are full and I want to check the time. A quick twist of the wrist turns the screen on, but when driving or holding something, it’s not easy to achieve the motion that the firmware responds to. Instead I have to drop what I’m doing, free my other hand, press the wake button on the watch face, just to read the time.

It gets better because when I plug the watch in, the charging notification blocks the time readout. Thus I can’t use the watch as a watch when it’s charging, a limitation experienced weekly.

Next, if I’m outdoors at night, I’m invariably using red light. The smart watch has white or blue LEDs. The light on the inside for measuring the pulse is insanely bright too. Sorry to my camp neighbors because I’m sure I’ve dazzled them by flicking my wrist when unzipping a tent or opening a vehicle door.

Don’t get me wrong, I like the pulse feature, but I disable all the other features. But it has more silly limitations. Can’t set the time without pairing with a phone. Can’t follow daylight savings or timezone changes without pairing with a phone. I’ve broken two phones in less than a year. The fragile glass sandwiches that don’t even sit flat, so doesn’t even revert to a decent coaster when it completely stops working! Even with phone sync off and all these features disabled, the watch needs tending to on a weekly basis. It’ll nag me a few times about low battery and other silly things. (Just stop working when it’s out of juice, I don’t need to be pestered about it!)

And yet there’s more silliness.

The original proprietary cable failed. BestBuy and other brick-n-mortar stores don’t stock anything but the latest smart watch charging cables. So the watch sat. I waited for a special delivery from Amazon get lost, then found again, and finally I was able to charge the watch. That is until I lost that cable. Then it sat again, and I found it a month later. Haven’t lost it since but anything is possible.

And the particularly stupid part is one GARMIN CONNECT isn’t merely useful for configuration. You need app in order to set the damn time.

Oh, right, and yes there is even more. If one uses the other functions on the smart watch, it won’t revert back to the time-reading screen until you interact with it again. This means using the timer/stopwatch/alarm is actually more effort & takes longer than using it on a phone or laptop computer.

From my perspective, the smart watch that I have is very dumb, dumber than my sub-$20 Casio F91w that I wish I could revert back to.