]> git.eshelyaron.com Git - emacs.git/commitdiff
; Improve documentation of 'define-alternatives'
authorEli Zaretskii <eliz@gnu.org>
Tue, 15 Aug 2023 14:08:12 +0000 (17:08 +0300)
committerEli Zaretskii <eliz@gnu.org>
Tue, 15 Aug 2023 14:08:12 +0000 (17:08 +0300)
* doc/lispref/commands.texi (Generic Commands):
* lisp/simple.el (define-alternatives): Improve documentation of
'define-alternatives'.

doc/lispref/commands.texi
lisp/simple.el

index f84afcf52bdbaede175a79e7301a8eeca9947264..0298a5d77eec93df5479c32159825f00b0f695ff 100644 (file)
@@ -710,29 +710,77 @@ context.
 @node Generic Commands
 @subsection Select among Command Alternatives
 @cindex generic commands
-@cindex alternatives, defining
-
-The macro @code{define-alternatives} can be used to define
-@dfn{generic commands}.  These are interactive functions whose
-implementation can be selected from several alternatives, as a matter
-of user preference.
+@cindex alternative commands, defining
+
+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 @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
-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 invoked, the macro creates an interactive Lisp closure
+(@pxref{Closures}).  When the user runs @w{@kbd{M-x @var{command}
+@key{RET}}} for the first time, Emacs asks to select one of the
+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} can be created before
+calling @code{define-alternatives}, with the appropriate values;
+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}.
 
-When a user runs @kbd{M-x @var{command} @key{RET}} for the first time,
-Emacs prompts for which real form of the command to use, and records
-the selection by way of a custom variable.  Using a prefix argument
-repeats this process of choosing an alternative.
+Here is an example of a simple generic dispatcher command named
+@code{open} with 3 alternative implementations:
 
-The variable @code{@var{command}-alternatives} should contain an alist
-with alternative implementations of @var{command}.
-Until this variable is set, @code{define-alternatives} has no effect.
+@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
 
 @node Interactive Call
index 86f65d9d98e4253f18ded6c8e386024591d8face..abd587245fe4310fe88494e4ad35da7cdc222e95 100644 (file)
@@ -10664,10 +10664,13 @@ warning using STRING as the message.")
 \f
 ;;; Generic dispatcher commands
 
-;; Macro `define-alternatives' is used to create generic commands.
-;; Generic commands are these (like web, mail, news, encrypt, irc, etc.)
-;; that can have different alternative implementations where choosing
-;; among them is exclusively a matter of user preference.
+;; Macro `define-alternatives' can be used to create generic commands.
+;; Generic commands are commands that can have different alternative
+;; implementations, and choosing among them is the matter of user
+;; 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
 ;; 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
 
 (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 \
-the first time prompts for which
-alternative to use and records the selected command as a custom
-variable.
+the first time prompts for the
+alternative implementation to use and records the selected alternative.
+Thereafter, `\\[execute-extended-command] COMMAND RET' will \
+automatically invoke the recorded selection.
 
 Running `\\[universal-argument] \\[execute-extended-command] COMMAND RET' \
-prompts again for an alternative
-and overwrites the previous choice.
-
-The variable `COMMAND-alternatives' contains an alist with
-alternative implementations of COMMAND.  `define-alternatives'
-does not have any effect until this variable is set.
-
-CUSTOMIZATIONS, if non-nil, should be composed of alternating
-`defcustom' keywords and values to add to the declaration of
-`COMMAND-alternatives' (typically :group and :version)."
+again prompts for an alternative
+and overwrites the previous selection.
+
+The macro creates a `defcustom' named `COMMAND-alternatives'.
+CUSTOMIZATIONS, if non-nil, should be pairs of `defcustom'
+keywords and values to add to the definition of that `defcustom';
+typically, these keywords will be :group and :version with the
+appropriate values.
+
+To be useful, the value of `COMMAND-alternatives' should be an
+alist describing the alternative implementations of COMMAND.
+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))
   (let* ((command-name (symbol-name command))
          (varalt-name (concat command-name "-alternatives"))