diff options
author | Juanma Barranquero <[email protected]> | 2013-07-06 11:35:37 +0200 |
---|---|---|
committer | Juanma Barranquero <[email protected]> | 2013-07-06 11:35:37 +0200 |
commit | 61e56e2c8ae166d7a4430b0ba717f71faae78ff9 (patch) | |
tree | 0d375c7b824cf1a894f507f15d2063b16ebe120e | |
parent | 3323c263c78e74385bc03d5270cdd44399b0a8d1 (diff) |
lisp/simple.el (alternatives-define): New macro.
etc/NEWS: Document new "generic commands" support.
-rw-r--r-- | etc/ChangeLog | 4 | ||||
-rw-r--r-- | etc/NEWS | 4 | ||||
-rw-r--r-- | lisp/ChangeLog | 4 | ||||
-rw-r--r-- | lisp/simple.el | 61 |
4 files changed, 73 insertions, 0 deletions
diff --git a/etc/ChangeLog b/etc/ChangeLog index 93ba05bc37..9dbcc70ee0 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2013-07-06 Juanma Barranquero <[email protected]> + + * NEWS: Document new "generic commands" support. + 2013-06-27 Juanma Barranquero <[email protected]> * NEWS: Document new Desktop option `desktop-save-windows'. @@ -133,6 +133,10 @@ monitor, use the new functions above. Similar notes also apply to `x-display-pixel-width', `x-display-pixel-height', `display-mm-width', `display-mm-height', `x-display-mm-width', and `x-display-mm-height'. +** New macro `alternatives-define' can be used to define generic commands. +Generic commands are interactive functions whose implementation can be +selected among several alternatives, as a matter of user preference. + * Editing Changes in Emacs 24.4 diff --git a/lisp/ChangeLog b/lisp/ChangeLog index dc554bc542..901e582d15 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-07-06 Juanma Barranquero <[email protected]> + + * simple.el (alternatives-define): New macro. + 2013-07-06 Stefan Monnier <[email protected]> * subr.el (read-quoted-char): Use read-key. diff --git a/lisp/simple.el b/lisp/simple.el index 61f32363db..9e83a224f5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -7346,6 +7346,67 @@ warning using STRING as the message.") (with-eval-after-load pkg (bad-package-check pkg)))) + +;;; Generic dispatcher commands + +;; Macro `alternatives-define' 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. + +;; (alternatives-define COMMAND) creates a new interactive command +;; M-x COMMAND and a customizable variable COMMAND-alternatives. +;; Typically, the user will not need to customize this variable; packages +;; wanting to add alternative implementations should use +;; +;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives + +(defmacro alternatives-define (command &rest customizations) + "Define new command `COMMAND'. +The variable `COMMAND-alternatives' will contain alternative +implementations of COMMAND, so that running `C-u M-x COMMAND' +will allow the user to chose among them. +CUSTOMIZATIONS, if non-nil, should be composed of alternating +`defcustom' keywords and values to add to the declaration of +`COMMAND-alternatives' (typically to add new groups)." + (let* ((command-name (symbol-name command)) + (varalt-name (concat command-name "-alternatives")) + (varalt-sym (intern varalt-name)) + (varimp-sym (intern (concat command-name "--implementation")))) + `(progn + + (defcustom ,varalt-sym nil + ,(format "Alist of alternative implementations for the `%s' command. + +Each entry must be a pair (ALTNAME . ALTFUN), where: +ALTNAME - The name shown at user to describe the alternative implementation. +ALTFUN - The function called to implement this alternative." + command-name) + :type '(alist :key-type string :value-type function) + :group 'dispatcher + ,@customizations) + + (defvar ,varimp-sym nil "Internal use only.") + + (defun ,command (&optional arg) + ,(format "Run generic command `%s'. +If used for the first time, or with interactive ARG, ask the user which +implementation to use for `%s'. The variable `%s' +contains the list of implementations currently supported for this command." + command-name command-name varalt-name) + (interactive "P") + (when (or arg (null ,varimp-sym)) + (let ((val (completing-read + ,(format "Select implementation for command `%s': " command-name) + ,varalt-sym nil t))) + (unless (string-equal val "") + (customize-save-variable ',varimp-sym + (cdr (assoc-string val ,varalt-sym)))))) + (if ,varimp-sym + (funcall ,varimp-sym) + (message ,(format "No implementation selected for command `%s'" + command-name))))))) + (provide 'simple) ;;; simple.el ends here |