;;;###autoload
(defmacro easy-menu-define (symbol maps doc menu)
"Define a menu bar submenu in maps MAPS, according to MENU.
-The menu keymap is stored in symbol SYMBOL, both as its value
-and as its function definition. DOC is used as the doc string for SYMBOL.
+
+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.
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
A menu item can be a list with the same format as MENU. This is a submenu."
`(progn
- (defvar ,symbol nil ,doc)
+ ,(if symbol `(defvar ,symbol nil ,doc))
(easy-menu-do-define (quote ,symbol) ,maps ,doc ,menu)))
;;;###autoload
;; compatible. Therefore everything interesting is done in this
;; function.
(let ((keymap (easy-menu-create-menu (car menu) (cdr menu))))
- (set symbol keymap)
- (fset symbol
- `(lambda (event) ,doc (interactive "@e")
- ;; FIXME: XEmacs uses popup-menu which calls the binding
- ;; while x-popup-menu only returns the selection.
- (x-popup-menu event
- (or (and (symbolp ,symbol)
- (funcall
- (or (plist-get (get ,symbol 'menu-prop)
- :filter)
- 'identity)
- (symbol-function ,symbol)))
- ,symbol))))
+ (when symbol
+ (set symbol keymap)
+ (fset symbol
+ `(lambda (event) ,doc (interactive "@e")
+ ;; FIXME: XEmacs uses popup-menu which calls the binding
+ ;; while x-popup-menu only returns the selection.
+ (x-popup-menu event
+ (or (and (symbolp ,symbol)
+ (funcall
+ (or (plist-get (get ,symbol 'menu-prop)
+ :filter)
+ 'identity)
+ (symbol-function ,symbol)))
+ ,symbol)))))
(mapcar (lambda (map)
(define-key map (vector 'menu-bar (easy-menu-intern (car menu)))
(cons 'menu-item
easy-menu-converted-items-table)))
(defun easy-menu-convert-item-1 (item)
- "Parse an item description and add the item to a keymap.
-This is the function that is used for item definition by the other easy-menu
-functions.
-MENU is a sparse keymap i.e. a list starting with the symbol `keymap'.
-ITEM defines an item as in `easy-menu-define'.
-Optional argument BEFORE is nil or a key in MENU. If BEFORE is not nil
-put item before BEFORE in MENU, otherwise if item is already present in
-MENU, just change it, otherwise put it last in MENU."
+ "Parse an item description and convert it to a menu keymap element.
+ITEM defines an item as in `easy-menu-define'."
(let (name command label prop remove help)
(cond
((stringp item) ; An item or separator.
(postfix
(if (< (match-end 1) (match-end 0))
(substring keys (match-end 1))))
- (cmd (intern (substring keys (match-beginning 2)
- (match-end 2)))))
+ (cmd (intern (match-string 2 keys))))
(setq keys (and (or prefix postfix)
(cons prefix postfix)))
(setq keys
(eq (car-safe item) name)
(if (stringp name)
;; Match against the text that is displayed to the user.
- (or (member-ignore-case name item)
+ (or (condition-case nil (member-ignore-case name item)
+ (error nil)) ;`item' might not be a proper list.
;; Also check the string version of the symbol name,
;; for backwards compatibility.
- (eq (car-safe item) (intern name)))))))
+ (eq (car-safe item) (intern name))
+ (eq (car-safe item) (easy-menu-intern name)))))))
(defun easy-menu-always-true (x)
"Return true if form X never evaluates to nil."
Either call this from `menu-bar-update-hook' or use a menu filter,
to implement dynamic menus."
- (easy-menu-add-item nil path (cons name items) before))
+ (easy-menu-add-item nil path (easy-menu-create-menu name items) before))
;; XEmacs needs the following two functions to add and remove menus.
;; In Emacs this is done automatically when switching keymaps, so
;; here easy-menu-remove is a noop and easy-menu-add only precalculates
;; equivalent keybindings (if easy-menu-precalculate-equivalent-keybindings
;; is on).
-(defalias 'easy-menu-remove 'ignore)
+(defalias 'easy-menu-remove 'ignore
+ "Remove MENU from the current menu bar.
+Contrary to XEmacs, this is a nop on Emacs since menus are automatically
+\(de)activated when the corresponding keymap is (de)activated.
+
+\(fn MENU)")
(defun easy-menu-add (menu &optional map)
"Add the menu to the menubar.
However, if BEFORE is a string and there is an item in the submenu
with that name, then ITEM is added before that item.
-MAP should normally be a keymap; nil stands for the global menu-bar keymap.
+MAP should normally be a keymap; nil stands for the local menu-bar keymap.
It can also be a symbol, which has earlier been used as the first
argument in a call to `easy-menu-define', or the value of such a symbol.
;; Prefer a map that already contains the to-be-modified entry.
(when to-modify
(dolist (map maps)
- (when (and map (not (integerp map))
+ (when (and (keymapp map)
(easy-menu-get-map-look-for-name to-modify map))
(throw 'found map))))
;; Use the first valid map.
(dolist (map maps)
- (when (and map (not (integerp map)))
+ (when (keymapp map)
(throw 'found map)))
;; Otherwise, make one up.
;; Hardcoding current-local-map is lame, but it's difficult