]> code.delx.au - gnu-emacs/blobdiff - lisp/international/quail.el
*** empty log message ***
[gnu-emacs] / lisp / international / quail.el
index f5b41ba8238061173cd875321aff1fb28a78ff62..60c8884be3833e2154cb107d490409619a132a5f 100644 (file)
@@ -2,7 +2,7 @@
 
 ;; Copyright (C) 1995, 2000 Electrotechnical Laboratory, JAPAN.
 ;; Licensed to the Free Software Foundation.
-;; Copyright (C) 2001 Free Software Foundation, Inc.
+;; Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
 ;; Author: Kenichi HANDA <handa@etl.go.jp>
 ;;        Naoto TAKAHASHI <ntakahas@etl.go.jp>
@@ -66,20 +66,19 @@ See the documentation of `quail-package-alist' for the format.")
 (make-variable-buffer-local 'quail-current-package)
 (put 'quail-current-package 'permanent-local t)
 
-;; Quail uses the following two buffers to assist users.
-;; A buffer to show available key sequence or translation list.
-(defvar quail-guidance-buf nil)
+;; Quail uses the following variables to assist users.
+;; A string containing available key sequences or translation list.
+(defvar quail-guidance-str nil)
 ;; A buffer to show completion list of the current key sequence.
 (defvar quail-completion-buf nil)
+;; We may display the guidance string in a buffer on a one-line frame.
+(defvar quail-guidance-buf nil)
+(defvar quail-guidance-frame nil)
 
 ;; Each buffer in which Quail is activated should use different
-;; guidance buffers.
-(make-variable-buffer-local 'quail-guidance-buf)
-(put 'quail-guidance-buf 'permanent-local t)
-
-;; A main window showing Quail guidance buffer.
-(defvar quail-guidance-win nil)
-(make-variable-buffer-local 'quail-guidance-win)
+;; guidance string.
+(make-variable-buffer-local 'quail-guidance-str)
+(put 'quail-guidance-str 'permanent-local t)
 
 (defvar quail-overlay nil
   "Overlay which covers the current translation region of Quail.")
@@ -147,7 +146,7 @@ See the documentation of `quail-define-package' for the other elements.")
        title
       (condition-case nil
          (mapconcat
-          (lambda (x) 
+          (lambda (x)
             (cond ((stringp x) x)
                   ((and (listp x) (symbolp (car x)) (= (length x) 3))
                    (if (symbol-value (car x))
@@ -514,7 +513,7 @@ non-Quail commands."
   (let ((pos (point)))
     (if (overlayp quail-overlay)
        (move-overlay quail-overlay pos pos)
-      (setq quail-overlay (make-overlay pos pos nil nil t))
+      (setq quail-overlay (make-overlay pos pos))
       (if input-method-highlight-flag
          (overlay-put quail-overlay 'face 'underline))
       (let ((l (quail-overlay-plist)))
@@ -525,7 +524,7 @@ non-Quail commands."
        (if (overlayp quail-conv-overlay)
            (if (not (overlay-start quail-conv-overlay))
                (move-overlay quail-conv-overlay pos pos))
-         (setq quail-conv-overlay (make-overlay pos pos nil nil t))
+         (setq quail-conv-overlay (make-overlay pos pos))
          (if input-method-highlight-flag
              (overlay-put quail-conv-overlay 'face 'underline))))))
 
@@ -536,11 +535,6 @@ non-Quail commands."
   (if (and (overlayp quail-conv-overlay) (overlay-start quail-conv-overlay))
       (delete-overlay quail-conv-overlay)))
 
-;; Kill Quail guidance buffer.  Set in kill-buffer-hook.
-(defun quail-kill-guidance-buf ()
-  (if (buffer-live-p quail-guidance-buf)
-      (kill-buffer quail-guidance-buf)))
-
 (defun quail-inactivate ()
   "Inactivate Quail input method.
 
@@ -562,9 +556,10 @@ While this input method is active, the variable
       ;; Let's inactivate Quail input method.
       (unwind-protect
          (progn
-           (quail-hide-guidance-buf)
            (quail-delete-overlays)
            (setq describe-current-input-method-function nil)
+           (quail-hide-guidance)
+           (remove-hook 'post-command-hook 'quail-show-guidance t)
            (run-hooks 'quail-inactivate-hook))
        (kill-local-variable 'input-method-function))
     ;; Let's activate Quail input method.
@@ -578,12 +573,13 @@ While this input method is active, the variable
     (setq inactivate-current-input-method-function 'quail-inactivate)
     (setq describe-current-input-method-function 'quail-help)
     (quail-delete-overlays)
-    (quail-show-guidance-buf)
+    (setq quail-guidance-str "")
+    (quail-show-guidance)
     ;; If we are in minibuffer, turn off the current input method
     ;; before exiting.
-    (if (eq (selected-window) (minibuffer-window))
-       (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer))
-    (add-hook 'kill-buffer-hook 'quail-kill-guidance-buf nil t)
+    (when (eq (selected-window) (minibuffer-window))
+      (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer)
+      (add-hook 'post-command-hook 'quail-show-guidance nil t))
     (run-hooks 'quail-activate-hook)
     (make-local-variable 'input-method-function)
     (setq input-method-function 'quail-input-method)))
@@ -618,20 +614,6 @@ This layout is almost the same as that of VT100,
  but the location of key \\ (backslash) is just right of key ' (single-quote),
  not right of RETURN key.")
 
-(defvar quail-keyboard-layout quail-keyboard-layout-standard
-  "A string which represents physical key layout of a particular keyboard.
-We assume there are six rows and each row has 15 keys (columns),
-       the first row is above the `1' - `0' row,
-       the first column of the second row is left of key `1',
-       the first column of the third row is left of key `q',
-       the first column of the fourth row is left of key `a',
-       the first column of the fifth row is left of key `z',
-       the sixth row is below the `z' - `/' row.
-Nth (N is even) and (N+1)th characters in the string are non-shifted
-and shifted characters respectively at the same location.
-The location of Nth character is row (N / 30) and column ((N mod 30) / 2).
-The command `quail-set-keyboard-layout' usually sets this variable.")
-
 (defconst quail-keyboard-layout-len 180)
 
 ;; Here we provide several examples of famous keyboard layouts.
@@ -671,7 +653,7 @@ The command `quail-set-keyboard-layout' usually sets this variable.")
                               ")
    '("pc105-uk" . "\
                               \
-`\2541!2\3\243$5%6^7&8*9(0)-_=+    \
+`\2541!2\"3\2434$5%6^7&8*9(0)-_=+     \
   qQwWeErRtTyYuUiIoOpP[{]}    \
   aAsSdDfFgGhHjJkKlL;:'@#~    \
 \\|zZxXcCvVbBnNmM,<.>/?        \
@@ -681,6 +663,26 @@ The command `quail-set-keyboard-layout' usually sets this variable.")
 See the documentation of `quail-keyboard-layout' for the format of
 the layout string.")
 
+(defcustom quail-keyboard-layout quail-keyboard-layout-standard
+  "A string which represents physical key layout of a particular keyboard.
+We assume there are six rows and each row has 15 keys (columns),
+       the first row is above the `1' - `0' row,
+       the first column of the second row is left of key `1',
+       the first column of the third row is left of key `q',
+       the first column of the fourth row is left of key `a',
+       the first column of the fifth row is left of key `z',
+       the sixth row is below the `z' - `/' row.
+Nth (N is even) and (N+1)th characters in the string are non-shifted
+and shifted characters respectively at the same location.
+The location of Nth character is row (N / 30) and column ((N mod 30) / 2).
+The command `quail-set-keyboard-layout' usually sets this variable."
+  :group 'quail
+  :type `(choice
+         ,@(mapcar (lambda (pair)
+                     (list 'const :tag (car pair) (cdr pair)))
+                   quail-keyboard-layout-alist)
+         (string :tag "Other")))
+
 ;; A non-standard keyboard layout may miss some key locations of the
 ;; standard layout while having additional key locations not in the
 ;; standard layout.  This alist maps those additional key locations to
@@ -894,7 +896,7 @@ The format of KBD-LAYOUT is the same as `quail-keyboard-layout'."
 The variable `quail-keyboard-layout-type' holds the currently selected
 keyboard type."
   (interactive
-   (list (completing-read "Keyboard type (default, current choise): "
+   (list (completing-read "Keyboard type (default, current choice): "
                          quail-keyboard-layout-alist
                          nil t)))
   (or (and keyboard-type (> (length keyboard-type) 0))
@@ -1295,25 +1297,17 @@ If STR has `advice' text property, append the following special event:
     (quail-setup-overlays (quail-conversion-keymap))
     (let ((modified-p (buffer-modified-p))
          (buffer-undo-list t))
-      (or (and quail-guidance-win
-              (window-live-p quail-guidance-win)
-              (eq (window-buffer quail-guidance-win) quail-guidance-buf)
-              (not input-method-use-echo-area))
-         (quail-show-guidance-buf))
       (unwind-protect
          (let ((input-string (if (quail-conversion-keymap)
                                  (quail-start-conversion key)
                                (quail-start-translation key))))
+           (setq quail-guidance-str "")
            (when (and (stringp input-string)
                       (> (length input-string) 0))
              (if input-method-exit-on-first-char
                  (list (aref input-string 0))
                (quail-input-string-to-events input-string))))
        (quail-delete-overlays)
-       (if (buffer-live-p quail-guidance-buf)
-           (with-current-buffer quail-guidance-buf
-             (erase-buffer)))
-       (quail-hide-guidance-buf)
        (set-buffer-modified-p modified-p)
        ;; Run this hook only when the current input method doesn't require
        ;; conversion.  When conversion is required, the conversion function
@@ -1360,6 +1354,7 @@ Return the input string."
            (setq unread-command-events (cons key unread-command-events)))
        (while quail-translating
          (set-buffer-modified-p modified-p)
+         (quail-show-guidance)
          (let* ((keyseq (read-key-sequence
                          (and input-method-use-echo-area
                               (concat input-method-previous-message
@@ -1424,8 +1419,7 @@ Return the input string."
                      quail-current-str ""
                      quail-translating t)
                (quail-setup-overlays nil)))
-         ;; Hide '... loaded' message.
-         (message nil)
+         (quail-show-guidance)
          (let* ((keyseq (read-key-sequence
                          (and input-method-use-echo-area
                               (concat input-method-previous-message
@@ -1474,9 +1468,7 @@ Return the input string."
 (defun quail-terminate-translation ()
   "Terminate the translation of the current key."
   (setq quail-translating nil)
-  (if (buffer-live-p quail-guidance-buf)
-      (with-current-buffer quail-guidance-buf
-       (erase-buffer))))
+  (setq quail-guidance-str " "))
 
 (defun quail-select-current ()
   "Accept the currently selected translation."
@@ -1517,9 +1509,18 @@ with more keys."
                        (quail-simple))
                   (setq control-flag t)))))))
   (or input-method-use-echo-area
-      (progn
+      (let (pos)
        (quail-delete-region)
-       (insert quail-current-str)))
+       (setq pos (point))
+       (insert quail-current-str)
+       (move-overlay quail-overlay pos (point))
+       (if (overlayp quail-conv-overlay)
+           (if (not (overlay-start quail-conv-overlay))
+               (move-overlay quail-conv-overlay pos (point))
+             (if (< (overlay-end quail-conv-overlay) (point))
+                 (move-overlay quail-conv-overlay
+                               (overlay-start quail-conv-overlay)
+                               (point)))))))
   (let (quail-current-str)
     (quail-update-guidance))
   (or (stringp quail-current-str)
@@ -1583,7 +1584,7 @@ Make RELATIVE-INDEX the current translation."
            (< cur start)               ; We moved to the previous block.
            (>= cur end))               ; We moved to the next block.
        (let ((len (length (cdr quail-current-translations)))
-             (maxcol (- (window-width quail-guidance-win)
+             (maxcol (- (window-width)
                         quail-guidance-translations-starting-column))
              (block (nth 3 indices))
              col idx width trans num-items blocks)
@@ -1679,6 +1680,10 @@ sequence counting from the head."
 
            (t
             ;; No way to handle the last character in this context.
+            (setq def (quail-map-definition
+                       (quail-lookup-key quail-current-key (1- len))))
+            (if def (setq quail-current-str
+                          (quail-get-current-str (1- len) def)))
             (1- len))))))
 
 (defun quail-next-translation ()
@@ -1845,8 +1850,8 @@ Remaining args are for FUNC."
 
 ;; Guidance, Completion, and Help buffer handlers.
 
-(defun quail-make-guidance-frame (buf)
-  "Make a new one-line frame for Quail guidance buffer."
+(defun quail-make-guidance-frame ()
+  "Make a new one-line frame for Quail guidance."
   (let* ((fparam (frame-parameters))
         (top (cdr (assq 'top fparam)))
         (border (cdr (assq 'border-width fparam)))
@@ -1854,14 +1859,11 @@ Remaining args are for FUNC."
         (newtop (- top
                    (frame-char-height) (* internal-border 2) (* border 2))))
     (if (< newtop 0)
-       (setq newtop (+ top (frame-pixel-height))))
-    (let* ((frame (make-frame (append '((user-position . t) (height . 1)
-                                       (minibuffer) (menu-bar-lines . 0))
-                                     (cons (cons 'top newtop) fparam))))
-          (win (frame-first-window frame)))
-      (set-window-buffer win buf)
-      ;;(set-window-dedicated-p win t)
-      )))
+       (setq newtop (+ top (frame-pixel-height) internal-border border)))
+    (make-frame (append '((user-position . t) (height . 1)
+                         (minibuffer)
+                         (menu-bar-lines . 0) (tool-bar-lines . 0))
+                       (cons (cons 'top newtop) fparam)))))
 
 (defun quail-setup-completion-buf ()
   "Setup Quail completion buffer."
@@ -1882,124 +1884,96 @@ Remaining args are for FUNC."
             (not (quail-simple))
           t))))
 
-(defun quail-show-guidance-buf ()
-  "Display a guidance buffer for Quail input method in some window.
-Create the buffer if it does not exist yet.
-The buffer is normally displayed at the echo area,
-but if the current buffer is a minibuffer, it is shown in
-the bottom-most ordinary window of the same frame,
-or in a newly created frame (if the selected frame has no other windows)."
-  (when (quail-require-guidance-buf)
-    ;; At first, setup a guidance buffer.
-    (let ((default-enable-multibyte-characters enable-multibyte-characters))
-      (or (buffer-live-p quail-guidance-buf)
-         (setq quail-guidance-buf (generate-new-buffer " *Quail-guidance*"))))
-    (let ((name (quail-name))
-         (title (quail-title)))
-      (with-current-buffer quail-guidance-buf
-       ;; To show the title of Quail package.
-       (setq current-input-method name
-             current-input-method-title title)
-       (erase-buffer)
-       (or (overlayp quail-overlay)
-           (progn
-             (setq quail-overlay (make-overlay 1 1))
-             (overlay-put quail-overlay 'face 'highlight)))
-       (delete-overlay quail-overlay)
-       (set-buffer-modified-p nil)))
-    (bury-buffer quail-guidance-buf)
-
-    ;; Assign the buffer " *Minibuf-N*" to all windows which are now
-    ;; displaying quail-guidance-buf.
-    (let ((win-list (get-buffer-window-list quail-guidance-buf t t)))
-      (while win-list
-       (set-window-buffer (car win-list)
-                          (format " *Minibuf-%d*" (minibuffer-depth)))
-       (setq win-list (cdr win-list))))
-
-    ;; Then, display it in an appropriate window.
-    (let ((win (minibuffer-window)))
-      (if (or (eq (selected-window) win)
-             input-method-use-echo-area)
-         ;; Since we are in minibuffer, we can't use it for guidance.
-         (if (eq win (frame-root-window))
-             ;; Create a frame.  It is sure that we are using some
-             ;; window system.
-             (quail-make-guidance-frame quail-guidance-buf)
-           ;; Find the bottom window and split it if necessary.
-           (setq win (window-at
-                      0 (1- (- (frame-height) (window-height win)))))
-           (let ((height (window-height win))
-                 (window-min-height 2))
-             ;; If WIN is tall enough, split it vertically and use
-             ;; the lower one.
-             (when (>= height 4)
-               ;; Here, `split-window' returns a lower window
-               ;; which is what we wanted.
-               (setq win (split-window win (- height 2))))
-             (set-window-buffer win quail-guidance-buf)
-             (with-current-buffer quail-guidance-buf
-               (fit-window-to-buffer win nil (window-height win)))))
-       (set-window-buffer win quail-guidance-buf)
-       (set-minibuffer-window win))
-      (setq quail-guidance-win win)))
-
-  ;; And, create a buffer for completion.
+
+;; Quail specific version of minibuffer-message.  It displays STRING
+;; with timeout 1000000 seconds instead of two seconds.
+
+(defun quail-minibuffer-message (string)
+  (message nil)
+  (let ((point-max (point-max))
+       (inhibit-quit t))
+    (save-excursion
+      (goto-char point-max)
+      (insert string))
+    (sit-for 1000000)
+    (delete-region point-max (point-max))
+    (when quit-flag
+      (setq quit-flag nil
+           unread-command-events '(7)))))
+
+(defun quail-show-guidance ()
+  "Display a guidance for Quail input method in some window.
+The guidance is normally displayed at the echo area,
+or in a newly created frame (if the current buffer is a
+minibuffer and the selected frame has no other windows)."
+  ;; At first, setup a buffer for completion.
   (quail-setup-completion-buf)
-  (bury-buffer quail-completion-buf))
-
-(defun quail-hide-guidance-buf ()
-  "Hide the Quail guidance buffer."
-  (if (buffer-live-p quail-guidance-buf)
-      (let ((win-list (get-buffer-window-list quail-guidance-buf t t))
-           win)
-       (while win-list
-         (setq win (car win-list) win-list (cdr win-list))
-         (if (window-minibuffer-p win)
-             ;; We are using echo area for the guidance buffer.
-             ;; Vacate it to the deepest minibuffer.
-             (set-window-buffer win
-                                (format " *Minibuf-%d*" (minibuffer-depth)))
-           (if (eq win (frame-root-window (window-frame win)))
-               (progn
-                 ;; We are using a separate frame for guidance buffer.
-                 ;;(set-window-dedicated-p win nil)
-                 (delete-frame (window-frame win)))
-             ;;(set-window-dedicated-p win nil)
-             (delete-window win))))
-       (setq quail-guidance-win nil))))
+  (bury-buffer quail-completion-buf)
+
+  ;; Then, show the guidance.
+  (when (and (quail-require-guidance-buf)
+            (null unread-command-events)
+            (null unread-post-input-method-events))
+    (if (or (eq (selected-window) (minibuffer-window))
+           input-method-use-echo-area)
+       (if (eq (minibuffer-window) (frame-root-window))
+           ;; Use another frame.  It is sure that we are using some
+           ;; window system.
+           (let ((guidance quail-guidance-str))
+             (or (frame-live-p quail-guidance-frame)
+                 (setq quail-guidance-frame 
+                       (quail-make-guidance-frame)))
+             (or (buffer-live-p quail-guidance-buf)
+                 (setq quail-guidance-buf
+                       (get-buffer-create " *Quail-guidance*")))
+             (save-excursion
+               (set-buffer quail-guidance-buf)
+               (erase-buffer)
+               (setq cursor-type nil)
+               (insert guidance))
+             (set-window-buffer (frame-root-window quail-guidance-frame)
+                                quail-guidance-buf)
+             (quail-minibuffer-message
+              (format " [%s]" current-input-method-title)))
+         ;; Show the guidance in the next line of the currrent
+         ;; minibuffer.
+         (quail-minibuffer-message
+          (format "  [%s]\n%s" 
+                  current-input-method-title quail-guidance-str)))
+      ;; Show the guidance in echo area without logging.
+      (let ((message-log-max nil))
+       (message "%s" quail-guidance-str)))))
+
+(defun quail-hide-guidance ()
+  "Hide the Quail guidance."
+  (when (and (quail-require-guidance-buf)
+            (or (eq (selected-window) (minibuffer-window))
+                input-method-use-echo-area)
+            (eq (minibuffer-window) (frame-root-window)))
+    ;; We are using another frame for the guidance.
+    (if (frame-live-p quail-guidance-frame)
+       (delete-frame quail-guidance-frame))
+    (if (buffer-live-p quail-guidance-buf)
+       (kill-buffer quail-guidance-buf))))
 
 (defun quail-update-guidance ()
   "Update the Quail guidance buffer and completion buffer (if displayed now)."
-  ;; Update guidance buffer.
-  (if (quail-require-guidance-buf)
-      (let ((guidance (quail-guidance)))
-       (unless (and (eq (selected-frame) (window-frame (minibuffer-window)))
-                    (eq (selected-frame) (window-frame quail-guidance-win)))
-         ;; The guidance window is not shown in this frame, show it.
-         (quail-show-guidance-buf))
-       (cond ((or (eq guidance t)
-                  (consp guidance))
-              ;; Show the current possible translations.
-              (quail-show-translations))
-             ((null guidance)
-              ;; Show the current input keys.
-              (let ((key quail-current-key))
-                (if (quail-kbd-translate)
-                    (setq key (quail-keyseq-translate key)))
-                (with-current-buffer quail-guidance-buf
-                  (erase-buffer)
-                  (insert key)))))
-       ;; Make sure the height of the guidance window is OK --
-       ;; sometimes, if the minibuffer window expands due to user
-       ;; input (for instance if the newly inserted character is in a
-       ;; different font), it will cause the guidance window to be
-       ;; only partially visible.  We force a redisplay first because
-       ;; this automatic expansion doesn't happen until then, and we
-       ;; want to see the window sizes after the expansion.
-       (sit-for 0)
-       (fit-window-to-buffer quail-guidance-win nil
-                             (window-height quail-guidance-win))))
+  ;; Update the guidance string.
+  (when (quail-require-guidance-buf)
+    (let ((guidance (quail-guidance)))
+      (cond ((or (eq guidance t)
+                (consp guidance))
+            ;; Show the current possible translations.
+            (setq quail-guidance-str
+                  (quail-get-translations)))
+           ((null guidance)
+            ;; Show the current input keys.
+            (let ((key quail-current-key))
+              (if (quail-kbd-translate)
+                  (setq key (quail-keyseq-translate key)))
+              (setq quail-guidance-str (if (stringp key) key (string key)))))
+           (t
+            (setq quail-guidance-str " ")))))
 
   ;; Update completion buffer if displayed now.  We highlight the
   ;; selected candidate string in *Completion* buffer if any.
@@ -2018,8 +1992,8 @@ or in a newly created frame (if the selected frame has no other windows)."
              (delete-overlay quail-overlay)
            (setq pos (point))
            (if (and str (search-forward (concat "." str) nil t))
-                 (move-overlay quail-overlay (1+ (match-beginning 0)) (point))
-               (move-overlay quail-overlay (match-beginning 0) (point)))
+               (move-overlay quail-overlay (1+ (match-beginning 0)) (point))
+             (move-overlay quail-overlay (match-beginning 0) (point)))
            ;; Now POS points end of KEY and (point) points end of STR.
            (if (pos-visible-in-window-p (point) win)
                ;; STR is already visible.
@@ -2033,63 +2007,67 @@ or in a newly created frame (if the selected frame has no other windows)."
                  (set-window-start win pos))
              ))))))
 
-(defun quail-show-translations ()
-  "Show the current possible translations."
-  (let* ((key quail-current-key)
-        (map (quail-lookup-key quail-current-key))
-        (current-translations quail-current-translations))
+(defun quail-get-translations ()
+  "Return a string containing the current possible translations."
+  (let ((map (quail-lookup-key quail-current-key))
+       (str (copy-sequence quail-current-key)))
     (if quail-current-translations
        (quail-update-current-translations))
-    (with-current-buffer quail-guidance-buf
-      (erase-buffer)
-
-      ;; Show the current key.
-      (let ((guidance (quail-guidance)))
-       (if (listp guidance)
-           ;; We must show the specified PROMPTKEY instead of the
-           ;; actual typed keys.
-           (let ((i 0)
-                 (len (length key))
-                 prompt-key)
-             (while (< i len)
-               (setq prompt-key (cdr (assoc (aref key i) guidance)))
-               (insert (or prompt-key (aref key i)))
-               (setq i (1+ i))))
-         (insert key)))
 
-      ;; Show followable keys.
-      (if (and (> (length key) 0) (cdr map))
-         (let ((keys (mapcar (function (lambda (x) (car x)))
-                             (cdr map))))
-           (setq keys (sort keys '<))
-           (insert "[")
-           (while keys
-             (insert (car keys))
-             (setq keys (cdr keys)))
-           (insert "]")))
+    ;; Show the current key.
+    (let ((guidance (quail-guidance)))
+      (if (listp guidance)
+         ;; We must replace thetyped key with the specified PROMPTKEY.
+         (dotimes (i (length str))
+           (let ((prompt-key (cdr (assoc (aref str i) guidance))))
+             (if prompt-key
+                 (aset str i (aref prompt-key 0)))))))
 
+      ;; Show followable keys.
+      (if (and (> (length quail-current-key) 0) (cdr map))
+         (setq str
+               (format "%s[%s]"
+                       str
+                       (concat (sort (mapcar (function (lambda (x) (car x)))
+                                             (cdr map))
+                                     '<)))))
       ;; Show list of translations.
-      (if (and current-translations
+      (if (and quail-current-translations
               (not (quail-deterministic)))
-         (let* ((indices (car current-translations))
+         (let* ((indices (car quail-current-translations))
                 (cur (car indices))
                 (start (nth 1 indices))
                 (end (nth 2 indices))
                 (idx start))
-           (indent-to (- quail-guidance-translations-starting-column 7))
-           (insert (format "(%02d/"(nth 3 indices))
-                   (if (nth 4 indices)
-                       (format "%02d)" (nth 4 indices))
-                     "??)"))
+           (if (< (string-width str)
+                  (- quail-guidance-translations-starting-column 7))
+               (setq str
+                     (concat str
+                             (make-string
+                              (- quail-guidance-translations-starting-column
+                                 7 (string-width str))
+                              32))))
+           (setq str (format "%s(%02d/%s)" 
+                             str (nth 3 indices)
+                             (if (nth 4 indices)
+                                 (format "%02d" (nth 4 indices))
+                               "??")))
            (while (< idx end)
-             (insert (format " %d." (if (= (- idx start) 9) 0
-                                      (1+ (- idx start)))))
-             (let ((pos (point)))
-               (insert (aref (cdr current-translations) idx))
+             (let ((len (length str))
+                   (trans (aref (cdr quail-current-translations) idx)))
+               (or (stringp trans)
+                   (setq trans (string trans)))
+               (setq str (format "%s %d.%s" 
+                                 str
+                                 (if (= (- idx start) 9) 0
+                                   (1+ (- idx start)))
+                                 trans))
                (if (= idx cur)
-                   (move-overlay quail-overlay pos (point))))
-             (setq idx (1+ idx)))))
-      )))
+                   (put-text-property (+ len 3) (length str)
+                                     'face 'highlight str))
+               (setq idx (1+ idx))))))
+
+      str))
 
 (defvar quail-completion-max-depth 5
   "The maximum depth of Quail completion list.")
@@ -2112,7 +2090,10 @@ are shown (at most to the depth specified `quail-completion-max-depth')."
          ;; shown.  We just scroll it appropriately.
          (if (pos-visible-in-window-p (point-max) win)
              (set-window-start win (point-min))
-           (let ((other-window-scroll-buffer quail-completion-buf))
+           (let ((other-window-scroll-buffer quail-completion-buf)
+                 ;; This nil binding is necessary to surely scroll
+                 ;; quail-completion-buf.
+                 (minibuffer-scroll-window nil))
              (scroll-other-window)))
        (setq quail-current-key key)
        (erase-buffer)
@@ -2383,7 +2364,7 @@ should be made by `quail-build-decode-map' (which see)."
 
 (define-button-type 'quail-keyboard-layout-button
   :supertype 'help-xref
-  'help-function '(lambda (layout) 
+  'help-function '(lambda (layout)
                    (help-setup-xref `(quail-keyboard-layout-button ,layout) nil)
                    (quail-show-keyboard-layout layout))
   'help-echo (purecopy "mouse-2, RET: show keyboard layout"))
@@ -2499,7 +2480,7 @@ KEY BINDINGS FOR CONVERSION
       (setq quail-current-package nil)
       ;; Resize the help window again, now that it has all its contents.
       (save-selected-window
-       (select-window (get-buffer-window (current-buffer)))
+       (select-window (get-buffer-window (current-buffer) t))
        (run-hooks 'temp-buffer-show-hook)))))
 
 (defun quail-help-insert-keymap-description (keymap &optional header)