emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: reverting CJK input methods


From: Kenichi Handa
Subject: Re: reverting CJK input methods
Date: Sat, 8 May 2004 11:56:11 +0900 (JST)
User-agent: SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.2 Emacs/21.3 (sparc-sun-solaris2.6) MULE/5.0 (SAKAKI)

In article <address@hidden>, Werner LEMBERG <address@hidden> writes:

>>  Oops, please try the attached new one.
> It works, thanks!  But I think it is too slow.  On my laptop, testing
> chinese-4corner, it takes up to two seconds until the result is
> displayed.  Maybe input methods with more than, say, six to seven
> thousand elements should use the inverse map.

I still insist on generating a key strings to type on demand
instead of generating a decode-map at loading an input
method because the generation anyway takes some time.

So, I decided to generate a halfly cooked decode-map on
demand, which results in, I hope, reasonable speed for M-x
quail-show-key both at the first attempt and the succeeding
attemts.

Please try the attached new one after byte-compiling it.

> Is it possible to get *all* possible input sequences?  For example, 说
> (shuo1) can also be input as `yue4' in chinese-tonepy, and this is
> what your code currently returns.

Yes, the new code shows all key strings.

---
Ken'ichi HANDA
address@hidden

(require 'quail)

;; Add KEY (string) to the element of TABLE (char-table) for CHAR if
;; it is not yet stored.

(defsubst quail-store-decode-map-key (table char key)
  (let ((elt (aref table char)))
    (if elt
        (if (consp elt)
            (or (member key elt)
                (aset table char (cons key elt)))
          (or (string= key elt)
              (aset table char (list key elt))))
      (aset table char key))))

;; Helper function for quail-gen-decode-map.  Store key strings to
;; type each character under MAP in TABLE (char-table).  MAP is an
;; element of the current Quail map reached by typing keys in KEY
;; (string).

(defun quail-gen-decode-map1 (map key table)
  (when (and (consp map) (listp (cdr map)))
    (let ((trans (car map)))
      (cond ((integerp trans)
             (quail-store-decode-map-key table trans key))
            ((stringp trans)
             (dotimes (i (length trans))
               (quail-store-decode-map-key table (aref trans i) key)))
            ((or (vectorp trans)
                 (and (consp trans)
                      (setq trans (cdr trans))))
             (dotimes (i (length trans))
               (let ((elt (aref trans i)))
                 (if (stringp elt)
                     (if (= (length elt) 1)
                         (quail-store-decode-map-key table (aref elt 0) key))
                   (quail-store-decode-map-key table elt key)))))))
    (if (> (length key) 1)
        (dolist (elt (cdr map))
          (quail-gen-decode-map1 (cdr elt) key table))
      (dolist (elt (cdr map))
        (quail-gen-decode-map1 (cdr elt) (format "%s%c" key (car elt))
                                 table)))))

(put 'quail-decode-map 'char-table-extra-slots 0)

;; Generate a decode map (char-table) for the current Quail map.

(defun quail-gen-decode-map ()
  (let ((table (make-char-table 'quail-decode-map nil)))
    (dolist (elt (cdr (quail-map)))
      (quail-gen-decode-map1 (cdr elt) (string (car elt)) table))
    table))

;; Helper function for quail-find-key.  Prepend key strings to type
;; for inputting CHAR by the current input method to KEY-LIST and
;; return the result.  MAP is an element of the current Quail map
;; reached by typing keys in KEY.

(defun quail-find-key1 (map key char key-list)
  (let ((trans (car map))
        (found-here nil))
    (cond ((stringp trans)
           (setq found-here
                 (and (= (length trans) 1) (= (aref trans 0) char))))
          ((or (vectorp trans) (consp trans))
           (if (consp trans)
               (setq trans (cdr trans)))
           (setq found-here
                 (catch 'tag
                   (dotimes (i (length trans))
                     (let ((target (aref trans i)))
                       (if (integerp target)
                           (if (= target char)
                               (throw 'tag t))
                         (if (and (= (length target) 1)
                                  (= (aref target 0) char))
                             (throw 'tag t))))))))
            ((integerp trans)
             (if (= trans char)
                 (setq found-here t))))
    (if found-here
        (setq key-list (cons key key-list)))
    (if (> (length key) 1)
        (dolist (elt (cdr map))
          (setq key-list
                (quail-find-key1 (cdr elt) (format "%s%c" key (car elt))
                                     char key-list))))
    key-list))

(defun quail-find-key (char)
  "Return a list of key strings to type for inputting CHAR."
  (let ((decode-map (or (quail-decode-map)
                        (setcar (nthcdr 10 quail-current-package)
                                (quail-gen-decode-map))))
        (key-list nil))
    (if (consp decode-map)
        (let ((str (string char)))
          (mapc #'(lambda (elt)
                    (if (string= str (car elt))
                        (setq key-list (cons (cdr elt) key-list))))
                (cdr decode-map)))
      (let ((key-head (aref decode-map char)))
        (if (stringp key-head)
            (setq key-list (quail-find-key1 
                            (quail-lookup-key key-head nil t)
                            key-head char nil))
          (mapc #'(lambda (elt)
                    (setq key-list
                          (quail-find-key1
                           (quail-lookup-key elt nil t) elt char key-list)))
                key-head))))
    key-list))

(defun quail-show-key ()
  "Show a list of key strings to type for inputting a character at point."
  (interactive)
  (let* ((char (following-char))
         (key-list (quail-find-key char)))
    (if key-list
        (message "To input `%c', type \"%s\""
                 char
                 (mapconcat 'identity key-list "\", \""))
      (message "%c can't be input by the current input method" char))))


reply via email to

[Prev in Thread] Current Thread [Next in Thread]