Mercurial > emacs
comparison lisp/international/quail.el @ 26891:651d521c8f52
(quail-install-map): New optional arg
NAME.
(quail-get-translation): If DEF is a symbol but not a function,
ignore it.
(quail-start-translation): Put a key sequence undefined in the
translation keymap in unread-command-events, not generated-events.
Return parameterized event (compose-last-chars N) if the input
characters should be composed.
(quail-map-definition): If DEF is t, treat it as nil.
(quail-delete-last-char): Delete the quail region.
(quail-show-translations): Don't show list of translations if the
quail package is deterministic.
(quail-completion-max-depth): New variable.
(quail-completion-1): Pay attention to the above variable. Fix
for the case that a translation is a function.
(quail-map-from-table, quail-map-from-table-1,
quail-map-from-table-2): New functions.
(quail-lookup-map-and-concat): New function
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 15 Dec 1999 00:42:43 +0000 |
parents | 7f6aadd2625b |
children | 2851f83ea432 |
comparison
equal
deleted
inserted
replaced
26890:4cd9407a4683 | 26891:651d521c8f52 |
---|---|
671 (quail-defrule-internal (car (car l)) (car (cdr (car l))) map t) | 671 (quail-defrule-internal (car (car l)) (car (cdr (car l))) map t) |
672 (setq l (cdr l))) | 672 (setq l (cdr l))) |
673 map))) | 673 map))) |
674 | 674 |
675 ;;;###autoload | 675 ;;;###autoload |
676 (defun quail-install-map (map) | 676 (defun quail-install-map (map &optional name) |
677 "Install the Quail map MAP in the current Quail package. | 677 "Install the Quail map MAP in the current Quail package. |
678 | |
679 Optional 2nd arg NAME, if non-nil, is a name of Quail package for | |
680 which to install MAP. | |
681 | |
678 The installed map can be referred by the function `quail-map'." | 682 The installed map can be referred by the function `quail-map'." |
679 (if (null quail-current-package) | 683 (if (null quail-current-package) |
680 (error "No current Quail package")) | 684 (error "No current Quail package")) |
681 (if (null (quail-map-p map)) | 685 (if (null (quail-map-p map)) |
682 (error "Invalid Quail map `%s'" map)) | 686 (error "Invalid Quail map `%s'" map)) |
784 The translation is either a character or a cons of the form (INDEX . VECTOR), | 788 The translation is either a character or a cons of the form (INDEX . VECTOR), |
785 where VECTOR is a vector of candidates (character or string) for | 789 where VECTOR is a vector of candidates (character or string) for |
786 the translation, and INDEX points into VECTOR to specify the currently | 790 the translation, and INDEX points into VECTOR to specify the currently |
787 selected translation." | 791 selected translation." |
788 (if (and def (symbolp def)) | 792 (if (and def (symbolp def)) |
789 ;; DEF is a symbol of a function which returns valid translation. | 793 (if (functionp def) |
790 (setq def (funcall def key len))) | 794 ;; DEF is a symbol of a function which returns valid translation. |
795 (setq def (funcall def key len)) | |
796 (setq def nil))) | |
791 (if (and (consp def) (not (vectorp (cdr def)))) | 797 (if (and (consp def) (not (vectorp (cdr def)))) |
792 (setq def (car def))) | 798 (setq def (car def))) |
793 | 799 |
794 (cond | 800 (cond |
795 ((or (integerp def) (consp def)) | 801 ((or (integerp def) (consp def)) |
953 (condition-case err | 959 (condition-case err |
954 (call-interactively cmd) | 960 (call-interactively cmd) |
955 (quail-error (message "%s" (cdr err)) (beep)))) | 961 (quail-error (message "%s" (cdr err)) (beep)))) |
956 ;; KEYSEQ is not defined in the translation keymap. | 962 ;; KEYSEQ is not defined in the translation keymap. |
957 ;; Let's return the event(s) to the caller. | 963 ;; Let's return the event(s) to the caller. |
958 (setq generated-events | 964 (setq unread-command-events |
959 (string-to-list (this-single-command-raw-keys))) | 965 (string-to-list (this-single-command-raw-keys))) |
960 (setq quail-translating nil)))) | 966 (setq quail-translating nil)))) |
961 (quail-delete-region) | 967 (quail-delete-region) |
962 (if (and quail-current-str (> (length quail-current-str) 0)) | 968 (if (and quail-current-str (> (length quail-current-str) 0)) |
963 (setq generated-events | 969 (let* ((len (length quail-current-str)) |
964 (append (string-to-list | 970 (idx 0) |
965 (if enable-multibyte-characters | 971 (val (find-composition 0 len quail-current-str)) |
966 quail-current-str | 972 char) |
967 (string-make-unibyte quail-current-str))) | 973 ;; Push characters in quail-current-str one by one to |
968 generated-events))) | 974 ;; generated-events while interleaving it with a special |
975 ;; event (compose-last-chars LEN) at each composition | |
976 ;; end. | |
977 (while (<= idx len) | |
978 (when (and val (= idx (nth 1 val))) | |
979 (setq generated-events | |
980 (cons (list 'compose-last-chars (- idx (car val))) | |
981 generated-events)) | |
982 (setq val (find-composition idx len quail-current-str))) | |
983 (when (< idx len) | |
984 (setq char (aref quail-current-str idx)) | |
985 (or enable-multibyte-characters | |
986 (setq char (multibyte-char-to-unibyte char))) | |
987 (setq generated-events (cons char generated-events))) | |
988 (setq idx (1+ idx))) | |
989 ;; Reorder generated-events. | |
990 (setq generated-events (nreverse generated-events)))) | |
969 (if (and input-method-exit-on-first-char generated-events) | 991 (if (and input-method-exit-on-first-char generated-events) |
970 (list (car generated-events)) | 992 (list (car generated-events)) |
971 generated-events)) | 993 generated-events)) |
972 | 994 |
973 ;; Since KEY doesn't start any translation, just return it. | 995 ;; Since KEY doesn't start any translation, just return it. |
1123 ;; Return the actual definition part of Quail map MAP. | 1145 ;; Return the actual definition part of Quail map MAP. |
1124 (defun quail-map-definition (map) | 1146 (defun quail-map-definition (map) |
1125 (let ((def (car map))) | 1147 (let ((def (car map))) |
1126 (if (and (consp def) (not (vectorp (cdr def)))) | 1148 (if (and (consp def) (not (vectorp (cdr def)))) |
1127 (setq def (car def))) | 1149 (setq def (car def))) |
1150 (if (eq def t) | |
1151 (setq def nil)) | |
1128 def)) | 1152 def)) |
1129 | 1153 |
1130 ;; Return a string to be shown as the current translation of key | 1154 ;; Return a string to be shown as the current translation of key |
1131 ;; sequence of length LEN. DEF is a definition part of Quail map for | 1155 ;; sequence of length LEN. DEF is a definition part of Quail map for |
1132 ;; the sequence. | 1156 ;; the sequence. |
1337 "Delete the last input character from the current Quail key sequence." | 1361 "Delete the last input character from the current Quail key sequence." |
1338 (interactive) | 1362 (interactive) |
1339 (if (= (length quail-current-key) 1) | 1363 (if (= (length quail-current-key) 1) |
1340 (quail-abort-translation) | 1364 (quail-abort-translation) |
1341 (setq quail-current-key (substring quail-current-key 0 -1)) | 1365 (setq quail-current-key (substring quail-current-key 0 -1)) |
1366 (quail-delete-region) | |
1342 (quail-update-translation (quail-translate-key)))) | 1367 (quail-update-translation (quail-translate-key)))) |
1343 | 1368 |
1344 ;; For conversion mode. | 1369 ;; For conversion mode. |
1345 | 1370 |
1346 (defsubst quail-point-in-conversion-region () | 1371 (defsubst quail-point-in-conversion-region () |
1634 (insert (car keys)) | 1659 (insert (car keys)) |
1635 (setq keys (cdr keys))) | 1660 (setq keys (cdr keys))) |
1636 (insert "]"))) | 1661 (insert "]"))) |
1637 | 1662 |
1638 ;; Show list of translations. | 1663 ;; Show list of translations. |
1639 (if current-translations | 1664 (if (and current-translations |
1665 (not (quail-deterministic))) | |
1640 (let* ((indices (car current-translations)) | 1666 (let* ((indices (car current-translations)) |
1641 (cur (car indices)) | 1667 (cur (car indices)) |
1642 (start (nth 1 indices)) | 1668 (start (nth 1 indices)) |
1643 (end (nth 2 indices)) | 1669 (end (nth 2 indices)) |
1644 (idx start)) | 1670 (idx start)) |
1655 (if (= idx cur) | 1681 (if (= idx cur) |
1656 (move-overlay quail-overlay pos (point)))) | 1682 (move-overlay quail-overlay pos (point)))) |
1657 (setq idx (1+ idx))))) | 1683 (setq idx (1+ idx))))) |
1658 ))) | 1684 ))) |
1659 | 1685 |
1686 (defvar quail-completion-max-depth 5 | |
1687 "The maximum depth of Quail completion list.") | |
1688 | |
1660 (defun quail-completion () | 1689 (defun quail-completion () |
1661 "List all completions for the current key. | 1690 "List all completions for the current key. |
1662 All possible translations of the current key and whole possible longer keys | 1691 All possible translations of the current key and whole possible longer keys |
1663 are shown." | 1692 are shown (at most to the depth specified `quail-completion-max-depth')." |
1664 (interactive) | 1693 (interactive) |
1665 (quail-setup-completion-buf) | 1694 (quail-setup-completion-buf) |
1666 (let ((win (get-buffer-window quail-completion-buf 'visible)) | 1695 (let ((win (get-buffer-window quail-completion-buf 'visible)) |
1667 (key quail-current-key) | 1696 (key quail-current-key) |
1668 (map (quail-lookup-key quail-current-key)) | 1697 (map (quail-lookup-key quail-current-key)) |
1698 (setq map (funcall map key len))) | 1727 (setq map (funcall map key len))) |
1699 (if (car map) | 1728 (if (car map) |
1700 (quail-completion-list-translations map key (+ indent len 1)) | 1729 (quail-completion-list-translations map key (+ indent len 1)) |
1701 (insert " -\n")) | 1730 (insert " -\n")) |
1702 (setq indent (+ indent 2)) | 1731 (setq indent (+ indent 2)) |
1703 (if (cdr map) | 1732 (if (and (cdr map) (< (/ (1- indent) 2) quail-completion-max-depth)) |
1704 (let ((l (cdr map)) | 1733 (let ((l (cdr map)) |
1705 (newkey (make-string (1+ len) 0)) | 1734 (newkey (make-string (1+ len) 0)) |
1706 (i 0)) | 1735 (i 0)) |
1736 (if (functionp l) | |
1737 (setq l (funcall l))) | |
1707 ;; Set KEY in the first LEN characters of NEWKEY. | 1738 ;; Set KEY in the first LEN characters of NEWKEY. |
1708 (while (< i len) | 1739 (while (< i len) |
1709 (aset newkey i (aref key i)) | 1740 (aset newkey i (aref key i)) |
1710 (setq i (1+ i))) | 1741 (setq i (1+ i))) |
1711 (while l ; L = ((CHAR . DEFN) ....) ; | 1742 (while l ; L = ((CHAR . DEFN) ....) ; |
1963 (message "%s" (substitute-command-keys scroll-help)) | 1994 (message "%s" (substitute-command-keys scroll-help)) |
1964 (sit-for 1) | 1995 (sit-for 1) |
1965 (message nil) | 1996 (message nil) |
1966 (quail-update-guidance) | 1997 (quail-update-guidance) |
1967 )))) | 1998 )))) |
1999 | |
2000 ;; Quail map generator from state transition table. | |
2001 | |
2002 (defun quail-map-from-table (table) | |
2003 "Make quail map from state transition table TABLE. | |
2004 | |
2005 TABLE is an alist, the form is: | |
2006 ((STATE-0 TRANSITION-0-1 TRANSITION-0-2 ...) (STATE-1 ...) ...) | |
2007 | |
2008 STATE-n are symbols to denote state. STATE-0 is the initial state. | |
2009 | |
2010 TRANSITION-n-m are transition rules from STATE-n, and have the form | |
2011 \(RULES . STATE-x) or RULES, where STATE-x is one of STATE-n above, | |
2012 RULES is a symbol whose value is an alist of keys \(string) vs the | |
2013 correponding characters or strings. The format of the symbol value of | |
2014 RULES is the same as arguments to `quail-define-rules'. | |
2015 | |
2016 If TRANSITION-n-m has the form (RULES . STATE-x), it means that | |
2017 STATE-n transits to STATE-x when keys in RULES are input. Recursive | |
2018 transition is allowed, i.e. STATE-x may be STATE-n. | |
2019 | |
2020 If TRANSITION-n-m has the form RULES, the transition terminates | |
2021 when keys in RULES are input. | |
2022 | |
2023 The generated map can be set for the current Quail package by the | |
2024 function `quail-install-map' (which see)." | |
2025 (let ((state-alist (mapcar (lambda (x) (list (car x))) table)) | |
2026 tail elt) | |
2027 ;; STATE-ALIST is an alist of states vs the correponding sub Quail | |
2028 ;; map. It is now initialized to ((STATE-0) (STATE-1) ...). | |
2029 ;; Set key sequence mapping rules in cdr part of each element. | |
2030 (while table | |
2031 (quail-map-from-table-1 state-alist (car table)) | |
2032 (setq table (cdr table))) | |
2033 | |
2034 ;; Now STATE-ALIST has the form ((STATE-0 MAPPING-RULES) ...). | |
2035 ;; Elements of MAPPING-RULES may have the form (STATE-x). Replace | |
2036 ;; them with MAPPING-RULES of STATE-x to make elements of | |
2037 ;; STATE-ALIST valid Quail maps. | |
2038 (setq tail state-alist) | |
2039 (while tail | |
2040 (setq elt (car tail) tail (cdr tail)) | |
2041 (quail-map-from-table-2 state-alist elt)) | |
2042 | |
2043 ;; Return the Quail map for the initial state. | |
2044 (car state-alist))) | |
2045 | |
2046 ;; STATE-INFO has the form (STATE TRANSITION ...). Set key sequence | |
2047 ;; mapping rules in the element of STATE-ALIST that corresponds to | |
2048 ;; STATE according to TRANSITION ... | |
2049 (defun quail-map-from-table-1 (state-alist state-info) | |
2050 (let* ((state (car state-info)) | |
2051 (map (assq state state-alist)) | |
2052 (transitions (cdr state-info)) | |
2053 elt) | |
2054 (while transitions | |
2055 (setq elt (car transitions) transitions (cdr transitions)) | |
2056 (let (rules dst-state key trans) | |
2057 ;; ELT has the form (RULES-SYMBOL . STATE-x) or RULES-SYMBOL. | |
2058 ;; STATE-x is one of car parts of STATE-ALIST's elements. | |
2059 (if (consp elt) | |
2060 (setq rules (symbol-value (car elt)) | |
2061 ;; Set (STATE-x) as branches for all keys in RULES. | |
2062 ;; It is replaced with actual branches for STATE-x | |
2063 ;; later in `quail-map-from-table-2'. | |
2064 dst-state (list (cdr elt))) | |
2065 (setq rules (symbol-value elt))) | |
2066 (while rules | |
2067 (setq key (car (car rules)) trans (cdr (car rules)) | |
2068 rules (cdr rules)) | |
2069 (if (stringp trans) | |
2070 (if (= (length trans) 1) | |
2071 (setq trans (aref trans 0)) | |
2072 (setq trans (string-to-vector trans)))) | |
2073 (set-nested-alist key trans map nil dst-state)))))) | |
2074 | |
2075 ;; ELEMENT is one element of STATE-ALIST. ELEMENT is a nested alist; | |
2076 ;; the form is: | |
2077 ;; (STATE (CHAR NESTED-ALIST) ...) | |
2078 ;; NESTED-ALIST is a nested alist; the form is: | |
2079 ;; (TRANS (CHAR NESTED-ALIST) ...) | |
2080 ;; or | |
2081 ;; (TRANS (CHAR NESTED-ALIST) ... . (STATE-x)) | |
2082 ;; Here, the task is to replace all occurrences of (STATE-x) with: | |
2083 ;; (cdr (assq STATE-x STATE-ALIST)) | |
2084 | |
2085 (defun quail-map-from-table-2 (state-alist element) | |
2086 (let ((prev element) | |
2087 (tail (cdr element)) | |
2088 elt) | |
2089 (while (cdr tail) | |
2090 (setq elt (car tail) prev tail tail (cdr tail)) | |
2091 (quail-map-from-table-2 state-alist (cdr elt))) | |
2092 (setq elt (car tail)) | |
2093 (if (consp elt) | |
2094 (quail-map-from-table-2 state-alist (cdr elt)) | |
2095 (setcdr prev (cdr (assq elt state-alist)))))) | |
2096 | |
2097 ;; Concatenate translations for all heading substrings of KEY in the | |
2098 ;; current Quail map. Here, `heading substring' means (substring KEY | |
2099 ;; 0 LEN), where LEN is 1, 2, ... (length KEY). | |
2100 (defun quail-lookup-map-and-concat (key) | |
2101 (let* ((len (length key)) | |
2102 (translation-list nil) | |
2103 map) | |
2104 (while (> len 0) | |
2105 (setq map (quail-lookup-key key len) | |
2106 len (1- len)) | |
2107 (if map | |
2108 (let* ((def (quail-map-definition map)) | |
2109 (trans (if (consp def) (aref (cdr def) (car (car def))) | |
2110 def))) | |
2111 (if (integerp trans) | |
2112 (setq trans (char-to-string trans))) | |
2113 (setq translation-list (cons trans translation-list))))) | |
2114 (apply 'concat translation-list))) | |
1968 | 2115 |
1969 | 2116 |
1970 (defvar quail-directory-name "quail" | 2117 (defvar quail-directory-name "quail" |
1971 "Name of Quail directory which contains Quail packages. | 2118 "Name of Quail directory which contains Quail packages. |
1972 This is a sub-directory of LEIM directory.") | 2119 This is a sub-directory of LEIM directory.") |