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