Today I’d like to write about an Emacs feature I didn’t know about, even though it’s part of Emacs since quite some time – it appeared in version 24.4, which means it is over 10 years old! It seems I’m not the only one who didn’t know this exists – I’ve just searched my ~/.emacs.d/elpa
directory (which contains almost a hundred packages now!), and none of the packages I have installed there uses it, either.
Assume you want to define a user command dired-play
which plays a media file the point is on in Dired. There are several ways to play a file, though – you could use mplayer, vlc, or mpv (the latter being probably the best choice, but that’s another topic). You can define three commands – dired-play-mplayer
, dired-play-vlc
and dired-play-mpv
– and allow the user some way to choose one (most probably via an option declared using defcustom
). There is, however, an alternative (pun totally intended!) to a defcustom
! Let’s define the three commands (for simplicity, they will be just dummies, and I won’t include docstrings for the sake of brevity) and use define-alternatives
to allow the user to choose one of them.
(defun dired-play-mplayer () (interactive) (message "playing the sound using mplayer")) (defun dired-play-vlc () (interactive) (message "playing the sound using vlc")) (defun dired-play-mpv () (interactive) (message "playing the sound using mpv")) (defvar dired-play-alternatives '(("MPlayer" . dired-play-mplayer) ("VLC" . dired-play-vlc) ("mpv" . dired-play-mpv))) (define-alternatives dired-play)
Now the user can say M-x dired-play
(of course, in practice this would be bound to some key in dired-mode-map
, and Emacs will ask them to choose one of the players. From now on, every invocation of dired-play
will use the selected player. Should the user want to change their choice, they can just invoke dired-play
with a prefix argument. How cool is that?
One thing I don’t like about this feature is that it silently uses customize-save-variable
to persist the customization. This means that it modifies and saves my init.el
behind the scenes. I’m not a fan of Emacs modifying my init file, but here it is. (Admittedly, it does make sense in this particular case.)
So, that’s basically it for today. Command alternatives seems a nice (and heavily underused) feature of Emacs – not a single one file in Emac core repository uses it, and not a single one of almost 90 packages I have installed in my Emacs uses it, either. Still, it’s there in case you need it.