12

My modeline is cluttered. Can I make it display pictures instead of mode names?

I could use unicode Emoji (such as 🐍 for Python or 🐓 for Coq), but some machines on which I use my Emacs config do not have the right fonts pre-installed (ideally, I'd also like to reuse this technique in a mode that I'm writing, so I can't expect users to have the right font setup).

I tried adding an :image display property to the modeline lighter of a toy minor-mode, but nothing appeared in the modeline:

(define-minor-mode my/test-mode
  "Test mode."
  :lighter (propertize " 🐓" 'display '(image :type imagemagick
                                             :file "/home/clement/.emacs.d/rooster.png")))

TWEmoji rooster (https://raw.githubusercontent.com/twitter/twemoji/gh-pages/72x72/1f413.png)

  • Is there a way to bring the fonts into your config? – PythonNut Dec 18 '15 at 17:45
  • 2
    Yes, it totally is possible to do that. See nyan-mode. Could it be that the image is too large to be displayed properly? – wasamasa Dec 18 '15 at 17:54
  • @wasamasa, Great point! Do you know how nyan-mode does it? – Clément Dec 18 '15 at 19:31
  • How to replace major-mode string in mode-line with this icon? – stardiviner Dec 28 '15 at 13:26
11

The mode line is rendered from a list of segments, each of which come with their own special rules. See Mode Line Data for the details. The symbol section contains a crucial hint to make your code work:

Unless SYMBOL is marked as “risky” (i.e., it has a non-‘nil’ ‘risky-local-variable’ property), all text properties specified in SYMBOL’s value are ignored. This includes the text properties of strings in SYMBOL’s value, as well as all ‘:eval’ and ‘:propertize’ forms in it. (The reason for this is security: non-risky variables could be set automatically from file variables without prompting the user.)

I suspect nyan-mode is doing it in a less than ideal way, so here's my minimal example:

(defvar my-nyan-mode-lighter
  (list " " (propertize ":3" 'display
                        `(image :type imagemagick
                                :file ,(expand-file-name "~/nyan.png")))))
(put 'my-nyan-mode-lighter 'risky-local-variable t)

(define-minor-mode my-nyan-mode
  "Nyan mode"
  :lighter my-nyan-mode-lighter)

(my-nyan-mode)

The reason why I use a list of a space and an image is because it is convention to start a lighter with a space for separating it from the preceding ones.

  • Actually, did you try this in emacs -Q? It works great with smart-mode-line enabled, but I can't make it work when I start from a bare Emacs. – Clément Dec 28 '15 at 1:45
  • Huh, you're right. I'll check what else is missing. – wasamasa Dec 28 '15 at 9:33
  • OK, I've figured it out. Apparently that package just uses strings inside a format string whereas the real deal walks through the mode line segments individually and does only recognize strings that are propertized from start to end, so I've went for a list of two strings to have a separator. – wasamasa Dec 28 '15 at 10:17
  • Brillian, many thanks! The list tricks the mode line formatter into not applying the top-level :propertize of the default mode-line-format. – Clément Dec 28 '15 at 14:44
  • @wasamasa Wow, that's nice. Now when you mouse over the image, there is a generic menu ; how would one put entries in it? Just a simple string as a mouse hover message would be fine, too. – yPhil Jul 19 '17 at 19:53
4

Good question.

You might try using something like this as the lighter: (concat " " (propertize " " 'display (create-image img-file))), where img-file is the name of your image file. (The first space char is just to separate this lighter from the previous one.)

Well, I just tried, using this code, but it did not work for me. You might try fiddling a bit more with it. Dunno whether it is possible.

(defvar my-lighter-string
        (concat " " (propertize " " 'display (create-image "/path/to/an/image/file.png"))))

(define-minor-mode foo "..." nil my-lighter-string)

The lighter just shows as an ordinary space char -- the display property does not seem to be respected.

If you don't get a good answer to this question, consider filing an Emacs enhancement request, using M-x report-emacs-bug.

One thing you can certainly do is to use one or two Unicode characters in the mode-line string. And you can use chars that are, in effect, graphics.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.