aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa1999-12-15 00:42:43 +0000
committerKenichi Handa1999-12-15 00:42:43 +0000
commit817e162fea669bc352b6c85314856d10147290ea (patch)
tree7da2aec731639ea70018335cc1960042cd7e75a8
parent72594565dbd47168be99134467cbbd15172cd6bc (diff)
downloademacs-817e162fea669bc352b6c85314856d10147290ea.tar.gz
emacs-817e162fea669bc352b6c85314856d10147290ea.zip
(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
-rw-r--r--lisp/international/quail.el173
1 files changed, 160 insertions, 13 deletions
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index d3bdafc5ad8..018fdd9ee07 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -673,8 +673,12 @@ If TRANSLATION is a Quail map or a function symbol which returns a Quail map,
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
679Optional 2nd arg NAME, if non-nil, is a name of Quail package for
680which to install MAP.
681
678The installed map can be referred by the function `quail-map'." 682The 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"))
@@ -786,8 +790,10 @@ where VECTOR is a vector of candidates (character or string) for
786the translation, and INDEX points into VECTOR to specify the currently 790the translation, and INDEX points into VECTOR to specify the currently
787selected translation." 791selected 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
@@ -955,17 +961,33 @@ The returned value is a Quail map specific to KEY."
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))
@@ -1125,6 +1147,8 @@ The returned value is a Quail map specific to KEY."
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
@@ -1339,6 +1363,7 @@ sequence counting from the head."
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.
@@ -1636,7 +1661,8 @@ or in a newly created frame (if the selected frame has no other windows)."
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))
@@ -1657,10 +1683,13 @@ or in a newly created frame (if the selected frame has no other windows)."
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.
1662All possible translations of the current key and whole possible longer keys 1691All possible translations of the current key and whole possible longer keys
1663 are shown." 1692are 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))
@@ -1700,10 +1729,12 @@ All possible translations of the current key and whole possible longer keys
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))
@@ -1965,6 +1996,122 @@ key binding
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
2005TABLE is an alist, the form is:
2006 ((STATE-0 TRANSITION-0-1 TRANSITION-0-2 ...) (STATE-1 ...) ...)
2007
2008STATE-n are symbols to denote state. STATE-0 is the initial state.
2009
2010TRANSITION-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,
2012RULES is a symbol whose value is an alist of keys \(string) vs the
2013correponding characters or strings. The format of the symbol value of
2014RULES is the same as arguments to `quail-define-rules'.
2015
2016If TRANSITION-n-m has the form (RULES . STATE-x), it means that
2017STATE-n transits to STATE-x when keys in RULES are input. Recursive
2018transition is allowed, i.e. STATE-x may be STATE-n.
2019
2020If TRANSITION-n-m has the form RULES, the transition terminates
2021when keys in RULES are input.
2022
2023The generated map can be set for the current Quail package by the
2024function `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"