Emacs Lisp: spotlight on format-spec
Just a quick warning: this is more for the Emacs Lisp library developer audience out there—yes, all three of you—and not really for Emacs end-users. Wait, you’re still here? OK, read on!
Emacs Lisp’s format
, like
C’s sprintf
, allows programmers to
produce formatted strings based on an input template. For
example, suppose you have a variable
name
and you’d like to produce a
string Hello, name! The relevant elisp
looks very similar to the relevant C:
(format "Hello, %s!" name)
instead of
sprintf("Hello, %s!", name);
The set
of valid format specifications is fixed in both C and elisp,
but what if you would like to provide some kind of custom string
formatting? Consider popular MUAs mutt and
Gnus. Both allow their users
to customize the listing of emails in a mailbox with sprintf
-like syntax.1 So %s
, for instance, might
mean the subject of the email, and %a
might mean
the email’s author.
Gnus accomplishes this using format-spec.el
, which ships with Gnus
(and thus with Emacs). It’s really easy to use;
here’s our example from before re-cast into format-spec
:
* (format-spec "Hello, %u!" '((?u . "ted")))
"Hello, ted!"
Of course, the idea isn’t to use it directly like that. Your library can expose the format string as a user-customizable option, like so:
(defvar hello-format "Hello, %u!"
"How this library should greet users.
The following characters are replaced:
%u: The username of the current user")
Several larger Emacs-based applications (like Gnus, ERC, etc.) make heavy
use of format-spec
; it’s a
great tool for putting a lot of formatting power in your
users’ hands, without scaring them too much with arcane
elisp snippets for their ~/.emacs
files. Try it today!
Notes
- For Mutt, see the documentation of index_format in §6.3 Configuration variables of the manual. For Gnus, see §8.4 Formatting Variables of the manual. ↩