Emacs: Nice Speedbar icons

2015-07-14

This post shortly describes how to use overlays to beautify speedbar icons and give them a modern look and feel.

Motivation

Recently, the big hype about Github’s new OpenSource Chrome-based editor Atom motivated me to have a detailed look on it. Undoubtly, it is a great peace of software with a modern look and feel. My good old Emacs, in contrast, looks a bit antiquated. Especially, Emacs Speedbar's ASCII style in comparision to the Atom’s icons-based navigation tree makes this point clear. But, I guess this is something we can try to fix.

Used icon-font set by Atom

The first step is to collect more information about the used icon-font set. If you dig into Atoms source code on Github you will find out, that Atom is using the octicons fonts from Github. Basically, there are several formats for this icon set (e.g. svg, ttf, wopf?). In this article I will use the .ttf format because it can be handled as regular text in Emacs.

Speedbar customization

With the fonts in place the next step is to customize Speedbar for the usage of the new icons. As usual, fonts in Emacs are handled by font-faces. If you search in the Speedbar documentation (info page) you’ll find the speedbar-button-face. Moreover, you should disable the usage of images in speedbar to see the results.

(setq speedbar-use-images nil)

First approach: Built-in customization

The first approach can be summarized as follows:

After figuring out that this way was wrong I fired up the #emacs IRC channel and posted my question. The result was very informative? but a little bit frustrating, but read it for your own.

<dc24x7> Hi. Short question. Is it possible to change the ascii symbols in speedbar? And if yes, how?
...
<twb> ?+ is passed literally in e.g. speedbar-insert-files-at-point
<twb> Not easy to change
...
<twb> You would have to monkey-patch that function I think
<twb> And several other long functions
<twb> Not nice
<twb> Look in speedbar.el for ?+ and ?-
<dc24x7> twb: I supected something in this direction :(
<twb> There is speedbar-change-expand-button-char but it operates on the current line
<twb> You could maybe write a hook that uses that every time speedbar changes
<dc24x7> twb: Okay thx, I will have a look on it

Second approach: Overlays

The second and working approach uses the overlay concept.

Fortunately, there is a emacs package by Shingo Fukuyama which exactly does this - the ov.el package. Shingo himself has ported the Awesome font-icon set with this package to emacs. You can find the Gist-Code here

After utilizing the overlay concept and applying the advise of twb using a hook the following simple code could be developed.

(require 'ov)

(defun my-overlay ()
    (ov-set "<\\+>" 'display "\xf078\xf016" 'face '(:family "octicons"))
    (ov-set "<\\->" 'display "\xf0a3\xf016" 'face '(:family "octicons"))
    (ov-set "\\[\\+\\]" 'display "\xf011"))

(add-hook 'speedbar-scanner-reset-hook 'my-overlay)

Result

The following image shows the resutl. Nice font-icons in speedbar.