Use `declare' in defmacros.
[bpt/emacs.git] / lisp / emacs-lisp / easymenu.el
index ca5151f..9992861 100644 (file)
@@ -1,17 +1,18 @@
 ;;; easymenu.el --- support the easymenu interface for defining a menu
 
 ;; Copyright (C) 1994, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;;   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 ;; Keywords: emulations
 ;; Author: Richard Stallman <rms@gnu.org>
+;; Package: emacs
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,9 +20,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
-(defcustom easy-menu-precalculate-equivalent-keybindings t
+(defvar easy-menu-precalculate-equivalent-keybindings nil
   "Determine when equivalent key bindings are computed for easy-menu menus.
 It can take some time to calculate the equivalent key bindings that are shown
 in a menu.  If the variable is on, then this calculation gives a (maybe
 noticeable) delay when a mode is first entered.  If the variable is off, then
 this delay will come when a menu is displayed the first time.  If you never use
-menus, turn this variable off, otherwise it is probably better to keep it on."
-  :type 'boolean
-  :group 'menu
-  :version "20.3")
+menus, turn this variable off, otherwise it is probably better to keep it on.")
+(make-obsolete-variable
+ 'easy-menu-precalculate-equivalent-keybindings nil "23.1")
 
 (defsubst easy-menu-intern (s)
   (if (stringp s) (intern s) s))
 
-;;;###autoload
-(put 'easy-menu-define 'lisp-indent-function 'defun)
 ;;;###autoload
 (defmacro easy-menu-define (symbol maps doc menu)
   "Define a menu bar submenu in maps MAPS, according to MENU.
@@ -153,6 +149,7 @@ 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))
   `(progn
      ,(if symbol `(defvar ,symbol nil ,doc))
      (easy-menu-do-define (quote ,symbol) ,maps ,doc ,menu)))
@@ -279,9 +276,25 @@ conversion is done from within a filter.
 This also helps when the NAME of the entry is recreated each time:
 since the menu is built and traversed separately, the lookup
 would always fail because the key is `equal' but not `eq'."
-  (or (gethash item easy-menu-converted-items-table)
-      (puthash item (easy-menu-convert-item-1 item)
-              easy-menu-converted-items-table)))
+  (let* ((cache (gethash item easy-menu-converted-items-table))
+        (result (or cache (easy-menu-convert-item-1 item)))
+        (key (car-safe result)))
+    (when (and (listp easy-menu-avoid-duplicate-keys) (symbolp key))
+      ;; Merging multiple entries with the same name is sometimes what we
+      ;; want, but not when the entries are actually different (e.g. same
+      ;; name but different :suffix as seen in cal-menu.el) and appear in
+      ;; the same menu.  So we try to detect and resolve conflicts.
+      (while (memq key easy-menu-avoid-duplicate-keys)
+       ;; We need to use some distinct object, ideally a symbol, ideally
+       ;; related to the `name'.  Uninterned symbols do not work (they
+       ;; are apparently turned into strings and re-interned later on).
+       (setq key (intern (format "%s-%d" (symbol-name key)
+                                 (length easy-menu-avoid-duplicate-keys))))
+       (setq result (cons key (cdr result))))
+      (push key easy-menu-avoid-duplicate-keys))
+
+    (unless cache (puthash item result easy-menu-converted-items-table))
+    result))
 
 (defun easy-menu-convert-item-1 (item)
   "Parse an item description and convert it to a menu keymap element.
@@ -378,20 +391,6 @@ ITEM defines an item as in `easy-menu-define'."
     ;; It also makes it easier/possible to lookup/change menu bindings
     ;; via keymap functions.
     (let ((key (easy-menu-intern name)))
-      (when (listp easy-menu-avoid-duplicate-keys)
-        ;; Merging multiple entries with the same name is sometimes what we
-        ;; want, but not when the entries are actually different (e.g. same
-        ;; name but different :suffix as seen in cal-menu.el) and appear in
-        ;; the same menu.  So we try to detect and resolve conflicts.
-        (while (and (stringp name)
-                    (memq key easy-menu-avoid-duplicate-keys))
-          ;; We need to use some distinct object, ideally a symbol, ideally
-          ;; related to the `name'.  Uninterned symbols do not work (they
-          ;; are apparently turned into strings and re-interned later on).
-          (setq key (intern (format "%s (%d)" (symbol-name key)
-                                    (length easy-menu-avoid-duplicate-keys)))))
-        (push key easy-menu-avoid-duplicate-keys))
-
       (cons key
             (and (not remove)
                  (cons 'menu-item
@@ -470,7 +469,10 @@ When non-nil, NOEXP indicates that CALLBACK cannot be an expression
         (make-symbol (format "menu-function-%d" easy-menu-item-count))))
     (setq easy-menu-item-count (1+ easy-menu-item-count))
     (fset command
-         (if (or (keymapp callback) (functionp callback) noexp) callback
+         (if (or (keymapp callback) (commandp callback)
+                  ;; `functionp' is probably not needed.
+                  (functionp callback) noexp)
+              callback
            `(lambda () (interactive) ,callback)))
     command))
 
@@ -496,9 +498,7 @@ To implement dynamic menus, either call this from
 
 ;; 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).
+;; here easy-menu-remove is a noop.
 (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
@@ -512,17 +512,9 @@ On Emacs, menus are already automatically activated when the
 corresponding keymap is activated.  On XEmacs this is needed to
 actually add the menu to the current menubar.
 
-This also precalculates equivalent key bindings when
-`easy-menu-precalculate-equivalent-keybindings' is on.
-
 You should call this once the menu and keybindings are set up
 completely and menu filter functions can be expected to work."
-  (when easy-menu-precalculate-equivalent-keybindings
-    (if (and (symbolp menu) (not (keymapp menu)) (boundp menu))
-       (setq menu (symbol-value menu)))
-    (and (keymapp menu) (fboundp 'x-popup-menu)
-        (x-popup-menu nil menu))
-    ))
+  )
 
 (defun add-submenu (menu-path submenu &optional before in-menu)
   "Add submenu SUBMENU in the menu at MENU-PATH.