]> code.delx.au - gnu-emacs/blobdiff - lisp/emacs-lisp/easymenu.el
Update copyright year to 2015
[gnu-emacs] / lisp / emacs-lisp / easymenu.el
index 9992861fc3c2437751866a12ddc4af0062e01001..ad2ba6994f292ac402a4b2e34efcc5a3ab01cae0 100644 (file)
@@ -1,7 +1,6 @@
-;;; easymenu.el --- support the easymenu interface for defining a menu
+;;; easymenu.el --- support the easymenu interface for defining a menu  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1994, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1996, 1998-2015 Free Software Foundation, Inc.
 
 ;; Keywords: emulations
 ;; Author: Richard Stallman <rms@gnu.org>
@@ -45,111 +44,102 @@ menus, turn this variable off, otherwise it is probably better to keep it on.")
 
 ;;;###autoload
 (defmacro easy-menu-define (symbol maps doc menu)
-  "Define a menu bar submenu in maps MAPS, according to MENU.
+  "Define a pop-up menu and/or menu bar menu specified by MENU.
+If SYMBOL is non-nil, define SYMBOL as a function to pop up the
+submenu defined by MENU, with DOC as its doc string.
 
-If SYMBOL is non-nil, store the menu keymap in the value of SYMBOL,
-and define SYMBOL as a function to pop up the menu, with DOC as its doc string.
-If SYMBOL is nil, just store the menu keymap into MAPS.
+MAPS, if non-nil, should be a keymap or a list of keymaps; add
+the submenu defined by MENU to the keymap or each of the keymaps,
+as a top-level menu bar item.
 
-The first element of MENU must be a string.  It is the menu bar item name.
-It may be followed by the following keyword argument pairs
+The first element of MENU must be a string.  It is the menu bar
+item name.  It may be followed by the following keyword argument
+pairs:
 
-   :filter FUNCTION
+ :filter FUNCTION
+    FUNCTION must be a function which, if called with one
+    argument---the list of the other menu items---returns the
+    items to actually display.
 
-FUNCTION is a function with one argument, the rest of menu items.
-It returns the remaining items of the displayed menu.
+ :visible INCLUDE
+    INCLUDE is an expression.  The menu is visible if the
+    expression evaluates to a non-nil value.  `:included' is an
+    alias for `:visible'.
 
-   :visible INCLUDE
+ :active ENABLE
+    ENABLE is an expression.  The menu is enabled for selection
+    if the expression evaluates to a non-nil value.  `:enable' is
+    an alias for `:active'.
 
-INCLUDE is an expression; this menu is only visible if this
-expression has a non-nil value.  `:included' is an alias for `:visible'.
+The rest of the elements in MENU are menu items.
+A menu item can be a vector of three elements:
 
-   :active ENABLE
-
-ENABLE is an expression; the menu is enabled for selection
-whenever this expression's value is non-nil.
-
-The rest of the elements in MENU, are menu items.
-
-A menu item is usually a vector of three elements:  [NAME CALLBACK ENABLE]
+  [NAME CALLBACK ENABLE]
 
 NAME is a string--the menu item name.
 
-CALLBACK is a command to run when the item is chosen,
-or a list to evaluate when the item is chosen.
+CALLBACK is a command to run when the item is chosen, or an
+expression to evaluate when the item is chosen.
 
-ENABLE is an expression; the item is enabled for selection
-whenever this expression's value is non-nil.
+ENABLE is an expression; the item is enabled for selection if the
+expression evaluates to a non-nil value.
 
 Alternatively, a menu item may have the form:
 
-   [ NAME CALLBACK [ KEYWORD ARG ] ... ]
-
-Where KEYWORD is one of the symbols defined below.
-
-   :keys KEYS
-
-KEYS is a string; a complex keyboard equivalent to this menu item.
-This is normally not needed because keyboard equivalents are usually
-computed automatically.
-KEYS is expanded with `substitute-command-keys' before it is used.
-
-   :key-sequence KEYS
+   [ NAME CALLBACK [ KEYWORD ARG ]... ]
 
-KEYS is nil, a string or a vector; nil or a keyboard equivalent to this
-menu item.
-This is a hint that will considerably speed up Emacs' first display of
-a menu.  Use `:key-sequence nil' when you know that this menu item has no
-keyboard equivalent.
+where NAME and CALLBACK have the same meanings as above, and each
+optional KEYWORD and ARG pair should be one of the following:
 
-   :active ENABLE
+ :keys KEYS
+    KEYS is a string; a keyboard equivalent to the menu item.
+    This is normally not needed because keyboard equivalents are
+    usually computed automatically.  KEYS is expanded with
+    `substitute-command-keys' before it is used.
 
-ENABLE is an expression; the item is enabled for selection
-whenever this expression's value is non-nil.
+ :key-sequence KEYS
+    KEYS is a hint for speeding up Emacs's first display of the
+    menu.  It should be nil if you know that the menu item has no
+    keyboard equivalent; otherwise it should be a string or
+    vector specifying a keyboard equivalent for the menu item.
 
-   :visible INCLUDE
+ :active ENABLE
+    ENABLE is an expression; the item is enabled for selection
+    whenever this expression's value is non-nil.  `:enable' is an
+    alias for `:active'.
 
-INCLUDE is an expression; this item is only visible if this
-expression has a non-nil value.  `:included' is an alias for `:visible'.
+ :visible INCLUDE
+    INCLUDE is an expression; this item is only visible if this
+    expression has a non-nil value.  `:included' is an alias for
+    `:visible'.
 
-   :label FORM
+ :label FORM
+    FORM is an expression that is dynamically evaluated and whose
+    value serves as the menu item's label (the default is NAME).
 
-FORM is an expression that will be dynamically evaluated and whose
-value will be used for the menu entry's text label (the default is NAME).
+ :suffix FORM
+    FORM is an expression that is dynamically evaluated and whose
+    value is concatenated with the menu entry's label.
 
-   :suffix FORM
+ :style STYLE
+    STYLE is a symbol describing the type of menu item; it should
+    be `toggle' (a checkbox), or `radio' (a radio button), or any
+    other value (meaning an ordinary menu item).
 
-FORM is an expression that will be dynamically evaluated and whose
-value will be concatenated to the menu entry's label.
+ :selected SELECTED
+    SELECTED is an expression; the checkbox or radio button is
+    selected whenever the expression's value is non-nil.
 
-   :style STYLE
+ :help HELP
+    HELP is a string, the help to display for the menu item.
 
-STYLE is a symbol describing the type of menu item.  The following are
-defined:
+Alternatively, a menu item can be a string.  Then that string
+appears in the menu as unselectable text.  A string consisting
+solely of dashes is displayed as a menu separator.
 
-toggle: A checkbox.
-        Prepend the name with `(*) ' or `( ) ' depending on if selected or not.
-radio: A radio button.
-       Prepend the name with `[X] ' or `[ ] ' depending on if selected or not.
-button: Surround the name with `[' and `]'.  Use this for an item in the
-        menu bar itself.
-anything else means an ordinary menu item.
-
-   :selected SELECTED
-
-SELECTED is an expression; the checkbox or radio button is selected
-whenever this expression's value is non-nil.
-
-   :help HELP
-
-HELP is a string, the help to display for the menu item.
-
-A menu item can be a string.  Then that string appears in the menu as
-unselectable text.  A string consisting solely of hyphens is displayed
-as a solid horizontal line.
-
-A menu item can be a list with the same format as MENU.  This is a submenu."
-  (declare (indent defun))
+Alternatively, a menu item can be a list with the same format as
+MENU.  This is a submenu."
+  (declare (indent defun) (debug (symbolp body)))
   `(progn
      ,(if symbol `(defvar ,symbol nil ,doc))
      (easy-menu-do-define (quote ,symbol) ,maps ,doc ,menu)))
@@ -163,10 +153,13 @@ This is expected to be bound to a mouse event."
                    (prog1 (get menu 'menu-prop)
                      (setq menu (symbol-function menu))))))
     (cons 'menu-item
-          (cons (or item-name
-                    (if (keymapp menu)
-                        (keymap-prompt menu))
-                    "")
+          (cons (if (eq :label (car props))
+                    (prog1 (cadr props)
+                      (setq props (cddr props)))
+                  (or item-name
+                      (if (keymapp menu)
+                          (keymap-prompt menu))
+                      ""))
                 (cons menu props)))))
 
 ;;;###autoload
@@ -225,22 +218,22 @@ MENU-NAME is a string, the name of the menu.  MENU-ITEMS is a list of items
 possibly preceded by keyword pairs as described in `easy-menu-define'."
   (let ((menu (make-sparse-keymap menu-name))
         (easy-menu-avoid-duplicate-keys nil)
-       prop keyword arg label enable filter visible help)
+       prop keyword label enable filter visible help)
     ;; Look for keywords.
     (while (and menu-items
                (cdr menu-items)
                (keywordp (setq keyword (car menu-items))))
-      (setq arg (cadr menu-items))
-      (setq menu-items (cddr menu-items))
-      (cond
-       ((eq keyword :filter)
-       (setq filter `(lambda (menu)
-                       (easy-menu-filter-return (,arg menu) ,menu-name))))
-       ((eq keyword :active) (setq enable (or arg ''nil)))
-       ((eq keyword :label) (setq label arg))
-       ((eq keyword :help) (setq help arg))
-       ((or (eq keyword :included) (eq keyword :visible))
-       (setq visible (or arg ''nil)))))
+      (let ((arg (cadr menu-items)))
+        (setq menu-items (cddr menu-items))
+        (pcase keyword
+          (`:filter
+           (setq filter (lambda (menu)
+                          (easy-menu-filter-return (funcall arg menu)
+                                                   menu-name))))
+          ((or `:enable `:active) (setq enable (or arg ''nil)))
+          (`:label (setq label arg))
+          (`:help (setq help arg))
+          ((or `:included `:visible) (setq visible (or arg ''nil))))))
     (if (equal visible ''nil)
        nil                             ; Invisible menu entry, return nil.
       (if (and visible (not (easy-menu-always-true-p visible)))
@@ -249,14 +242,14 @@ possibly preceded by keyword pairs as described in `easy-menu-define'."
          (setq prop (cons :enable (cons enable prop))))
       (if filter (setq prop (cons :filter (cons filter prop))))
       (if help (setq prop (cons :help (cons help prop))))
-      (if label (setq prop (cons nil (cons label prop))))
-      (if filter
-         ;; The filter expects the menu in its XEmacs form and the pre-filter
-         ;; form will only be passed to the filter anyway, so we'd better
-         ;; not convert it at all (it will be converted on the fly by
-         ;; easy-menu-filter-return).
-         (setq menu menu-items)
-       (setq menu (append menu (mapcar 'easy-menu-convert-item menu-items))))
+      (if label (setq prop (cons :label (cons label prop))))
+      (setq menu (if filter
+                     ;; The filter expects the menu in its XEmacs form and the
+                     ;; pre-filter form will only be passed to the filter
+                     ;; anyway, so we'd better not convert it at all (it will
+                     ;; be converted on the fly by easy-menu-filter-return).
+                     menu-items
+                   (append menu (mapcar 'easy-menu-convert-item menu-items))))
       (when prop
        (setq menu (easy-menu-make-symbol menu 'noexp))
        (put menu 'menu-prop prop))
@@ -312,7 +305,7 @@ ITEM defines an item as in `easy-menu-define'."
          ;; Invisible menu item. Don't insert into keymap.
          (setq remove t)
        (when (and (symbolp command) (setq prop (get command 'menu-prop)))
-         (when (null (car prop))
+         (when (eq :label (car prop))
            (setq label (cadr prop))
            (setq prop (cddr prop)))
          (setq command (symbol-function command)))))
@@ -331,30 +324,28 @@ ITEM defines an item as in `easy-menu-define'."
                (setq keyword (aref item count))
                (setq arg (aref item (1+ count)))
                (setq count (+ 2 count))
-               (cond
-                ((or (eq keyword :included) (eq keyword :visible))
-                 (setq visible (or arg ''nil)))
-                ((eq keyword :key-sequence)
-                 (setq cache arg cache-specified t))
-                ((eq keyword :keys) (setq keys arg no-name nil))
-                ((eq keyword :label) (setq label arg))
-                ((eq keyword :active) (setq active (or arg ''nil)))
-                ((eq keyword :help) (setq prop (cons :help (cons arg prop))))
-                ((eq keyword :suffix) (setq suffix arg))
-                ((eq keyword :style) (setq style arg))
-                ((eq keyword :selected) (setq selected (or arg ''nil)))))
+               (pcase keyword
+                  ((or `:included `:visible) (setq visible (or arg ''nil)))
+                  (`:key-sequence (setq cache arg cache-specified t))
+                  (`:keys (setq keys arg no-name nil))
+                  (`:label (setq label arg))
+                  ((or `:active `:enable) (setq active (or arg ''nil)))
+                  (`:help (setq prop (cons :help (cons arg prop))))
+                  (`:suffix (setq suffix arg))
+                  (`:style (setq style arg))
+                  (`:selected (setq selected (or arg ''nil)))))
              (if suffix
                  (setq label
                        (if (stringp suffix)
                            (if (stringp label) (concat label " " suffix)
-                             (list 'concat label (concat " " suffix)))
+                             `(concat ,label ,(concat " " suffix)))
                          (if (stringp label)
-                             (list 'concat (concat label " ") suffix)
-                           (list 'concat label " " suffix)))))
+                             `(concat ,(concat label " ") ,suffix)
+                           `(concat ,label " " ,suffix)))))
              (cond
               ((eq style 'button)
                (setq label (if (stringp label) (concat "[" label "]")
-                             (list 'concat "[" label "]"))))
+                             `(concat "[" ,label "]"))))
               ((and selected
                     (setq style (assq style easy-menu-button-prefix)))
                (setq prop (cons :button
@@ -506,7 +497,7 @@ Contrary to XEmacs, this is a nop on Emacs since menus are automatically
 
 \(fn MENU)")
 
-(defun easy-menu-add (menu &optional map)
+(defun easy-menu-add (_menu &optional _map)
   "Add the menu to the menubar.
 On Emacs, menus are already automatically activated when the
 corresponding keymap is activated.  On XEmacs this is needed to
@@ -674,5 +665,4 @@ In some cases we use that to select between the local and global maps."
 
 (provide 'easymenu)
 
-;; arch-tag: 2a04020d-90d2-476d-a7c6-71e072007a4a
 ;;; easymenu.el ends here