comparison lisp/leim/quail.el @ 197:acd284d43ca1 r20-3b25

Import from CVS: tag r20-3b25
author cvs
date Mon, 13 Aug 2007 10:00:02 +0200
parents 6075d714658b
children 78f53ef88e17
comparison
equal deleted inserted replaced
196:58e0786448ca 197:acd284d43ca1
1 ;;; quail.el --- Provides simple input method for multilingual text 1 ;;; quail.el --- Provides simple input method for multilingual text
2 2
3 ;; Copyright (C) 1995 Free Software Foundation, Inc.
4 ;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN. 3 ;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN.
4 ;; Licensed to the Free Software Foundation.
5 ;; Copyright (C) 1997 MORIOKA Tomohiko 5 ;; Copyright (C) 1997 MORIOKA Tomohiko
6 6
7 ;; Author: Kenichi HANDA <handa@etl.go.jp> 7 ;; Author: Kenichi HANDA <handa@etl.go.jp>
8 ;; Naoto TAKAHASHI <ntakahas@etl.go.jp> 8 ;; Naoto TAKAHASHI <ntakahas@etl.go.jp>
9 ;; modified by MORIOKA Tomohiko <morioka@jaist.ac.jp> for XEmacs 9 ;; modified by MORIOKA Tomohiko <morioka@jaist.ac.jp> for XEmacs
58 )) 58 ))
59 59
60 ;; Buffer local variables 60 ;; Buffer local variables
61 61
62 (defvar quail-current-package nil 62 (defvar quail-current-package nil
63 "The current Quail package to input multilingual text in Quail minor mode. 63 "The current Quail package, which depends on the current input method.
64 See the documentation of `quail-package-alist' for the format.") 64 See the documentation of `quail-package-alist' for the format.")
65 (make-variable-buffer-local 'quail-current-package) 65 (make-variable-buffer-local 'quail-current-package)
66 (put 'quail-current-package 'permanent-local t) 66 (put 'quail-current-package 'permanent-local t)
67 67
68 ;; Quail uses the following two buffers to assist users. 68 ;; Quail uses the following two buffers to assist users.
69 ;; A buffer to show available key sequence or translation list. 69 ;; A buffer to show available key sequence or translation list.
70 (defvar quail-guidance-buf nil) 70 (defvar quail-guidance-buf nil)
71 ;; A buffer to show completion list of the current key sequence. 71 ;; A buffer to show completion list of the current key sequence.
72 (defvar quail-completion-buf nil) 72 (defvar quail-completion-buf nil)
73 73
74 ;; Each buffer in which Quail is activated should use different
75 ;; guidance buffers.
76 (make-variable-buffer-local 'quail-guidance-buf)
77 (put 'quail-guidance-buf 'permanent-local t)
78
79 ;; A main window showing Quail guidance buffer.
80 (defvar quail-guidance-win nil)
81 (make-variable-buffer-local 'quail-guidance-win)
82
74 (defvar quail-mode nil 83 (defvar quail-mode nil
75 "Non-nil if in Quail minor mode.") 84 "Non-nil if in Quail minor mode.")
76 (make-variable-buffer-local 'quail-mode) 85 (make-variable-buffer-local 'quail-mode)
77 (put 'quail-mode 'permanent-local t) 86 (put 'quail-mode 'permanent-local t)
78 87
89 98
90 (defvar quail-current-str nil 99 (defvar quail-current-str nil
91 "Currently selected translation of the current key.") 100 "Currently selected translation of the current key.")
92 101
93 (defvar quail-current-translations nil 102 (defvar quail-current-translations nil
94 "Cons of indices and vector of possible translations of the current key.") 103 "Cons of indices and vector of possible translations of the current key.
104 Indices is a list of (CURRENT START END BLOCK BLOCKS), where
105 CURRENT is an index of the current translation,
106 START and END are indices of the start and end of the current block,
107 BLOCK is the current block index,
108 BLOCKS is a number of blocks of translation.")
95 109
96 (defvar quail-current-data nil 110 (defvar quail-current-data nil
97 "Any Lisp object holding information of current translation status. 111 "Any Lisp object holding information of current translation status.
98 When a key sequence is mapped to TRANS and TRANS is a cons 112 When a key sequence is mapped to TRANS and TRANS is a cons
99 of actual translation and some Lisp object to be refered 113 of actual translation and some Lisp object to be refered
100 for translating the longer key sequence, this variable is set 114 for translating the longer key sequence, this variable is set
101 to that Lisp object.") 115 to that Lisp object.")
116 (make-variable-buffer-local 'quail-current-data)
102 117
103 ;; A flag to control conversion region. Normally nil, but if set to 118 ;; A flag to control conversion region. Normally nil, but if set to
104 ;; t, it means we must start the new conversion region if new key to 119 ;; t, it means we must start the new conversion region if new key to
105 ;; be translated is input. 120 ;; be translated is input.
106 (defvar quail-reset-conversion-region nil) 121 (defvar quail-reset-conversion-region nil)
111 "List of Quail packages. 126 "List of Quail packages.
112 A Quail package is a list of these elements: 127 A Quail package is a list of these elements:
113 NAME, TITLE, QUAIL-MAP, GUIDANCE, DOCSTRING, TRANSLATION-KEYS, 128 NAME, TITLE, QUAIL-MAP, GUIDANCE, DOCSTRING, TRANSLATION-KEYS,
114 FORGET-LAST-SELECTION, DETERMINISTIC, KBD-TRANSLATE, SHOW-LAYOUT, 129 FORGET-LAST-SELECTION, DETERMINISTIC, KBD-TRANSLATE, SHOW-LAYOUT,
115 DECODE-MAP, MAXIMUM-SHORTEST, OVERLAY-PLIST, UPDATE-TRANSLATION-FUNCTION, 130 DECODE-MAP, MAXIMUM-SHORTEST, OVERLAY-PLIST, UPDATE-TRANSLATION-FUNCTION,
116 CONVERSION-KEYS. 131 CONVERSION-KEYS, SIMPLE.
117 132
118 QUAIL-MAP is a data structure to map key strings to translations. For 133 QUAIL-MAP is a data structure to map key strings to translations. For
119 the format, see the documentation of `quail-map-p'. 134 the format, see the documentation of `quail-map-p'.
120 135
121 DECODE-MAP is an alist of translations and corresponding keys. 136 DECODE-MAP is an alist of translations and corresponding keys.
177 (defsubst quail-conversion-keymap () 192 (defsubst quail-conversion-keymap ()
178 "Return conversion keymap in the current Quail package. 193 "Return conversion keymap in the current Quail package.
179 Conversion keymap is a keymap used while conversion region is active 194 Conversion keymap is a keymap used while conversion region is active
180 but translation region is not active." 195 but translation region is not active."
181 (nth 14 quail-current-package)) 196 (nth 14 quail-current-package))
197 (defsubst quail-simple ()
198 "Return t if the current Quail package is simple."
199 (nth 15 quail-current-package))
182 200
183 (defsubst quail-package (name) 201 (defsubst quail-package (name)
184 "Return Quail package named NAME." 202 "Return Quail package named NAME."
185 (assoc name quail-package-alist)) 203 (assoc name quail-package-alist))
186 204
202 220
203 ;;;###autoload 221 ;;;###autoload
204 (defun quail-use-package (package-name &rest libraries) 222 (defun quail-use-package (package-name &rest libraries)
205 "Start using Quail package PACKAGE-NAME. 223 "Start using Quail package PACKAGE-NAME.
206 The remaining arguments are libraries to be loaded before using the package." 224 The remaining arguments are libraries to be loaded before using the package."
207 (while libraries 225 (let ((package (quail-package package-name)))
208 (if (not (load (car libraries) t)) 226 (if (null package)
209 (progn 227 ;; Perhaps we have not yet loaded necessary libraries.
210 (with-output-to-temp-buffer "*Help*" 228 (while libraries
211 (princ "Quail package \"") 229 (if (not (load (car libraries) t))
212 (princ package-name) 230 (progn
213 (princ "\" can't be activated\n because library \"") 231 (with-output-to-temp-buffer "*Help*"
214 (princ (car libraries)) 232 (princ "Quail package \"")
215 (princ "\" is not in `load-path'. 233 (princ package-name)
234 (princ "\" can't be activated\n because library \"")
235 (princ (car libraries))
236 (princ "\" is not in `load-path'.
216 237
217 The most common case is that you have not yet installed appropriate 238 The most common case is that you have not yet installed appropriate
218 libraries in LEIM (Libraries of Emacs Input Method) which is 239 libraries in LEIM (Libraries of Emacs Input Method) which is
219 distributed separately from Emacs. 240 distributed separately from Emacs.
220 241
221 Installation of LEIM for Quail is very simple, just copy Quail
222 packages (byte-compiled Emacs Lisp files) to somewhere in your
223 `load-path'.
224
225 LEIM is available from the same ftp directory as Emacs.")) 242 LEIM is available from the same ftp directory as Emacs."))
226 (error "")) 243 (error "Can't use the Quail package `%s'" package-name))
227 (setq libraries (cdr libraries)))) 244 (setq libraries (cdr libraries))))))
228 (quail-select-package package-name) 245 (quail-select-package package-name)
229 (setq current-input-method-title (quail-title)) 246 (setq current-input-method-title (quail-title))
230 (quail-mode 1)) 247 (quail-mode 1))
231 248
232 (defun quail-inactivate () 249 (defun quail-inactivate ()
233 "Turn off Quail input method." 250 "Turn off Quail input method."
234 (interactive) 251 (interactive)
235 (throw 'quail-tag t)) 252 (setq overriding-terminal-local-map nil)
253 (quail-mode -1))
236 254
237 (or (assq 'quail-mode minor-mode-alist) 255 (or (assq 'quail-mode minor-mode-alist)
238 (setq minor-mode-alist 256 (setq minor-mode-alist
239 (cons '(quail-mode " Quail") minor-mode-alist))) 257 (cons '(quail-mode " Quail") minor-mode-alist)))
240 258
241 (defvar quail-mode-map 259 (defvar quail-mode-map
242 (let ((map (make-keymap)) 260 (let ((map (make-keymap))
243 (i ? )) 261 (i ? ))
244 (while (< i 127) 262 (while (< i 127)
245 (define-key map (char-to-string i) 'quail-start-translation) 263 (define-key map (char-to-string i) 'quail-start-translation)
264 (setq i (1+ i)))
265 (setq i 128)
266 (while (< i 256)
267 (define-key map (vector (int-char i)) 'quail-start-translation)
246 (setq i (1+ i))) 268 (setq i (1+ i)))
247 map) 269 map)
248 "Keymap for Quail mode.") 270 "Keymap for Quail mode.")
249 271
250 (or (assq 'quail-mode minor-mode-map-alist) 272 (or (assq 'quail-mode minor-mode-map-alist)
269 (setq i (1+ i))) 291 (setq i (1+ i)))
270 (while (< i 127) 292 (while (< i 127)
271 (define-key map (char-to-string i) 'quail-self-insert-command) 293 (define-key map (char-to-string i) 'quail-self-insert-command)
272 (setq i (1+ i))) 294 (setq i (1+ i)))
273 (define-key map "\177" 'quail-delete-last-char) 295 (define-key map "\177" 'quail-delete-last-char)
274 (define-key map "\C-\\" 'quail-inactivate) 296 ;; (define-key map "\C-\\" 'quail-inactivate)
275 (define-key map "\C-f" 'quail-next-translation) 297 (define-key map "\C-f" 'quail-next-translation)
276 (define-key map "\C-b" 'quail-prev-translation) 298 (define-key map "\C-b" 'quail-prev-translation)
277 (define-key map "\C-n" 'quail-next-translation-block) 299 (define-key map "\C-n" 'quail-next-translation-block)
278 (define-key map "\C-p" 'quail-prev-translation-block) 300 (define-key map "\C-p" 'quail-prev-translation-block)
279 (define-key map "\C-i" 'quail-completion) 301 (define-key map "\C-i" 'quail-completion)
280 (define-key map "\C-@" 'quail-select-current) 302 (define-key map "\C-@" 'quail-select-current)
281 (define-key map "\C-c" 'quail-abort-translation) 303 ;; (define-key map "\C-c" 'quail-abort-translation)
282 (define-key map "\C-h" 'quail-translation-help) 304 (define-key map "\C-h" 'quail-translation-help)
283 ;; 1997/5/26 by MORIOKA Tomohiko 305 ;;; This interferes with handling of escape sequences on non-X terminals.
284 ;; modified for XEmacs 306 ;;; (define-key map "\e" '(keymap (t . quail-execute-non-quail-command)))
285 ;;(define-key map "\e" '(keymap (t . quail-execute-non-quail-command))) 307 (define-key map [?\C-\ ] 'quail-select-current)
286 (let ((emap (make-sparse-keymap)))
287 (set-keymap-default-binding emap 'quail-execute-non-quail-command)
288 (define-key map "\e" emap)
289 )
290 (define-key map [tab] 'quail-completion) 308 (define-key map [tab] 'quail-completion)
291 (define-key map [delete] 'quail-delete-last-char) 309 (define-key map [delete] 'quail-delete-last-char)
292 (define-key map [backspace] 'quail-delete-last-char) 310 (define-key map [backspace] 'quail-delete-last-char)
311 (let ((meta-map (make-sparse-keymap)))
312 (define-key map (char-to-string meta-prefix-char) meta-map)
313 (define-key map [escape] meta-map))
314 (define-key map (vector meta-prefix-char t)
315 'quail-execute-non-quail-command)
293 ;; At last, define default key binding. 316 ;; At last, define default key binding.
294 (set-keymap-default-binding map 'quail-execute-non-quail-command) 317 (set-keymap-default-binding map 'quail-execute-non-quail-command)
295 map) 318 map)
296 "Keymap used processing translation in Quail mode. 319 "Keymap used processing translation in complex Quail modes.
320 Only a few especially complex input methods use this map;
321 most use `quail-simple-translation-keymap' instead.
322 This map is activated while translation region is active.")
323
324 (defvar quail-simple-translation-keymap
325 (let ((map (make-keymap))
326 (i 0))
327 (while (< i ?\ )
328 (define-key map (char-to-string i) 'quail-execute-non-quail-command)
329 (setq i (1+ i)))
330 (while (< i 127)
331 (define-key map (char-to-string i) 'quail-self-insert-command)
332 (setq i (1+ i)))
333 (define-key map "\177" 'quail-delete-last-char)
334 (define-key map [delete] 'quail-delete-last-char)
335 (define-key map [backspace] 'quail-delete-last-char)
336 ;;; This interferes with handling of escape sequences on non-X terminals.
337 ;;; (define-key map "\e" '(keymap (t . quail-execute-non-quail-command)))
338 (let ((meta-map (make-sparse-keymap)))
339 (define-key map (char-to-string meta-prefix-char) meta-map)
340 (define-key map [escape] meta-map))
341 (define-key map (vector meta-prefix-char t)
342 'quail-execute-non-quail-command)
343 ;; At last, define default key binding.
344 (set-keymap-default-binding map 'quail-execute-non-quail-command)
345 map)
346 "Keymap used while processing translation in simple Quail modes.
347 A few especially complex input methods use `quail--translation-keymap' instead.
297 This map is activated while translation region is active.") 348 This map is activated while translation region is active.")
298 349
299 (defvar quail-conversion-keymap 350 (defvar quail-conversion-keymap
300 (let ((map (make-keymap)) 351 (let ((map (make-keymap))
301 (i 0)) 352 (i 0))
310 (define-key map "\C-f" 'quail-conversion-forward-char) 361 (define-key map "\C-f" 'quail-conversion-forward-char)
311 (define-key map "\C-a" 'quail-conversion-beginning-of-region) 362 (define-key map "\C-a" 'quail-conversion-beginning-of-region)
312 (define-key map "\C-e" 'quail-conversion-end-of-region) 363 (define-key map "\C-e" 'quail-conversion-end-of-region)
313 (define-key map "\C-d" 'quail-conversion-delete-char) 364 (define-key map "\C-d" 'quail-conversion-delete-char)
314 (define-key map "\C-h" 'quail-conversion-help) 365 (define-key map "\C-h" 'quail-conversion-help)
315 (define-key map "\C-\\" 'quail-inactivate) 366 ;; (define-key map "\C-\\" 'quail-inactivate)
316 ;; 1997/5/26 by MORIOKA Tomohiko 367 ;;; This interferes with handling of escape sequences on non-X terminals.
317 ;; modified for XEmacs 368 ;;; (define-key map "\e" '(keymap (t . quail-execute-non-quail-command)))
318 ;;(define-key map "\e" '(keymap (t . quail-execute-non-quail-command)))
319 (let ((emap (make-sparse-keymap)))
320 (set-keymap-default-binding emap 'quail-execute-non-quail-command)
321 (define-key map "\e" emap)
322 )
323 (define-key map "\177" 'quail-conversion-backward-delete-char) 369 (define-key map "\177" 'quail-conversion-backward-delete-char)
324 (define-key map [delete] 'quail-conversion-backward-delete-char) 370 (define-key map [delete] 'quail-conversion-backward-delete-char)
325 (define-key map [backspace] 'quail-conversion-backward-delete-char) 371 (define-key map [backspace] 'quail-conversion-backward-delete-char)
372 (let ((meta-map (make-sparse-keymap)))
373 (define-key map (char-to-string meta-prefix-char) meta-map)
374 (define-key map [escape] meta-map))
375 (define-key map (vector meta-prefix-char t)
376 'quail-execute-non-quail-command)
326 ;; At last, define default key binding. 377 ;; At last, define default key binding.
327 (set-keymap-default-binding map 'quail-execute-non-quail-command) 378 (set-keymap-default-binding map 'quail-execute-non-quail-command)
328 map) 379 map)
329 "Keymap used for processing conversion in Quail mode. 380 "Keymap used for processing conversion in Quail mode.
330 This map is activated while convesion region is active but translation 381 This map is activated while convesion region is active but translation
331 region is not active.") 382 region is not active.")
332 383
384 ;;;###autoload
333 (defun quail-define-package (name language title 385 (defun quail-define-package (name language title
334 &optional guidance docstring translation-keys 386 &optional guidance docstring translation-keys
335 forget-last-selection deterministic 387 forget-last-selection deterministic
336 kbd-translate show-layout create-decode-map 388 kbd-translate show-layout create-decode-map
337 maximum-shortest overlay-plist 389 maximum-shortest overlay-plist
338 update-translation-function 390 update-translation-function
339 conversion-keys) 391 conversion-keys simple)
340 "Define NAME as a new Quail package for input LANGUAGE. 392 "Define NAME as a new Quail package for input LANGUAGE.
341 TITLE is a string to be displayed at mode-line to indicate this package. 393 TITLE is a string to be displayed at mode-line to indicate this package.
342 Optional arguments are GUIDANCE, DOCSTRING, TRANLSATION-KEYS, 394 Optional arguments are GUIDANCE, DOCSTRING, TRANLSATION-KEYS,
343 FORGET-LAST-SELECTION, DETERMINISTIC, KBD-TRANSLATE, SHOW-LAYOUT, 395 FORGET-LAST-SELECTION, DETERMINISTIC, KBD-TRANSLATE, SHOW-LAYOUT,
344 CREATE-DECODE-MAP, MAXIMUM-SHORTEST, OVERLAY-PLIST, 396 CREATE-DECODE-MAP, MAXIMUM-SHORTEST, OVERLAY-PLIST,
345 UPDATE-TRANSLATION-FUNCTION, and CONVERSION-KEYS. 397 UPDATE-TRANSLATION-FUNCTION, CONVERSION-KEYS and SIMPLE.
346 398
347 GUIDANCE specifies how a guidance string is shown in echo area. 399 GUIDANCE specifies how a guidance string is shown in echo area.
348 If it is t, list of all possible translations for the current key is shown 400 If it is t, list of all possible translations for the current key is shown
349 with the currently selected translation being highlighted. 401 with the currently selected translation being highlighted.
350 If it is an alist, the element has the form (CHAR . STRING). Each character 402 If it is an alist, the element has the form (CHAR . STRING). Each character
402 default, a tranlated text or a user's key sequence (if no transltion 454 default, a tranlated text or a user's key sequence (if no transltion
403 for it) is inserted. 455 for it) is inserted.
404 456
405 CONVERSION-KEYS specifies additional key bindings used while 457 CONVERSION-KEYS specifies additional key bindings used while
406 conversion region is active. It is an alist of single key character 458 conversion region is active. It is an alist of single key character
407 vs. corresponding command to be called." 459 vs. corresponding command to be called.
460
461 If SIMPLE is non-nil, then we do not alter the meanings of
462 commands such as C-f, C-b, C-n, C-p and TAB; they are treated as
463 non-Quail commands."
408 (let (translation-keymap conversion-keymap) 464 (let (translation-keymap conversion-keymap)
409 (if deterministic (setq forget-last-selection t)) 465 (if deterministic (setq forget-last-selection t))
410 (if translation-keys 466 (if translation-keys
411 (progn 467 (progn
412 (setq translation-keymap (copy-keymap quail-translation-keymap)) 468 (setq translation-keymap (copy-keymap
413 (while translation-keys 469 (if simple quail-simple-translation-keymap
414 (define-key translation-keymap 470 quail-translation-keymap)))
415 (car (car translation-keys)) (cdr (car translation-keys))) 471 (while translation-keys
416 (setq translation-keys (cdr translation-keys)))) 472 (define-key translation-keymap
417 (setq translation-keymap quail-translation-keymap)) 473 (car (car translation-keys)) (cdr (car translation-keys)))
418 (if conversion-keys 474 (setq translation-keys (cdr translation-keys))))
419 (progn 475 (setq translation-keymap
420 (setq conversion-keymap (copy-keymap quail-conversion-keymap)) 476 (if simple quail-simple-translation-keymap
421 (while conversion-keys 477 quail-translation-keymap)))
422 (define-key conversion-keymap 478 (when conversion-keys
423 (car (car conversion-keys)) (cdr (car conversion-keys))) 479 (setq conversion-keymap (copy-keymap quail-conversion-keymap))
424 (setq conversion-keys (cdr conversion-keys))))) 480 (while conversion-keys
481 (define-key conversion-keymap
482 (car (car conversion-keys)) (cdr (car conversion-keys)))
483 (setq conversion-keys (cdr conversion-keys))))
425 (quail-add-package 484 (quail-add-package
426 (list name title (list nil) guidance (or docstring "") 485 (list name title (list nil) guidance (or docstring "")
427 translation-keymap 486 translation-keymap
428 forget-last-selection deterministic kbd-translate show-layout 487 forget-last-selection deterministic kbd-translate show-layout
429 (if create-decode-map (list 'decode-map) nil) 488 (if create-decode-map (list 'decode-map) nil)
430 maximum-shortest overlay-plist update-translation-function 489 maximum-shortest overlay-plist update-translation-function
431 conversion-keymap))) 490 conversion-keymap simple))
432 (register-input-method language (list name 'quail-use-package)) 491
492 ;; Update input-method-alist.
493 (let ((slot (assoc name input-method-alist))
494 (val (list language 'quail-use-package title docstring)))
495 (if slot (setcdr slot val)
496 (setq input-method-alist (cons (cons name val) input-method-alist)))))
497
433 (quail-select-package name)) 498 (quail-select-package name))
434 499
435 ;; Quail minor mode handlers. 500 ;; Quail minor mode handlers.
436 501
437 ;; Setup overlays used in Quail mode. 502 ;; Setup overlays used in Quail mode.
438 (defun quail-setup-overlays () 503 (defun quail-setup-overlays (conversion-mode)
439 (let ((pos (point))) 504 (let ((pos (point)))
440 (if (overlayp quail-overlay) 505 (if (overlayp quail-overlay)
441 (move-overlay quail-overlay pos pos) 506 (move-overlay quail-overlay pos pos)
442 (setq quail-overlay (make-overlay pos pos nil nil t)) 507 (setq quail-overlay (make-overlay pos pos nil nil t))
443 (overlay-put quail-overlay 'face 'underline) 508 (if input-method-highlight-flag
509 (overlay-put quail-overlay 'face 'underline))
444 (let ((l (quail-overlay-plist))) 510 (let ((l (quail-overlay-plist)))
445 (while l 511 (while l
446 (overlay-put quail-overlay (car l) (car (cdr l))) 512 (overlay-put quail-overlay (car l) (car (cdr l)))
447 (setq l (cdr (cdr l)))))) 513 (setq l (cdr (cdr l))))))
448 (if (overlayp quail-conv-overlay) 514 (if conversion-mode
449 (move-overlay quail-conv-overlay pos pos) 515 (if (overlayp quail-conv-overlay)
450 (setq quail-conv-overlay (make-overlay pos pos nil nil t)) 516 (if (not (overlay-start quail-conv-overlay))
451 (overlay-put quail-conv-overlay 'face 'underline) 517 (move-overlay quail-conv-overlay pos pos))
452 ;;(overlay-put quail-conv-overlay 'modification-hooks 518 (setq quail-conv-overlay (make-overlay pos pos nil nil t))
453 ;;'(quail-conv-overlay-modification-hook)) 519 (if input-method-highlight-flag
454 ))) 520 (overlay-put quail-conv-overlay 'face 'underline))))))
455 521
456 ;; Delete overlays used in Quail mode. 522 ;; Delete overlays used in Quail mode.
457 (defun quail-delete-overlays () 523 (defun quail-delete-overlays ()
458 (if (overlayp quail-overlay) 524 (if (overlayp quail-overlay)
459 (delete-overlay quail-overlay)) 525 (delete-overlay quail-overlay))
460 (if (overlayp quail-conv-overlay) 526 (if (overlayp quail-conv-overlay)
461 (delete-overlay quail-conv-overlay))) 527 (delete-overlay quail-conv-overlay)))
462 528
463 ;; While translating and converting, we enter the recursive edit and 529 ;; Kill Quail guidance buffer. Set in kill-buffer-hook.
464 ;; exit it frequently, which results in frequent and annoying change 530 (defun quail-kill-guidance-buf ()
465 ;; of and annoying in mode line. To avoid it, we use a modified 531 (if (buffer-live-p quail-guidance-buf)
466 ;; mode-line-format. 532 (kill-buffer quail-guidance-buf)))
467 (defvar quail-mode-line-format nil)
468
469 ;; Return a modified mode-line-format which doesn't show the recursive
470 ;; editing level. But, we only pay attention to the top level
471 ;; elements of the current mode-line-format.
472 (defun quail-generate-mode-line-format ()
473 (if (listp mode-line-format)
474 (let ((new (copy-sequence mode-line-format))
475 l elt idx)
476 (setq l new)
477 (while l
478 (setq elt (car l))
479 (if (and (stringp elt)
480 (or (setq idx (string-match "%\\[" elt))
481 (setq idx (string-match "%\\]" elt))))
482 (setcar l (concat (substring elt 0 idx)
483 (substring elt (+ idx 2)))))
484 (setq l (cdr l)))
485 new)
486 mode-line-format))
487 533
488 (defun quail-mode (&optional arg) 534 (defun quail-mode (&optional arg)
489 "Toggle Quail minor mode. 535 "Toggle Quail minor mode.
490 With arg, turn Quail mode on if and only if arg is positive. 536 With arg, turn Quail mode on if and only if arg is positive.
491 Try \\[describe-bindings] in Quail mode to see the available key binding. 537
538 You should not turn on and off Quail mode manually, instead use
539 the commands `toggle-input-method' or `select-input-methods' (which
540 see). They automatically turn on or off this mode.
541
542 Try \\[describe-bindings] in Quail mode to see the available key bindings.
492 The command \\[describe-input-method] describes the current Quail package." 543 The command \\[describe-input-method] describes the current Quail package."
493 (interactive "P")
494 (setq quail-mode 544 (setq quail-mode
495 (if (null arg) (null quail-mode) 545 (if (null arg) (null quail-mode)
496 (> (prefix-numeric-value arg) 0))) 546 (> (prefix-numeric-value arg) 0)))
497 (if (null quail-mode) 547 (if (null quail-mode)
498 ;; Let's turn off Quail mode. 548 ;; Let's turn off Quail mode.
499 (progn 549 (progn
500 (quail-hide-guidance-buf) 550 (quail-hide-guidance-buf)
501 (quail-delete-overlays) 551 (quail-delete-overlays)
502 (setq describe-current-input-method-function nil) 552 (setq describe-current-input-method-function nil)
503 (setq current-input-method nil) 553 (run-hooks 'quail-mode-exit-hook))
504 (run-hooks 'quail-mode-exit-hook)
505 (run-hooks 'input-method-inactivate-hook))
506 ;; Let's turn on Quail mode. 554 ;; Let's turn on Quail mode.
507 ;; At first, be sure that quail-mode is at the first element of 555 ;; At first, be sure that quail-mode is at the first element of
508 ;; minor-mode-map-alist. 556 ;; minor-mode-map-alist.
509 ;; The following code removed by slb because it corrupts the XEmacs 557 ;; The following code removed by slb because it corrupts the XEmacs
510 ;; minor-mode-map-alist 558 ;; minor-mode-map-alist
516 ; (setcdr l (cdr (cdr l))) 564 ; (setcdr l (cdr (cdr l)))
517 ; (setq l nil)) 565 ; (setq l nil))
518 ; (setq l (cdr l)))) 566 ; (setq l (cdr l))))
519 ; (setq minor-mode-map-alist (cons 'quail-mode minor-mode-map-alist)))) 567 ; (setq minor-mode-map-alist (cons 'quail-mode minor-mode-map-alist))))
520 ;; End bogus code removal. 568 ;; End bogus code removal.
521 (delete-if (lambda (item) (eq (car item) 'quail-mode))
522 minor-mode-map-alist)
523 (setq minor-mode-map-alist
524 (cons (cons 'quail-mode quail-mode-map) minor-mode-map-alist))
525
526 (if (null quail-current-package) 569 (if (null quail-current-package)
527 ;; Quail package is not yet selected. Select one now. 570 ;; Quail package is not yet selected. Select one now.
528 (let (name) 571 (let (name)
529 (if quail-package-alist 572 (if quail-package-alist
530 (setq name (car (car quail-package-alist))) 573 (setq name (car (car quail-package-alist)))
531 (setq quail-mode nil) 574 (setq quail-mode nil)
532 (error "No Quail package loaded")) 575 (error "No Quail package loaded"))
533 (quail-select-package name))) 576 (quail-select-package name)))
534 (setq inactivate-current-input-method-function 'quail-mode) 577 (setq inactivate-current-input-method-function 'quail-inactivate)
535 (setq describe-current-input-method-function 'quail-help) 578 (setq describe-current-input-method-function 'quail-help)
536 (setq quail-mode-line-format (quail-generate-mode-line-format))
537 (quail-delete-overlays) 579 (quail-delete-overlays)
538 (quail-show-guidance-buf) 580 (quail-show-guidance-buf)
539 ;; If we are in minibuffer, turn off Quail mode before exiting. 581 ;; If we are in minibuffer, turn off the current input method
582 ;; before exiting.
540 (if (eq (selected-window) (minibuffer-window)) 583 (if (eq (selected-window) (minibuffer-window))
541 (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer)) 584 (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer))
542 (make-local-hook 'post-command-hook) 585 (make-local-hook 'post-command-hook)
543 (run-hooks 'quail-mode-hook) 586 (make-local-hook 'kill-buffer-hook)
544 (run-hooks 'input-method-activate-hook)) 587 (add-hook 'kill-buffer-hook 'quail-kill-guidance-buf nil t)
588 (run-hooks 'quail-mode-hook))
545 (force-mode-line-update)) 589 (force-mode-line-update))
546 590
547 (defun quail-exit-from-minibuffer () 591 (defun quail-exit-from-minibuffer ()
548 (if quail-mode (quail-mode -1)) 592 (inactivate-input-method)
549 (if (<= (minibuffer-depth) 1) 593 (if (<= (minibuffer-depth) 1)
550 (remove-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer))) 594 (remove-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer)))
551 595
552 (defvar quail-saved-overriding-local-map nil) 596 (defvar quail-saved-current-map nil)
553 (defvar quail-saved-current-buffer nil) 597 (defvar quail-saved-current-buffer nil)
554 598
555 ;; Toggle `quail-mode'. This function is added to `post-command-hook' 599 ;; Toggle Quail mode. This function is added to `post-command-hook'
556 ;; in Quail mode, to turn Quail mode temporarily off, or back on 600 ;; in Quail mode, to turn Quail mode temporarily off, or back on after
557 ;; after one non-Quail command. 601 ;; one non-Quail command.
558 (defun quail-toggle-mode-temporarily () 602 (defun quail-toggle-mode-temporarily ()
559 (if quail-mode 603 (if quail-mode
560 ;; We are going to handle following events out of Quail mode. 604 ;; We are going to handle following events out of Quail mode.
561 (setq quail-mode nil 605 (setq quail-saved-current-buffer (current-buffer)
562 quail-saved-overriding-local-map overriding-local-map 606 quail-saved-current-map overriding-terminal-local-map
563 quail-saved-current-buffer (current-buffer) 607 quail-mode nil
564 overriding-local-map nil) 608 overriding-terminal-local-map nil)
565 ;; We have just executed one non-Quail command. We don't need 609 ;; We have just executed one non-Quail command. We don't need
566 ;; this hook any more. 610 ;; this hook any more.
567 (remove-hook 'post-command-hook 'quail-toggle-mode-temporarily t) 611 (remove-hook 'post-command-hook 'quail-toggle-mode-temporarily t)
568 ;; If the command changed the current buffer, we should not go 612 (if (eq (current-buffer) quail-saved-current-buffer)
569 ;; back to Quail mode. 613 ;; We should go back to Quail mode only when the current input
570 (if (not (eq (current-buffer) quail-saved-current-buffer)) 614 ;; method was not turned off by the last command.
571 (throw 'quail-tag nil) 615 (when current-input-method
572 ;; Let's go back to Quail mode. 616 (setq quail-mode t
573 (setq quail-mode t) 617 overriding-terminal-local-map quail-saved-current-map)
574 (setq overriding-local-map quail-saved-overriding-local-map) 618 (if input-method-exit-on-invalid-key
575 ;; If whole text in conversion area was deleted, exit from the 619 (inactivate-input-method)))
576 ;; recursive edit. 620 ;; The last command changed the current buffer, we should not go
577 ;; 1997/6/24 modified by MORIOKA Tomohiko <morioka@jaist.ac.jp> 621 ;; back to Quail mode in this new buffer, but should turn on
578 ;; for XEmacs 622 ;; Quail mode in the original buffer.
579 (let ((start (and quail-conv-overlay 623 (save-excursion
580 (overlay-start quail-conv-overlay)))) 624 (set-buffer quail-saved-current-buffer)
581 (if (and start (= start (overlay-end quail-conv-overlay))) 625 (setq quail-mode t)
582 (throw 'quail-tag nil))) 626 (quail-delete-overlays)))))
583 )))
584 627
585 (defun quail-execute-non-quail-command () 628 (defun quail-execute-non-quail-command ()
586 "Execute one non-Quail command in Quail mode. 629 "Execute one non-Quail command out of Quail mode.
587 The current translation and conversion are terminated." 630 The current translation and conversion are terminated."
588 (interactive) 631 (interactive)
589 (setq unread-command-events (cons last-input-event unread-command-events)) 632 (let* ((key (this-command-keys))
633 (keylist (listify-key-sequence key)))
634 (setq unread-command-events
635 (append keylist unread-command-events)))
636 (reset-this-command-lengths)
637 (quail-terminate-translation)
590 (quail-delete-overlays) 638 (quail-delete-overlays)
639 (setq overriding-terminal-local-map nil)
591 (if (buffer-live-p quail-guidance-buf) 640 (if (buffer-live-p quail-guidance-buf)
592 (save-excursion 641 (save-excursion
593 (set-buffer quail-guidance-buf) 642 (set-buffer quail-guidance-buf)
594 (erase-buffer))) 643 (erase-buffer)))
595 (throw 'quail-tag nil)) 644 (add-hook 'post-command-hook 'quail-toggle-mode-temporarily nil t))
596 645
597 ;; Keyboard layout translation handlers. 646 ;; Keyboard layout translation handlers.
598 647
599 ;; Some Quail packages provide localized keyboard simulation which 648 ;; Some Quail packages provide localized keyboard simulation which
600 ;; requires a particular keyboard layout. In this case, what we need 649 ;; requires a particular keyboard layout. In this case, what we need
628 the first column of the fourth row is left of key `a', 677 the first column of the fourth row is left of key `a',
629 the first column of the fifth row is left of key `z', 678 the first column of the fifth row is left of key `z',
630 the sixth row is below the `z' - `/' row. 679 the sixth row is below the `z' - `/' row.
631 Nth (N is even) and (N+1)th characters in the string are non-shifted 680 Nth (N is even) and (N+1)th characters in the string are non-shifted
632 and shifted characters respectively at the same location. 681 and shifted characters respectively at the same location.
633 The location of Nth character is row (N / 30) and column ((N mod 30) / 2).") 682 The location of Nth character is row (N / 30) and column ((N mod 30) / 2).
683 The command `quail-set-keyboard-layout' usually sets this variable.")
634 684
635 (defconst quail-keyboard-layout-len 180) 685 (defconst quail-keyboard-layout-len 180)
636 686
637 ;; Here we provide several examples of famous keyboard layouts. 687 ;; Here we provide several examples of famous keyboard layouts.
638 688
643 1!2@3#4$5%6^7&8*9(0)-_=+\\|`~\ 693 1!2@3#4$5%6^7&8*9(0)-_=+\\|`~\
644 qQwWeErRtTyYuUiIoOpP[{]} \ 694 qQwWeErRtTyYuUiIoOpP[{]} \
645 aAsSdDfFgGhHjJkKlL;:'\" \ 695 aAsSdDfFgGhHjJkKlL;:'\" \
646 zZxXcCvVbBnNmM,<.>/? \ 696 zZxXcCvVbBnNmM,<.>/? \
647 ") 697 ")
698 '("atari-german" . "\
699 \
700 1!2\"3\2474$5%6&7/8(9)0=\337?'`#^ \
701 qQwWeErRtTzZuUiIoOpP\374\334+* \
702 aAsSdDfFgGhHjJkKlL\366\326\344\304~| \
703 <>yYxXcCvVbBnNmM,;.:-_ \
704 ")
648 (cons "standard" quail-keyboard-layout-standard)) 705 (cons "standard" quail-keyboard-layout-standard))
649 "Alist of keyboard names and corresponding layout strings. 706 "Alist of keyboard names and corresponding layout strings.
650 See the documentation of `quail-keyboard-layout' for the format of 707 See the documentation of `quail-keyboard-layout' for the format of
651 the layout string.") 708 the layout string.")
652 709
710 ;;;###autoload
653 (defun quail-set-keyboard-layout (kbd-type) 711 (defun quail-set-keyboard-layout (kbd-type)
654 "Set the current keyboard layout to the same as keyboard KBD-TYPE. 712 "Set the current keyboard layout to the same as keyboard KBD-TYPE.
655 713
656 Since some Quail packages depends on a physical layout of keys (not 714 Since some Quail packages depends on a physical layout of keys (not
657 characters generated by them), those are created by assuming the 715 characters generated by them), those are created by assuming the
671 (setq quail-keyboard-layout (cdr layout)))) 729 (setq quail-keyboard-layout (cdr layout))))
672 730
673 (defun quail-keyboard-translate (ch) 731 (defun quail-keyboard-translate (ch)
674 "Translate CHAR according to `quail-keyboard-layout' and return the result." 732 "Translate CHAR according to `quail-keyboard-layout' and return the result."
675 (if (eq quail-keyboard-layout quail-keyboard-layout-standard) 733 (if (eq quail-keyboard-layout quail-keyboard-layout-standard)
734 ;; All Quail packages are designed based on
735 ;; `quail-keyboard-layout-standard'.
676 ch 736 ch
677 (let ((i 0)) 737 (let ((i 0))
678 (while (and (< i quail-keyboard-layout-len) 738 (while (and (< i quail-keyboard-layout-len)
679 (/= ch (aref quail-keyboard-layout i))) 739 (/= ch (aref quail-keyboard-layout i)))
680 (setq i (1+ i))) 740 (setq i (1+ i)))
681 (if (= i quail-keyboard-layout-len) 741 (if (= i quail-keyboard-layout-len)
682 (error "Character `%c' not found in your keyboard layout" ch)) 742 ;; CH is not in quail-keyboard-layout, which means that a
683 (aref quail-keyboard-layout-standard i)))) 743 ;; user typed a key which generated a character code to be
744 ;; handled out of Quail. Just return CH and make
745 ;; quail-execute-non-quail-command handle it correctly.
746 ch
747 (let ((char (aref quail-keyboard-layout-standard i)))
748 (if (= char ?\ )
749 ;; A user typed a key at the location not convered by
750 ;; quail-keyboard-layout-standard. Just return CH as
751 ;; well as above.
752 ch
753 char))))))
684 754
685 ;; Quail map 755 ;; Quail map
686 756
687 (defsubst quail-map-p (object) 757 (defsubst quail-map-p (object)
688 "Return t if OBJECT is a Quail map. 758 "Return t if OBJECT is a Quail map.
710 (and (consp translation) (not (vectorp (cdr translation)))))) 780 (and (consp translation) (not (vectorp (cdr translation))))))
711 (let ((alist (cdr object))) 781 (let ((alist (cdr object)))
712 (or (and (listp alist) (consp (car alist))) 782 (or (and (listp alist) (consp (car alist)))
713 (symbolp alist))))) 783 (symbolp alist)))))
714 784
785 ;;;###autoload
715 (defmacro quail-define-rules (&rest rules) 786 (defmacro quail-define-rules (&rest rules)
716 "Define translation rules of the current Quail package. 787 "Define translation rules of the current Quail package.
717 Each argument is a list of KEY and TRANSLATION. 788 Each argument is a list of KEY and TRANSLATION.
718 KEY is a string meaning a sequence of keystrokes to be translated. 789 KEY is a string meaning a sequence of keystrokes to be translated.
719 TRANSLATION is a character, a string, a vector, a Quail map, or a function. 790 TRANSLATION is a character, a string, a vector, a Quail map, or a function.
731 (while l 802 (while l
732 (quail-defrule-internal (car (car l)) (car (cdr (car l))) map) 803 (quail-defrule-internal (car (car l)) (car (cdr (car l))) map)
733 (setq l (cdr l))) 804 (setq l (cdr l)))
734 map))) 805 map)))
735 806
807 ;;;###autoload
736 (defun quail-install-map (map) 808 (defun quail-install-map (map)
737 "Install the Quail map MAP in the current Quail package. 809 "Install the Quail map MAP in the current Quail package.
738 The installed map can be referred by the function `quail-map'." 810 The installed map can be referred by the function `quail-map'."
739 (if (null quail-current-package) 811 (if (null quail-current-package)
740 (error "No current Quail package")) 812 (error "No current Quail package"))
741 (if (null (quail-map-p map)) 813 (if (null (quail-map-p map))
742 (error "Invalid Quail map `%s'" map)) 814 (error "Invalid Quail map `%s'" map))
743 (setcar (cdr (cdr quail-current-package)) map)) 815 (setcar (cdr (cdr quail-current-package)) map))
744 816
817 ;;;###autoload
745 (defun quail-defrule (key translation &optional name) 818 (defun quail-defrule (key translation &optional name)
746 "Add one translation rule, KEY to TRANSLATION, in the current Quail package. 819 "Add one translation rule, KEY to TRANSLATION, in the current Quail package.
747 KEY is a string meaning a sequence of keystrokes to be translated. 820 KEY is a string meaning a sequence of keystrokes to be translated.
748 TRANSLATION is a character, a string, a vector, a Quail map, 821 TRANSLATION is a character, a string, a vector, a Quail map,
749 a function, or a cons. 822 a function, or a cons.
750 It it is a character, it is the sole translation of KEY. 823 It it is a character, it is the sole translation of KEY.
751 If it is a string, each character is a candidate for the translation. 824 If it is a string, each character is a candidate for the translation.
752 If it is a vector, each element (string or character) is a candidate 825 If it is a vector, each element (string or character) is a candidate
753 for the translation. 826 for the translation.
754 If it is a cons, the car is one of the above and the cdr is a function 827 If it is a cons, the car is one of the above and the cdr is a function
755 to call when translating KEY. 828 to call when translating KEY (the return value is assigned to the
829 variable `quail-current-data'). If the cdr part is not a function,
830 the value itself is assigned to `quail-current-data'.
756 In these cases, a key specific Quail map is generated and assigned to KEY. 831 In these cases, a key specific Quail map is generated and assigned to KEY.
757 832
758 If TRANSLATION is a Quail map or a function symbol which returns a Quail map, 833 If TRANSLATION is a Quail map or a function symbol which returns a Quail map,
759 it is used to handle KEY. 834 it is used to handle KEY.
760 Optional argument NAME, if specified, says which Quail package 835 Optional argument NAME, if specified, says which Quail package
765 (if (null package) 840 (if (null package)
766 (error "No Quail package `%s'" name)) 841 (error "No Quail package `%s'" name))
767 (setq quail-current-package package))) 842 (setq quail-current-package package)))
768 (quail-defrule-internal key translation (quail-map))) 843 (quail-defrule-internal key translation (quail-map)))
769 844
770 ;; Define KEY as TRANS in a Quail map MAP. 845 ;;;###autoload
771 (defun quail-defrule-internal (key trans map) 846 (defun quail-defrule-internal (key trans map)
847 "Define KEY as TRANS in a Quail map MAP."
772 (if (null (stringp key)) 848 (if (null (stringp key))
773 "Invalid Quail key `%s'" key) 849 "Invalid Quail key `%s'" key)
774 ;; 1997/5/26 by MORIOKA Tomohiko 850 ;; 1997/5/26 by MORIOKA Tomohiko
775 ;; modified for XEmacs 851 ;; modified for XEmacs
776 (if (not (or (characterp trans) (stringp trans) (vectorp trans) 852 (if (not (or (characterp trans) (stringp trans) (vectorp trans)
841 ;; No translation. 917 ;; No translation.
842 nil) 918 nil)
843 919
844 ((stringp def) 920 ((stringp def)
845 ;; Each character in DEF is a candidate of translation. Reform 921 ;; Each character in DEF is a candidate of translation. Reform
846 ;; it as (INDEX . VECTOR). 922 ;; it as (INDICES . VECTOR).
847 (setq def (string-to-vector def)) 923 (setq def (string-to-vector def))
848 ;; But if the length is 1, we don't need vector but a single 924 ;; But if the length is 1, we don't need vector but a single
849 ;; candidate as the translation. 925 ;; candidate as the translation.
850 (if (= (length def) 1) 926 (if (= (length def) 1)
851 (aref def 0) 927 (aref def 0)
852 (cons 0 def))) 928 (cons (list 0 0 0 0 nil) def)))
853 929
854 ((vectorp def) 930 ((vectorp def)
855 ;; Each element (string or character) in DEF is a candidate of 931 ;; Each element (string or character) in DEF is a candidate of
856 ;; translation. Reform it as (INDEX . VECTOR). 932 ;; translation. Reform it as (INDICES . VECTOR).
857 (cons 0 def)) 933 (cons (list 0 0 0 0 nil) def))
858 934
859 (t 935 (t
860 (error "Invalid object in Quail map: %s" def)))) 936 (error "Invalid object in Quail map: %s" def))))
861 937
862 (defun quail-lookup-key (key len) 938 (defun quail-lookup-key (key &optional len)
863 "Lookup KEY of length LEN in the current Quail map and return the definition. 939 "Lookup KEY of length LEN in the current Quail map and return the definition.
864 The returned value is a Quail map specific to KEY." 940 The returned value is a Quail map specific to KEY."
941 (or len
942 (setq len (length key)))
865 (let ((idx 0) 943 (let ((idx 0)
866 (map (quail-map)) 944 (map (quail-map))
867 (kbd-translate (quail-kbd-translate)) 945 (kbd-translate (quail-kbd-translate))
868 slot ch translation def) 946 slot ch translation def)
869 (while (and map (< idx len)) 947 (while (and map (< idx len))
875 (setq slot (assq ch (cdr map))) 953 (setq slot (assq ch (cdr map)))
876 (if (and (cdr slot) (symbolp (cdr slot))) 954 (if (and (cdr slot) (symbolp (cdr slot)))
877 (setcdr slot (funcall (cdr slot) key idx))) 955 (setcdr slot (funcall (cdr slot) key idx)))
878 (setq map (cdr slot))) 956 (setq map (cdr slot)))
879 (setq def (car map)) 957 (setq def (car map))
958 (setq quail-current-translations nil)
880 (if (and map (setq translation (quail-get-translation def key len))) 959 (if (and map (setq translation (quail-get-translation def key len)))
881 (progn 960 (progn
882 (if (and (consp def) (not (vectorp (cdr def)))) 961 (if (and (consp def) (not (vectorp (cdr def))))
883 (progn 962 (progn
884 (if (not (equal (car def) translation)) 963 (if (not (equal (car def) translation))
893 (setcar map translation))) 972 (setcar map translation)))
894 (if (and (consp translation) (vectorp (cdr translation))) 973 (if (and (consp translation) (vectorp (cdr translation)))
895 (progn 974 (progn
896 (setq quail-current-translations translation) 975 (setq quail-current-translations translation)
897 (if (quail-forget-last-selection) 976 (if (quail-forget-last-selection)
898 (setcar quail-current-translations 0)))) 977 (setcar (car quail-current-translations) 0))))
899 ;; We may have to reform cdr part of MAP. 978 ;; We may have to reform cdr part of MAP.
900 (if (and (cdr map) (symbolp (cdr map))) 979 (if (and (cdr map) (symbolp (cdr map)))
901 (progn 980 (progn
902 (setcdr map (funcall (cdr map) key len)))) 981 (setcdr map (funcall (cdr map) key len))))
903 )) 982 ))
904 map)) 983 map))
905 984
906 (defun quail-conv-overlay-modification-hook (overlay after &rest ignore)
907 (if (and after
908 (= (overlay-start overlay) (overlay-end overlay)))
909 ;; Whole text in conversion area was deleted. Let's exit from
910 ;; the recursive edit.
911 (throw 'exit nil)))
912
913 (defvar quail-suppress-conversion nil
914 "If non-nil, suppress converting facility of the current Quail package.")
915
916 ;; If set to non-nil, exit conversion mode before starting new translation. 985 ;; If set to non-nil, exit conversion mode before starting new translation.
917 (defvar quail-exit-conversion-mode nil) 986 (defvar quail-exit-conversion-mode nil)
918 987
919 (defun quail-start-translation () 988 (defvar quail-prefix-arg nil)
989
990 (defun quail-start-translation (arg)
920 "Start translating the typed character in Quail mode." 991 "Start translating the typed character in Quail mode."
921 (interactive "*") 992 (interactive "*p")
993 (setq prefix-arg arg)
994 (setq quail-prefix-arg arg)
922 (setq unread-command-events 995 (setq unread-command-events
923 (cons last-command-event unread-command-events)) 996 (cons last-command-event unread-command-events))
924 ;; Check the possibility of translating the last key. 997 ;; Check the possibility of translating the last key.
925 ;; 1997/5/26 by MORIOKA Tomohiko <morioka@jaist.ac.jp> 998 (if (and (characterp (event-to-character last-command-event))
926 ;; modified for XEmacs 999 (assq (if (quail-kbd-translate)
927 (if (assq (event-key last-command-event) (cdr (quail-map))) 1000 (quail-keyboard-translate
1001 (event-to-character last-command-event))
1002 (event-to-character last-command-event))
1003 (cdr (quail-map))))
928 ;; Ok, we can start translation. 1004 ;; Ok, we can start translation.
929 (let ((mode-line-format quail-mode-line-format)) 1005 (if (quail-conversion-keymap)
930 (quail-setup-overlays) 1006 ;; We must start translation in conversion mode.
931 (if (catch 'quail-tag 1007 (setq quail-exit-conversion-mode nil
932 (if (and (not quail-suppress-conversion) 1008 overriding-terminal-local-map (quail-conversion-keymap))
933 (quail-conversion-keymap)) 1009 (quail-setup-overlays nil)
934 ;; We must start translation in conversion mode. 1010 (setq quail-current-key "")
935 (let ((overriding-local-map (quail-conversion-keymap))) 1011 (setq overriding-terminal-local-map (quail-translation-keymap)))
936 (setq quail-exit-conversion-mode nil) 1012 ;; Since the last event doesn't start any translation, handle it
937 (recursive-edit) 1013 ;; out of Quail mode. We come back to Quail mode later by setting
938 (if (and auto-fill-function 1014 ;; function `quail-toggle-mode-temporarily' in
939 (> (current-column) (current-fill-column)))
940 (run-hooks 'auto-fill-function)))
941 (let ((overriding-local-map (quail-translation-keymap)))
942 (setq quail-current-key "")
943 (recursive-edit)))
944 (let ((start (overlay-start quail-conv-overlay))
945 (end (overlay-end quail-conv-overlay)))
946 (if (and start end
947 (prog1 (< start end)
948 (delete-overlay quail-conv-overlay)))
949 (run-hooks 'input-method-after-insert-chunk-hook)))
950 nil)
951 ;; Someone has thrown a tag with value t, which means
952 ;; we should turn Quail mode off.
953 (quail-mode -1)))
954 ;; Since the typed character doesn't start any translation, handle
955 ;; it out of Quail mode. We come back to Quail mode later because
956 ;; function `quail-toggle-mode-temporarily' is in
957 ;; `post-command-hook'. 1015 ;; `post-command-hook'.
958 (add-hook 'post-command-hook 'quail-toggle-mode-temporarily nil t))) 1016 (add-hook 'post-command-hook 'quail-toggle-mode-temporarily nil t)))
959 1017
960 (defsubst quail-point-in-conversion-region () 1018 (defsubst quail-point-in-conversion-region ()
961 "Return non-nil value if the point is in conversion region of Quail mode." 1019 "Return non-nil value if the point is in conversion region of Quail mode."
967 (defun quail-start-translation-in-conversion-mode () 1025 (defun quail-start-translation-in-conversion-mode ()
968 "Start translating the typed character in conversion mode of Quail mode." 1026 "Start translating the typed character in conversion mode of Quail mode."
969 (interactive "*") 1027 (interactive "*")
970 (setq unread-command-events 1028 (setq unread-command-events
971 (cons last-command-event unread-command-events)) 1029 (cons last-command-event unread-command-events))
972 (if (or quail-exit-conversion-mode 1030 ;; Check the possibility of translating the last key.
973 (not (quail-point-in-conversion-region))) 1031 (if (and (characterp (event-to-character last-command-event))
1032 (assq (if (quail-kbd-translate)
1033 (quail-keyboard-translate
1034 (event-to-character last-command-event))
1035 (event-to-character last-command-event))
1036 (cdr (quail-map))))
1037 ;; Ok, we can start translation.
974 (progn 1038 (progn
975 ;; We must start translation with new conversion region. 1039 (quail-setup-overlays t)
976 (setq quail-exit-conversion-mode nil)
977 (throw 'exit nil)))
978 ;; Check the possibility of translating the last key.
979 ;; 1997/5/26 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
980 ;; modified for XEmacs
981 (if (assq (event-key last-command-event) (cdr (quail-map)))
982 ;; Ok, we can start translation.
983 (let ((overriding-local-map (quail-translation-keymap)))
984 (setq quail-current-key "") 1040 (setq quail-current-key "")
985 (move-overlay quail-overlay (point) (point)) 1041 (setq overriding-terminal-local-map (quail-translation-keymap))
986 (recursive-edit)) 1042 (move-overlay quail-overlay (point) (point)))
987 ;; Since the typed character doesn't start any translation, handle 1043 ;; Since the last event doesn't start any translation, handle it
988 ;; it out of Quail mode. We come back to Quail mode later because 1044 ;; out of Quail mode. We come back to Quail mode later by setting
989 ;; function `quail-toggle-mode-temporarily' is in 1045 ;; function `quail-toggle-mode-temporarily' in
990 ;; `post-command-hook'. 1046 ;; `post-command-hook'.
991 (add-hook 'post-command-hook 'quail-toggle-mode-temporarily nil t))) 1047 (add-hook 'post-command-hook 'quail-toggle-mode-temporarily nil t)))
992 1048
1049 (defsubst quail-delete-region ()
1050 "Delete the text in the current translation region of Quail."
1051 (if (overlay-start quail-overlay)
1052 (delete-region (overlay-start quail-overlay)
1053 (overlay-end quail-overlay))))
1054
993 (defun quail-terminate-translation () 1055 (defun quail-terminate-translation ()
994 "Terminate the translation of the current key." 1056 "Terminate the translation of the current key."
995 (let ((start (overlay-start quail-overlay))) 1057 (when (overlayp quail-overlay)
996 (if (and start 1058 (let ((start (overlay-start quail-overlay)))
997 (< start (overlay-end quail-overlay))) 1059 (if (and start
998 ;; Here we simulate self-insert-command. 1060 (< start (overlay-end quail-overlay)))
999 (let (last-command-char) 1061 ;; Here we simulate self-insert-command.
1000 (goto-char start) 1062 (let ((seq (string-to-sequence
1001 ;; The first one might want to expand an abbrev. 1063 (buffer-substring (overlay-start quail-overlay)
1002 (setq last-command-char (following-char)) 1064 (overlay-end quail-overlay))
1003 (delete-char 1) 1065 'list))
1004 (self-insert-command 1) 1066 last-command-char)
1005 (let ((end (overlay-end quail-overlay))) 1067 (goto-char start)
1006 (if (and end (< (point) end)) 1068 (quail-delete-region)
1007 (if overwrite-mode 1069 (setq last-command-char (car seq))
1008 (while (< (point) end) 1070 (self-insert-command (or quail-prefix-arg 1))
1009 (setq last-command-char (following-char)) 1071 (setq quail-prefix-arg nil)
1010 (delete-char 1) 1072 (setq seq (cdr seq))
1011 (self-insert-command 1)) 1073 (while seq
1012 ;; The last one might still want to auto-fill. 1074 (setq last-command-char (car seq))
1013 (goto-char end) 1075 (self-insert-command 1)
1014 (let ((last-command-char (preceding-char))) 1076 (setq seq (cdr seq))))))
1015 (delete-char -1) 1077 (delete-overlay quail-overlay))
1016 (self-insert-command 1))))))))
1017 (delete-overlay quail-overlay)
1018 (if (buffer-live-p quail-guidance-buf) 1078 (if (buffer-live-p quail-guidance-buf)
1019 (save-excursion 1079 (save-excursion
1020 (set-buffer quail-guidance-buf) 1080 (set-buffer quail-guidance-buf)
1021 (erase-buffer))) 1081 (erase-buffer)))
1022 (throw 'exit nil)) 1082 (setq overriding-terminal-local-map
1023 1083 (quail-conversion-keymap))
1024 (defsubst quail-delete-region () 1084 ;; Run this hook only when the current input method doesn't require
1025 "Delete the text in the current translation region of Quail." 1085 ;; conversion. When conversion is required, the conversion function
1026 (let ((start (overlay-start quail-overlay)) 1086 ;; should run this hook at a proper timing.
1027 (end (overlay-end quail-overlay))) 1087 (unless (quail-conversion-keymap)
1028 (and start end (delete-region start end)))) 1088 (run-hooks 'input-method-after-insert-chunk-hook)))
1029 1089
1030 (defun quail-select-current () 1090 (defun quail-select-current ()
1031 "Select the current text shown in Quail translation region." 1091 "Select the current text shown in Quail translation region."
1032 (interactive) 1092 (interactive)
1033 (quail-terminate-translation)) 1093 (quail-terminate-translation))
1039 ;; If CONTROL-FLAG is t, terminate the translation for the whole keys 1099 ;; If CONTROL-FLAG is t, terminate the translation for the whole keys
1040 ;; in quail-current-key. 1100 ;; in quail-current-key.
1041 ;; If CONTROL-FLAG is nil, proceed the translation with more keys. 1101 ;; If CONTROL-FLAG is nil, proceed the translation with more keys.
1042 1102
1043 (defun quail-update-translation (control-flag) 1103 (defun quail-update-translation (control-flag)
1044 (quail-delete-region) 1104 ;; 1997/9/26 Comment outed by MORIOKA Tomohiko
1105 ;; `overlay' emulation of XEmacs can not represent 0 length region
1106 ;;(quail-delete-region)
1045 (let ((func (quail-update-translation-function))) 1107 (let ((func (quail-update-translation-function)))
1046 (if func 1108 (if func
1047 (funcall func control-flag) 1109 (funcall func control-flag)
1048 (if (numberp control-flag) 1110 (let ((start (overlay-start quail-overlay))
1049 (let ((len (length quail-current-key))) 1111 (end (overlay-end quail-overlay)))
1050 (while (> len control-flag) 1112 (if (numberp control-flag)
1051 (setq len (1- len)) 1113 (let ((len (length quail-current-key)))
1052 (setq unread-command-events 1114 (while (> len control-flag)
1053 ;; 1997/5/26 by MORIOKA Tomohiko 1115 (setq len (1- len))
1054 ;; modified for XEmacs 1116 (setq unread-command-events
1055 (cons (character-to-event (aref quail-current-key len)) 1117 ;; 1997/5/26 by MORIOKA Tomohiko
1056 unread-command-events))) 1118 ;; modified for XEmacs
1057 (insert (or quail-current-str 1119 (cons (character-to-event (aref quail-current-key len))
1058 (substring quail-current-key 0 len)))) 1120 unread-command-events)))
1059 (insert (or quail-current-str quail-current-key))))) 1121 (insert (or quail-current-str
1122 (substring quail-current-key 0 len)))
1123 )
1124 (insert (or quail-current-str quail-current-key))
1125 )
1126 (if (and start end)
1127 (delete-region start end)
1128 ))))
1060 (quail-update-guidance) 1129 (quail-update-guidance)
1061 (if control-flag 1130 (if control-flag
1062 (quail-terminate-translation))) 1131 (quail-terminate-translation)))
1063 1132
1064 (defun quail-self-insert-command () 1133 (defun quail-self-insert-command ()
1067 ;; 1997/5/26 by MORIOKA Tomohiko <morioka@jaist.ac.jp> 1136 ;; 1997/5/26 by MORIOKA Tomohiko <morioka@jaist.ac.jp>
1068 ;; modified for XEmacs 1137 ;; modified for XEmacs
1069 (setq quail-current-key 1138 (setq quail-current-key
1070 (concat quail-current-key (char-to-string 1139 (concat quail-current-key (char-to-string
1071 (event-to-character last-command-event)))) 1140 (event-to-character last-command-event))))
1072 (quail-update-translation (quail-translate-key))) 1141 (unless (catch 'quail-tag
1142 (quail-update-translation (quail-translate-key))
1143 t)
1144 ;; If someone throws for `quail-tag' by value nil, we exit from
1145 ;; translation mode.
1146 (setq overriding-terminal-local-map nil)))
1147
1148 ;; Return the actual definition part of Quail map MAP.
1149 (defun quail-map-definition (map)
1150 (let ((def (car map)))
1151 (if (and (consp def) (not (vectorp (cdr def))))
1152 (setq def (car def)))
1153 def))
1154
1155 ;; Return a string to be shown as the current translation of key
1156 ;; sequence of length LEN. DEF is a definition part of Quail map for
1157 ;; the sequence.
1158 (defun quail-get-current-str (len def)
1159 (or (and (consp def) (aref (cdr def) (car (car def))))
1160 def
1161 (and (> len 1)
1162 (let ((str (quail-get-current-str
1163 (1- len)
1164 (quail-map-definition (quail-lookup-key
1165 quail-current-key (1- len))))))
1166 (if str
1167 (concat (if (stringp str) str (char-to-string str))
1168 (substring quail-current-key (1- len) len)))))))
1169
1170 (defvar quail-guidance-translations-starting-column 20)
1171
1172 ;; Update `quail-current-translations' to make RELATIVE-INDEX the
1173 ;; current translation.
1174 (defun quail-update-current-translations (&optional relative-index)
1175 (let* ((indices (car quail-current-translations))
1176 (cur (car indices))
1177 (start (nth 1 indices))
1178 (end (nth 2 indices)))
1179 ;; Validate the index number of current translation.
1180 (if (< cur 0)
1181 (setcar indices (setq cur 0))
1182 (if (>= cur (length (cdr quail-current-translations)))
1183 (setcar indices
1184 (setq cur (1- (length (cdr quail-current-translations)))))))
1185
1186 (if (or (null end) ; We have not yet calculated END.
1187 (< cur start) ; We moved to the previous block.
1188 (>= cur end)) ; We moved to the next block.
1189 (let ((len (length (cdr quail-current-translations)))
1190 (maxcol (- (window-width quail-guidance-win)
1191 quail-guidance-translations-starting-column))
1192 (block (nth 3 indices))
1193 col idx width trans num-items blocks)
1194 (if (< cur start)
1195 ;; We must calculate from the head.
1196 (setq start 0 block 0)
1197 (if end ; i.e. (>= cur end)
1198 (setq start end)))
1199 (setq idx start col 0 end start num-items 0)
1200 ;; Loop until we hit the tail, or reach the block of CUR.
1201 (while (and (< idx len) (>= cur end))
1202 (if (= num-items 0)
1203 (setq start idx col 0 block (1+ block)))
1204 (setq trans (aref (cdr quail-current-translations) idx))
1205 (setq width (if (characterp trans) (char-width trans)
1206 (string-width trans)))
1207 (setq col (+ col width 3) num-items (1+ num-items))
1208 (if (and (> num-items 0)
1209 (or (>= col maxcol) (> num-items 10)))
1210 (setq end idx num-items 0)
1211 (setq idx (1+ idx))))
1212 (setcar (nthcdr 3 indices) block)
1213 (if (>= idx len)
1214 (progn
1215 ;; We hit the tail before reaching MAXCOL.
1216 (setq end idx)
1217 (setcar (nthcdr 4 indices) block)))
1218 (setcar (cdr indices) start)
1219 (setcar (nthcdr 2 indices) end)))
1220 (if relative-index
1221 (if (>= (+ start relative-index) end)
1222 (setcar indices end)
1223 (setcar indices (+ start relative-index))))
1224 (setq quail-current-str
1225 (aref (cdr quail-current-translations) (car indices)))))
1073 1226
1074 (defun quail-translate-key () 1227 (defun quail-translate-key ()
1075 "Translate the current key sequence according to the current Quail map. 1228 "Translate the current key sequence according to the current Quail map.
1076 Return t if we can terminate the translation. 1229 Return t if we can terminate the translation.
1077 Return nil if the current key sequence may be followed by more keys. 1230 Return nil if the current key sequence may be followed by more keys.
1080 sequence counting from the head." 1233 sequence counting from the head."
1081 (let* ((len (length quail-current-key)) 1234 (let* ((len (length quail-current-key))
1082 (map (quail-lookup-key quail-current-key len)) 1235 (map (quail-lookup-key quail-current-key len))
1083 def ch) 1236 def ch)
1084 (if map 1237 (if map
1085 (let ((def (car map))) 1238 (let ((def (quail-map-definition map)))
1086 (if (and (consp def) (not (vectorp (cdr def)))) 1239 (setq quail-current-str (quail-get-current-str len def))
1087 (setq def (car def)))
1088 (setq quail-current-str
1089 (if (consp def) (aref (cdr def) (car def)) def))
1090 ;; Return t only if we can terminate the current translation. 1240 ;; Return t only if we can terminate the current translation.
1091 (and 1241 (and
1092 ;; No alternative translations. 1242 ;; No alternative translations.
1093 (or (null (consp def)) (= (length (cdr def)) 1)) 1243 (or (null (consp def)) (= (length (cdr def)) 1))
1094 ;; No translation for the longer key. 1244 ;; No translation for the longer key.
1103 ;; There's no translation for the current key sequence. Before 1253 ;; There's no translation for the current key sequence. Before
1104 ;; giving up, we must check two possibilities. 1254 ;; giving up, we must check two possibilities.
1105 (cond ((and 1255 (cond ((and
1106 (quail-maximum-shortest) 1256 (quail-maximum-shortest)
1107 (>= len 4) 1257 (>= len 4)
1108 (setq def (car (quail-lookup-key quail-current-key (- len 2)))) 1258 (setq def (quail-map-definition
1109 (if (and (consp def) (not (vectorp (cdr def)))) 1259 (quail-lookup-key quail-current-key (- len 2))))
1110 (setq def (car def)))
1111 (quail-lookup-key (substring quail-current-key -2) 2)) 1260 (quail-lookup-key (substring quail-current-key -2) 2))
1112 ;; Now the sequence is "...ABCD", which can be split into 1261 ;; Now the sequence is "...ABCD", which can be split into
1113 ;; "...AB" and "CD..." to get valid translation. 1262 ;; "...AB" and "CD..." to get valid translation.
1114 ;; At first, get translation of "...AB". 1263 ;; At first, get translation of "...AB".
1115 (setq quail-current-str 1264 (setq quail-current-str (quail-get-current-str (- len 2) def))
1116 (if (consp def) (aref (cdr def) (car def)) def))
1117 ;; Then, return the length of "...AB". 1265 ;; Then, return the length of "...AB".
1118 (- len 2)) 1266 (- len 2))
1119 1267
1120 ((and quail-current-translations 1268 ((and (> len 0)
1269 (quail-lookup-key (substring quail-current-key 0 -1))
1270 quail-current-translations
1121 (not (quail-deterministic)) 1271 (not (quail-deterministic))
1122 (setq ch (aref quail-current-key (1- len))) 1272 (setq ch (aref quail-current-key (1- len)))
1123 (>= ch ?0) (<= ch ?9)) 1273 (>= ch ?0) (<= ch ?9))
1124 ;; A numeric key is entered to select a desirable translation. 1274 ;; A numeric key is entered to select a desirable translation.
1125 (setq quail-current-key (substring quail-current-key 0 -1)) 1275 (setq quail-current-key (substring quail-current-key 0 -1))
1126 (quail-select-translation 1276 ;; We treat key 1,2..,9,0 as specifying 0,1,..8,9.
1127 (+ (* (/ (car quail-current-translations) 10) 10) 1277 (setq ch (if (= ch ?0) 9 (- ch ?1)))
1128 ;; We treat key 1,2..,9,0 as specifying 0,1,..8,9. 1278 (quail-update-current-translations ch)
1129 (if (= ch ?0) 9 (- ch ?1))))
1130 ;; And, we can terminate the current translation. 1279 ;; And, we can terminate the current translation.
1131 t) 1280 t)
1132 1281
1133 (t 1282 (t
1134 ;; No way to handle the last character in this context. 1283 ;; No way to handle the last character in this context.
1136 1285
1137 (defun quail-next-translation () 1286 (defun quail-next-translation ()
1138 "Select next translation in the current batch of candidates." 1287 "Select next translation in the current batch of candidates."
1139 (interactive) 1288 (interactive)
1140 (if quail-current-translations 1289 (if quail-current-translations
1141 (progn 1290 (let ((indices (car quail-current-translations)))
1142 (quail-select-translation (1+ (car quail-current-translations))) 1291 (if (= (1+ (car indices)) (length (cdr quail-current-translations)))
1143 (quail-update-translation nil)) 1292 ;; We are already at the tail.
1144 (beep))) 1293 (beep)
1294 (setcar indices (1+ (car indices)))
1295 (quail-update-current-translations)
1296 (quail-update-translation nil)))
1297 (quail-execute-non-quail-command)))
1145 1298
1146 (defun quail-prev-translation () 1299 (defun quail-prev-translation ()
1147 "Select previous translation in the current batch of candidates." 1300 "Select previous translation in the current batch of candidates."
1148 (interactive) 1301 (interactive)
1149 (if quail-current-translations 1302 (if quail-current-translations
1150 (progn 1303 (let ((indices (car quail-current-translations)))
1151 (quail-select-translation (1- (car quail-current-translations))) 1304 (if (= (car indices) 0)
1152 (quail-update-translation nil)) 1305 ;; We are already at the head.
1153 (beep))) 1306 (beep)
1307 (setcar indices (1- (car indices)))
1308 (quail-update-current-translations)
1309 (quail-update-translation nil)))
1310 (quail-execute-non-quail-command)))
1154 1311
1155 (defun quail-next-translation-block () 1312 (defun quail-next-translation-block ()
1156 "Select the next batch of 10 translation candidates." 1313 "Select from the next block of translations."
1157 (interactive) 1314 (interactive)
1158 (if quail-current-translations 1315 (if quail-current-translations
1159 (let ((limit (1- (length (cdr quail-current-translations)))) 1316 (let* ((indices (car quail-current-translations))
1160 (n (car quail-current-translations))) 1317 (offset (- (car indices) (nth 1 indices))))
1161 (if (< (/ n 10) (/ limit 10)) 1318 (if (>= (nth 2 indices) (length (cdr quail-current-translations)))
1162 (progn 1319 ;; We are already at the last block.
1163 (quail-select-translation (min (+ n 10) limit)) 1320 (beep)
1164 (quail-update-translation nil)) 1321 (setcar indices (+ (nth 2 indices) offset))
1165 ;; We are already at the last block. 1322 (quail-update-current-translations)
1166 (beep))) 1323 (quail-update-translation nil)))
1167 (beep))) 1324 (quail-execute-non-quail-command)))
1168 1325
1169 (defun quail-prev-translation-block () 1326 (defun quail-prev-translation-block ()
1170 "Select the previous batch of 10 translation candidates." 1327 "Select the previous batch of 10 translation candidates."
1171 (interactive) 1328 (interactive)
1172 (if (and quail-current-translations 1329 (if quail-current-translations
1173 (>= (car quail-current-translations) 10)) 1330 (let* ((indices (car quail-current-translations))
1174 (progn 1331 (offset (- (car indices) (nth 1 indices))))
1175 (quail-select-translation (- (car quail-current-translations) 10)) 1332 (if (= (nth 1 indices) 0)
1176 (quail-update-translation nil)) 1333 ;; We are already at the first block.
1177 (beep))) 1334 (beep)
1178 1335 (setcar indices (1- (nth 1 indices)))
1179 (defun quail-select-translation (n) 1336 (quail-update-current-translations)
1180 "Select Nth translation in the current batch of translation candidates." 1337 (if (< (+ (nth 1 indices) offset) (nth 2 indices))
1181 (if (or (< n 0) (>= n (length (cdr quail-current-translations)))) 1338 (progn
1182 (beep) 1339 (setcar indices (+ (nth 1 indices) offset))
1183 (setcar quail-current-translations n) 1340 (quail-update-current-translations)))
1184 (setq quail-current-str (aref (cdr quail-current-translations) n)))) 1341 (quail-update-translation nil)))
1342 (quail-execute-non-quail-command)))
1185 1343
1186 (defun quail-abort-translation () 1344 (defun quail-abort-translation ()
1187 "Abort translation and delete the current Quail key sequence." 1345 "Abort translation and delete the current Quail key sequence."
1188 (interactive) 1346 (interactive)
1189 (quail-delete-region) 1347 (quail-delete-region)
1222 (defun quail-conversion-delete-char () 1380 (defun quail-conversion-delete-char ()
1223 (interactive) 1381 (interactive)
1224 (if (>= (point) (overlay-end quail-conv-overlay)) 1382 (if (>= (point) (overlay-end quail-conv-overlay))
1225 (error "End of conversion region")) 1383 (error "End of conversion region"))
1226 (delete-char 1) 1384 (delete-char 1)
1227 (if (= (overlay-start quail-conv-overlay) 1385 (when (= (overlay-start quail-conv-overlay)
1228 (overlay-end quail-conv-overlay)) 1386 (overlay-end quail-conv-overlay))
1229 (throw 'quail-tag nil))) 1387 (quail-delete-overlays)
1388 (setq overriding-terminal-local-map nil)))
1230 1389
1231 (defun quail-conversion-backward-delete-char () 1390 (defun quail-conversion-backward-delete-char ()
1232 (interactive) 1391 (interactive)
1233 (if (<= (point) (overlay-start quail-conv-overlay)) 1392 (if (<= (point) (overlay-start quail-conv-overlay))
1234 (error "Beginning of conversion region")) 1393 (error "Beginning of conversion region"))
1235 (delete-char -1) 1394 (delete-char -1)
1236 (if (= (overlay-start quail-conv-overlay) 1395 (when (= (overlay-start quail-conv-overlay)
1237 (overlay-end quail-conv-overlay)) 1396 (overlay-end quail-conv-overlay))
1238 (throw 'quail-tag nil))) 1397 (quail-delete-overlays)
1398 (setq overriding-terminal-local-map nil)))
1239 1399
1240 (defun quail-do-conversion (func &rest args) 1400 (defun quail-do-conversion (func &rest args)
1241 "Call FUNC to convert text in the current conversion region of Quail. 1401 "Call FUNC to convert text in the current conversion region of Quail.
1242 Remaining args are for FUNC." 1402 Remaining args are for FUNC."
1243 (delete-overlay quail-overlay) 1403 (delete-overlay quail-overlay)
1244 (apply func args)) 1404 (apply func args))
1245 1405
1246 (defun quail-no-conversion () 1406 (defun quail-no-conversion ()
1247 "Do no conversion of the current conversion region of Quail." 1407 "Do no conversion of the current conversion region of Quail."
1248 (interactive) 1408 (interactive)
1249 (throw 'exit nil)) 1409 (quail-delete-overlays)
1410 (setq overriding-terminal-local-map nil)
1411 (run-hooks 'input-method-after-insert-chunk-hook))
1250 1412
1251 ;; Guidance, Completion, and Help buffer handlers. 1413 ;; Guidance, Completion, and Help buffer handlers.
1252 1414
1415 ;; Make a new one-line frame for Quail guidance buffer.
1416 (defun quail-make-guidance-frame (buf)
1417 (let* ((fparam (frame-parameters))
1418 (top (cdr (assq 'top fparam)))
1419 (border (cdr (assq 'border-width fparam)))
1420 (internal-border (cdr (assq 'internal-border-width fparam)))
1421 (newtop (- top
1422 (frame-char-height) (* internal-border 2) (* border 2))))
1423 (if (< newtop 0)
1424 (setq newtop (+ top (frame-pixel-height))))
1425 (let* ((frame (make-frame (append '((user-position . t) (height . 1)
1426 (minibuffer) (menu-bar-lines . 0))
1427 (cons (cons 'top newtop) fparam))))
1428 (win (frame-first-window frame)))
1429 (set-window-buffer win buf)
1430 ;;(set-window-dedicated-p win t)
1431 )))
1432
1433 ;; Setup Quail completion buffer.
1434 (defun quail-setup-completion-buf ()
1435 (unless (buffer-live-p quail-completion-buf)
1436 (setq quail-completion-buf (get-buffer-create "*Quail Completions*"))
1437 (save-excursion
1438 (set-buffer quail-completion-buf)
1439 (setq quail-overlay (make-overlay 1 1))
1440 (overlay-put quail-overlay 'face 'highlight))))
1441
1442 ;; Return t iff the current Quail package requires showing guidance
1443 ;; buffer.
1444 (defun quail-require-guidance-buf ()
1445 (and input-method-verbose-flag
1446 (not (and (eq (selected-window) (minibuffer-window))
1447 (quail-simple)))))
1448
1253 (defun quail-show-guidance-buf () 1449 (defun quail-show-guidance-buf ()
1254 "Display a Quail guidance buffer in some window. 1450 "Display a guidance buffer for Quail input method in some window.
1255 Create the buffer if it does not exist yet. 1451 Create the buffer if it does not exist yet.
1256 The window is normally shown in a minibuffer, 1452 The buffer is normally displayed at the echo area,
1257 but if the selected window is a minibuffer, it is shown in 1453 but if the current buffer is a minibuffer, it is shown in
1258 the bottommost ordinary window." 1454 the bottom-most ordinary window of the same frame,
1259 1455 or in a newly created frame (if the selected frame has no other windows)."
1260 (if (or (null input-method-tersely-flag) 1456 (when (quail-require-guidance-buf)
1261 (not (eq (selected-window) (minibuffer-window)))) 1457 ;; At first, setup a guidance buffer.
1262 (progn 1458 (or (buffer-live-p quail-guidance-buf)
1263 ;; At first, setup a guidance buffer. 1459 (setq quail-guidance-buf (generate-new-buffer " *Quail-guidance*")))
1264 (or (buffer-live-p quail-guidance-buf) 1460 (let ((title (quail-title)))
1265 (setq quail-guidance-buf 1461 (save-excursion
1266 (get-buffer-create " *Quail-guidance*"))) 1462 (set-buffer quail-guidance-buf)
1267 (save-excursion 1463 ;; To show the title of Quail package.
1268 (let ((title (quail-title))) 1464 (setq current-input-method t
1269 (set-buffer quail-guidance-buf) 1465 current-input-method-title title)
1270 ;; Show the title of Quail package in the left of mode-line. 1466 (erase-buffer)
1271 (setq current-input-method nil) 1467 (or (overlayp quail-overlay)
1272 (setq current-input-method-title title) 1468 (progn
1273 (setq mode-line-format (cons '("[" current-input-method-title "]") 1469 (setq quail-overlay (make-overlay 1 1))
1274 default-mode-line-format)) 1470 (overlay-put quail-overlay 'face 'highlight)))
1275 (erase-buffer) 1471 (delete-overlay quail-overlay)
1276 (or (overlayp quail-overlay) 1472 (set-buffer-modified-p nil)))
1277 (progn 1473 (bury-buffer quail-guidance-buf)
1278 (setq quail-overlay (make-overlay 1 1)) 1474
1279 (overlay-put quail-overlay 'face 'highlight))) 1475 ;; Then, display it in an appropriate window.
1280 (delete-overlay quail-overlay) 1476 (let ((win (minibuffer-window)))
1281 (set-buffer-modified-p nil))) 1477 (if (eq (selected-window) win)
1282 (bury-buffer quail-guidance-buf) 1478 ;; Since we are in minibuffer, we can't use it for guidance.
1283 1479 (if (eq win (frame-root-window))
1284 ;; Then, display it in an appropriate window. 1480 ;; Create a frame. It is sure that we are using some
1285 (if (not (get-buffer-window quail-guidance-buf)) 1481 ;; window system.
1286 ;; Guidance buffer is not yet shown in any window. 1482 (quail-make-guidance-frame quail-guidance-buf)
1287 (let ((win (minibuffer-window))) 1483 ;; Find the bottom window and split it if necessary.
1288 (if (eq (selected-window) win) 1484 (let (height)
1289 ;; Since we are in minibuffer, we can't use it for guidance. 1485 (setq win (window-at 0 (- (frame-height) 2)))
1290 ;; Let's find the bottom window. 1486 (setq height (window-height win))
1291 (let (height) 1487 ;; If WIN is tall enough, split it vertically and use
1292 (setq win (window-at 0 (- (frame-height) 2))) 1488 ;; the lower one.
1293 (setq height (window-height win)) 1489 (if (>= height 4)
1294 ;; If WIN is too tall, split it vertically and use 1490 (let ((window-min-height 2))
1295 ;; the lower one. 1491 ;; Here, `split-window' returns a lower window
1296 (if (>= height 4) 1492 ;; which is what we wanted.
1297 (let ((window-min-height 2)) 1493 (setq win (split-window win (- height 2)))))
1298 ;; Here, `split-window' returns a lower window 1494 (set-window-buffer win quail-guidance-buf)
1299 ;; which is what we wanted. 1495 ;;(set-window-dedicated-p win t)
1300 (setq win (split-window win (- height 2))))) 1496 ))
1301 (set-window-buffer win quail-guidance-buf) 1497 (set-window-buffer win quail-guidance-buf))
1302 (set-window-dedicated-p win t)) 1498 (setq quail-guidance-win win)))
1303 (set-window-buffer win quail-guidance-buf))))))
1304 1499
1305 ;; And, create a buffer for completion. 1500 ;; And, create a buffer for completion.
1306 (or (buffer-live-p quail-completion-buf) 1501 (quail-setup-completion-buf)
1307 (progn
1308 (setq quail-completion-buf (get-buffer-create "*Quail Completions*"))
1309 (save-excursion
1310 (set-buffer quail-completion-buf)
1311 (setq quail-overlay (make-overlay 1 1))
1312 (overlay-put quail-overlay 'face 'highlight))))
1313 (bury-buffer quail-completion-buf)) 1502 (bury-buffer quail-completion-buf))
1314 1503
1315 (defun quail-hide-guidance-buf () 1504 (defun quail-hide-guidance-buf ()
1316 "Hide the Quail guidance buffer." 1505 "Hide the Quail guidance buffer."
1317 (let* ((win (minibuffer-window)) 1506 (if (buffer-live-p quail-guidance-buf)
1318 (buf (window-buffer win))) 1507 (let ((win-list (get-buffer-window-list quail-guidance-buf t t))
1319 (if (eq buf quail-guidance-buf) 1508 win)
1320 ;; Quail guidance buffer is at echo area. Vacate it to the 1509 (while win-list
1321 ;; deepest minibuffer. 1510 (setq win (car win-list) win-list (cdr win-list))
1322 (set-window-buffer win (format " *Minibuf-%d*" (minibuffer-depth))) 1511 (if (eq win (minibuffer-window))
1323 ;; Delete the window for guidance buffer. 1512 ;; We are using echo area for the guidance buffer.
1324 (if (or (null input-method-tersely-flag) 1513 ;; Vacate it to the deepest minibuffer.
1325 (not (eq (selected-window) (minibuffer-window)))) 1514 (set-window-buffer win
1326 (progn 1515 (format " *Minibuf-%d*" (minibuffer-depth)))
1327 (setq win (get-buffer-window quail-guidance-buf)) 1516 (if (eq win (frame-root-window (window-frame win)))
1328 (set-window-dedicated-p win nil) 1517 (progn
1329 (delete-window win)))))) 1518 ;; We are using a separate frame for guidance buffer.
1519 ;;(set-window-dedicated-p win nil)
1520 (delete-frame (window-frame win)))
1521 ;;(set-window-dedicated-p win nil)
1522 (delete-window win)))))))
1330 1523
1331 (defun quail-update-guidance () 1524 (defun quail-update-guidance ()
1332 "Update the Quail guidance buffer and completion buffer (if displayed now)." 1525 "Update the Quail guidance buffer and completion buffer (if displayed now)."
1333 ;; Update guidance buffer. 1526 ;; Update guidance buffer.
1334 (if (or (null input-method-tersely-flag) 1527 (if (quail-require-guidance-buf)
1335 (not (eq (selected-window) (minibuffer-window))))
1336 (let ((guidance (quail-guidance))) 1528 (let ((guidance (quail-guidance)))
1337 (cond ((eq guidance t) 1529 (cond ((or (eq guidance t)
1530 (listp guidance))
1338 ;; Show the current possible translations. 1531 ;; Show the current possible translations.
1339 (quail-show-translations)) 1532 (quail-show-translations))
1340 ((null guidance) 1533 ((null guidance)
1341 ;; Show the current input keys. 1534 ;; Show the current input keys.
1342 (let ((key quail-current-key)) 1535 (let ((key quail-current-key))
1343 (save-excursion 1536 (save-excursion
1344 (set-buffer quail-guidance-buf) 1537 (set-buffer quail-guidance-buf)
1345 (erase-buffer) 1538 (erase-buffer)
1346 (insert key)))) 1539 (insert key)))))))
1347 ((listp guidance)
1348 ;; Show alternative characters specified in this alist.
1349 (let* ((key quail-current-key)
1350 (len (length key))
1351 (i 0)
1352 ch alternative)
1353 (save-excursion
1354 (set-buffer quail-guidance-buf)
1355 (erase-buffer)
1356 (while (< i len)
1357 (setq ch (aref key i))
1358 (setq alternative (cdr (assoc ch guidance)))
1359 (insert (or alternative ch))
1360 (setq i (1+ i)))))))))
1361 1540
1362 ;; Update completion buffer if displayed now. We highlight the 1541 ;; Update completion buffer if displayed now. We highlight the
1363 ;; selected candidate string in *Completion* buffer if any. 1542 ;; selected candidate string in *Completion* buffer if any.
1364 (let ((win (get-buffer-window quail-completion-buf)) 1543 (let ((win (get-buffer-window quail-completion-buf))
1365 key str pos) 1544 key str pos)
1366 (if win 1545 (if win
1367 (save-excursion 1546 (save-excursion
1368 (setq str (if (stringp quail-current-str) 1547 (setq str (if (stringp quail-current-str)
1369 quail-current-str 1548 quail-current-str
1370 (if (numberp quail-current-str) 1549 (if (characterp quail-current-str)
1371 (char-to-string quail-current-str))) 1550 (char-to-string quail-current-str)))
1372 key quail-current-key) 1551 key quail-current-key)
1373 (set-buffer quail-completion-buf) 1552 (set-buffer quail-completion-buf)
1374 (goto-char (point-min)) 1553 (goto-char (point-min))
1375 (if (null (search-forward (concat " " key ":") nil t)) 1554 (if (null (search-forward (concat " " key ":") nil t))
1392 )))))) 1571 ))))))
1393 1572
1394 (defun quail-show-translations () 1573 (defun quail-show-translations ()
1395 "Show the current possible translations." 1574 "Show the current possible translations."
1396 (let* ((key quail-current-key) 1575 (let* ((key quail-current-key)
1397 (map (quail-lookup-key quail-current-key (length quail-current-key))) 1576 (map (quail-lookup-key quail-current-key)))
1398 (def (car map))) 1577 (if quail-current-translations
1399 (if (and (consp def) (not (vectorp (cdr def)))) 1578 (quail-update-current-translations))
1400 (setq def (car def)))
1401 (save-excursion 1579 (save-excursion
1402 (set-buffer quail-guidance-buf) 1580 (set-buffer quail-guidance-buf)
1403 (erase-buffer) 1581 (erase-buffer)
1404 1582
1405 ;; Show the current key. 1583 ;; Show the current key.
1406 (insert key) 1584 (let ((guidance (quail-guidance)))
1407 1585 (if (listp guidance)
1408 ;; Show possible following keys. 1586 ;; We must show the specified PROMPTKEY instead of the
1587 ;; actual typed keys.
1588 (let ((i 0)
1589 (len (length key))
1590 prompt-key)
1591 (while (< i len)
1592 (setq prompt-key (cdr (assoc (aref key i) guidance)))
1593 (insert (or prompt-key (aref key i)))
1594 (setq i (1+ i))))
1595 (insert key)))
1596
1597 ;; Show followable keys.
1409 (if (cdr map) 1598 (if (cdr map)
1410 (let ((l (cdr map))) 1599 (let ((l (cdr map)))
1411 (insert "[") 1600 (insert "[")
1412 (while l 1601 (while l
1413 (insert (car (car l))) 1602 (insert (car (car l)))
1414 (setq l (cdr l))) 1603 (setq l (cdr l)))
1415 (insert "]"))) 1604 (insert "]")))
1416 1605
1417 ;; Show list of translations. 1606 ;; Show list of translations.
1418 (if (and (not (quail-deterministic)) (consp def)) 1607 (if quail-current-translations
1419 (let* ((idx (car def)) 1608 (let* ((indices (car quail-current-translations))
1420 (translations (cdr def)) 1609 (cur (car indices))
1421 (from (* (/ idx 10) 10)) 1610 (start (nth 1 indices))
1422 (to (min (+ from 10) (length translations)))) 1611 (end (nth 2 indices))
1423 (indent-to 10) 1612 (idx start))
1424 (insert (format "(%d/%d)" 1613 (indent-to (- quail-guidance-translations-starting-column 7))
1425 (1+ (/ from 10)) 1614 (insert (format "(%02d/"(nth 3 indices))
1426 (1+ (/ (length translations) 10)))) 1615 (if (nth 4 indices)
1427 (while (< from to) 1616 (format "%02d)" (nth 4 indices))
1428 ;; We show the last digit of FROM, but by changing 1617 "??)"))
1429 ;; 0,1,..,9 to 1,2,..,0. 1618 (while (< idx end)
1430 (insert (format " %d." 1619 (insert (format " %d." (if (= (- idx start) 9) 0
1431 (if (= (% from 10) 9) 0 (1+ (% from 10))))) 1620 (1+ (- idx start)))))
1432 (let ((pos (point))) 1621 (let ((pos (point)))
1433 (insert (aref translations from)) 1622 (insert (aref (cdr quail-current-translations) idx))
1434 (if (= idx from) 1623 (if (= idx cur)
1435 (move-overlay quail-overlay pos (point)))) 1624 (move-overlay quail-overlay pos (point))))
1436 (setq from (1+ from))))) 1625 (setq idx (1+ idx)))))
1437 ))) 1626 )))
1438 1627
1439 (defun quail-completion () 1628 (defun quail-completion ()
1440 "List all completions for the current key. 1629 "List all completions for the current key.
1441 All possible translations of the current key and whole possible longer keys 1630 All possible translations of the current key and whole possible longer keys
1442 are shown." 1631 are shown."
1443 (interactive) 1632 (interactive)
1633 (quail-setup-completion-buf)
1444 (let ((key quail-current-key) 1634 (let ((key quail-current-key)
1445 (map (quail-lookup-key quail-current-key (length quail-current-key)))) 1635 (map (quail-lookup-key quail-current-key)))
1446 (save-excursion 1636 (save-excursion
1447 (set-buffer quail-completion-buf) 1637 (set-buffer quail-completion-buf)
1448 (erase-buffer) 1638 (erase-buffer)
1449 (insert "Possible completion and corresponding translations are:\n") 1639 (insert "Possible completion and corresponding translations are:\n")
1450 (quail-completion-1 key map 1) 1640 (quail-completion-1 key map 1)
1486 ;; We need only vector part. 1676 ;; We need only vector part.
1487 (setq translations (cdr translations)) 1677 (setq translations (cdr translations))
1488 ;; Insert every 10 elements with indices in a line. 1678 ;; Insert every 10 elements with indices in a line.
1489 (let ((len (length translations)) 1679 (let ((len (length translations))
1490 (i 0) 1680 (i 0)
1491 (first t)
1492 num) 1681 num)
1493 (while (< i len) 1682 (while (< i len)
1494 (if first 1683 (when (zerop (% i 10))
1495 (progn 1684 (when (>= i 10)
1496 (insert "(1/1)") 1685 (newline)
1497 (setq first nil)) 1686 (indent-to indent))
1498 (if (= (% i 10) 0) 1687 (insert (format "(%d/%d)" (1+ (/ i 10)) (1+ (/ len 10)))))
1499 (progn
1500 (newline)
1501 (indent-to indent)
1502 (insert (format "(%d/%d)" (1+ (/ i 10)) (1+ (/ len 10)))))))
1503 ;; We show the last digit of FROM while converting 1688 ;; We show the last digit of FROM while converting
1504 ;; 0,1,..,9 to 1,2,..,0. 1689 ;; 0,1,..,9 to 1,2,..,0.
1505 (insert (format " %d." (if (= (% i 10) 9) 0 (1+ (% i 10))))) 1690 (insert (format " %d." (% (1+ i) 10)))
1506 (insert (aref translations i)) 1691 (insert (aref translations i))
1507 (setq i (1+ i))) 1692 (setq i (1+ i)))
1508 (newline))))) 1693 (newline)))))
1509 1694
1510 (defun quail-help () 1695 (defun quail-help ()
1511 "Show brief description of the current Quail package." 1696 "Show brief description of the current Quail package."
1512 (interactive) 1697 (interactive)
1513 (let ((package quail-current-package) 1698 (let ((package quail-current-package))
1514 (buf (get-buffer-create "*Quail-help*"))) 1699 (with-output-to-temp-buffer "*Quail-Help*"
1515 (save-excursion 1700 (save-excursion
1516 (set-buffer buf) 1701 (set-buffer standard-output)
1517 (erase-buffer) 1702 (let ((quail-current-package package))
1518 (setq quail-current-package package) 1703 (insert "Quail input method (name:"
1519 (insert "Quail input method (name:" 1704 (quail-name)
1520 (quail-name) 1705 ", mode line indicator:["
1521 ", mode line indicator:[" 1706 (quail-title)
1522 (quail-title) 1707 "])\n---- Documentation ----\n"
1523 "])\n---- Documentation ----\n" 1708 (quail-docstring))
1524 (quail-docstring)) 1709 (newline)
1525 (newline) 1710 (if (quail-show-layout) (quail-show-kbd-layout))
1526 (if (quail-show-layout) (quail-show-kbd-layout)) 1711 (quail-help-insert-keymap-description
1527 (insert ) 1712 quail-mode-map
1528 (quail-help-insert-keymap-description 1713 "---- Key bindings (before starting translation) ----
1529 quail-mode-map
1530 "---- Key bindings (before starting translation) ----
1531 key binding 1714 key binding
1532 --- -------\n") 1715 --- -------\n")
1533 (quail-help-insert-keymap-description 1716 (quail-help-insert-keymap-description
1534 (quail-translation-keymap) 1717 (quail-translation-keymap)
1535 "--- Key bindings (while translating) --- 1718 "--- Key bindings (while translating) ---
1536 key binding 1719 key binding
1537 --- -------\n") 1720 --- -------\n")
1538 (if (quail-conversion-keymap) 1721 (if (quail-conversion-keymap)
1539 (quail-help-insert-keymap-description 1722 (quail-help-insert-keymap-description
1540 (quail-conversion-keymap) 1723 (quail-conversion-keymap)
1541 "--- Key bindings (while converting) --- 1724 "--- Key bindings (while converting) ---
1542 key binding 1725 key binding
1543 --- -------\n")) 1726 --- -------\n"))
1544 (goto-char (point-min)) 1727 (help-mode))))))
1545 (set-buffer-modified-p nil)
1546 (help-mode))
1547 (display-buffer buf)))
1548 1728
1549 (defun quail-help-insert-keymap-description (keymap &optional header) 1729 (defun quail-help-insert-keymap-description (keymap &optional header)
1550 (let (from to) 1730 (let (from to)
1551 (if header 1731 (if header
1552 (insert header)) 1732 (insert header))
1553 (save-excursion 1733 (save-excursion
1554 (save-window-excursion 1734 (save-window-excursion
1555 (let ((overriding-local-map keymap)) 1735 (let ((overriding-terminal-local-map keymap))
1556 (describe-bindings)) 1736 (describe-bindings))
1557 (set-buffer "*Help*") 1737 (set-buffer "*Help*")
1558 (goto-char (point-min)) 1738 (goto-char (point-min))
1559 (forward-line 4) 1739 (forward-line 4)
1560 (setq from (point)) 1740 (setq from (point))
1573 (newline) 1753 (newline)
1574 (indent-to (/ i 30))) 1754 (indent-to (/ i 30)))
1575 (if (= (% i 2) 0) 1755 (if (= (% i 2) 0)
1576 (insert " "))) 1756 (insert " ")))
1577 (setq ch (aref quail-keyboard-layout i)) 1757 (setq ch (aref quail-keyboard-layout i))
1578 (if (= ch ?\ ) 1758 (when (and (quail-kbd-translate)
1579 (insert ch) 1759 (/= ch ?\ ))
1580 (let* ((map (cdr (assq ch (cdr (quail-map))))) 1760 ;; This is the case that the current input method simulates
1581 (translation (and map (quail-get-translation 1761 ;; some keyboard layout (which means it requires keyboard
1582 (car map) (char-to-string ch) 1)))) 1762 ;; translation) and a key at location `i' exists on users
1583 (if (integerp translation) 1763 ;; keyboard. We must translate that key by
1584 (insert translation) 1764 ;; `quail-keyboard-layout-standard'. But if if there's no
1585 (if (consp translation) 1765 ;; corresponding key in that standard layout, we must simulate
1586 (insert (aref (cdr translation) (car translation))) 1766 ;; what is inserted if that key is pressed by setting CH a
1587 (insert ch))))) 1767 ;; minus value.
1768 (setq ch (aref quail-keyboard-layout-standard i))
1769 (if (= ch ?\ )
1770 (setq ch (- (aref quail-keyboard-layout i)))))
1771 (if (< ch 0)
1772 (let ((last-command-event (character-to-event (- ch))))
1773 (self-insert-command 1))
1774 (if (= ch ?\ )
1775 (insert ch)
1776 (let* ((map (cdr (assq ch (cdr (quail-map)))))
1777 (translation (and map (quail-get-translation
1778 (car map) (char-to-string ch) 1))))
1779 (if (characterp translation)
1780 (insert translation)
1781 (if (consp translation)
1782 (insert (aref (cdr translation) (car translation)))
1783 (let ((last-command-event (character-to-event ch)))
1784 (self-insert-command 1)))))))
1588 (setq i (1+ i)))) 1785 (setq i (1+ i))))
1589 (newline)) 1786 (newline))
1590 1787
1591 (defun quail-translation-help () 1788 (defun quail-translation-help ()
1592 "Show help message while translating in Quail mode." 1789 "Show help message while translating in Quail mode."
1593 (interactive) 1790 (interactive)
1594 (let ((package quail-current-package) 1791 (let ((package quail-current-package)
1595 (current-key quail-current-key) 1792 (current-key quail-current-key))
1596 (buf (get-buffer-create "*Quail-Help*"))) 1793 (with-output-to-temp-buffer "*Quail-Help*"
1597 (save-excursion 1794 (save-excursion
1598 (set-buffer buf) 1795 (set-buffer standard-output)
1599 (erase-buffer) 1796 (let ((quail-current-package package))
1600 (setq quail-current-package package) 1797 (princ "You are translating the key sequence ")
1601 (insert 1798 (prin1 quail-current-key)
1602 (format "You are translating the key sequence \"%s\" in Quail mode.\n" 1799 (princ" in Quail mode.\n")
1603 quail-current-key)) 1800 (quail-help-insert-keymap-description
1604 (quail-help-insert-keymap-description 1801 (quail-translation-keymap)
1605 (quail-translation-keymap) 1802 "-----------------------
1606 "-----------------------
1607 key binding 1803 key binding
1608 --- -------\n") 1804 --- -------\n"))
1609 (goto-char (point-min)) 1805 (help-mode)))))
1610 (set-buffer-modified-p nil)) 1806
1611 (display-buffer buf)))
1612
1613 (defun quail-conversion-help () 1807 (defun quail-conversion-help ()
1614 "Show help message while converting in Quail mode." 1808 "Show help message while converting in Quail mode."
1615 (interactive) 1809 (interactive)
1616 (let ((package quail-current-package) 1810 (let ((package quail-current-package)
1617 (str (buffer-substring (overlay-start quail-conv-overlay) 1811 (str (buffer-substring (overlay-start quail-conv-overlay)
1618 (overlay-end quail-conv-overlay))) 1812 (overlay-end quail-conv-overlay))))
1619 (buf (get-buffer-create "*Quail-Help*"))) 1813 (with-output-to-temp-buffer "*Quail-Help*"
1814 (save-excursion
1815 (set-buffer standard-output)
1816 (let ((quail-current-package package))
1817 (princ "You are converting the string ")
1818 (prin1 str)
1819 (princ " in Quail mode.\n")
1820 (quail-help-insert-keymap-description
1821 (quail-conversion-keymap)
1822 "-----------------------
1823 key binding
1824 --- -------\n"))
1825 (help-mode)))))
1826
1827
1828 (defvar quail-directory-name "quail"
1829 "Name of Quail directory which cotains Quail packages.
1830 This is a sub-directory of LEIM directory.")
1831
1832 ;;;###autoload
1833 (defun quail-update-leim-list-file (dirname &rest dirnames)
1834 "Update entries for Quail packages in `LEIM' list file in directory DIRNAME.
1835 DIRNAME is a directory containing Emacs input methods;
1836 normally, it should specify the `leim' subdirectory
1837 of the Emacs source tree.
1838
1839 It searches for Quail packages under `quail' subdirectory of DIRNAME,
1840 and update the file \"leim-list.el\" in DIRNAME.
1841
1842 When called from a program, the remaining arguments are additional
1843 directory names to search for Quail packages under `quail' subdirectory
1844 of each directory."
1845 (interactive "FDirectory of LEIM: ")
1846 (setq dirname (expand-file-name dirname))
1847 (let ((leim-list (expand-file-name leim-list-file-name dirname))
1848 quail-dirs list-buf pkg-list pkg-buf pos)
1849 (if (not (file-writable-p leim-list))
1850 (error "Can't write to file \"%s\"" leim-list))
1851 (message "Updating %s ..." leim-list)
1852 (setq list-buf (find-file-noselect leim-list))
1853
1854 ;; At first, clean up the file.
1620 (save-excursion 1855 (save-excursion
1621 (set-buffer buf) 1856 (set-buffer list-buf)
1622 (erase-buffer) 1857 (goto-char 1)
1623 (setq quail-current-package package) 1858
1624 (insert 1859 ;; Insert the correct header.
1625 (format "You are converting the string \"%s\" in Quail mode.\n" str)) 1860 (if (looking-at (regexp-quote leim-list-header))
1626 (quail-help-insert-keymap-description 1861 (goto-char (match-end 0))
1627 (quail-conversion-keymap) 1862 (insert leim-list-header))
1628 "----------------------- 1863 (setq pos (point))
1629 key binding 1864 (if (not (re-search-forward leim-list-entry-regexp nil t))
1630 --- -------\n") 1865 nil
1631 (goto-char (point-min)) 1866
1632 (set-buffer-modified-p nil)) 1867 ;; Remove garbages after the header.
1633 (display-buffer buf))) 1868 (goto-char (match-beginning 0))
1634 1869 (if (< pos (point))
1870 (delete-region pos (point)))
1871
1872 ;; Remove all entries for Quail.
1873 (while (re-search-forward leim-list-entry-regexp nil 'move)
1874 (goto-char (match-beginning 0))
1875 (setq pos (point))
1876 (condition-case nil
1877 (let ((form (read list-buf)))
1878 (when (equal (nth 3 form) ''quail-use-package)
1879 (if (eolp) (forward-line 1))
1880 (delete-region pos (point))))
1881 (error
1882 ;; Delete the remaining contents because it seems that
1883 ;; this file is broken.
1884 (message "Garbages in %s deleted" leim-list)
1885 (delete-region pos (point-max)))))))
1886
1887 ;; Search for `quail' subdirector under each DIRNAMES.
1888 (setq dirnames (cons dirname dirnames))
1889 (let ((l dirnames))
1890 (while l
1891 (setcar l (expand-file-name (car l)))
1892 (setq dirname (expand-file-name quail-directory-name (car l)))
1893 (if (file-readable-p dirname)
1894 (setq quail-dirs (cons dirname quail-dirs))
1895 (message "%s doesn't has `%s' subdirectory, just ignored"
1896 (car l) quail-directory-name)
1897 (setq quail-dirs (cons nil quail-dirs)))
1898 (setq l (cdr l)))
1899 (setq quail-dirs (nreverse quail-dirs)))
1900
1901 ;; Insert input method registering forms.
1902 (while quail-dirs
1903 (setq dirname (car quail-dirs))
1904 (when dirname
1905 (setq pkg-list (directory-files dirname 'full "\\.el$" 'nosort))
1906 (while pkg-list
1907 (message "Checking %s ..." (car pkg-list))
1908 (with-temp-buffer
1909 (insert-file-contents (car pkg-list))
1910 (goto-char (point-min))
1911 (while (search-forward "(quail-define-package" nil t)
1912 (goto-char (match-beginning 0))
1913 (condition-case nil
1914 (let ((form (read (current-buffer))))
1915 (save-excursion
1916 (set-buffer list-buf)
1917 (insert
1918 (format "(register-input-method
1919 %S %S '%s
1920 %S %S
1921 %S)\n"
1922 (nth 1 form) ; PACKAGE-NAME
1923 (nth 2 form) ; LANGUAGE
1924 'quail-use-package ; ACTIVATE-FUNC
1925 (nth 3 form) ; PACKAGE-TITLE
1926 (progn ; PACKAGE-DESCRIPTION (one line)
1927 (string-match ".*" (nth 5 form))
1928 (match-string 0 (nth 5 form)))
1929 (file-relative-name ; PACKAGE-FILENAME
1930 (file-name-sans-extension (car pkg-list))
1931 (car dirnames))))))
1932 (error
1933 ;; Ignore the remaining contents of this file.
1934 (goto-char (point-max))
1935 (message "Some part of \"%s\" is broken" dirname)))))
1936 (setq pkg-list (cdr pkg-list)))
1937 (setq quail-dirs (cdr quail-dirs) dirnames (cdr dirnames))))
1938
1939 ;; At last, write out LEIM list file.
1940 (save-excursion
1941 (set-buffer list-buf)
1942 (setq buffer-file-coding-system 'iso-2022-7bit)
1943 (save-buffer 0))
1944 (kill-buffer list-buf)
1945 (message "Updating %s ... done" leim-list)))
1635 ;; 1946 ;;
1636 (provide 'quail) 1947 (provide 'quail)
1637 1948
1638 ;;; quail.el ends here 1949 ;;; quail.el ends here