Merge from emacs-24; up to 2012-05-07T14:57:18Z!michael.albinus@gmx.de
[bpt/emacs.git] / lisp / tmm.el
index 3d8433e..4bc1c9a 100644 (file)
@@ -1,7 +1,6 @@
 ;;; tmm.el --- text mode access to menu-bar
 
-;; Copyright (C) 1994, 1995, 1996, 2000, 2001, 2002, 2003,
-;;   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 1994-1996, 2000-2012 Free Software Foundation, Inc.
 
 ;; Author: Ilya Zakharevich <ilya@math.mps.ohio-state.edu>
 ;; Maintainer: FSF
@@ -38,7 +37,6 @@
 ;;; The following will be localized, added only to pacify the compiler.
 (defvar tmm-short-cuts)
 (defvar tmm-old-mb-map nil)
-(defvar tmm-old-comp-map)
 (defvar tmm-c-prompt nil)
 (defvar tmm-km-list)
 (defvar tmm-next-shortcut-digit)
@@ -99,7 +97,7 @@ See the documentation for `tmm-prompt'."
 
 (defcustom tmm-mid-prompt "==>"
   "String to insert between shortcut and menu item.
-If nil, there will be no shortcuts. It should not consist only of spaces,
+If nil, there will be no shortcuts.  It should not consist only of spaces,
 or else the correct item might not be found in the `*Completions*' buffer."
   :type 'string
   :group 'tmm)
@@ -159,7 +157,7 @@ Its value should be an event that has a binding in MENU."
   (let ((gl-str "Menu bar")  ;; The menu bar itself is not a menu keymap
                                        ; so it doesn't have a name.
        tmm-km-list out history history-len tmm-table-undef tmm-c-prompt
-       tmm-old-mb-map tmm-old-comp-map tmm-short-cuts
+       tmm-old-mb-map tmm-short-cuts
        chosen-string choice
        (not-menu (not (keymapp menu))))
     (run-hooks 'activate-menubar-hook)
@@ -167,15 +165,13 @@ Its value should be an event that has a binding in MENU."
     ;; tmm-km-list is an alist of (STRING . MEANING).
     ;; It has no other elements.
     ;; The order of elements in tmm-km-list is the order of the menu bar.
-    (mapc (lambda (elt)
-           (if (stringp elt)
-               (setq gl-str elt)
-             (cond
-              ((listp elt) (tmm-get-keymap elt not-menu))
-              ((vectorp elt)
-               (dotimes (i (length elt))
-                 (tmm-get-keymap (cons i (aref elt i)) not-menu))))))
-           menu)
+    (dolist (elt menu)
+      (cond
+       ((stringp elt) (setq gl-str elt))
+       ((listp elt) (tmm-get-keymap elt not-menu))
+       ((vectorp elt)
+        (dotimes (i (length elt))
+          (tmm-get-keymap (cons i (aref elt i)) not-menu)))))
     ;; Choose an element of tmm-km-list; put it in choice.
     (if (and not-menu (= 1 (length tmm-km-list)))
        ;; If this is the top-level of an x-popup-menu menu,
@@ -221,27 +217,19 @@ Its value should be an event that has a binding in MENU."
             (setq history-len (length history))
             (setq history (append history history history history))
             (setq tmm-c-prompt (nth (- history-len 1 index-of-default) history))
-            (add-hook 'minibuffer-setup-hook 'tmm-add-prompt)
-            (if default-item
-                (setq out (car (nth index-of-default tmm-km-list)))
-              (save-excursion
-                (unwind-protect
-                    (setq out
-                          (completing-read
-                           (concat gl-str
-                                   " (up/down to change, PgUp to menu): ")
-                           tmm-km-list nil t nil
-                           (cons 'history
-                                 (- (* 2 history-len) index-of-default))))
-                   (remove-hook 'minibuffer-setup-hook 'tmm-add-prompt)
-                   (if (get-buffer "*Completions*")
-                       (with-current-buffer "*Completions*"
-                         (use-local-map tmm-old-comp-map)
-                         (bury-buffer (current-buffer)))))))))
+             (setq out
+                   (if default-item
+                       (car (nth index-of-default tmm-km-list))
+                     (minibuffer-with-setup-hook #'tmm-add-prompt
+                       (completing-read
+                        (concat gl-str
+                                " (up/down to change, PgUp to menu): ")
+                        tmm-km-list nil t nil
+                        (cons 'history
+                              (- (* 2 history-len) index-of-default))))))))
       (setq choice (cdr (assoc out tmm-km-list)))
       (and (null choice)
-          (> (length out) (length tmm-c-prompt))
-          (string= (substring out 0 (length tmm-c-prompt)) tmm-c-prompt)
+           (string-prefix-p tmm-c-prompt out)
           (setq out (substring out (length tmm-c-prompt))
                 choice (cdr (assoc out tmm-km-list))))
       (and (null choice) out
@@ -272,7 +260,7 @@ Its value should be an event that has a binding in MENU."
             choice)))))
 
 (defun tmm-add-shortcuts (list)
-  "Adds shortcuts to cars of elements of the list.
+  "Add shortcuts to cars of elements of the list.
 Takes a list of lists with a string as car, returns list with
 shortcuts added to these cars.
 Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
@@ -323,15 +311,13 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
 (defun tmm-define-keys (minibuffer)
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map t)
-    (mapc
-     (lambda (c)
-       (if (listp tmm-shortcut-style)
-          (define-key map (char-to-string c) 'tmm-shortcut)
-        ;; only one kind of letters are shortcuts, so map both upcase and
-        ;; downcase input to the same
-        (define-key map (char-to-string (downcase c)) 'tmm-shortcut)
-        (define-key map (char-to-string (upcase c)) 'tmm-shortcut)))
-     tmm-short-cuts)
+    (dolist (c tmm-short-cuts)
+      (if (listp tmm-shortcut-style)
+          (define-key map (char-to-string c) 'tmm-shortcut)
+        ;; only one kind of letters are shortcuts, so map both upcase and
+        ;; downcase input to the same
+        (define-key map (char-to-string (downcase c)) 'tmm-shortcut)
+        (define-key map (char-to-string (upcase c)) 'tmm-shortcut)))
     (if minibuffer
        (progn
           (define-key map [pageup] 'tmm-goto-completions)
@@ -343,9 +329,9 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
       (use-local-map (append map (current-local-map))))))
 
 (defun tmm-completion-delete-prompt ()
-  (set-buffer standard-output)
+  (with-current-buffer standard-output
   (goto-char (point-min))
-  (delete-region (point) (search-forward "Possible completions are:\n")))
+    (delete-region (point) (search-forward "Possible completions are:\n"))))
 
 (defun tmm-remove-inactive-mouse-face ()
   "Remove the mouse-face property from inactive menu items."
@@ -364,41 +350,23 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
     (set-buffer-modified-p nil)))
 
 (defun tmm-add-prompt ()
-  (remove-hook 'minibuffer-setup-hook 'tmm-add-prompt)
-  (add-hook 'minibuffer-exit-hook 'tmm-delete-map nil t)
   (unless tmm-c-prompt
     (error "No active menu entries"))
-  (let ((win (selected-window)))
-    (setq tmm-old-mb-map (tmm-define-keys t))
-    ;; Get window and hide it for electric mode to get correct size
-    (save-window-excursion
-      (let ((completions
-            (mapcar 'car minibuffer-completion-table)))
-        (or tmm-completion-prompt
-            (add-hook 'completion-setup-hook
-                      'tmm-completion-delete-prompt 'append))
-        (unwind-protect
-            (with-output-to-temp-buffer "*Completions*"
-              (display-completion-list completions))
-          (remove-hook 'completion-setup-hook 'tmm-completion-delete-prompt)))
-      (set-buffer "*Completions*")
-      (tmm-remove-inactive-mouse-face)
-      (when tmm-completion-prompt
-       (let ((buffer-read-only nil))
-         (goto-char (point-min))
-         (insert tmm-completion-prompt))))
-    (save-selected-window
-      (other-window 1)                 ; Electric-pop-up-window does
-                                       ; not work in minibuffer
-      (Electric-pop-up-window "*Completions*")
-      (with-current-buffer "*Completions*"
-       (setq tmm-old-comp-map (tmm-define-keys nil))))
-    (insert tmm-c-prompt)))
-
-(defun tmm-delete-map ()
-  (remove-hook 'minibuffer-exit-hook 'tmm-delete-map t)
-  (if tmm-old-mb-map
-      (use-local-map tmm-old-mb-map)))
+  (setq tmm-old-mb-map (tmm-define-keys t))
+  ;; Get window and hide it for electric mode to get correct size
+  (or tmm-completion-prompt
+      (add-hook 'completion-setup-hook
+                'tmm-completion-delete-prompt 'append))
+  (unwind-protect
+      (minibuffer-completion-help)
+    (remove-hook 'completion-setup-hook 'tmm-completion-delete-prompt))
+  (with-current-buffer "*Completions*"
+    (tmm-remove-inactive-mouse-face)
+    (when tmm-completion-prompt
+      (let ((inhibit-read-only t))
+       (goto-char (point-min))
+       (insert tmm-completion-prompt))))
+  (insert tmm-c-prompt))
 
 (defun tmm-shortcut ()
   "Choose the shortcut that the user typed."
@@ -415,28 +383,29 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
              (choose-completion))
          ;; In minibuffer
          (delete-region (minibuffer-prompt-end) (point-max))
-         (mapc (lambda (elt)
-                 (if (string=
-                      (substring (car elt) 0
-                                 (min (1+ (length tmm-mid-prompt))
-                                      (length (car elt))))
-                      (concat (char-to-string c) tmm-mid-prompt))
-                     (setq s (car elt))))
-                 tmm-km-list)
+         (dolist (elt tmm-km-list)
+            (if (string=
+                 (substring (car elt) 0
+                            (min (1+ (length tmm-mid-prompt))
+                                 (length (car elt))))
+                 (concat (char-to-string c) tmm-mid-prompt))
+                (setq s (car elt))))
          (insert s)
          (exit-minibuffer)))))
 
 (defun tmm-goto-completions ()
+  "Jump to the completions buffer."
   (interactive)
   (let ((prompt-end (minibuffer-prompt-end)))
     (setq tmm-c-prompt (buffer-substring prompt-end (point-max)))
+    ;; FIXME: Why?
     (delete-region prompt-end (point-max)))
   (switch-to-buffer-other-window "*Completions*")
   (search-forward tmm-c-prompt)
   (search-backward tmm-c-prompt))
 
 (defun tmm-get-keymap (elt &optional in-x-menu)
-  "Prepends (DOCSTRING EVENT BINDING) to free variable `tmm-km-list'.
+  "Prepend (DOCSTRING EVENT BINDING) to free variable `tmm-km-list'.
 The values are deduced from the argument ELT, that should be an
 element of keymap, an `x-popup-menu' argument, or an element of
 `x-popup-menu' argument (when IN-X-MENU is not-nil).
@@ -497,7 +466,7 @@ It uses the free variable `tmm-table-undef' to keep undefined keys."
               (if (or in-x-menu (stringp (car-safe elt)))
                   (setq str event event nil km elt)
                 (setq str event event nil km (cons 'keymap elt)))))
-        (unless (eq km 'ignore)
+        (unless (or (eq km 'ignore) (null str))
           (let ((binding (where-is-internal km nil t)))
             (when binding
               (setq binding (key-description binding))
@@ -536,6 +505,10 @@ of `menu-bar-final-items'."
        (progn
          ;; Otherwise, it is a prefix, so make a list of the subcommands.
          ;; Make a list of all the bindings in all the keymaps.
+          ;; FIXME: we'd really like to just use `key-binding' now that it
+          ;; returns a keymap that contains really all the bindings under that
+          ;; prefix, but `keyseq' is always [menu-bar], so the desired order of
+          ;; the bindings is difficult to recover.
          (setq minorbind (mapcar 'cdr (minor-mode-key-binding keyseq)))
          (setq localbind (local-key-binding keyseq))
          (setq globalbind (copy-sequence (cdr (global-key-binding keyseq))))
@@ -552,21 +525,16 @@ of `menu-bar-final-items'."
          (setq allbind (cons globalbind (cons localbind minorbind)))
 
          ;; Merge all the elements of ALLBIND into one keymap.
-         (mapc (lambda (in)
-                 (if (and (symbolp in) (keymapp in))
-                     (setq in (symbol-function in)))
-                 (and in (keymapp in)
-                      (if (keymapp bind)
-                          (setq bind (nconc bind (copy-sequence (cdr in))))
-                        (setq bind (copy-sequence in)))))
-                 allbind)
+         (dolist (in allbind)
+            (if (and (symbolp in) (keymapp in))
+                (setq in (symbol-function in)))
+            (and in (keymapp in)
+                 (setq bind (if (keymapp bind)
+                                (nconc bind (copy-sequence (cdr in)))
+                              (copy-sequence in)))))
          ;; Return that keymap.
          bind))))
 
-;; Huh?  What's that about?  --Stef
-(add-hook 'calendar-load-hook (lambda () (require 'cal-menu)))
-
 (provide 'tmm)
 
-;; arch-tag: e7ddbdb6-4b95-4da3-afbe-ad6063d112f4
 ;;; tmm.el ends here