Emacs sometimes uses buttons (for clicking on) or small graphics (to illustrate something). Since Emacs is available on a wide variety of systems with different capabilities, and users have different preferences, Emacs provides a facility to handle this in a convenient way, allowing customization, graceful degradation, accessibility, as well as themability: Icons.
The central macro here is define-icon
, and here’s a simple
example:
(define-icon outline-open button '((image "right.svg" "open.xpm" "open.pbm" :height line) (emoji "▶️") (symbol "▶" "➤") (text "open" :face icon-button)) "Icon used for buttons for opening a section in outline buffers." :version "29.1" :help-echo "Open this section")
Which alternative will actually be displayed depends on the value of
the user option icon-preference
(see Icons in The GNU
Emacs Manual) and on the results of run-time checks for what the
current frame’s terminal can actually display.
The macro in the example above defines outline-open
as an icon,
and inherits properties from the icon called button
(so this is
meant as a clickable button to be inserted in a buffer). It is
followed by a list of icon types along with the actual icon
shapes themselves. In addition, there’s a doc string and various
keywords that contain additional information and properties.
To instantiate an icon, you use icon-string
, which will
consult the current Customize theming, and the icon-preference
user option, and finally what the Emacs is able to actually display.
If icon-preference
is (image emoji symbol text)
(i.e.,
allowing all of these forms of icons), in this case,
icon-string
will first check that Emacs is able to display
images at all, and then whether it has support for each of those
different image formats. If that fails, Emacs will check whether
Emacs can display emojis (in the current frame). If that fails, it’ll
check whether it can display the symbol in question. If that fails,
it’ll use the plain text version.
For instance, if icon-preference
doesn’t contain image
or emoji
, it’ll skip those entries.
Code can confidently call icon-string
in all circumstances and
be sure that something readable will appear on the screen, no
matter whether the user is on a graphical terminal or a text terminal,
and no matter which features Emacs was built with.
Define an icon name, a symbol, with the display alternatives in
spec, that can be later instantiated using icon-string
.
The name is the name of the resulting keyword.
The resulting icon will inherit specs from parent, and from their parent’s parents, and so on, and the lowest descendent element wins.
specs is a list of icon specifications. The first element of each specification is the type, and the rest is something that can be used as an icon of that type, and then optionally followed by a keyword list. The following icon types are available:
image
In this case, there may be many images listed as candidates. Emacs
will choose the first one that the current Emacs instance can show.
If an image is listed is an absolute file name, it’s used as is, but it’s
otherwise looked up in the list image-load-path
(see Defining Images).
emoji
This should be a (possibly colorful) emoji.
symbol
This should be a (monochrome) symbol character.
text
Icons should also have a textual fallback. This can also be used for
the visually impaired: if icon-preference
is just
(text)
, all icons will be replaced by text.
Various keywords may follow the list of icon specifications. For instance:
(symbol "▶" "➤" :face icon-button)
Unknown keywords are ignored. The following keywords are allowed:
:face
The face to be used for the icon.
:height
This is only valid for image
icons, and can be either a number
(which specifies the height in pixels), or the symbol line
,
which will use the default line height in the currently selected
window.
:width
This is only valid for image
icons, and can be either a number
(which specifies the width in pixels), or the symbol font
,
which will use the width in pixels of the current buffer’s default
face font.
doc should be a doc string.
keywords is a list of keyword/value pairs. The following keywords are allowed:
:version
The (approximate) Emacs version this button first appeared. (This keyword is mandatory.)
:group
The customization group this icon belongs in. If not present, it is inferred.
:help-echo
The help string shown when hovering over the icon with the mouse pointer.
This function returns a string suitable for display in the current buffer for icon.
Alternatively, you can get a “deconstructed” version of icon
with this function. It returns a plist (see Property Lists) where
the keys are string
, face
and image. (The latter
is only present if the icon is represented by an image.) This can be
useful if the icon isn’t to be inserted directly in the buffer, but
needs some sort of pre-processing first.
Icons can be customized with M-x customize-icon. Themes can specify changes to icons with, for instance:
(custom-theme-set-icons 'my-theme '(outline-open ((image :height 100) (text " OPEN "))) '(outline-close ((image :height 100) (text " CLOSE " :face warning))))