-;;; 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-2014 Free Software Foundation, Inc.
;; Keywords: emulations
;; Author: Richard Stallman <rms@gnu.org>
;;;###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)))
(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
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)))
(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))
;; 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)))))
(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
\(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
(provide 'easymenu)
-;; arch-tag: 2a04020d-90d2-476d-a7c6-71e072007a4a
;;; easymenu.el ends here