comparison lisp/international/quail.el @ 55541:1cd6f125aac9

(quail-install-decode-map): Accept a char-table whose subtype is `quail-decode-map'. (quail-store-decode-map-key, quail-gen-decode-map1) (quail-gen-decode-map, quail-find-key1, quail-find-key) (quail-show-key): New functions.
author Kenichi Handa <handa@m17n.org>
date Wed, 12 May 2004 02:32:45 +0000
parents 894e3fd388c2
children 0a72a48de076
comparison
equal deleted inserted replaced
55540:30c03f9042b8 55541:1cd6f125aac9
1041 which to install MAP. 1041 which to install MAP.
1042 1042
1043 The installed decode map can be referred by the function `quail-decode-map'." 1043 The installed decode map can be referred by the function `quail-decode-map'."
1044 (if (null quail-current-package) 1044 (if (null quail-current-package)
1045 (error "No current Quail package")) 1045 (error "No current Quail package"))
1046 (if (not (and (consp decode-map) (eq (car decode-map) 'decode-map))) 1046 (if (if (consp decode-map)
1047 (error "Invalid Quail decode map `%s'" decode-map)) 1047 (eq (car decode-map) 'decode-map)
1048 (setcar (nthcdr 10 quail-current-package) decode-map)) 1048 (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
1049 1053
1050 ;;;###autoload 1054 ;;;###autoload
1051 (defun quail-defrule (key translation &optional name append) 1055 (defun quail-defrule (key translation &optional name append)
1052 "Add one translation rule, KEY to TRANSLATION, in the current Quail package. 1056 "Add one translation rule, KEY to TRANSLATION, in the current Quail package.
1053 KEY is a string meaning a sequence of keystrokes to be translated. 1057 KEY is a string meaning a sequence of keystrokes to be translated.
2588 (sit-for 1) 2592 (sit-for 1)
2589 (message nil) 2593 (message nil)
2590 (quail-update-guidance) 2594 (quail-update-guidance)
2591 )))) 2595 ))))
2592 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 (let ((decode-map (or (quail-decode-map)
2692 (setcar (nthcdr 10 quail-current-package)
2693 (quail-gen-decode-map))))
2694 (key-list nil))
2695 (if (consp decode-map)
2696 (let ((str (string char)))
2697 (mapc #'(lambda (elt)
2698 (if (string= str (car elt))
2699 (setq key-list (cons (cdr elt) key-list))))
2700 (cdr decode-map)))
2701 (let ((key-head (aref decode-map char)))
2702 (if (stringp key-head)
2703 (setq key-list (quail-find-key1
2704 (quail-lookup-key key-head nil t)
2705 key-head char nil))
2706 (mapc #'(lambda (elt)
2707 (setq key-list
2708 (quail-find-key1
2709 (quail-lookup-key elt nil t) elt char key-list)))
2710 key-head))))
2711 (or key-list
2712 (and (< char 128)
2713 (not (quail-lookup-key (string char) 1))))))
2714
2715 (defun quail-show-key ()
2716 "Show a list of key strings to type for inputting a character at point."
2717 (interactive)
2718 (or current-input-method
2719 (error "No input method is activated"))
2720 (let* ((char (following-char))
2721 (key-list (quail-find-key char)))
2722 (cond ((consp key-list)
2723 (message "To input `%c', type \"%s\""
2724 char
2725 (mapconcat 'identity key-list "\", \"")))
2726 ((eq key-list t)
2727 (message "To input `%s', just type it"
2728 (single-key-description char)))
2729 (t
2730 (message "%c can't be input by the current input method" char)))))
2731
2732
2593 ;; Quail map generator from state transition table. 2733 ;; Quail map generator from state transition table.
2594 2734
2595 (defun quail-map-from-table (table) 2735 (defun quail-map-from-table (table)
2596 "Make quail map from state transition table TABLE. 2736 "Make quail map from state transition table TABLE.
2597 2737