Mercurial > emacs
diff lisp/international/quail.el @ 89943:4c90ffeb71c5
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-15
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-218
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-220
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-221
Restore deleted tagline in etc/TUTORIAL.ru
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-222
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-228
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-229
Remove TeX output files from the archive
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-230
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-247
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-248
src/lisp.h (CYCLE_CHECK): Macro moved from xfaces.c
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-249
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-256
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-258
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-263
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-264
Update from CVS: lispref/display.texi: emacs -> Emacs.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-265
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-274
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-275
Update from CVS: man/makefile.w32-in: Revert last change
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-276
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-295
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-296
Allow restarting an existing debugger session that's exited
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-297
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-299
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-300
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-327
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-328
Update from CVS: src/.gdbinit (xsymbol): Fix last change.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-329
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-344
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-345
Tweak source regexps so that building in place won't cause problems
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-346
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-351
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-352
Update from CVS: lisp/flymake.el: New file.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-353
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-361
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-362
Support " [...]" style defaults in minibuffer-electric-default-mode
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-363
(read-number): Use canonical format for default in prompt.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-364
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-367
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-368
Improve display-supports-face-attributes-p on non-ttys
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-369
Rewrite face-differs-from-default-p
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-370
Move `display-supports-face-attributes-p' entirely into C code
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-371
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-372
Simplify face-differs-from-default-p; don't consider :stipple.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-373
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-374
(tty_supports_face_attributes_p): Ensure attributes differ from default
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-375
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-376
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-377
(Fdisplay_supports_face_attributes_p): Work around bootstrapping problem
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-378
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-380
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-381
Face merging cleanups
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-382
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-384
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-385
src/xfaces.c (push_named_merge_point): Return 0 if a cycle is detected
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-386
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-395
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-396
Tweak arch tagging to make build/install-in-place less annoying
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-397
Work around vc-arch problems when building eshell
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-398
Tweak permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-399
Tweak directory permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-400
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-401
More build-in-place tweaking of arch tagging
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-402
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-403
Yet more build-in-place tweaking of arch tagging
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-404
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-409
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-410
Make sure image types are initialized for lookup too
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-411
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-416
Update from CVS
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 28 Jun 2004 07:56:49 +0000 |
parents | 68c22ea6027c 0a72a48de076 |
children | eac554634bfa |
line wrap: on
line diff
--- a/lisp/international/quail.el Sat May 29 02:17:09 2004 +0000 +++ b/lisp/international/quail.el Mon Jun 28 07:56:49 2004 +0000 @@ -1043,9 +1043,13 @@ The installed decode map can be referred by the function `quail-decode-map'." (if (null quail-current-package) (error "No current Quail package")) - (if (not (and (consp decode-map) (eq (car decode-map) 'decode-map))) - (error "Invalid Quail decode map `%s'" decode-map)) - (setcar (nthcdr 10 quail-current-package) decode-map)) + (if (if (consp decode-map) + (eq (car decode-map) 'decode-map) + (if (char-table-p decode-map) + (eq (char-table-subtype decode-map) 'quail-decode-map))) + (setcar (nthcdr 10 quail-current-package) decode-map) + (error "Invalid Quail decode map `%s'" decode-map))) + ;;;###autoload (defun quail-defrule (key translation &optional name append) @@ -1218,7 +1222,7 @@ (t (error "Invalid object in Quail map: %s" def)))) -(defun quail-lookup-key (key &optional len) +(defun quail-lookup-key (key &optional len not-reset-indices) "Lookup KEY of length LEN in the current Quail map and return the definition. The returned value is a Quail map specific to KEY." (or len @@ -1256,7 +1260,7 @@ (if (and (consp translation) (vectorp (cdr translation))) (progn (setq quail-current-translations translation) - (if (quail-forget-last-selection) + (if (and (not not-reset-indices) (quail-forget-last-selection)) (setcar (car quail-current-translations) 0)))))) ;; We may have to reform cdr part of MAP. (if (and (cdr map) (functionp (cdr map))) @@ -1512,6 +1516,28 @@ (let (pos) (quail-delete-region) (setq pos (point)) + (or enable-multibyte-characters + (let (char) + (if (stringp quail-current-str) + (catch 'tag + (mapc #'(lambda (ch) + (when (/= (unibyte-char-to-multibyte + (multibyte-char-to-unibyte ch)) + ch) + (setq char ch) + (throw 'tag nil))) + quail-current-str)) + (if (/= (unibyte-char-to-multibyte + (multibyte-char-to-unibyte quail-current-str)) + quail-current-str) + (setq char quail-current-str))) + (when char + (message "Can't input %c in the current unibyte buffer" char) + (ding) + (sit-for 2) + (message nil) + (setq quail-current-str nil) + (throw 'quail-tag nil)))) (insert quail-current-str) (move-overlay quail-overlay pos (point)) (if (overlayp quail-conv-overlay) @@ -2009,7 +2035,7 @@ (defun quail-get-translations () "Return a string containing the current possible translations." - (let ((map (quail-lookup-key quail-current-key)) + (let ((map (quail-lookup-key quail-current-key nil t)) (str (copy-sequence quail-current-key))) (if quail-current-translations (quail-update-current-translations)) @@ -2080,7 +2106,7 @@ (quail-setup-completion-buf) (let ((win (get-buffer-window quail-completion-buf 'visible)) (key quail-current-key) - (map (quail-lookup-key quail-current-key)) + (map (quail-lookup-key quail-current-key nil t)) (require-update nil)) (with-current-buffer quail-completion-buf (if (and win @@ -2556,6 +2582,143 @@ (quail-update-guidance) )))) +;; Add KEY (string) to the element of TABLE (char-table) for CHAR if +;; it is not yet stored. As a result, the element is a string or a +;; list of strings. + +(defsubst quail-store-decode-map-key (table char key) + (let ((elt (aref table char))) + (if elt + (if (consp elt) + (or (member key elt) + (aset table char (cons key elt))) + (or (string= key elt) + (aset table char (list key elt)))) + (aset table char key)))) + +;; Helper function for quail-gen-decode-map. Store key strings to +;; type each character under MAP in TABLE (char-table). MAP is an +;; element of the current Quail map reached by typing keys in KEY +;; (string). + +(defun quail-gen-decode-map1 (map key table) + (when (and (consp map) (listp (cdr map))) + (let ((trans (car map))) + (cond ((integerp trans) + (quail-store-decode-map-key table trans key)) + ((stringp trans) + (dotimes (i (length trans)) + (quail-store-decode-map-key table (aref trans i) key))) + ((or (vectorp trans) + (and (consp trans) + (setq trans (cdr trans)))) + (dotimes (i (length trans)) + (let ((elt (aref trans i))) + (if (stringp elt) + (if (= (length elt) 1) + (quail-store-decode-map-key table (aref elt 0) key)) + (quail-store-decode-map-key table elt key))))))) + (if (> (length key) 1) + (dolist (elt (cdr map)) + (quail-gen-decode-map1 (cdr elt) key table)) + (dolist (elt (cdr map)) + (quail-gen-decode-map1 (cdr elt) (format "%s%c" key (car elt)) + table))))) + +(put 'quail-decode-map 'char-table-extra-slots 0) + +;; Generate a halfly-cooked decode map (char-table) for the current +;; Quail map. An element for a character C is a key string or a list +;; of a key strings to type to input C. The lenth of key string is at +;; most 2. If it is 2, more keys may be required to input C. + +(defun quail-gen-decode-map () + (let ((table (make-char-table 'quail-decode-map nil))) + (dolist (elt (cdr (quail-map))) + (quail-gen-decode-map1 (cdr elt) (string (car elt)) table)) + table)) + +;; Helper function for quail-find-key. Prepend key strings to type +;; for inputting CHAR by the current input method to KEY-LIST and +;; return the result. MAP is an element of the current Quail map +;; reached by typing keys in KEY. + +(defun quail-find-key1 (map key char key-list) + (let ((trans (car map)) + (found-here nil)) + (cond ((stringp trans) + (setq found-here + (and (= (length trans) 1) (= (aref trans 0) char)))) + ((or (vectorp trans) (consp trans)) + (if (consp trans) + (setq trans (cdr trans))) + (setq found-here + (catch 'tag + (dotimes (i (length trans)) + (let ((target (aref trans i))) + (if (integerp target) + (if (= target char) + (throw 'tag t)) + (if (and (= (length target) 1) + (= (aref target 0) char)) + (throw 'tag t)))))))) + ((integerp trans) + (if (= trans char) + (setq found-here t)))) + (if found-here + (setq key-list (cons key key-list))) + (if (> (length key) 1) + (dolist (elt (cdr map)) + (setq key-list + (quail-find-key1 (cdr elt) (format "%s%c" key (car elt)) + char key-list)))) + key-list)) + +(defun quail-find-key (char) + "Return a list of keys to type to input CHAR in the current input method. +If CHAR is an ASCII character and can be input by typing itself, return t." + (let ((decode-map (or (quail-decode-map) + (setcar (nthcdr 10 quail-current-package) + (quail-gen-decode-map)))) + (key-list nil)) + (if (consp decode-map) + (let ((str (string char))) + (mapc #'(lambda (elt) + (if (string= str (car elt)) + (setq key-list (cons (cdr elt) key-list)))) + (cdr decode-map))) + (let ((key-head (aref decode-map char))) + (if (stringp key-head) + (setq key-list (quail-find-key1 + (quail-lookup-key key-head nil t) + key-head char nil)) + (mapc #'(lambda (elt) + (setq key-list + (quail-find-key1 + (quail-lookup-key elt nil t) elt char key-list))) + key-head)))) + (or key-list + (and (< char 128) + (not (quail-lookup-key (string char) 1)))))) + +(defun quail-show-key () + "Show a list of key strings to type for inputting a character at point." + (interactive) + (or current-input-method + (error "No input method is activated")) + (let* ((char (following-char)) + (key-list (quail-find-key char))) + (cond ((consp key-list) + (message "To input `%c', type \"%s\"" + char + (mapconcat 'identity key-list "\", \""))) + ((eq key-list t) + (message "To input `%s', just type it" + (single-key-description char))) + (t + (message "%c can't be input by the current input method" char))))) + + ;; Quail map generator from state transition table. (defun quail-map-from-table (table) @@ -2661,7 +2824,7 @@ (translation-list nil) map) (while (> len 0) - (setq map (quail-lookup-key key len) + (setq map (quail-lookup-key key len t) len (1- len)) (if map (let* ((def (quail-map-definition map))