comparison lisp/international/quail.el @ 30656:321084a896d1

(quail-define-rules): Handle Quail decode map correctly. Add code for supporting annotations. (quail-install-decode-map): New function. (quail-defrule-internal): New optional arguments decode-map and props. (quail-advice): New function.
author Kenichi Handa <handa@m17n.org>
date Tue, 08 Aug 2000 01:39:26 +0000
parents a81355bcaaeb
children 8e8fa4dbc0bc
comparison
equal deleted inserted replaced
30655:10eb745f65eb 30656:321084a896d1
674 If it is a vector, each element (string or character) is a candidate 674 If it is a vector, each element (string or character) is a candidate
675 for the translation. 675 for the translation.
676 In these cases, a key specific Quail map is generated and assigned to KEY. 676 In these cases, a key specific Quail map is generated and assigned to KEY.
677 677
678 If TRANSLATION is a Quail map or a function symbol which returns a Quail map, 678 If TRANSLATION is a Quail map or a function symbol which returns a Quail map,
679 it is used to handle KEY." 679 it is used to handle KEY.
680 `(quail-install-map 680
681 ',(let ((l rules) 681 The first argument may be an alist of annotations for the following
682 (map (list nil))) 682 rules. Each element has the form (ANNOTATION . VALUE), where
683 ANNOTATION is a symbol indicating the annotation type. Currently
684 the following annotation types are supported.
685
686 append -- the value non-nil means that the following rules should
687 be appended to the rules of the current Quail package.
688
689 face -- the value is a face to use for displaying TRANSLATIONs in
690 candidate list.
691
692 advice -- the value is a function to call after one of RULES is
693 selected. The function is called with one argument, the
694 selected TRANSLATION string, after the TRANSLATION is
695 inserted.
696
697 no-decode-map --- the value non-nil means that decoding map is not
698 generated for the following translations."
699 (let ((l rules)
700 append no-decode-map props)
701 ;; If the first argument is an alist of annotations, handle them.
702 (if (consp (car (car l)))
703 (let ((annotations (car l)))
704 (setq append (assq 'append annotations))
705 (if append
706 (setq annotations (delete append annotations)
707 append (cdr append)))
708 (setq no-decode-map (assq 'no-decode-map annotations))
709 (if no-decode-map
710 (setq annotations (delete no-decode-map annotations)
711 no-decode-map (cdr no-decode-map)))
712 ;; Convert the remaining annoations to property list PROPS.
713 (while annotations
714 (setq props
715 (cons (car (car annotations))
716 (cons (cdr (car annotations))
717 props))
718 annotations (cdr annotations)))
719 (setq l (cdr l))))
720 ;; Process the remaining arguments one by one.
721 (if append
722 ;; There's no way to add new rules at compiling time.
723 `(let ((tail ',l)
724 (map (quail-map))
725 (decode-map (and (quail-decode-map) (not ,no-decode-map)))
726 (properties ',props)
727 key trans)
728 (while tail
729 (setq key (car (car tail)) trans (car (cdr (car tail)))
730 tail (cdr tail))
731 (quail-defrule-internal key trans map t decode-map properties)))
732 ;; We can build up quail map and decode map at compiling time.
733 (let ((map (list nil))
734 (decode-map (if (not no-decode-map) (list 'decode-map)))
735 key trans)
683 (while l 736 (while l
684 (quail-defrule-internal (car (car l)) (car (cdr (car l))) map t) 737 (setq key (car (car l)) trans (car (cdr (car l))) l (cdr l))
685 (setq l (cdr l))) 738 (quail-defrule-internal key trans map t decode-map props))
686 map))) 739 `(if (not (quail-decode-map))
740 (quail-install-map ',map)
741 (quail-install-map ',map)
742 (quail-install-decode-map ',decode-map))))))
687 743
688 ;;;###autoload 744 ;;;###autoload
689 (defun quail-install-map (map &optional name) 745 (defun quail-install-map (map &optional name)
690 "Install the Quail map MAP in the current Quail package. 746 "Install the Quail map MAP in the current Quail package.
691 747
696 (if (null quail-current-package) 752 (if (null quail-current-package)
697 (error "No current Quail package")) 753 (error "No current Quail package"))
698 (if (null (quail-map-p map)) 754 (if (null (quail-map-p map))
699 (error "Invalid Quail map `%s'" map)) 755 (error "Invalid Quail map `%s'" map))
700 (setcar (cdr (cdr quail-current-package)) map)) 756 (setcar (cdr (cdr quail-current-package)) map))
757
758 ;;;###autoload
759 (defun quail-install-decode-map (decode-map &optional name)
760 "Install the Quail decode map DECODE-MAP in the current Quail package.
761
762 Optional 2nd arg NAME, if non-nil, is a name of Quail package for
763 which to install MAP.
764
765 The installed decode map can be referred by the function `quail-decode-map'."
766 (if (null quail-current-package)
767 (error "No current Quail package"))
768 (if (not (and (consp decode-map) (eq (car decode-map) 'decode-map)))
769 (error "Invalid Quail decode map `%s'" decode-map))
770 (setcar (nthcdr 10 quail-current-package) decode-map))
701 771
702 ;;;###autoload 772 ;;;###autoload
703 (defun quail-defrule (key translation &optional name append) 773 (defun quail-defrule (key translation &optional name append)
704 "Add one translation rule, KEY to TRANSLATION, in the current Quail package. 774 "Add one translation rule, KEY to TRANSLATION, in the current Quail package.
705 KEY is a string meaning a sequence of keystrokes to be translated. 775 KEY is a string meaning a sequence of keystrokes to be translated.
730 (error "No Quail package `%s'" name)) 800 (error "No Quail package `%s'" name))
731 (setq quail-current-package package))) 801 (setq quail-current-package package)))
732 (quail-defrule-internal key translation (quail-map) append)) 802 (quail-defrule-internal key translation (quail-map) append))
733 803
734 ;;;###autoload 804 ;;;###autoload
735 (defun quail-defrule-internal (key trans map &optional append) 805 (defun quail-defrule-internal (key trans map &optional append decode-map props)
736 "Define KEY as TRANS in a Quail map MAP." 806 "Define KEY as TRANS in a Quail map MAP.
807
808 If Optional 4th arg APPEND is non-nil, TRANS is appended to the
809 current translations for KEY instead of replacing them.
810
811 Optional 5th arg DECODE-MAP is a Quail decode map.
812
813 Optional 6th arg PROPS is a property list annotating TRANS. See the
814 function `quail-define-rules' for the detail."
737 (if (null (stringp key)) 815 (if (null (stringp key))
738 "Invalid Quail key `%s'" key) 816 "Invalid Quail key `%s'" key)
739 (if (not (or (numberp trans) (stringp trans) (vectorp trans) 817 (if (not (or (numberp trans) (stringp trans) (vectorp trans)
740 (consp trans) 818 (consp trans)
741 (symbolp trans) 819 (symbolp trans)
780 ;; define a rule for "AB" as a symbol but a rule 858 ;; define a rule for "AB" as a symbol but a rule
781 ;; for "ABC" is already defined. 859 ;; for "ABC" is already defined.
782 (error "Quail key %s is too short" key) 860 (error "Quail key %s is too short" key)
783 (setcdr entry trans)) 861 (setcdr entry trans))
784 (setcdr entry (append trans (cdr map))))) 862 (setcdr entry (append trans (cdr map)))))
863 ;; If PROPS is non-nil or DECODE-MAP is non-nil, convert TRANS
864 ;; to a vector of strings, add PROPS to each string and record
865 ;; this rule in DECODE-MAP.
866 (when (and (or props decode-map)
867 (not (consp trans)) (not (symbolp trans)))
868 (if (integerp trans)
869 (setq trans (vector trans))
870 (if (stringp trans)
871 (setq trans (string-to-vector trans))))
872 (let ((len (length trans))
873 elt)
874 (while (> len 0)
875 (setq len (1- len))
876 (setq elt (aref trans len))
877 (if (integerp elt)
878 (setq elt (char-to-string elt)))
879 (aset trans len elt)
880 (if props
881 (add-text-properties 0 (length elt) props elt))
882 (if decode-map
883 (setcdr decode-map
884 (cons (cons elt key) (cdr decode-map)))))))
785 (if (and (car map) append) 885 (if (and (car map) append)
786 (let ((prev (quail-get-translation (car map) key len))) 886 (let ((prev (quail-get-translation (car map) key len)))
787 (if (integerp prev) 887 (if (integerp prev)
788 (setq prev (vector prev)) 888 (setq prev (vector prev))
789 (setq prev (cdr prev))) 889 (setq prev (cdr prev)))
982 (quail-delete-region) 1082 (quail-delete-region)
983 (if (and quail-current-str (> (length quail-current-str) 0)) 1083 (if (and quail-current-str (> (length quail-current-str) 0))
984 (let* ((len (length quail-current-str)) 1084 (let* ((len (length quail-current-str))
985 (idx 0) 1085 (idx 0)
986 (val (find-composition 0 len quail-current-str)) 1086 (val (find-composition 0 len quail-current-str))
1087 (advice (get-text-property idx 'advice quail-current-str))
987 char) 1088 char)
1089 ;; If the selected input has `advice' function, generate
1090 ;; a special event (quail-advice QUAIL-CURRENT-STR).
1091 (if advice
1092 (setq generated-events
1093 (cons (list 'quail-advice quail-current-str)
1094 generated-events)))
988 ;; Push characters in quail-current-str one by one to 1095 ;; Push characters in quail-current-str one by one to
989 ;; generated-events while interleaving it with a special 1096 ;; generated-events while interleaving it with a special
990 ;; event (compose-last-chars LEN) at each composition 1097 ;; event (compose-last-chars LEN) at each composition
991 ;; end. 1098 ;; end.
992 (while (<= idx len) 1099 (while (<= idx len)
2249 (set-buffer list-buf) 2356 (set-buffer list-buf)
2250 (setq buffer-file-coding-system 'iso-2022-7bit) 2357 (setq buffer-file-coding-system 'iso-2022-7bit)
2251 (save-buffer 0)) 2358 (save-buffer 0))
2252 (kill-buffer list-buf) 2359 (kill-buffer list-buf)
2253 (message "Updating %s ... done" leim-list))) 2360 (message "Updating %s ... done" leim-list)))
2361
2362 (defun quail-advice (args)
2363 "Advice users about the characters input by the current Quail package.
2364 The argument is a parameterized event of the form:
2365 (quail-advice STRING)
2366 where STRING is a string containing the input characters.
2367 If STRING has property `advice' and the value is a function,
2368 call it with one argument STRING."
2369 (interactive "e")
2370 (let* ((string (nth 1 args))
2371 (func (get-text-property 0 'advice string)))
2372 (if (functionp func)
2373 (funcall func string))))
2374
2375 (global-set-key [quail-advice] 'quail-advice)
2376
2254 ;; 2377 ;;
2255 (provide 'quail) 2378 (provide 'quail)
2256 2379
2257 ;;; quail.el ends here 2380 ;;; quail.el ends here