My Emacs mode line, and a config tip

Published 2025-06-12

tag(s): #emacs

I wrote the "only a tip" version of this post while my tea was brewing. But checking it out for errors a while later, before publishing, I realized it was a good opportunity explain in detail my mode line setup.
So now I have a chance to introduce new grammar and typing errors. Yay!

What is it? For the uninitiated

It is a status line of sorts, at the bottom of each "panel" in the UI, that gives you information about the contents of it.
Here is the manual entry, but I figure if you don't use Emacs, you will skip this one :) [1]

Why write your own?

I explained before why I don't use the default mode line.
There are tons of alternatives but they do a lot more than I need. At first I didn't care, and tested whichever one looked fancy, like telephone-line. If you want maximum customization, that one is pretty cool. But even something as tuned as doom-modeline would have the occasional bug or slowdown. And it required a lot of config...just to disable all the features I don't use.

Behold! My mode line

Screenshot of an Emacs mode-line.
(direct link to image)

The code lives in my "dotfiles" repository.
From the left:

And then aligned to the right (new feature in Emacs 30): I see this is a good combination of simple and keeping the info I use the most visible.

The tip (or, the original post)

So the tip that prompted the post, is a simple but an important implementation note. Lets look at how I defined the mode segment in older versions:


(defun hoagie-mode-line-major-mode ()
  "Mode-line major mode segment.
Show minor modes in the echo area/a tooltip."
  (propertize (format-mode-line mode-name)
              'face 'mode-line-buffer-id
              'help-echo (format-mode-line minor-mode-alist)))
    

Then I would (:eval (hoagie-mode-line-major-mode)) when setting mode-line-format.
Contrasting with the new version:


(setq-default mode-line-modes
     '(:propertize mode-name
                   help-echo (format-mode-line minor-mode-alist)))
    

The difference is, instead of defining a new function or variable to hold the configuration, I rely on the standard variable.
And it makes a difference! Because if a mode adds information to the mode line, it will rely on those default variables. I have an example.

I noticed csv-mode was supposed to display the column at point. Checking out its code, I found out that it was concatenating the information to the variable mode-line-position. But by using a custom function, I completely ignored its value!
And rather than add the variable in the function definition, I just revisited the entire thing to re-define it, in terms of the standard mode line constructs.
And this in turn led to using fewer (:eval... segments.

Since then I have seen quite a few custom mode lines using their own segment definitions. It might be fine if they incorporate the default variables...but honestly, it is easier to just re-use the defaults.

Footnotes
  1. My days of trying to convert everyone to Emacs are well behind me...that said, if you are curious about it, email me =P

Share your thoughts (via email)

Back to top

Back to homepage