]> code.delx.au - gnu-emacs/blobdiff - lisp/tmm.el
Fix the prefix action of shr-copy-url
[gnu-emacs] / lisp / tmm.el
index 36c11a0f4b0e24c9a423234bc7e78bd68e4f65d4..d1a08ab26235ab70723ee7f58ea9fb628e4da4ea 100644 (file)
@@ -1,9 +1,9 @@
 ;;; tmm.el --- text mode access to menu-bar  -*- lexical-binding: t -*-
 
-;; Copyright (C) 1994-1996, 2000-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1994-1996, 2000-2016 Free Software Foundation, Inc.
 
 ;; Author: Ilya Zakharevich <ilya@math.mps.ohio-state.edu>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: convenience
 
 ;; This file is part of GNU Emacs.
@@ -54,7 +54,7 @@ we make that menu bar item (the one at that position) the default choice.
 
 Note that \\[menu-bar-open] by default drops down TTY menus; if you want it
 to invoke `tmm-menubar' instead, customize the variable
-\`tty-menu-open-use-tmm' to a non-nil value."
+`tty-menu-open-use-tmm' to a non-nil value."
   (interactive)
   (run-hooks 'menu-bar-update-hook)
   ;; Obey menu-bar-final-items; put those items last.
@@ -72,13 +72,15 @@ to invoke `tmm-menubar' instead, customize the variable
      (tmm-get-keybind [menu-bar]))
     (setq menu-bar `(keymap ,@(nreverse menu-bar) ,@(nreverse menu-end)))
     (if x-position
-       (let ((column 0))
+       (let ((column 0)
+              prev-key)
           (catch 'done
             (map-keymap
              (lambda (key binding)
                (when (> column x-position)
-                 (setq menu-bar-item key)
+                 (setq menu-bar-item prev-key)
                  (throw 'done nil))
+               (setq prev-key key)
                (pcase binding
                  ((or `(,(and (pred stringp) name) . ,_) ;Simple menu item.
                       `(menu-item ,name ,_cmd            ;Extended menu item.
@@ -149,6 +151,8 @@ specify nil for this variable."
        '(metadata (display-sort-function . identity))
       (complete-with-action action items string pred))))
 
+(defvar tmm--history nil)
+
 ;;;###autoload
 (defun tmm-prompt (menu &optional in-popup default-item)
   "Text-mode emulation of calling the bindings in keymap.
@@ -167,7 +171,7 @@ Its value should be an event that has a binding in MENU."
   ;; That is used for recursive calls only.
   (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-km-list out history-len tmm-table-undef tmm-c-prompt
        tmm-old-mb-map tmm-short-cuts
        chosen-string choice
        (not-menu (not (keymapp menu))))
@@ -185,7 +189,6 @@ Its value should be an event that has a binding in MENU."
          ((vectorp elt)
           (dotimes (i (length elt))
             (tmm-get-keymap (cons i (aref elt i)) not-menu))))))
-    (setq tmm-km-list (nreverse tmm-km-list))
     ;; 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,25 +224,34 @@ Its value should be an event that has a binding in MENU."
                         (setq index-of-default (1+ index-of-default)))
                     (setq tail (cdr tail)))))
              (let ((prompt (concat "^." (regexp-quote tmm-mid-prompt))))
-               (setq history
+               (setq tmm--history
                      (reverse (delq nil
                                     (mapcar
                                      (lambda (elt)
                                        (if (string-match prompt (car elt))
                                            (car elt)))
                                      tmm-km-list)))))
-            (setq history-len (length history))
-            (setq history (append history history history history))
-            (setq tmm-c-prompt (nth (- history-len 1 index-of-default) history))
+            (setq history-len (length tmm--history))
+            (setq tmm--history (append tmm--history tmm--history
+                                        tmm--history tmm--history))
+            (setq tmm-c-prompt (nth (- history-len 1 index-of-default)
+                                     tmm--history))
              (setq out
                    (if default-item
                        (car (nth index-of-default tmm-km-list))
                      (minibuffer-with-setup-hook #'tmm-add-prompt
+                       ;; tmm-km-list is reversed, because history
+                       ;; needs it in LIFO order.  But completion
+                       ;; needs it in non-reverse order, so that the
+                       ;; menu items are displayed as completion
+                       ;; candidates in the order they are shown on
+                       ;; the menu bar.  So pass completing-read the
+                       ;; reversed copy of the list.
                        (completing-read
                         (concat gl-str
                                 " (up/down to change, PgUp to menu): ")
-                        (tmm--completion-table tmm-km-list) nil t nil
-                        (cons 'history
+                        (tmm--completion-table (reverse tmm-km-list)) nil t nil
+                        (cons 'tmm--history
                               (- (* 2 history-len) index-of-default))))))))
       (setq choice (cdr (assoc out tmm-km-list)))
       (and (null choice)
@@ -367,7 +379,6 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
   (unless tmm-c-prompt
     (error "No active menu entries"))
   (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))
@@ -377,9 +388,15 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'."
   (with-current-buffer "*Completions*"
     (tmm-remove-inactive-mouse-face)
     (when tmm-completion-prompt
-      (let ((inhibit-read-only t))
+      (let ((inhibit-read-only t)
+           (window (get-buffer-window "*Completions*")))
        (goto-char (point-min))
-       (insert tmm-completion-prompt))))
+       (insert tmm-completion-prompt)
+       (when window
+         ;; Try to show everything just inserted and preserve height of
+         ;; *Completions* window.  This should fix a behavior described
+         ;; in Bug#1291.
+         (fit-window-to-buffer window nil nil nil nil t)))))
   (insert tmm-c-prompt))
 
 (defun tmm-shortcut ()