# HG changeset patch # User Kenichi Handa # Date 1050033480 0 # Node ID ad343b711d5e5a19519d54bd7f3c153204baf1af # Parent 0f0bc7773998729183c8564a1b5ef5d9088b18ed * international/quail.el (quail-guidance-str) (quail-guidance-frame): New variables. (quail-guidance-win): Delete this variable. (quail-setup-overlays): Make overlay not rear-advancing. (quail-kill-guidance-buf): Delete this function. (quail-activate): Add/remove quail-show-guidance to/from post-command-hook. (quail-input-method): Don't setup quail-guidance-buf. Initialize quail-guidance-str to "". (quail-start-translation): Call quail-show-guidance at first. (quail-start-conversion): Likewise. (quail-terminate-translation): Don't erase quail-guidance-buf. (quail-update-translation): Stretch overlays if their starting and ending positions are same. (quail-update-current-translations): Check the width of the current window, not the width of quail-guidance-win. (quail-make-guidance-frame): Delete the arg BUF. Fix position calculation. Don't set the window buffer, just return the new frame. (quail-minibuffer-message): New function. (quail-show-guidance): Renamed from quail-show-guidance-buf. Use message and quail-minibuffer-message to display the guidance. (quail-hide-guidance): Renamed from quail-hide-guidance-buf. Only delete quail-guidance-frame. (quail-update-guidance): Just update quail-guidance-str, not display it. (quail-get-translations): Renamed from quail-show-translations. Return a string instead of inserting it in quail-guaidance-buf. diff -r 0f0bc7773998 -r ad343b711d5e lisp/international/quail.el --- a/lisp/international/quail.el Fri Apr 11 02:07:08 2003 +0000 +++ b/lisp/international/quail.el Fri Apr 11 03:58:00 2003 +0000 @@ -66,20 +66,19 @@ (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.") @@ -514,7 +513,7 @@ (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 @@ (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 @@ (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 @@ ;; 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 @@ (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))) @@ -1313,25 +1309,17 @@ (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 @@ -1378,6 +1366,7 @@ (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 @@ -1442,8 +1431,7 @@ 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 @@ -1492,9 +1480,7 @@ (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." @@ -1535,9 +1521,18 @@ (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) @@ -1601,7 +1596,7 @@ (< 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) @@ -1863,8 +1858,8 @@ ;; 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))) @@ -1872,14 +1867,11 @@ (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." @@ -1900,124 +1892,96 @@ (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 ((package quail-current-package)) - (with-current-buffer quail-guidance-buf - ;; To show the title of Quail package. - (setq quail-current-package package - current-input-method (quail-name) - current-input-method-title (quail-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) + +;; Quail specific version of minibuffer-message. It displays STRING +;; with timeout 1000000 seconds instead of two seconds. - ;; 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)))) +(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) - ;; 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))) + ;; 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))))) - ;; And, create 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)))) +(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. @@ -2036,8 +2000,8 @@ (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. @@ -2051,63 +2015,67 @@ (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 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 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 "]"))) - + (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.")