; Improve documentation of 'define-alternatives'
* doc/lispref/commands.texi (Generic Commands): * lisp/simple.el (define-alternatives): Improve documentation of 'define-alternatives'.
This commit is contained in:
parent
32280205e2
commit
221ed70b90
2 changed files with 97 additions and 34 deletions
|
@ -710,29 +710,77 @@ context.
|
||||||
@node Generic Commands
|
@node Generic Commands
|
||||||
@subsection Select among Command Alternatives
|
@subsection Select among Command Alternatives
|
||||||
@cindex generic commands
|
@cindex generic commands
|
||||||
@cindex alternatives, defining
|
@cindex alternative commands, defining
|
||||||
|
|
||||||
The macro @code{define-alternatives} can be used to define
|
Sometimes it is useful to define a command that serves as a ``generic
|
||||||
@dfn{generic commands}. These are interactive functions whose
|
dispatcher'' capable of invoking one of a set of commands according to
|
||||||
implementation can be selected from several alternatives, as a matter
|
the user's needs. For example, imagine that you want to define a
|
||||||
of user preference.
|
command named @samp{open} that can ``open'' and display several
|
||||||
|
different types of objects. Or you could have a command named
|
||||||
|
@samp{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 @code{define-alternatives} can be used to define such
|
||||||
|
@dfn{generic commands}. A generic command is an interactive function
|
||||||
|
whose implementation can be selected from several alternatives, as a
|
||||||
|
matter of user preference.
|
||||||
|
|
||||||
@defmac define-alternatives command &rest customizations
|
@defmac define-alternatives command &rest customizations
|
||||||
Define the new command @var{command}, a symbol.
|
This macro defines the new generic @var{command}, which can have
|
||||||
|
several alternative implementations. The argument @var{command}
|
||||||
|
should be an unquoted symbol.
|
||||||
|
|
||||||
When a user runs @kbd{M-x @var{command} @key{RET}} for the first time,
|
When invoked, the macro creates an interactive Lisp closure
|
||||||
Emacs prompts for which real form of the command to use, and records
|
(@pxref{Closures}). When the user runs @w{@kbd{M-x @var{command}
|
||||||
the selection by way of a custom variable. Using a prefix argument
|
@key{RET}}} for the first time, Emacs asks to select one of the
|
||||||
repeats this process of choosing an alternative.
|
alternative implementations of @var{command}, offering completion for
|
||||||
|
the names of these alternatives. These names come from the user
|
||||||
|
option whose name is @code{@var{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
|
||||||
|
@w{@code{(@var{alt-name} . @var{alt-func})}}, where @var{alt-name} is
|
||||||
|
the name of the alternative and @var{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 @kbd{M-x @var{command}} again. To
|
||||||
|
choose a different alternative, type @w{@kbd{C-u M-x @var{command}
|
||||||
|
@key{RET}}}--then Emacs will again prompt for one of the alternatives,
|
||||||
|
and the selection will override the previous one.
|
||||||
|
|
||||||
The variable @code{@var{command}-alternatives} should contain an alist
|
The variable @code{@var{command}-alternatives} can be created before
|
||||||
with alternative implementations of @var{command}.
|
calling @code{define-alternatives}, with the appropriate values;
|
||||||
Until this variable is set, @code{define-alternatives} has no effect.
|
otherwise the macro creates the variable with a @code{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 @code{autoload} cookies
|
||||||
|
(@pxref{Autoload}) to add to the alist, for example:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
;;;###autoload (push '("My name" . my-foo-symbol) foo-alternatives
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
If the optional argument @var{customizations} is non-@code{nil}, it
|
||||||
|
should consist of alternating @code{defcustom} keywords (typically
|
||||||
|
@code{:group} and @code{:version}) and values to add to the definition
|
||||||
|
of the @code{defcustom} @code{@var{command}-alternatives}.
|
||||||
|
|
||||||
|
Here is an example of a simple generic dispatcher command named
|
||||||
|
@code{open} with 3 alternative implementations:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
(define-alternatives open
|
||||||
|
:group 'files
|
||||||
|
:version "42.1")
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
|
(setq open-alternatives
|
||||||
|
'(("file" . find-file)
|
||||||
|
("directory" . dired)
|
||||||
|
("hexl" . hexl-find-file)))
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
If @var{customizations} is non-@code{nil}, it should consist of
|
|
||||||
alternating @code{defcustom} keywords (typically @code{:group} and
|
|
||||||
@code{:version}) and values to add to the declaration of
|
|
||||||
@code{@var{command}-alternatives}.
|
|
||||||
@end defmac
|
@end defmac
|
||||||
|
|
||||||
@node Interactive Call
|
@node Interactive Call
|
||||||
|
|
|
@ -10664,10 +10664,13 @@ warning using STRING as the message.")
|
||||||
|
|
||||||
;;; Generic dispatcher commands
|
;;; Generic dispatcher commands
|
||||||
|
|
||||||
;; Macro `define-alternatives' is used to create generic commands.
|
;; Macro `define-alternatives' can be used to create generic commands.
|
||||||
;; Generic commands are these (like web, mail, news, encrypt, irc, etc.)
|
;; Generic commands are commands that can have different alternative
|
||||||
;; that can have different alternative implementations where choosing
|
;; implementations, and choosing among them is the matter of user
|
||||||
;; among them is exclusively a matter of user preference.
|
;; preference in each case. For example, you could have a generic
|
||||||
|
;; command `open' capable of "opening" a text file, a URL, a
|
||||||
|
;; directory, or a binary file, and each of these alternatives would
|
||||||
|
;; invoke a different Emacs function.
|
||||||
|
|
||||||
;; (define-alternatives COMMAND) creates a new interactive command
|
;; (define-alternatives COMMAND) creates a new interactive command
|
||||||
;; M-x COMMAND and a customizable variable COMMAND-alternatives.
|
;; M-x COMMAND and a customizable variable COMMAND-alternatives.
|
||||||
|
@ -10677,26 +10680,38 @@ warning using STRING as the message.")
|
||||||
;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives
|
;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives
|
||||||
|
|
||||||
(defmacro define-alternatives (command &rest customizations)
|
(defmacro define-alternatives (command &rest customizations)
|
||||||
"Define the new command `COMMAND'.
|
"Define a new generic COMMAND which can have several implementations.
|
||||||
|
|
||||||
The argument `COMMAND' should be a symbol.
|
The argument `COMMAND' should be an unquoted symbol.
|
||||||
|
|
||||||
Running `\\[execute-extended-command] COMMAND RET' for \
|
Running `\\[execute-extended-command] COMMAND RET' for \
|
||||||
the first time prompts for which
|
the first time prompts for the
|
||||||
alternative to use and records the selected command as a custom
|
alternative implementation to use and records the selected alternative.
|
||||||
variable.
|
Thereafter, `\\[execute-extended-command] COMMAND RET' will \
|
||||||
|
automatically invoke the recorded selection.
|
||||||
|
|
||||||
Running `\\[universal-argument] \\[execute-extended-command] COMMAND RET' \
|
Running `\\[universal-argument] \\[execute-extended-command] COMMAND RET' \
|
||||||
prompts again for an alternative
|
again prompts for an alternative
|
||||||
and overwrites the previous choice.
|
and overwrites the previous selection.
|
||||||
|
|
||||||
The variable `COMMAND-alternatives' contains an alist with
|
The macro creates a `defcustom' named `COMMAND-alternatives'.
|
||||||
alternative implementations of COMMAND. `define-alternatives'
|
CUSTOMIZATIONS, if non-nil, should be pairs of `defcustom'
|
||||||
does not have any effect until this variable is set.
|
keywords and values to add to the definition of that `defcustom';
|
||||||
|
typically, these keywords will be :group and :version with the
|
||||||
|
appropriate values.
|
||||||
|
|
||||||
CUSTOMIZATIONS, if non-nil, should be composed of alternating
|
To be useful, the value of `COMMAND-alternatives' should be an
|
||||||
`defcustom' keywords and values to add to the declaration of
|
alist describing the alternative implementations of COMMAND.
|
||||||
`COMMAND-alternatives' (typically :group and :version)."
|
The elements of this alist should be of the form
|
||||||
|
(ALTERNATIVE-NAME . FUNCTION)
|
||||||
|
where ALTERNATIVE-NAME is the name of the alternative to be shown
|
||||||
|
to the user as a selectable alternative, and FUNCTION is the
|
||||||
|
interactive function to call which implements that alternative.
|
||||||
|
The variable could be populated with associations describing the
|
||||||
|
alternatives either before or after invoking `define-alternatives';
|
||||||
|
if the variable is not defined when `define-alternatives' is invoked,
|
||||||
|
the macro will create it with a nil value, and your Lisp program
|
||||||
|
should then populate it."
|
||||||
(declare (indent defun))
|
(declare (indent defun))
|
||||||
(let* ((command-name (symbol-name command))
|
(let* ((command-name (symbol-name command))
|
||||||
(varalt-name (concat command-name "-alternatives"))
|
(varalt-name (concat command-name "-alternatives"))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue