summaryrefslogtreecommitdiff
path: root/lisp/international/quail.el
diff options
context:
space:
mode:
authorKenichi Handa <handa@m17n.org>2003-04-11 03:58:22 +0000
committerKenichi Handa <handa@m17n.org>2003-04-11 03:58:22 +0000
commit17388a6277f5e4ed891def2c5fc4a40580cd8032 (patch)
treefed4f534b083df19fa00c78038d72e15e63d0cc5 /lisp/international/quail.el
parent389144243f4235ba0cd408992da809a781f8be5f (diff)
downloademacs-17388a6277f5e4ed891def2c5fc4a40580cd8032.tar.gz
* 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.
Diffstat (limited to 'lisp/international/quail.el')
-rw-r--r--lisp/international/quail.el388
1 files changed, 178 insertions, 210 deletions
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 81a991263fa..187a7532091 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -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.")
@@ -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)))
@@ -1313,25 +1309,17 @@ Do so while interleaving with the following special events:
(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 @@ 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
@@ -1442,8 +1431,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
@@ -1492,9 +1480,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."
@@ -1535,9 +1521,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)
@@ -1601,7 +1596,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)
@@ -1863,8 +1858,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)))
@@ -1872,14 +1867,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."
@@ -1900,124 +1892,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 ((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)
-
- ;; 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.
@@ -2036,8 +2000,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.
@@ -2051,63 +2015,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.")