]> code.delx.au - gnu-emacs/blobdiff - lisp/menu-bar.el
(sit_for): New arg initial_display.
[gnu-emacs] / lisp / menu-bar.el
index 01c65a07c67af33cf9d0ba468e3c9d084233cc25..41bc628c895ef8c0927cb1017e6fccf3f5ccd59f 100644 (file)
@@ -1,10 +1,10 @@
 ;;; menu-bar.el --- define a default menu bar.
 
 ;;; menu-bar.el --- define a default menu bar.
 
+;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
 ;; Author: RMS
 ;; Keywords: internal
 
 ;; Author: RMS
 ;; Keywords: internal
 
-;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
 ;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Avishai Yacobi suggested some menu rearrangements.
 
 ;;; Code:
 
 
 ;;; Code:
 
+;;; User options:
+
+(defcustom buffers-menu-max-size 10
+  "*Maximum number of entries which may appear on the Buffers menu.
+If this is 10, then only the ten most-recently-selected buffers are shown.
+If this is nil, then all buffers are shown.
+A large number or nil slows down menu responsiveness."
+  :type '(choice integer
+                (const :tag "All" nil))
+  :group 'mouse)
+
 ;; Don't clobber an existing menu-bar keymap, to preserve any menu-bar key
 ;; definitions made in loaddefs.el.
 (or (lookup-key global-map [menu-bar])
 ;; Don't clobber an existing menu-bar keymap, to preserve any menu-bar key
 ;; definitions made in loaddefs.el.
 (or (lookup-key global-map [menu-bar])
 (defvar menu-bar-help-menu (make-sparse-keymap "Help"))
 
 ;; Force Help item to come last, after the major mode's own items.
 (defvar menu-bar-help-menu (make-sparse-keymap "Help"))
 
 ;; Force Help item to come last, after the major mode's own items.
-(setq menu-bar-final-items '(help))
+;; The symbol used to be called `help', but that gets confused with the
+;; help key.
+(setq menu-bar-final-items '(help-menu))
 
 
-(define-key global-map [menu-bar help] (cons "Help" menu-bar-help-menu))
+(define-key global-map [menu-bar help-menu] (cons "Help" menu-bar-help-menu))
 (defvar menu-bar-search-menu (make-sparse-keymap "Search"))
 (define-key global-map [menu-bar search] (cons "Search" menu-bar-search-menu))
 (defvar menu-bar-edit-menu (make-sparse-keymap "Edit"))
 (defvar menu-bar-search-menu (make-sparse-keymap "Search"))
 (define-key global-map [menu-bar search] (cons "Search" menu-bar-search-menu))
 (defvar menu-bar-edit-menu (make-sparse-keymap "Edit"))
 (define-key global-map [menu-bar tools] (cons "Tools" menu-bar-tools-menu))
 (defvar menu-bar-files-menu (make-sparse-keymap "Files"))
 (define-key global-map [menu-bar files] (cons "Files" menu-bar-files-menu))
 (define-key global-map [menu-bar tools] (cons "Tools" menu-bar-tools-menu))
 (defvar menu-bar-files-menu (make-sparse-keymap "Files"))
 (define-key global-map [menu-bar files] (cons "Files" menu-bar-files-menu))
+
+;; This alias is for compatibility with 19.28 and before.
+(defvar menu-bar-file-menu menu-bar-files-menu)
 \f
 (defvar vc-menu-map (make-sparse-keymap "Version Control"))
 
 \f
 (defvar vc-menu-map (make-sparse-keymap "Version Control"))
 
+(define-key menu-bar-tools-menu [gdb] '("Debugger..." . gdb))
+(define-key menu-bar-tools-menu [compile] '("Compile..." . compile))
+(define-key menu-bar-tools-menu [grep] '("Search Files..." . grep))
+
+(define-key menu-bar-tools-menu [separator-1]
+  '("--"))
+
 (define-key menu-bar-tools-menu [calendar] '("Display Calendar" . calendar))
 (define-key menu-bar-tools-menu [calendar] '("Display Calendar" . calendar))
+(define-key menu-bar-tools-menu [compose-mail] '("Send Mail" . compose-mail))
 (define-key menu-bar-tools-menu [rmail] '("Read Mail" . rmail))
 (define-key menu-bar-tools-menu [gnus] '("Read Net News" . gnus))
 
 (define-key menu-bar-tools-menu [separator-vc]
   '("--"))
 
 (define-key menu-bar-tools-menu [rmail] '("Read Mail" . rmail))
 (define-key menu-bar-tools-menu [gnus] '("Read Net News" . gnus))
 
 (define-key menu-bar-tools-menu [separator-vc]
   '("--"))
 
-(define-key menu-bar-tools-menu [vc-menu]
+(define-key menu-bar-tools-menu [vc]
   (cons "Version Control" vc-menu-map))
 
 (define-key menu-bar-tools-menu [separator-compare]
   (cons "Version Control" vc-menu-map))
 
 (define-key menu-bar-tools-menu [separator-compare]
@@ -61,7 +88,7 @@
   '("Apply Patch" . menu-bar-epatch-menu))
 (define-key menu-bar-tools-menu [ediff-merge]
   '("Merge" . menu-bar-ediff-merge-menu))
   '("Apply Patch" . menu-bar-epatch-menu))
 (define-key menu-bar-tools-menu [ediff-merge]
   '("Merge" . menu-bar-ediff-merge-menu))
-(define-key menu-bar-tools-menu [ediff]
+(define-key menu-bar-tools-menu [compare]
   '("Compare" . menu-bar-ediff-menu))
 
 (define-key menu-bar-tools-menu [separator-print]
   '("Compare" . menu-bar-ediff-menu))
 
 (define-key menu-bar-tools-menu [separator-print]
 
 (if (fboundp 'delete-frame)
     (progn
 
 (if (fboundp 'delete-frame)
     (progn
-      (define-key menu-bar-files-menu [delete-frame]
+      ;; Don't use delete-frame as event name
+      ;; because that is a special event.
+      (define-key menu-bar-files-menu [delete-this-frame]
        '("Delete Frame" . delete-frame))
       (define-key menu-bar-files-menu [make-frame-on-display]
        '("Open New Display..." . make-frame-on-display))
        '("Delete Frame" . delete-frame))
       (define-key menu-bar-files-menu [make-frame-on-display]
        '("Open New Display..." . make-frame-on-display))
 (define-key menu-bar-files-menu [kill-buffer]
   '("Kill Current Buffer" . kill-this-buffer))
 (define-key menu-bar-files-menu [insert-file]
 (define-key menu-bar-files-menu [kill-buffer]
   '("Kill Current Buffer" . kill-this-buffer))
 (define-key menu-bar-files-menu [insert-file]
-  '("Insert File" . insert-file))
+  '("Insert File..." . insert-file))
 (define-key menu-bar-files-menu [revert-buffer]
   '("Revert Buffer" . revert-buffer))
 (define-key menu-bar-files-menu [write-file]
 (define-key menu-bar-files-menu [revert-buffer]
   '("Revert Buffer" . revert-buffer))
 (define-key menu-bar-files-menu [write-file]
 (define-key menu-bar-files-menu [dired] '("Open Directory..." . dired))
 (define-key menu-bar-files-menu [open-file] '("Open File..." . find-file))
 
 (define-key menu-bar-files-menu [dired] '("Open Directory..." . dired))
 (define-key menu-bar-files-menu [open-file] '("Open File..." . find-file))
 
-;; This is just one element of the ediff menu--the first.
-(define-key menu-bar-ediff-menu [window]
-  '("This Window And Next Window" . compare-windows))
 \f
 (defun nonincremental-search-forward (string)
   "Read a string and search for it nonincrementally."
 \f
 (defun nonincremental-search-forward (string)
   "Read a string and search for it nonincrementally."
     (isearch-update-ring string t)
     (re-search-backward string)))
 
     (isearch-update-ring string t)
     (re-search-backward string)))
 
-(defun noninteractive-repeat-search-forward ()
+(defun nonincremental-repeat-search-forward ()
   "Search forward for the previous search string."
   (interactive)
   (search-forward (car search-ring)))
 
   "Search forward for the previous search string."
   (interactive)
   (search-forward (car search-ring)))
 
-(defun noninteractive-repeat-search-backward ()
+(defun nonincremental-repeat-search-backward ()
   "Search backward for the previous search string."
   (interactive)
   (search-backward (car search-ring)))
 
   "Search backward for the previous search string."
   (interactive)
   (search-backward (car search-ring)))
 
-(defun noninteractive-repeat-re-search-forward ()
+(defun nonincremental-repeat-re-search-forward ()
   "Search forward for the previous regular expression."
   (interactive)
   (re-search-forward (car regexp-search-ring)))
 
   "Search forward for the previous regular expression."
   (interactive)
   (re-search-forward (car regexp-search-ring)))
 
-(defun noninteractive-repeat-re-search-backward ()
+(defun nonincremental-repeat-re-search-backward ()
   "Search backward for the previous regular expression."
   (interactive)
   (re-search-backward (car regexp-search-ring)))
 
   "Search backward for the previous regular expression."
   (interactive)
   (re-search-backward (car regexp-search-ring)))
 
+(define-key menu-bar-search-menu [query-replace-regexp]
+  '("Query Replace Regexp..." . query-replace-regexp))
 (define-key menu-bar-search-menu [query-replace]
 (define-key menu-bar-search-menu [query-replace]
-  '("Query Replace" . query-replace))
+  '("Query Replace..." . query-replace))
 (define-key menu-bar-search-menu [find-tag]
 (define-key menu-bar-search-menu [find-tag]
-  '("Find Tag" . find-tag))
-(put 'find-tag 'menu-enable 'tags-table-list)
+  '("Find Tag..." . find-tag))
 (define-key menu-bar-search-menu [bookmark]
   '("Bookmarks" . menu-bar-bookmark-map))
 
 (define-key menu-bar-search-menu [separator-search]
   '("--"))
 
 (define-key menu-bar-search-menu [bookmark]
   '("Bookmarks" . menu-bar-bookmark-map))
 
 (define-key menu-bar-search-menu [separator-search]
   '("--"))
 
-(define-key menu-bar-search-menu [nonincremental-repeat-re-search-back]
+(define-key menu-bar-search-menu [repeat-regexp-back]
   '("Repeat Regexp Backwards" . nonincremental-repeat-re-search-backward))
   '("Repeat Regexp Backwards" . nonincremental-repeat-re-search-backward))
-(define-key menu-bar-search-menu [nonincremental-repeat-search-back]
+(define-key menu-bar-search-menu [repeat-search-back]
   '("Repeat Backwards" . nonincremental-repeat-search-backward))
   '("Repeat Backwards" . nonincremental-repeat-search-backward))
-(define-key menu-bar-search-menu [nonincremental-repeat-re-search-fwd]
+(define-key menu-bar-search-menu [repeat-regexp-fwd]
   '("Repeat Regexp" . nonincremental-repeat-re-search-forward))
   '("Repeat Regexp" . nonincremental-repeat-re-search-forward))
-(define-key menu-bar-search-menu [nonincremental-repeat-search-fwd]
+(define-key menu-bar-search-menu [repeat-search-fwd]
   '("Repeat Search" . nonincremental-repeat-search-forward))
 
 (define-key menu-bar-search-menu [separator-repeat]
   '("--"))
 
   '("Repeat Search" . nonincremental-repeat-search-forward))
 
 (define-key menu-bar-search-menu [separator-repeat]
   '("--"))
 
-(define-key menu-bar-search-menu [re-search-back]
-  '("Regexp Search Backwards" . nonincremental-re-search-backward))
-(define-key menu-bar-search-menu [search-back]
-  '("Search Backwards" . nonincremental-search-backward))
-(define-key menu-bar-search-menu [re-search-fwd]
-  '("Regexp Search" . nonincremental-re-search-forward))
-(define-key menu-bar-search-menu [search-fwd]
-  '("Search" . nonincremental-search-forward))
+(define-key menu-bar-search-menu [re-search-backward]
+  '("Regexp Search Backwards..." . nonincremental-re-search-backward))
+(define-key menu-bar-search-menu [search-backward]
+  '("Search Backwards..." . nonincremental-search-backward))
+(define-key menu-bar-search-menu [re-search-forward]
+  '("Regexp Search..." . nonincremental-re-search-forward))
+(define-key menu-bar-search-menu [search-forward]
+  '("Search..." . nonincremental-search-forward))
 \f
 \f
-(define-key menu-bar-edit-menu [spell] '("Spell" . ispell-menu-map))
+(if (fboundp 'start-process)
+    (define-key menu-bar-edit-menu [spell] '("Spell" . ispell-menu-map)))
 (define-key menu-bar-edit-menu [fill] '("Fill" . fill-region))
 (define-key menu-bar-edit-menu [props] '("Text Properties" . facemenu-menu))
 
 (define-key menu-bar-edit-menu [fill] '("Fill" . fill-region))
 (define-key menu-bar-edit-menu [props] '("Text Properties" . facemenu-menu))
 
       (message "Select a region with the mouse does `copy' automatically")
     (kill-ring-save beg end)))
 
       (message "Select a region with the mouse does `copy' automatically")
     (kill-ring-save beg end)))
 
-(put 'fill-region 'menu-enable 'mark-active)
-(put 'kill-region 'menu-enable 'mark-active)
+(put 'fill-region 'menu-enable '(and mark-active (not buffer-read-only)))
+(put 'kill-region 'menu-enable '(and mark-active (not buffer-read-only)))
 (put 'menu-bar-kill-ring-save 'menu-enable 'mark-active)
 (put 'menu-bar-kill-ring-save 'menu-enable 'mark-active)
-(put 'yank 'menu-enable '(x-selection-exists-p))
-(put 'yank-menu 'menu-enable '(cdr yank-menu))
+(put 'yank 'menu-enable '(and (x-selection-exists-p) (not buffer-read-only)))
+(put 'yank-menu 'menu-enable '(and (cdr yank-menu) (not buffer-read-only)))
 (put 'delete-region 'menu-enable '(and mark-active
 (put 'delete-region 'menu-enable '(and mark-active
+                                      (not buffer-read-only)
                                       (not (mouse-region-match))))
                                       (not (mouse-region-match))))
-(put 'undo 'menu-enable '(if (eq last-command 'undo)
-                            pending-undo-list
-                          (consp buffer-undo-list)))
+(put 'undo 'menu-enable '(and (not buffer-read-only)
+                             (if (eq last-command 'undo)
+                                 pending-undo-list
+                               (consp buffer-undo-list))))
 (put 'query-replace 'menu-enable '(not buffer-read-only))
 (put 'query-replace 'menu-enable '(not buffer-read-only))
+(put 'query-replace-regexp 'menu-enable '(not buffer-read-only))
 
 (autoload 'ispell-menu-map "ispell" nil t 'keymap)
 
 
 (autoload 'ispell-menu-map "ispell" nil t 'keymap)
 
@@ -288,13 +319,34 @@ Do the same for the keys of the same name."
   (define-key global-map [copy] 'clipboard-kill-ring-save)
   (define-key global-map [paste] 'clipboard-yank))
 \f
   (define-key global-map [copy] 'clipboard-kill-ring-save)
   (define-key global-map [paste] 'clipboard-yank))
 \f
+
+;;; Menu support
+
+(defvar menu-bar-custom-menu (make-sparse-keymap "Customize"))
+
+(define-key menu-bar-custom-menu [custom-menu-update]
+  '("Update This Menu" . custom-menu-update))
+(define-key menu-bar-custom-menu [customize-apropos]
+  '("Apropos..." . customize-apropos))
+(define-key menu-bar-custom-menu [customize-group]
+  '("Specific Group..." . customize-group))
+(define-key menu-bar-custom-menu [customize-face]
+  '("Specific Face..." . customize-face))
+(define-key menu-bar-custom-menu [customize-variable]
+  '("Specific Variable..." . customize-variable))
+(define-key menu-bar-custom-menu [customize]
+  '("Browse Hierarchy of User Options" . customize))
+
 (define-key menu-bar-help-menu [emacs-version]
   '("Show Version" . emacs-version))
 (define-key menu-bar-help-menu [report-emacs-bug]
 (define-key menu-bar-help-menu [emacs-version]
   '("Show Version" . emacs-version))
 (define-key menu-bar-help-menu [report-emacs-bug]
-  '("Send Bug Report" . report-emacs-bug))
+  '("Send Bug Report..." . report-emacs-bug))
+(define-key menu-bar-help-menu [finder-by-keyword]
+  '("Find Lisp Packages..." . finder-by-keyword))
 (define-key menu-bar-help-menu [emacs-tutorial]
   '("Emacs Tutorial" . help-with-tutorial))
 (define-key menu-bar-help-menu [emacs-tutorial]
   '("Emacs Tutorial" . help-with-tutorial))
-(define-key menu-bar-help-menu [man] '("Man..." . manual-entry))
+(define-key menu-bar-help-menu [man]
+  '("Man..." . manual-entry))
 (define-key menu-bar-help-menu [describe-variable]
   '("Describe Variable..." . describe-variable))
 (define-key menu-bar-help-menu [describe-function]
 (define-key menu-bar-help-menu [describe-variable]
   '("Describe Variable..." . describe-variable))
 (define-key menu-bar-help-menu [describe-function]
@@ -310,6 +362,8 @@ Do the same for the keys of the same name."
 (define-key menu-bar-help-menu [info] '("Browse Manuals" . info))
 (define-key menu-bar-help-menu [emacs-faq] '("Emacs FAQ" . view-emacs-FAQ))
 (define-key menu-bar-help-menu [emacs-news] '("Emacs News" . view-emacs-news))
 (define-key menu-bar-help-menu [info] '("Browse Manuals" . info))
 (define-key menu-bar-help-menu [emacs-faq] '("Emacs FAQ" . view-emacs-FAQ))
 (define-key menu-bar-help-menu [emacs-news] '("Emacs News" . view-emacs-news))
+(define-key menu-bar-help-menu [customize-menu]
+  (cons "Customize" menu-bar-custom-menu))
 
 (defun kill-this-buffer ()     ; for the menubar
   "Kills the current buffer."
 
 (defun kill-this-buffer ()     ; for the menubar
   "Kills the current buffer."
@@ -323,24 +377,46 @@ Do the same for the keys of the same name."
       (or (string-match "^ " (buffer-name (car buffers)))
          (setq count (1+ count)))
       (setq buffers (cdr buffers)))
       (or (string-match "^ " (buffer-name (car buffers)))
          (setq count (1+ count)))
       (setq buffers (cdr buffers)))
-    (> count 1)))
+    (and (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))
+        (> count 1))))
+
+(put 'kill-this-buffer 'menu-enable '(kill-this-buffer-enabled-p))
+
+(put 'save-buffer 'menu-enable
+     '(and (buffer-modified-p)
+          (not (window-minibuffer-p (frame-selected-window menu-updating-frame)))))
+
+(put 'write-file 'menu-enable
+     '(not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+
+(put 'find-file 'menu-enable
+     '(not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+
+(put 'dired 'menu-enable
+     '(not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
+
+(put 'insert-file 'menu-enable
+     '(not (window-minibuffer-p (frame-selected-window menu-updating-frame))))
 
 
-(put 'save-buffer 'menu-enable '(buffer-modified-p))
 (put 'revert-buffer 'menu-enable
      '(or revert-buffer-function revert-buffer-insert-file-contents-function
          (and (buffer-file-name)
               (or (buffer-modified-p)
                   (not (verify-visited-file-modtime (current-buffer)))))))
 (put 'revert-buffer 'menu-enable
      '(or revert-buffer-function revert-buffer-insert-file-contents-function
          (and (buffer-file-name)
               (or (buffer-modified-p)
                   (not (verify-visited-file-modtime (current-buffer)))))))
+
 ;; Permit deleting frame if it would leave a visible or iconified frame.
 (put 'delete-frame 'menu-enable
 ;; Permit deleting frame if it would leave a visible or iconified frame.
 (put 'delete-frame 'menu-enable
-     '(let ((frames (frame-list))
-           (count 0))
-       (while frames
-         (if (cdr (assq 'visibility (frame-parameters (car frames))))
-             (setq count (1+ count)))
-         (setq frames (cdr frames)))
-       (> count 1)))
-(put 'kill-this-buffer 'menu-enable '(kill-this-buffer-enabled-p))
+     '(delete-frame-enabled-p))
+
+(defun delete-frame-enabled-p ()
+  "Return non-nil if `delete-frame' should be enabled in the menu bar."
+  (let ((frames (frame-list))
+       (count 0))
+    (while frames
+      (if (frame-visible-p (car frames))
+         (setq count (1+ count)))
+      (setq frames (cdr frames)))
+    (> count 1)))
 
 (put 'advertised-undo 'menu-enable
      '(and (not (eq t buffer-undo-list))
 
 (put 'advertised-undo 'menu-enable
      '(and (not (eq t buffer-undo-list))
@@ -349,8 +425,10 @@ Do the same for the keys of the same name."
                    pending-undo-list)
             buffer-undo-list)))
 
                    pending-undo-list)
             buffer-undo-list)))
 
-(defvar yank-menu-length 20
-  "*Maximum length to display in the yank-menu.")
+(defcustom yank-menu-length 20
+  "*Maximum length to display in the yank-menu."
+  :type 'integer
+  :group 'mouse)
 
 (defun menu-bar-update-yank-menu (string old)
   (let ((front (car (cdr yank-menu)))
 
 (defun menu-bar-update-yank-menu (string old)
   (let ((front (car (cdr yank-menu)))
@@ -360,6 +438,10 @@ Do the same for the keys of the same name."
                        (substring string 0 (/ yank-menu-length 2))
                        "..."
                        (substring string (- (/ yank-menu-length 2)))))))
                        (substring string 0 (/ yank-menu-length 2))
                        "..."
                        (substring string (- (/ yank-menu-length 2)))))))
+    ;; Don't let the menu string be all dashes
+    ;; because that has a special meaning in a menu.
+    (if (string-match "\\`-+\\'" menu-string)
+       (setq menu-string (concat menu-string " ")))
     ;; If we're supposed to be extending an existing string, and that
     ;; string really is at the front of the menu, then update it in place.
     (if (and old (or (eq old (car front))
     ;; If we're supposed to be extending an existing string, and that
     ;; string really is at the front of the menu, then update it in place.
     (if (and old (or (eq old (car front))
@@ -379,15 +461,10 @@ Do the same for the keys of the same name."
   (push-mark (point))
   (insert last-command-event))
 \f
   (push-mark (point))
   (insert last-command-event))
 \f
-(define-key global-map [menu-bar buffer] '("Buffers" . menu-bar-buffers))
-
-(defalias 'menu-bar-buffers (make-sparse-keymap "Buffers"))
-
-(defvar buffers-menu-max-size 10
-  "*Maximum number of entries which may appear on the Buffers menu.
-If this is 10, then only the ten most-recently-selected buffers are shown.
-If this is nil, then all buffers are shown.
-A large number or nil slows down menu responsiveness.")
+;; This definition is just to show what this looks like.
+;; It gets overridden below when menu-bar-update-buffers is called.
+(define-key global-map [menu-bar buffer]
+  (cons "Buffers" (make-sparse-keymap "Buffers")))
 
 (defvar list-buffers-directory nil)
 
 
 (defvar list-buffers-directory nil)
 
@@ -425,12 +502,15 @@ A large number or nil slows down menu responsiveness.")
           file))
        (car elt)))
 
           file))
        (car elt)))
 
+(defvar menu-bar-buffers-menu-list-buffers-entry nil)
+
 (defun menu-bar-update-buffers ()
   ;; If user discards the Buffers item, play along.
   (and (lookup-key (current-global-map) [menu-bar buffer])
        (frame-or-buffer-changed-p)
        (let ((buffers (buffer-list))
             (frames (frame-list))
 (defun menu-bar-update-buffers ()
   ;; If user discards the Buffers item, play along.
   (and (lookup-key (current-global-map) [menu-bar buffer])
        (frame-or-buffer-changed-p)
        (let ((buffers (buffer-list))
             (frames (frame-list))
+            (maxlen 0)
             buffers-menu frames-menu)
         ;; If requested, list only the N most recently selected buffers.
         (if (and (integerp buffers-menu-max-size)
             buffers-menu frames-menu)
         ;; If requested, list only the N most recently selected buffers.
         (if (and (integerp buffers-menu-max-size)
@@ -445,7 +525,6 @@ A large number or nil slows down menu responsiveness.")
                             (mapcar 'list buffers))
                            tail
                            (menu-bar-update-buffers-maxbuf 0)
                             (mapcar 'list buffers))
                            tail
                            (menu-bar-update-buffers-maxbuf 0)
-                           (maxlen 0)
                            alist
                            head)
                       ;; Put into each element of buffer-list
                            alist
                            head)
                       ;; Put into each element of buffer-list
@@ -482,6 +561,25 @@ A large number or nil slows down menu responsiveness.")
                                (setq maxlen (length (car (car alist))))))
                         (setq tail (cdr tail)))
                       (setq alist (nreverse alist))
                                (setq maxlen (length (car (car alist))))))
                         (setq tail (cdr tail)))
                       (setq alist (nreverse alist))
+                      ;; Make the menu item for list-buffers
+                      ;; or reuse the one we already have.
+                      ;; The advantage in reusing one
+                      ;; is that it already has the keyboard equivalent
+                      ;; cached, so we save the time to look that up again.
+                      (or menu-bar-buffers-menu-list-buffers-entry
+                          (setq menu-bar-buffers-menu-list-buffers-entry
+                                (cons
+                                 'list-buffers
+                                 (cons
+                                  ""
+                                  'list-buffers))))
+                      ;; Update the item string for menu's new width.
+                      (setcar (cdr menu-bar-buffers-menu-list-buffers-entry)
+                              (concat (make-string (max (- (/ maxlen 2) 8) 0)
+                                                   ?\ )
+                                      "List All Buffers"))
+                      ;; Now make the actual list of items,
+                      ;; ending with the list-buffers item.
                       (nconc (mapcar '(lambda (pair)
                                         ;; This is somewhat risque, to use
                                         ;; the buffer name itself as the event
                       (nconc (mapcar '(lambda (pair)
                                         ;; This is somewhat risque, to use
                                         ;; the buffer name itself as the event
@@ -494,41 +592,36 @@ A large number or nil slows down menu responsiveness.")
                                                      (cons nil nil))
                                                'menu-bar-select-buffer))
                                      alist)
                                                      (cons nil nil))
                                                'menu-bar-select-buffer))
                                      alist)
-                             (list
-                              (cons
-                               'list-buffers
-                               (cons
-                                (concat (make-string (max (- (/ maxlen 2) 8) 0)
-                                                     ?\ )
-                                        "List All Buffers")
-                                'list-buffers)))))))
+                             (list menu-bar-buffers-menu-list-buffers-entry)))))
 
 
         ;; Make a Frames menu if we have more than one frame.
         (if (cdr frames)
 
 
         ;; Make a Frames menu if we have more than one frame.
         (if (cdr frames)
-            (setq frames-menu
-                  (cons "Select Frame"
-                        (mapcar '(lambda (frame)
-                                   (nconc (list frame
-                                                (cdr (assq 'name
-                                                           (frame-parameters frame)))
-                                                (cons nil nil))
-                                          'menu-bar-select-frame))
-                                frames))))
+            (let ((name (concat (make-string (max (- (/ maxlen 2) 3) 0)
+                                             ?\ )
+                                "Frames"))
+                  (frames-menu
+                   (cons 'keymap
+                         (cons "Select Frame"
+                               (mapcar '(lambda (frame)
+                                          (nconc (list frame
+                                                       (cdr (assq 'name
+                                                                  (frame-parameters frame)))
+                                                       (cons nil nil))
+                                                 'menu-bar-select-frame))
+                                       frames)))))
+              ;; Put it underneath the Buffers menu.
+              (setq buffers-menu (cons (cons 'frames (cons name frames-menu))
+                                       buffers-menu))))
         (if buffers-menu
             (setq buffers-menu (cons 'keymap buffers-menu)))
         (if buffers-menu
             (setq buffers-menu (cons 'keymap buffers-menu)))
-        (if frames-menu
-            (setq frames-menu (cons 'keymap frames-menu)))
         (define-key (current-global-map) [menu-bar buffer]
         (define-key (current-global-map) [menu-bar buffer]
-          (cons "Buffers"
-                (if (and buffers-menu frames-menu)
-                    (list 'keymap "Buffers and Frames"
-                          (cons 'buffers (cons "Buffers" buffers-menu))
-                          (cons 'frames (cons "Frames" frames-menu)))
-                  (or buffers-menu frames-menu 'undefined)))))))
+          (cons "Buffers" buffers-menu)))))
 
 (add-hook 'menu-bar-update-hook 'menu-bar-update-buffers)
 
 
 (add-hook 'menu-bar-update-hook 'menu-bar-update-buffers)
 
+(menu-bar-update-buffers)
+
 ;; this version is too slow
 ;;;(defun format-buffers-menu-line (buffer)
 ;;;  "Returns a string to represent the given buffer in the Buffer menu.
 ;; this version is too slow
 ;;;(defun format-buffers-menu-line (buffer)
 ;;;  "Returns a string to represent the given buffer in the Buffer menu.
@@ -546,6 +639,46 @@ A large number or nil slows down menu responsiveness.")
 ;;;           mode-name
 ;;;           (or (buffer-file-name) ""))))))
 \f
 ;;;           mode-name
 ;;;           (or (buffer-file-name) ""))))))
 \f
+;;; Set up a menu bar menu for the minibuffer.
+
+(mapcar
+ (function
+  (lambda (map)
+    (define-key map [menu-bar minibuf]
+      (cons "Minibuf" (make-sparse-keymap "Minibuf")))))
+ (list minibuffer-local-ns-map
+       minibuffer-local-must-match-map
+       minibuffer-local-isearch-map
+       minibuffer-local-map
+       minibuffer-local-completion-map))
+
+(mapcar
+ (function
+  (lambda (map)
+    (define-key map [menu-bar minibuf ?\?]
+      '("List Completions" . minibuffer-completion-help))
+    (define-key map [menu-bar minibuf space]
+      '("Complete Word" . minibuffer-complete-word))
+    (define-key map [menu-bar minibuf tab]
+      '("Complete" . minibuffer-complete))
+    ))
+ (list minibuffer-local-must-match-map
+       minibuffer-local-completion-map))
+
+(mapcar
+ (function
+  (lambda (map)
+    (define-key map [menu-bar minibuf quit]
+      '("Quit" . keyboard-escape-quit))
+    (define-key map [menu-bar minibuf return]
+      '("Enter" . exit-minibuffer))
+    ))
+ (list minibuffer-local-ns-map
+       minibuffer-local-must-match-map
+       minibuffer-local-isearch-map
+       minibuffer-local-map
+       minibuffer-local-completion-map))
+\f
 (defvar menu-bar-mode nil)
 
 (defun menu-bar-mode (flag)
 (defvar menu-bar-mode nil)
 
 (defun menu-bar-mode (flag)