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)))))