diff options
| author | Kenichi Handa | 2000-08-08 01:39:26 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-08-08 01:39:26 +0000 |
| commit | bb63aae5917bd574ddc985a36ec9d2f6fef68872 (patch) | |
| tree | cf1768a7cd903210c6f6f1e76d2347e07805dc10 | |
| parent | c5a525299cfe4f4f6cf32b9f8e5d51bfb742e01e (diff) | |
| download | emacs-bb63aae5917bd574ddc985a36ec9d2f6fef68872.tar.gz emacs-bb63aae5917bd574ddc985a36ec9d2f6fef68872.zip | |
(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.
| -rw-r--r-- | lisp/international/quail.el | 141 |
1 files changed, 132 insertions, 9 deletions
diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 8cc46ce1bfd..199d8c69109 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el | |||
| @@ -676,14 +676,70 @@ If it is a vector, each element (string or character) is a candidate | |||
| 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) |
| @@ -700,6 +756,20 @@ The installed map can be referred by the function `quail-map'." | |||
| 700 | (setcar (cdr (cdr quail-current-package)) map)) | 756 | (setcar (cdr (cdr quail-current-package)) map)) |
| 701 | 757 | ||
| 702 | ;;;###autoload | 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)) | ||
| 771 | |||
| 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. |
| @@ -732,8 +802,16 @@ to the current translations for KEY instead of replacing them." | |||
| 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) |
| @@ -782,6 +860,28 @@ to the current translations for KEY instead of replacing them." | |||
| 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) |
| @@ -984,7 +1084,14 @@ The returned value is a Quail map specific to KEY." | |||
| 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 |
| @@ -2251,6 +2358,22 @@ of each directory." | |||
| 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 | ||