Search code examples
emacsmodeline

easily display useful information in custom emacs minor mode -- mode-line woes


Background:

I'm creating a minor mode that gives the user "hints" about whether the buffer they're visiting uses tabs or spaces for indentation (simply by examining the first character of each line in the buffer). Some features I plan to add include an informational display in the mode-line and a few functions to switch between using tabs or spaces, tab-width, etc.

I'm not really concerned about the usefulness of this minor mode. In fact, I would be surprised if there's not already something out there that does this same thing. Mostly this is an exercise in writing minor modes.


Question:

What would be a clean, non-obtrusive way to insert/remove text from the mode-line when enabling/disabling my minor mode? I don't want the user to have to modify their mode-line-format, I just want non-destructively insert and remove text. Right now I'm using a function that looks something like:

(defun update-indent-hints-mode-line (what-this-buffer-loves)
  (let ((indent-hints-mode-line-text (concat " " "[" what-this-buffer-loves "-loving" "]"))
        (my-mode-line-buffer-identification
         (remq " [Tab-loving]" (remq " [Space-loving]" mode-line-buffer-identification))))
    (setq mode-line-buffer-identification
          (add-to-list 'my-mode-line-buffer-identification
                       indent-hints-mode-line-text
                       t))
    (force-mode-line-update)))

It's working okay but searching for and removing " [Tab-loving]" and " [Space-loving]" seems pretty hackish and ugly... Is there a cleaner way to do it?

Bonus Points: Any comments on the humble beginnings of my equally humble minor-mode: https://github.com/mgalgs/indent-hints-mode/blob/master/indent-hints.el I'm obviously an elisp n00b, but I'm here to learn.


Solution

  • Check out the variable minor-mode-alist, which associates variables with strings in the mode-line. If you change your code to either set the variable tab-loving to t or space-loving to t (and set the other variable to the nil), you can get what you want with:

    (setq minor-mode-alist (cons '(space-loving " [Space-loving]")
                                 (cons '(tab-loving " [Tab-loving]")
                                       minor-mode-alist)))