Sometimes it is useful to define a command that serves as a “generic
dispatcher” capable of invoking one of a set of commands according to
the user’s needs. For example, imagine that you want to define a
command named ‘open’ that can “open” and display several
different types of objects. Or you could have a command named
‘mua’ (which stands for Mail User Agent) that can read and send
email using one of several email backends, such as Rmail, Gnus, or
MH-E. The macro define-alternatives
can be used to define such
generic commands. A generic command is an interactive function
whose implementation can be selected from several alternatives, as a
matter of user preference.
This macro defines the new generic command, which can have several alternative implementations. The argument command should be an unquoted symbol.
When invoked, the macro creates an interactive Lisp closure
(see Closures). When the user runs M-x command RET for the first time, Emacs asks to select one of the
alternative implementations of command, offering completion for
the names of these alternatives. These names come from the user
option whose name is command-alternatives
, which the
macro creates (if it didn’t exist before). To be useful, this
variable’s value should be an alist whose elements have the form
(alt-name . alt-func)
, where alt-name is
the name of the alternative and alt-func is the interactive
function to be called if this alternative is selected. When the user
selects an alternative, Emacs remembers the selection, and will
thereafter automatically call that selected alternative without
prompting when the user invokes M-x command again. To
choose a different alternative, type C-u M-x command RET–then Emacs will again prompt for one of the alternatives,
and the selection will override the previous one.
The variable command-alternatives
can be created before
calling define-alternatives
, with the appropriate values;
otherwise the macro creates the variable with a nil
value, and
it should then be populated with the associations describing the
alternatives. Packages that wish to provide their own implementation
of an existing generic command can use autoload
cookies
(see Autoload) to add to the alist, for example:
;;;###autoload (push '("My name" . my-foo-symbol) foo-alternatives
If the optional argument customizations is non-nil
, it
should consist of alternating defcustom
keywords (typically
:group
and :version
) and values to add to the definition
of the defcustom
command-alternatives
.
Here is an example of a simple generic dispatcher command named
open
with 3 alternative implementations:
(define-alternatives open :group 'files :version "42.1")
(setq open-alternatives '(("file" . find-file) ("directory" . dired) ("hexl" . hexl-find-file)))