The Emacs Modeline

The modeline is the descriptive line at the bottom of your emacs window (right above the minibuffer, to be precise). It provides the basic information like what file you are working on, what mode you are in and so on.

I decided to modify my modeline to solve a particular problem: I needed to know what host I was running on. The reason I need to do this is I now run gnu screen on my local laptop, and inside one of the screen windows, I run another remote screen on my work computer.

Since I am an inveterate emacs user, I want to run it in both the local and remote screen session. Yes, I know about tramp-mode to access files remotely in emacs, but I don't want to deal with that. I just needed a way to quickly identify whether I was in the local or remote emacs, since they look pretty much identical on the console in the default configuration.

The solution as I mentioned was to modify my modeline on both systems. I would put the hostname in the modeline on each system, and change the modeline colors for quick identification.

This stack overflow question seemed to have the answer, but I had zero luck getting that solution to work. I then started reading the modeline docs and things got real. A few hours later I realized that messing with your modeline is a fools errand. Luckily for you, I did the work and wrote it down here so you don't have to waste any time.

Basically, the modeline configuration is controlled by the variable mode_line_format (except for the color, which I will get to in a bit). In older versions of emacs, you put various %X escape sequences in a list in this variable.

Newer emacsen still support this syntax, but it's use is discouraged. Instead you can insert various modeline variables. One of these (system-name) contains the hostname and that ended up being just what I needed.

Here's what you need to add to your .emacs to get my modeline. Note the use of setq-default instead of just setq. This is necessary to make the change global - if you just use setq, the variable becomes mode-specific.

;; Set the modeline to tell me the filename, hostname, etc..
(setq-default mode-line-format
      (list " "
            ; */% indicators if the file has been modified
            ; the name of the buffer (i.e. filename)
            ; note this gets automatically highlighted
            ; major and minor modes in effect
            ; if which-func-mode is in effect, display which
            ; function we are currently in.
            '(which-func-mode ("" which-func-format "--"))
            ; line, column, file %
            ; if vc-mode is in effect, display version control
            ; info here
            `(vc-mode vc-mode)
            ; hostname
            ; dashes sufficient to fill rest of modeline.

This results in a modeline like this:

 **--.emacs --[(Emacs-Lisp)]--[prefix-region]--28% (201,23) --ourtownadd-lm----------------------

which is the info I need. Now, on to the color. You set the modeline color with set-face-foreground and set-face-background. Bizarrely, you must have mode-line-inverse-video set, otherwise modeline colors are ignored. This inverts the color meaning, so setting foreground actually sets the modeline background. Here's how I dealt with that:

;; set the modeline to white on red
; you HAVE to set mode-line-inverse-video to t, otherwise the face
; gets ignored. Retarded.  That means you have to reverse the colors -
; setting foreground color actually sets background.
; see this gem: http://www.delorie.com/gnu/docs/emacs/emacs_89.html
 ((not window-system)
  (setq mode-line-inverse-video t)
  (set-face-foreground 'modeline "red")
  (set-face-background 'modeline "white")

Note I wrap this in a check to see if I'm running in a gui, because white text on red will probably look horrible in that case. If I do run a gui emacs, I let the system use it's default colors.

And there you go - hopefully this is the definitive reference on how to modify your emacs modeline. Let me know if it works for you.




Our Founder
ToolboxClick to hide/show
RecentChanges Click to hide/show