Emacs: Nice Speedbar icons
2015-07-14This 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:
Set speedbar-button-face for using octicons font
Overwrite speedbar-expand-image-button-alist with new font symbols
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.