1043 |
The installed decode map can be referred by the function `quail-decode-map'." |
The installed decode map can be referred by the function `quail-decode-map'." |
1044 |
(if (null quail-current-package) |
(if (null quail-current-package) |
1045 |
(error "No current Quail package")) |
(error "No current Quail package")) |
1046 |
(if (not (and (consp decode-map) (eq (car decode-map) 'decode-map))) |
(if (if (consp decode-map) |
1047 |
(error "Invalid Quail decode map `%s'" decode-map)) |
(eq (car decode-map) 'decode-map) |
1048 |
(setcar (nthcdr 10 quail-current-package) decode-map)) |
(if (char-table-p decode-map) |
1049 |
|
(eq (char-table-subtype decode-map) 'quail-decode-map))) |
1050 |
|
(setcar (nthcdr 10 quail-current-package) decode-map) |
1051 |
|
(error "Invalid Quail decode map `%s'" decode-map))) |
1052 |
|
|
1053 |
|
|
1054 |
;;;###autoload |
;;;###autoload |
1055 |
(defun quail-defrule (key translation &optional name append) |
(defun quail-defrule (key translation &optional name append) |
2594 |
(quail-update-guidance) |
(quail-update-guidance) |
2595 |
)))) |
)))) |
2596 |
|
|
2597 |
|
;; Add KEY (string) to the element of TABLE (char-table) for CHAR if |
2598 |
|
;; it is not yet stored. As a result, the element is a string or a |
2599 |
|
;; list of strings. |
2600 |
|
|
2601 |
|
(defsubst quail-store-decode-map-key (table char key) |
2602 |
|
(let ((elt (aref table char))) |
2603 |
|
(if elt |
2604 |
|
(if (consp elt) |
2605 |
|
(or (member key elt) |
2606 |
|
(aset table char (cons key elt))) |
2607 |
|
(or (string= key elt) |
2608 |
|
(aset table char (list key elt)))) |
2609 |
|
(aset table char key)))) |
2610 |
|
|
2611 |
|
;; Helper function for quail-gen-decode-map. Store key strings to |
2612 |
|
;; type each character under MAP in TABLE (char-table). MAP is an |
2613 |
|
;; element of the current Quail map reached by typing keys in KEY |
2614 |
|
;; (string). |
2615 |
|
|
2616 |
|
(defun quail-gen-decode-map1 (map key table) |
2617 |
|
(when (and (consp map) (listp (cdr map))) |
2618 |
|
(let ((trans (car map))) |
2619 |
|
(cond ((integerp trans) |
2620 |
|
(quail-store-decode-map-key table trans key)) |
2621 |
|
((stringp trans) |
2622 |
|
(dotimes (i (length trans)) |
2623 |
|
(quail-store-decode-map-key table (aref trans i) key))) |
2624 |
|
((or (vectorp trans) |
2625 |
|
(and (consp trans) |
2626 |
|
(setq trans (cdr trans)))) |
2627 |
|
(dotimes (i (length trans)) |
2628 |
|
(let ((elt (aref trans i))) |
2629 |
|
(if (stringp elt) |
2630 |
|
(if (= (length elt) 1) |
2631 |
|
(quail-store-decode-map-key table (aref elt 0) key)) |
2632 |
|
(quail-store-decode-map-key table elt key))))))) |
2633 |
|
(if (> (length key) 1) |
2634 |
|
(dolist (elt (cdr map)) |
2635 |
|
(quail-gen-decode-map1 (cdr elt) key table)) |
2636 |
|
(dolist (elt (cdr map)) |
2637 |
|
(quail-gen-decode-map1 (cdr elt) (format "%s%c" key (car elt)) |
2638 |
|
table))))) |
2639 |
|
|
2640 |
|
(put 'quail-decode-map 'char-table-extra-slots 0) |
2641 |
|
|
2642 |
|
;; Generate a halfly-cooked decode map (char-table) for the current |
2643 |
|
;; Quail map. An element for a character C is a key string or a list |
2644 |
|
;; of a key strings to type to input C. The lenth of key string is at |
2645 |
|
;; most 2. If it is 2, more keys may be required to input C. |
2646 |
|
|
2647 |
|
(defun quail-gen-decode-map () |
2648 |
|
(let ((table (make-char-table 'quail-decode-map nil))) |
2649 |
|
(dolist (elt (cdr (quail-map))) |
2650 |
|
(quail-gen-decode-map1 (cdr elt) (string (car elt)) table)) |
2651 |
|
table)) |
2652 |
|
|
2653 |
|
;; Helper function for quail-find-key. Prepend key strings to type |
2654 |
|
;; for inputting CHAR by the current input method to KEY-LIST and |
2655 |
|
;; return the result. MAP is an element of the current Quail map |
2656 |
|
;; reached by typing keys in KEY. |
2657 |
|
|
2658 |
|
(defun quail-find-key1 (map key char key-list) |
2659 |
|
(let ((trans (car map)) |
2660 |
|
(found-here nil)) |
2661 |
|
(cond ((stringp trans) |
2662 |
|
(setq found-here |
2663 |
|
(and (= (length trans) 1) (= (aref trans 0) char)))) |
2664 |
|
((or (vectorp trans) (consp trans)) |
2665 |
|
(if (consp trans) |
2666 |
|
(setq trans (cdr trans))) |
2667 |
|
(setq found-here |
2668 |
|
(catch 'tag |
2669 |
|
(dotimes (i (length trans)) |
2670 |
|
(let ((target (aref trans i))) |
2671 |
|
(if (integerp target) |
2672 |
|
(if (= target char) |
2673 |
|
(throw 'tag t)) |
2674 |
|
(if (and (= (length target) 1) |
2675 |
|
(= (aref target 0) char)) |
2676 |
|
(throw 'tag t)))))))) |
2677 |
|
((integerp trans) |
2678 |
|
(if (= trans char) |
2679 |
|
(setq found-here t)))) |
2680 |
|
(if found-here |
2681 |
|
(setq key-list (cons key key-list))) |
2682 |
|
(if (> (length key) 1) |
2683 |
|
(dolist (elt (cdr map)) |
2684 |
|
(setq key-list |
2685 |
|
(quail-find-key1 (cdr elt) (format "%s%c" key (car elt)) |
2686 |
|
char key-list)))) |
2687 |
|
key-list)) |
2688 |
|
|
2689 |
|
(defun quail-find-key (char) |
2690 |
|
"Return a list of keys to type to input CHAR in the current input method. |
2691 |
|
If CHAR is an ASCII character and can be input by typing itself, return t." |
2692 |
|
(let ((decode-map (or (quail-decode-map) |
2693 |
|
(setcar (nthcdr 10 quail-current-package) |
2694 |
|
(quail-gen-decode-map)))) |
2695 |
|
(key-list nil)) |
2696 |
|
(if (consp decode-map) |
2697 |
|
(let ((str (string char))) |
2698 |
|
(mapc #'(lambda (elt) |
2699 |
|
(if (string= str (car elt)) |
2700 |
|
(setq key-list (cons (cdr elt) key-list)))) |
2701 |
|
(cdr decode-map))) |
2702 |
|
(let ((key-head (aref decode-map char))) |
2703 |
|
(if (stringp key-head) |
2704 |
|
(setq key-list (quail-find-key1 |
2705 |
|
(quail-lookup-key key-head nil t) |
2706 |
|
key-head char nil)) |
2707 |
|
(mapc #'(lambda (elt) |
2708 |
|
(setq key-list |
2709 |
|
(quail-find-key1 |
2710 |
|
(quail-lookup-key elt nil t) elt char key-list))) |
2711 |
|
key-head)))) |
2712 |
|
(or key-list |
2713 |
|
(and (< char 128) |
2714 |
|
(not (quail-lookup-key (string char) 1)))))) |
2715 |
|
|
2716 |
|
(defun quail-show-key () |
2717 |
|
"Show a list of key strings to type for inputting a character at point." |
2718 |
|
(interactive) |
2719 |
|
(or current-input-method |
2720 |
|
(error "No input method is activated")) |
2721 |
|
(let* ((char (following-char)) |
2722 |
|
(key-list (quail-find-key char))) |
2723 |
|
(cond ((consp key-list) |
2724 |
|
(message "To input `%c', type \"%s\"" |
2725 |
|
char |
2726 |
|
(mapconcat 'identity key-list "\", \""))) |
2727 |
|
((eq key-list t) |
2728 |
|
(message "To input `%s', just type it" |
2729 |
|
(single-key-description char))) |
2730 |
|
(t |
2731 |
|
(message "%c can't be input by the current input method" char))))) |
2732 |
|
|
2733 |
|
|
2734 |
;; Quail map generator from state transition table. |
;; Quail map generator from state transition table. |
2735 |
|
|
2736 |
(defun quail-map-from-table (table) |
(defun quail-map-from-table (table) |