egg-980315.
[elisp/egg.git] / its.el
diff --git a/its.el b/its.el
index 513e392..89c5bd2 100644 (file)
--- a/its.el
+++ b/its.el
@@ -31,7 +31,6 @@
 ;;; Code:
 
 (require 'cl)
-(require 'egg-edep)
 
 (defvar its-current-map nil)
 (make-variable-buffer-local 'its-current-map)
 ;;
 ;;
 
-(require 'its-keydef)
+(eval-when (eval load compile)
+  (require 'its-keydef))
 
 (defvar its-mode-map
   (let ((map (make-sparse-keymap))
     (define-key map "\M-k" 'its-katakana)
     (define-key map "\M-<" 'its-hankaku)
     (define-key map "\M->" 'its-zenkaku)
+    (its-define-select-keys map t)
     map)
   "Keymap for ITS mode.")
 
-(fset 'its-mode-map its-mode-map)
-
 (defvar its-fence-open  "|" "*\e$B%U%'%s%9$N;OE@$r<($9J8;zNs\e(B (1 \e$BJ8;z0J>e\e(B)")
 (defvar its-fence-close "|" "*\e$B%U%'%s%9$N=*E@$r<($9J8;zNs\e(B (1 \e$BJ8;z0J>e\e(B)")
 (defvar its-fence-face  nil "*\e$B%U%'%s%9I=<($KMQ$$$k\e(B face \e$B$^$?$O\e(B nil")
-(defvar its-fence-invisible  nil)
 
 (defconst its-setup-fence-before-insert-SYL nil)
 
     (if face (cdr face) its-fence-face)))
 
 (defun its-put-cursor (cursor)
-  (let ((p (point)))
+  (let ((p (point))
+       (map (copy-keymap its-mode-map)))
+    (its-define-select-keys map)
     (insert "!")
-    (add-text-properties p (point) (list 'local-map 'its-mode-map
+    (add-text-properties p (point) (list 'local-map map
                                         'read-only t
                                         'invisible t
                                         'intangible 'its-part-2
   (let ((open-props '(its-start t intangible its-part-1))
        (close-props '(rear-nonsticky t its-end t intangible its-part-2))
        (p (point)) p1)
-    ;; Put open-fence before inhibit-read-only to detect read-only
+    ;; Put open-fence before inhibit-read-only to detect read-nly
     (insert its-fence-open)
     (let ((inhibit-read-only t))
       (setq p1 (point))
       (add-text-properties p p1 open-props)
       (insert its-fence-close)
       (add-text-properties p1 (point) close-props)
-      (if its-fence-invisible
+      (if its-fence-face
          (put-text-property p (point) 'invisible t))
       (put-text-property p (point) 'read-only t)
       (goto-char p1)
-      (its-define-select-keys its-mode-map t)
       (its-put-cursor t))))
 
 (defun its-start (key)
     (its-input syl key)))
 
 (defun its-initial-ISYL ()
-  (its-get-start-state (symbol-value its-current-map)))
+  (its-get-start-state its-current-map))
 
 (defun its-make-VSYL (keyseq)
   (cons keyseq (length keyseq)))
                                 'read-only t
                                 'intangible 'its-part-1))
       (if its-fence-face
-         (egg-set-face p (point) (its-get-fence-face)))
+         (put-text-property p (point) 'face (its-get-fence-face)))
       (its-set-cursor-status cursor))))
 
 (defun its-buffer-delete-SYL (syl)
        cursor)
     (if (null syl)
        (setq syl (its-initial-ISYL)))
-    (if (numberp (cdr syl))
-       nil
-      (while (and syl (< i len))
-       (setq cursor (its-state-machine syl (aref keyseq i) emit))
-       (cond
-        ((eq cursor 'its-keyseq-test-failed)
-         (setq syl nil))
-        (cursor
-         (setq syl (its-initial-ISYL)))
-        (t
-         its-latest-SYL))
-       (setq i (1+ i)))
-      (if (and syl eol)
-         (setq cursor (its-state-machine syl -1 emit)))
-      (not (eq cursor 'its-keyseq-test-failed)))))
+    (while (and syl (< i len))
+      (setq cursor (its-state-machine syl (aref keyseq i) emit))
+      (cond
+       ((eq cursor 'its-keyseq-test-failed)
+       (setq syl nil))
+       (cursor
+       (setq syl (its-initial-ISYL)))
+       (t
+       its-latest-SYL))
+      (setq i (1+ i)))
+    (if (and syl eol)
+       (setq cursor (its-state-machine syl -1 emit)))
+    (not (eq cursor 'its-keyseq-test-failed))))
 \f
 ;;;
 ;;; Name --> map
 (defmacro define-its-state-machine (map name indicator lang doc &rest exprs)
   `(progn
      (eval-when (eval compile)
-       (let ((its-current-map 'its-temporaly-map)
-            (its-temporaly-map (its-new-map ,name ,indicator ,lang)))
+       (let ((its-current-map (its-new-map ,name ,indicator ,lang)))
         ,@exprs
-        (setq ,map its-temporaly-map)))
+        (setq ,map its-current-map)))
      (define-its-compiled-map ,map ,doc)))
 
 (defmacro define-its-compiled-map (map doc)
 
 (defmacro define-its-state-machine-append (map &rest exprs)
   (append
-   `(let ((its-current-map 'its-temporaly-map)
-         (its-temporaly-map ,map)))
+   `(let ((its-current-map ,map)))
    exprs
-   (list `(setq ,map its-temporaly-map))))
+   (list `(setq ,map its-current-map))))
 
 ;;
 ;; Construct State Machine
@@ -588,8 +583,7 @@ Return last state."
 (defun its-goto-state (input &optional initial-state build-if-none)
   (let ((len (length input))
        (i 0)
-       (state (or initial-state
-                  (its-get-start-state (symbol-value its-current-map)))))
+       (state (or initial-state (its-get-start-state its-current-map))))
     (while (< i len)
       (setq state
            (or (its-get-next-state state (aref input i))
@@ -644,22 +638,6 @@ Return last state."
                t))
 \f
 ;;;
-(defun its-set-part-1 (beg end)
-  (let ((inhibit-point-motion-hooks t)
-       (str (buffer-substring beg end)))
-    (goto-char beg)
-    (delete-region beg end)
-    (put-text-property 0 (- end beg) 'intangible 'its-part-1 str)
-    (insert str)))
-
-(defun its-set-part-2 (beg end)
-  (let ((inhibit-point-motion-hooks t)
-       (str (buffer-substring beg end)))
-    (goto-char beg)
-    (delete-region beg end)
-    (put-text-property 0 (- end beg) 'intangible 'its-part-2 str)
-    (insert str)))
-
 (defun its-beginning-of-input-buffer ()
   (interactive)
   (let ((inhibit-read-only t))
@@ -667,7 +645,7 @@ Return last state."
     (if (not (get-text-property (1- (point)) 'its-start))
        (let ((begpos (previous-single-property-change (point) 'its-start)))
          ;; Make SYLs have property of "part 2"
-         (its-set-part-2 begpos (point))
+         (put-text-property begpos (point) 'intangible 'its-part-2)
          (goto-char begpos)))
     (its-put-cursor t)))
 
@@ -678,7 +656,7 @@ Return last state."
     (if (not (get-text-property (point) 'its-end))
        (let ((endpos (next-single-property-change (point) 'its-end)))
          ;; Make SYLs have property of "part 1"
-         (its-set-part-1 (point) endpos)
+         (put-text-property (point) endpos 'intangible 'its-part-1)
          (goto-char endpos)))
     (its-put-cursor t)))
 
@@ -712,7 +690,7 @@ Return last state."
   (let ((inhibit-read-only t))
     (delete-region (if (get-text-property (1- (point)) 'its-start)
                       (point)
-                    (previous-single-property-change (point) 'its-start))
+                    (previous-single-property-change (1- (point)) 'its-start))
                   (if (get-text-property (point) 'its-end)
                       (point)
                     (next-single-property-change (point) 'its-end)))
@@ -733,7 +711,7 @@ Return last state."
       (setq syl (get-text-property (1- p) 'its-syl))
       (setq n (1- n)))
     ;; Make SYLs have property of "part 2"
-    (its-set-part-2 p old-point)
+    (put-text-property p old-point 'intangible 'its-part-2)
     (goto-char p)
     (its-put-cursor t)
     (if (> n 0)
@@ -753,7 +731,7 @@ Return last state."
       (setq syl (get-text-property p 'its-syl))
       (setq n (1- n)))
     ;; Make SYLs have property of "part 1"
-    (its-set-part-1 old-point p)
+    (put-text-property old-point p 'intangible 'its-part-1)
     (goto-char p)
     (its-put-cursor t)
     (if (> n 0)
@@ -821,53 +799,55 @@ Return last state."
 
 ;; TODO: killflag
 (defun its-delete-backward-within-SYL (syl n killflag)
-  (if (let* ((keyseq (its-get-keyseq-syl syl))
-            (len (length keyseq))
-            (p (- (point) (length (its-get-output syl))))
-            (its-current-map (get-text-property (1- (point)) 'its-map))
-            (its-current-language (get-text-property (1- (point)) 'egg-lang))
-            back pp)
-       (if (< n 0)
-           (signal 'args-out-of-range (list (- (point) n) (point))))
-       (if its-delete-by-keystroke
-           (while (null (or (eq p pp) (its-concrete-DSYL-p syl)))
-             (setq pp p)
-             (while (and (setq syl (get-text-property (1- p) 'its-syl))
-                         (its-DSYL-with-back-p syl)
-                         (<= (setq back (- (its-get-kst/t syl))) len)
-                         (> back (- len n))
-                         (equal (substring (its-get-keyseq syl) (- back))
-                                (substring keyseq 0 back)))
-               (setq keyseq (concat (its-get-keyseq-syl syl) keyseq)
-                     len (length keyseq)
-                     p (- p (length (its-get-output syl)))))
-             (if (and (eq p pp) syl (> n len))
-                 (setq n (- n len)
-                       keyseq (its-get-keyseq-syl syl)
-                       len (length keyseq)
-                       p (- p (length (its-get-output syl))))))
-         (if (and (> n len) (its-concrete-DSYL-p syl))
-             (setq len 1)))
-       (if (> n len)
-           (setq n (- n len)
-                 len 0))
-       (while (and (> n len) (setq syl (get-text-property (1- p) 'its-syl)))
-         (setq n (1- n)
-               p (- p (length (its-get-output syl)))))
-       (if (> n len)
-           (signal 'beginning-of-buffer nil))
-       (delete-region p (point))
-       (if (> len n)
-           (its-state-machine-keyseq (substring keyseq 0 (- len n)) 
-                                     'its-buffer-ins/del-SYL)
-         (its-set-cursor-status
-          (if (or (null its-delete-by-keystroke)
-                  (its-concrete-DSYL-p (get-text-property (1- p) 'its-syl)))
-              t
-            'its-cursor)))
-       (and (get-text-property (1- (point)) 'its-start)
-            (get-text-property (1+ (point)) 'its-end)))
-      (its-exit-mode-internal)))
+  (let* ((keyseq (its-get-keyseq-syl syl))
+        (len (length keyseq))
+        (p (- (point) (length (its-get-output syl))))
+        (its-current-map (get-text-property (1- (point)) 'its-map))
+        (its-current-language (get-text-property (1- (point)) 'egg-lang))
+        back pp)
+    (if (< n 0)
+       (signal 'args-out-of-range (list (- (point) n) (point))))
+    (if its-delete-by-keystroke
+      (while (null (or (eq p pp) (its-concrete-DSYL-p syl)))
+         (setq pp p)
+         (while (and (setq syl (get-text-property (1- p) 'its-syl))
+                     (its-DSYL-with-back-p syl)
+                     (<= (setq back (- (its-get-kst/t syl))) len)
+                     (> back (- len n))
+                     (equal (substring (its-get-keyseq syl) (- back))
+                            (substring keyseq 0 back)))
+           (setq keyseq (concat (its-get-keyseq-syl syl) keyseq)
+                 len (length keyseq)
+                 p (- p (length (its-get-output syl)))))
+         (if (and (eq p pp) syl (> n len))
+             (setq n (- n len)
+                   keyseq (its-get-keyseq-syl syl)
+                   len (length keyseq)
+                   p (- p (length (its-get-output syl))))))
+      (if (and (> n len) (its-concrete-DSYL-p syl))
+         (setq len 1)))
+    (if (> n len)
+       (setq n (- n len)
+             len 0))
+    (while (and (> n len) (setq syl (get-text-property (1- p) 'its-syl)))
+      (setq n (1- n)
+           p (- p (length (its-get-output syl)))))
+    (if (> n len)
+       (signal 'beginning-of-buffer nil))
+    (delete-region p (point))
+    (cond
+     ((> len n)
+      (its-state-machine-keyseq (substring keyseq 0 (- len n)) 
+                               'its-buffer-ins/del-SYL))
+     ;; Check if empty
+     ((and (get-text-property (1- (point)) 'its-start)
+          (get-text-property (1+ (point)) 'its-end))
+      (its-exit-mode-internal))
+     ((and its-delete-by-keystroke
+          (null (its-concrete-DSYL-p (get-text-property (1- p) 'its-syl))))
+      (its-set-cursor-status 'its-cursor))
+     (t
+      (its-set-cursor-status t)))))
 
 (defun its-transpose-chars (n)
   (interactive "p")
@@ -938,39 +918,29 @@ Return last state."
 
 (defun its-setup-yanked-portion (start end)
   (let ((yank-before (eq (point) end))
-       syl lang source no-prop-source len i j l)
-    (setq source (buffer-substring start end)
-         no-prop-source (buffer-substring-no-properties start end)
-         len (length source))
-    (remove-text-properties 0 len '(intangible nil) source)
-    (egg-separate-languages source (get-text-property (1- start) 'egg-lang))
-    (setq i 0)
-    (while (< i len)
-      (setq lang (get-text-property i 'egg-lang source))
+       (max-sisheng (make-char 'chinese-sisheng 127))
+       p syl lang)
+    (remove-text-properties start end '(intangible nil))
+    (egg-separate-languages start end t)
+    (goto-char start)
+    (while (< (point) end)
+      (setq p (point)
+           lang (get-text-property p 'egg-lang))
       (if (and
-          (or (eq lang 'Chinese-GB) (eq lang 'Chinese-CNS))
-          (setq l (egg-chinese-syllable source i)))
-         (setq j (+ i l))
-       (setq j (+ i (egg-char-bytes (egg-string-to-char-at source i)))))
-      (setq syl (substring no-prop-source i j))
-      (put-text-property i j 'its-syl (cons syl syl) source)
-      (setq i j))
-    (if its-fence-face
-       (let (its-current-language)
-         (setq i 0)
-         (while (< i len)
-           (setq j (egg-next-single-property-change i 'egg-lang source len)
-                 its-current-language (get-text-property i 'egg-lang source))
-         (egg-set-face i j (its-get-fence-face) source)
-         (setq i j))))
-    (delete-region start end)
+          (or (equal lang "Chinese-GB") (equal lang "Chinese-CNS"))
+          (<= (following-char) max-sisheng)
+          (setq len (egg-chinese-syllable (buffer-substring (point) end))))
+         (goto-char (+ (point) len))
+       (forward-char))
+      (setq syl (buffer-substring-no-properties p (point)))
+      (put-text-property p (point) 'its-syl (cons syl syl))
+      (if its-fence-face
+         (let ((its-current-language (get-text-property p 'egg-lang)))
+           (put-text-property p (point) 'face (its-get-fence-face)))))
     (if yank-before
-       (progn
-         (add-text-properties 0 len '(read-only t intangible its-part-1) source)
-         (insert source))
+       (add-text-properties start end '(read-only t intangible its-part-1))
+      (add-text-properties start end '(read-only t intangible its-part-2))
       (delete-region (point) (1+ (point)))
-      (add-text-properties 0 len '(read-only t intangible its-part-2) source)
-      (insert source)
       (goto-char start)
       (its-put-cursor t))))
 
@@ -979,8 +949,7 @@ Return last state."
   (let ((cursor (get-text-property (point) 'its-cursor)))
     ;; key "END"
     (if (null cursor)
-       (let ((its-current-language (get-text-property (1- (point)) 'egg-lang)))
-         (its-input (get-text-property (1- (point)) 'its-syl) -1)))
+       (its-input (get-text-property (1- (point)) 'its-syl) -1))
     (delete-region (point) (1+ (point)))))
 
 (defun its-exit-mode ()
@@ -1012,10 +981,7 @@ Return last state."
     (if proceed-to-conversion
        (egg-convert-region start end)
       ;; Remove all properties
-      (goto-char start)
-      (setq s (buffer-substring-no-properties start end))
-      (delete-region start end)
-      (insert s)
+      (set-text-properties start end nil)
       (egg-do-auto-fill)
       (run-hooks 'input-method-after-insert-chunk-hook))))
 
@@ -1079,7 +1045,7 @@ Return last state."
     (insert its-translation-result)))
 \f
 (defun its-set-mode-line-title ()
-  (let ((title (its-get-indicator (symbol-value its-current-map))))
+  (let ((title (its-get-indicator its-current-map)))
     (setq current-input-method-title (if its-previous-select-func
                                         (concat "<" title ">")
                                       title))