Mercurial > hg > xemacs-beta
comparison lisp/leim/quail.el @ 165:5a88923fcbfe r20-3b9
Import from CVS: tag r20-3b9
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:44:42 +0200 |
parents | 43dd3413c7c7 |
children | 15872534500d |
comparison
equal
deleted
inserted
replaced
164:4e0740e5aab2 | 165:5a88923fcbfe |
---|---|
1 ;;; quail.el -- provides simple input method for multilingual text | 1 ;;; quail.el --- Provides simple input method for multilingual text |
2 | 2 |
3 ;; Copyright (C) 1995 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1995 Free Software Foundation, Inc. |
4 ;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN. | 4 ;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN. |
5 ;; Copyright (C) 1997 MORIOKA Tomohiko | 5 ;; Copyright (C) 1997 MORIOKA Tomohiko |
6 | 6 |
90 (defvar quail-current-str nil | 90 (defvar quail-current-str nil |
91 "Currently selected translation of the current key.") | 91 "Currently selected translation of the current key.") |
92 | 92 |
93 (defvar quail-current-translations nil | 93 (defvar quail-current-translations nil |
94 "Cons of indices and vector of possible translations of the current key.") | 94 "Cons of indices and vector of possible translations of the current key.") |
95 | |
96 (defvar quail-current-data nil | |
97 "Any Lisp object holding information of current translation status. | |
98 When a key sequence is mapped to TRANS and TRANS is a cons | |
99 of actual translation and some Lisp object to be refered | |
100 for translating the longer key sequence, this variable is set | |
101 to that Lisp object.") | |
95 | 102 |
96 ;; A flag to control conversion region. Normally nil, but if set to | 103 ;; A flag to control conversion region. Normally nil, but if set to |
97 ;; t, it means we must start the new conversion region if new key to | 104 ;; t, it means we must start the new conversion region if new key to |
98 ;; be translated is input. | 105 ;; be translated is input. |
99 (defvar quail-reset-conversion-region nil) | 106 (defvar quail-reset-conversion-region nil) |
555 ;; Let's go back to Quail mode. | 562 ;; Let's go back to Quail mode. |
556 (setq quail-mode t) | 563 (setq quail-mode t) |
557 (setq overriding-local-map quail-saved-overriding-local-map) | 564 (setq overriding-local-map quail-saved-overriding-local-map) |
558 ;; If whole text in conversion area was deleted, exit from the | 565 ;; If whole text in conversion area was deleted, exit from the |
559 ;; recursive edit. | 566 ;; recursive edit. |
560 (let ((start (overlay-start quail-conv-overlay))) | 567 ;; 1997/6/24 modified by MORIOKA Tomohiko <morioka@jaist.ac.jp> |
568 ;; for XEmacs | |
569 (let ((start (and quail-conv-overlay | |
570 (overlay-start quail-conv-overlay)))) | |
561 (if (and start (= start (overlay-end quail-conv-overlay))) | 571 (if (and start (= start (overlay-end quail-conv-overlay))) |
562 (throw 'quail-tag nil))) | 572 (throw 'quail-tag nil))) |
563 ))) | 573 ))) |
564 | 574 |
565 (defun quail-execute-non-quail-command () | 575 (defun quail-execute-non-quail-command () |
682 vector. Then each element of the string or vector is a candidate for | 692 vector. Then each element of the string or vector is a candidate for |
683 the translation. These objects are transformed to cons cells in the | 693 the translation. These objects are transformed to cons cells in the |
684 format \(INDEX . VECTOR), as described above." | 694 format \(INDEX . VECTOR), as described above." |
685 (and (consp object) | 695 (and (consp object) |
686 (let ((translation (car object))) | 696 (let ((translation (car object))) |
687 (or (integerp translation) (consp translation) (null translation) | 697 (or (characterp translation) (null translation) |
688 (vectorp translation) (stringp translation) | 698 (vectorp translation) (stringp translation) |
689 (symbolp translation))) | 699 (symbolp translation) |
700 (and (consp translation) (not (vectorp (cdr translation)))))) | |
690 (let ((alist (cdr object))) | 701 (let ((alist (cdr object))) |
691 (or (listp alist) (symbolp alist))))) | 702 (or (and (listp alist) (consp (car alist))) |
703 (symbolp alist))))) | |
692 | 704 |
693 (defmacro quail-define-rules (&rest rules) | 705 (defmacro quail-define-rules (&rest rules) |
694 "Define translation rules of the current Quail package. | 706 "Define translation rules of the current Quail package. |
695 Each argument is a list of KEY and TRANSLATION. | 707 Each argument is a list of KEY and TRANSLATION. |
696 KEY is a string meaning a sequence of keystrokes to be translated. | 708 KEY is a string meaning a sequence of keystrokes to be translated. |
721 (setcar (cdr (cdr quail-current-package)) map)) | 733 (setcar (cdr (cdr quail-current-package)) map)) |
722 | 734 |
723 (defun quail-defrule (key translation &optional name) | 735 (defun quail-defrule (key translation &optional name) |
724 "Add one translation rule, KEY to TRANSLATION, in the current Quail package. | 736 "Add one translation rule, KEY to TRANSLATION, in the current Quail package. |
725 KEY is a string meaning a sequence of keystrokes to be translated. | 737 KEY is a string meaning a sequence of keystrokes to be translated. |
726 TRANSLATION is a character, a string, a vector, a Quail map, or a function. | 738 TRANSLATION is a character, a string, a vector, a Quail map, |
739 a function, or a cons. | |
727 It it is a character, it is the sole translation of KEY. | 740 It it is a character, it is the sole translation of KEY. |
728 If it is a string, each character is a candidate for the translation. | 741 If it is a string, each character is a candidate for the translation. |
729 If it is a vector, each element (string or character) is a candidate | 742 If it is a vector, each element (string or character) is a candidate |
730 for the translation. | 743 for the translation. |
744 If it is a cons, the car is one of the above and the cdr is a function | |
745 to call when translating KEY. | |
731 In these cases, a key specific Quail map is generated and assigned to KEY. | 746 In these cases, a key specific Quail map is generated and assigned to KEY. |
732 | 747 |
733 If TRANSLATION is a Quail map or a function symbol which returns a Quail map, | 748 If TRANSLATION is a Quail map or a function symbol which returns a Quail map, |
734 it is used to handle KEY. | 749 it is used to handle KEY. |
735 Optional argument NAME, if specified, says which Quail package | 750 Optional argument NAME, if specified, says which Quail package |
747 (if (null (stringp key)) | 762 (if (null (stringp key)) |
748 "Invalid Quail key `%s'" key) | 763 "Invalid Quail key `%s'" key) |
749 ;; 1997/5/26 by MORIOKA Tomohiko | 764 ;; 1997/5/26 by MORIOKA Tomohiko |
750 ;; modified for XEmacs | 765 ;; modified for XEmacs |
751 (if (not (or (characterp trans) (stringp trans) (vectorp trans) | 766 (if (not (or (characterp trans) (stringp trans) (vectorp trans) |
767 (consp trans) | |
752 (symbolp trans) | 768 (symbolp trans) |
753 (quail-map-p trans))) | 769 (quail-map-p trans))) |
754 (error "Invalid Quail translation `%s'" trans)) | 770 (error "Invalid Quail translation `%s'" trans)) |
755 (if (null (quail-map-p map)) | 771 (if (null (quail-map-p map)) |
756 (error "Invalid Quail map `%s'" map)) | 772 (error "Invalid Quail map `%s'" map)) |
757 (let ((len (length key)) | 773 (let ((len (length key)) |
758 (idx 0) | 774 (idx 0) |
759 ch entry) | 775 ch entry) |
776 ;; Make a map for registering TRANS if necessary. | |
760 (while (< idx len) | 777 (while (< idx len) |
761 (if (null (consp map)) | 778 (if (null (consp map)) |
762 ;; We come here, for example, when we try to define a rule | 779 ;; We come here, for example, when we try to define a rule |
763 ;; for "ABC" but a rule for "AB" is already defined as a | 780 ;; for "ABC" but a rule for "AB" is already defined as a |
764 ;; symbol. | 781 ;; symbol. |
792 (error "Quail key %s is too short" key) | 809 (error "Quail key %s is too short" key) |
793 (setcdr entry trans)) | 810 (setcdr entry trans)) |
794 (setcdr entry (append trans (cdr map))))) | 811 (setcdr entry (append trans (cdr map))))) |
795 (setcar map trans))))) | 812 (setcar map trans))))) |
796 | 813 |
797 (defun quail-get-translation (map key len) | 814 (defun quail-get-translation (def key len) |
798 "Return the translation specified in Quail map MAP for KEY of length LEN. | 815 "Return the translation specified as DEF for KEY of length LEN. |
799 The translation is either a character or a cons of the form (INDEX . VECTOR), | 816 The translation is either a character or a cons of the form (INDEX . VECTOR), |
800 where VECTOR is a vector of candidates (character or string) for | 817 where VECTOR is a vector of candidates (character or string) for |
801 the translation, and INDEX points into VECTOR to specify the currently | 818 the translation, and INDEX points into VECTOR to specify the currently |
802 selected translation." | 819 selected translation." |
803 (let ((def (car map))) | 820 (if (and def (symbolp def)) |
804 (if (and def (symbolp def)) | 821 ;; DEF is a symbol of a function which returns valid translation. |
805 ;; DEF is a symbol of a function which returns valid translation. | 822 (setq def (funcall def key len))) |
806 (setq def (funcall def key len))) | 823 (if (and (consp def) (not (vectorp (cdr def)))) |
807 (cond | 824 (setq def (car def))) |
808 ((or (characterp def) (consp def)) | 825 |
809 def) | 826 (cond |
810 | 827 ((or (characterp def) (consp def)) |
811 ((null def) | 828 def) |
812 ;; No translation. | 829 |
813 nil) | 830 ((null def) |
814 | 831 ;; No translation. |
815 ((stringp def) | 832 nil) |
816 ;; Each character in DEF is a candidate of translation. Reform | 833 |
817 ;; it as (INDEX . VECTOR). | 834 ((stringp def) |
818 (setq def (string-to-vector def)) | 835 ;; Each character in DEF is a candidate of translation. Reform |
819 ;; But if the length is 1, we don't need vector but a single | 836 ;; it as (INDEX . VECTOR). |
820 ;; character as the translation. | 837 (setq def (string-to-vector def)) |
821 (if (= (length def) 1) | 838 ;; But if the length is 1, we don't need vector but a single |
822 (aref def 0) | 839 ;; candidate as the translation. |
823 (cons 0 def))) | 840 (if (= (length def) 1) |
824 | 841 (aref def 0) |
825 ((vectorp def) | 842 (cons 0 def))) |
826 ;; Each element (string or character) in DEF is a candidate of | 843 |
827 ;; translation. Reform it as (INDEX . VECTOR). | 844 ((vectorp def) |
828 (cons 0 def)) | 845 ;; Each element (string or character) in DEF is a candidate of |
829 | 846 ;; translation. Reform it as (INDEX . VECTOR). |
830 (t | 847 (cons 0 def)) |
831 (error "Invalid object in Quail map: %s" def))))) | 848 |
849 (t | |
850 (error "Invalid object in Quail map: %s" def)))) | |
832 | 851 |
833 (defun quail-lookup-key (key len) | 852 (defun quail-lookup-key (key len) |
834 "Lookup KEY of length LEN in the current Quail map and return the definition. | 853 "Lookup KEY of length LEN in the current Quail map and return the definition. |
835 The returned value is a Quail map specific to KEY." | 854 The returned value is a Quail map specific to KEY." |
836 (let ((idx 0) | 855 (let ((idx 0) |
837 (map (quail-map)) | 856 (map (quail-map)) |
838 (kbd-translate (quail-kbd-translate)) | 857 (kbd-translate (quail-kbd-translate)) |
839 slot ch translation) | 858 slot ch translation def) |
840 (while (and map (< idx len)) | 859 (while (and map (< idx len)) |
841 (setq ch (if kbd-translate (quail-keyboard-translate (aref key idx)) | 860 (setq ch (if kbd-translate (quail-keyboard-translate (aref key idx)) |
842 (aref key idx))) | 861 (aref key idx))) |
843 (setq idx (1+ idx)) | 862 (setq idx (1+ idx)) |
844 (if (and (cdr map) (symbolp (cdr map))) | 863 (if (and (cdr map) (symbolp (cdr map))) |
845 (setcdr map (funcall (cdr map) key idx))) | 864 (setcdr map (funcall (cdr map) key idx))) |
846 (setq slot (assq ch (cdr map))) | 865 (setq slot (assq ch (cdr map))) |
847 (if (and (cdr slot) (symbolp (cdr slot))) | 866 (if (and (cdr slot) (symbolp (cdr slot))) |
848 (setcdr slot (funcall (cdr slot) key idx))) | 867 (setcdr slot (funcall (cdr slot) key idx))) |
849 (setq map (cdr slot))) | 868 (setq map (cdr slot))) |
850 (if (and map (setq translation (quail-get-translation map key len))) | 869 (setq def (car map)) |
870 (if (and map (setq translation (quail-get-translation def key len))) | |
851 (progn | 871 (progn |
852 ;; We may have to reform car part of MAP. | 872 (if (and (consp def) (not (vectorp (cdr def)))) |
853 (if (not (equal (car map) translation)) | 873 (progn |
854 (setcar map translation)) | 874 (if (not (equal (car def) translation)) |
855 (if (consp translation) | 875 ;; We must reflect TRANSLATION to car part of DEF. |
876 (setcar def translation)) | |
877 (setq quail-current-data | |
878 (if (functionp (cdr def)) | |
879 (funcall (cdr def)) | |
880 (cdr def)))) | |
881 (if (not (equal def translation)) | |
882 ;; We must reflect TRANSLATION to car part of MAP. | |
883 (setcar map translation))) | |
884 (if (and (consp translation) (vectorp (cdr translation))) | |
856 (progn | 885 (progn |
857 (setq quail-current-translations translation) | 886 (setq quail-current-translations translation) |
858 (if (quail-forget-last-selection) | 887 (if (quail-forget-last-selection) |
859 (setcar quail-current-translations 0)))) | 888 (setcar quail-current-translations 0)))) |
860 ;; We may have to reform cdr part of MAP. | 889 ;; We may have to reform cdr part of MAP. |
1042 (let* ((len (length quail-current-key)) | 1071 (let* ((len (length quail-current-key)) |
1043 (map (quail-lookup-key quail-current-key len)) | 1072 (map (quail-lookup-key quail-current-key len)) |
1044 def ch) | 1073 def ch) |
1045 (if map | 1074 (if map |
1046 (let ((def (car map))) | 1075 (let ((def (car map))) |
1076 (if (and (consp def) (not (vectorp (cdr def)))) | |
1077 (setq def (car def))) | |
1047 (setq quail-current-str | 1078 (setq quail-current-str |
1048 (if (consp def) (aref (cdr def) (car def)) def)) | 1079 (if (consp def) (aref (cdr def) (car def)) def)) |
1049 ;; Return t only if we can terminate the current translation. | 1080 ;; Return t only if we can terminate the current translation. |
1050 (and | 1081 (and |
1051 ;; No alternative translations. | 1082 ;; No alternative translations. |
1063 ;; giving up, we must check two possibilities. | 1094 ;; giving up, we must check two possibilities. |
1064 (cond ((and | 1095 (cond ((and |
1065 (quail-maximum-shortest) | 1096 (quail-maximum-shortest) |
1066 (>= len 4) | 1097 (>= len 4) |
1067 (setq def (car (quail-lookup-key quail-current-key (- len 2)))) | 1098 (setq def (car (quail-lookup-key quail-current-key (- len 2)))) |
1099 (if (and (consp def) (not (vectorp (cdr def)))) | |
1100 (setq def (car def))) | |
1068 (quail-lookup-key (substring quail-current-key -2) 2)) | 1101 (quail-lookup-key (substring quail-current-key -2) 2)) |
1069 ;; Now the sequence is "...ABCD", which can be split into | 1102 ;; Now the sequence is "...ABCD", which can be split into |
1070 ;; "...AB" and "CD..." to get valid translation. | 1103 ;; "...AB" and "CD..." to get valid translation. |
1071 ;; At first, get translation of "...AB". | 1104 ;; At first, get translation of "...AB". |
1072 (setq quail-current-str | 1105 (setq quail-current-str |
1348 (set-window-start win pos)) | 1381 (set-window-start win pos)) |
1349 )))))) | 1382 )))))) |
1350 | 1383 |
1351 (defun quail-show-translations () | 1384 (defun quail-show-translations () |
1352 "Show the current possible translations." | 1385 "Show the current possible translations." |
1353 (let ((key quail-current-key) | 1386 (let* ((key quail-current-key) |
1354 (map (quail-lookup-key quail-current-key (length quail-current-key)))) | 1387 (map (quail-lookup-key quail-current-key (length quail-current-key))) |
1388 (def (car map))) | |
1389 (if (and (consp def) (not (vectorp (cdr def)))) | |
1390 (setq def (car def))) | |
1355 (save-excursion | 1391 (save-excursion |
1356 (set-buffer quail-guidance-buf) | 1392 (set-buffer quail-guidance-buf) |
1357 (erase-buffer) | 1393 (erase-buffer) |
1358 | 1394 |
1359 ;; Show the current key. | 1395 ;; Show the current key. |
1367 (insert (car (car l))) | 1403 (insert (car (car l))) |
1368 (setq l (cdr l))) | 1404 (setq l (cdr l))) |
1369 (insert "]"))) | 1405 (insert "]"))) |
1370 | 1406 |
1371 ;; Show list of translations. | 1407 ;; Show list of translations. |
1372 (if (consp (car map)) | 1408 (if (and (not (quail-deterministic)) (consp def)) |
1373 (let* ((idx (car (car map))) | 1409 (let* ((idx (car def)) |
1374 (translations (cdr (car map))) | 1410 (translations (cdr def)) |
1375 (from (* (/ idx 10) 10)) | 1411 (from (* (/ idx 10) 10)) |
1376 (to (min (+ from 10) (length translations)))) | 1412 (to (min (+ from 10) (length translations)))) |
1377 (indent-to 10) | 1413 (indent-to 10) |
1378 (insert (format "(%d/%d)" | 1414 (insert (format "(%d/%d)" |
1379 (1+ (/ from 10)) | 1415 (1+ (/ from 10)) |
1429 (aset newkey len (car (car l))) | 1465 (aset newkey len (car (car l))) |
1430 (quail-completion-1 newkey (cdr (car l)) indent) | 1466 (quail-completion-1 newkey (cdr (car l)) indent) |
1431 (setq l (cdr l))))))) | 1467 (setq l (cdr l))))))) |
1432 | 1468 |
1433 ;; List all possible translations of KEY in Quail map MAP with | 1469 ;; List all possible translations of KEY in Quail map MAP with |
1434 ;; indentation INDENT." | 1470 ;; indentation INDENT. |
1435 (defun quail-completion-list-translations (map key indent) | 1471 (defun quail-completion-list-translations (map key indent) |
1436 (let ((translations | 1472 (let ((translations |
1437 (quail-get-translation map key (length key)))) | 1473 (quail-get-translation (car map) key (length key)))) |
1438 (if (integerp translations) | 1474 (if (integerp translations) |
1439 (insert "(1/1) 1." translations "\n") | 1475 (insert "(1/1) 1." translations "\n") |
1440 ;; We need only vector part. | 1476 ;; We need only vector part. |
1441 (setq translations (cdr translations)) | 1477 (setq translations (cdr translations)) |
1442 ;; Insert every 10 elements with indices in a line. | 1478 ;; Insert every 10 elements with indices in a line. |
1531 (setq ch (aref quail-keyboard-layout i)) | 1567 (setq ch (aref quail-keyboard-layout i)) |
1532 (if (= ch ?\ ) | 1568 (if (= ch ?\ ) |
1533 (insert ch) | 1569 (insert ch) |
1534 (let* ((map (cdr (assq ch (cdr (quail-map))))) | 1570 (let* ((map (cdr (assq ch (cdr (quail-map))))) |
1535 (translation (and map (quail-get-translation | 1571 (translation (and map (quail-get-translation |
1536 map (char-to-string ch) 1)))) | 1572 (car map) (char-to-string ch) 1)))) |
1537 (if (integerp translation) | 1573 (if (integerp translation) |
1538 (insert translation) | 1574 (insert translation) |
1539 (if (consp translation) | 1575 (if (consp translation) |
1540 (insert (aref (cdr translation) (car translation))) | 1576 (insert (aref (cdr translation) (car translation))) |
1541 (insert ch))))) | 1577 (insert ch))))) |