Mercurial > hg > xemacs-beta
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 |