Author: ek.kato
Date: Wed Feb 25 05:55:29 2009
New Revision: 5864

Modified:
   trunk/scm/social-ime-custom.scm
   trunk/scm/social-ime-key-custom.scm
   trunk/scm/social-ime.scm

Log:
* scm/social-ime.scm : Support input prediction.
  - (social-ime-internal-context-rec-spec) : Cache prediction
    candidates.
  - (social-ime-predict) : New.  Query prediction candidates.
  - (social-ime-lib-alloc-context) : Create interal-context here.
  - (social-ime-lib-begin-conversion) : from here.
  - (social-ime-lib-set-prediction-src-string)
  - (social-ime-lib-get-nr-predictions)
  - (social-ime-lib-get-nth-prediction)
  - (social-ime-lib-commit-nth-prediction)
    - New code to get prediction candidates.
  - (social-ime-context-rec-spec)
  - (social-ime-flush)
  - (social-ime-update-preedit)
  - (social-ime-move-prediction)
  - (social-ime-move-prediction-in-page)
  - (social-ime-prediction-select-non-existing-index?)
  - (social-ime-prediction-keys-handled?)
  - (social-ime-proc-prediction-state)
  - (social-ime-proc-input-state-with-preedit)
  - (social-ime-reset-prediction-window)
  - (social-ime-check-prediction)
  - (social-ime-proc-input-state)
  - (social-ime-predicting-state-preedit)
  - (social-ime-get-prediction-string)
  - (social-ime-learn-prediction-string)
  - (social-ime-do-commit-prediction)
  - (social-ime-press-key-handler)
  - (social-ime-get-candidate-handler)
  - (social-ime-set-candidate-index-handler)
    - Ported from anthy.scm.
* scm/social-ime-custom.scm
  - (social-ime-prediction) : New custom group.
  - (social-ime-prediction-api-path) : Prediction API path.
  - (social-ime-use-prediction?)
  - (social-ime-select-prediction-by-numeral-key?)
  - (social-ime-use-implicit-commit-prediction?)
    - Ported from anthy-custom.scm.
* scm/social-ime-key-custom.scm
  - (social-ime-next-prediction-key)
  - (social-ime-prev-prediction-key)
    - Ported from anthy-key-custom.scm.


Modified: trunk/scm/social-ime-custom.scm
==============================================================================
--- trunk/scm/social-ime-custom.scm     (original)
+++ trunk/scm/social-ime-custom.scm     Wed Feb 25 05:55:29 2009
@@ -47,6 +47,9 @@
                     (N_ "Social-IME (advanced)")
                     (N_ "long description will be here."))

+(define-custom-group 'social-ime-prediction
+                    (N_ "Prediction")
+                    (N_ "long description will be here."))
 ;;
 ;; segment separator
 ;;
@@ -313,6 +316,12 @@
   (N_ "Social-IME server path")
   (N_ "long description will be here."))

+(define-custom 'social-ime-prediction-api-path "/api2/predict.php"
+  '(social-ime-advanced social-ime-server)
+  '(string ".*")
+  (N_ "Social-IME server prediction API path")
+  (N_ "long description will be here."))
+
 (define-custom 'social-ime-user (or (user-name) "")
   '(social-ime-advanced social-ime-server)
   '(string ".*")
@@ -330,3 +339,33 @@
   '(boolean)
   (N_ "Enable input mode transition keys in direct (off state) input mode")
   (N_ "long description will be here."))
+
+;; prediction
+(define-custom 'social-ime-use-prediction? #f
+  '(social-ime-advanced social-ime-prediction)
+  '(boolean)
+  (N_ "Enable input prediction")
+  (N_ "long description will be here."))
+
+(define-custom 'social-ime-select-prediction-by-numeral-key? #f
+  '(social-ime-advanced social-ime-prediction)
+  '(boolean)
+  (N_ "Select prediction candidate by numeral keys")
+  (N_ "long description will be here."))
+
+(define-custom 'social-ime-use-implicit-commit-prediction? #t
+  '(social-ime-advanced social-ime-prediction)
+  '(boolean)
+  (N_ "Show selected prediction candidate in preedit area")
+  (N_ "long description will be here."))
+
+(custom-add-hook 'social-ime-use-candidate-window?
+                 'custom-get-hooks
+                 (lambda ()
+                   (if (not social-ime-use-candidate-window?)
+                       (set! social-ime-use-prediction? #f))))
+
+(custom-add-hook 'social-ime-use-prediction?
+                 'custom-activity-hooks
+                 (lambda ()
+                   social-ime-use-candidate-window?))

Modified: trunk/scm/social-ime-key-custom.scm
==============================================================================
--- trunk/scm/social-ime-key-custom.scm (original)
+++ trunk/scm/social-ime-key-custom.scm Wed Feb 25 05:55:29 2009
@@ -267,3 +267,15 @@
               '(key)
               (N_ "[Social-IME] toggle kana/alphanumeric mode")
               (N_ "long description will be here"))
+
+(define-custom 'social-ime-next-prediction-key '("tab" "down" "<IgnoreCase><Control>n" 
"<IgnoreCase><Control>i")
+               '(social-ime-keys4 prediction)
+               '(key)
+               (N_ "[Social-IME] Next prediction candidate")
+               (N_ "long description will be here"))
+
+(define-custom 'social-ime-prev-prediction-key '(generic-prev-candidate-key)
+               '(social-ime-keys4 prediction)
+               '(key)
+               (N_ "[Social-IME] Previous prediction candidate")
+               (N_ "long description will be here"))

Modified: trunk/scm/social-ime.scm
==============================================================================
--- trunk/scm/social-ime.scm    (original)
+++ trunk/scm/social-ime.scm    Wed Feb 25 05:55:29 2009
@@ -52,7 +52,9 @@
    (list
     (list 'str         "")
     (list 'candidates  '())
-    (list 'seg-cnts '()))))
+    (list 'seg-cnts '())
+    (list 'prediction-candidates '())
+    (list 'prediction-nr '()))))
(define-record 'social-ime-internal-context social-ime-internal-context-rec-spec) (define social-ime-internal-context-new-internal social-ime-internal-context-new)

@@ -116,11 +118,42 @@
   (let ((ret (social-ime-conversion-make-commit-query resize delta)))
     (if (not (string=? ret ""))
         (social-ime-conversion str ret))))
+(define (social-ime-predict str opts)
+  (define (make-query user)
+        (format "~a?string=~a&charset=EUC-JP&applicartion=uim~a~a"
+               social-ime-prediction-api-path
+                (http:encode-uri-string str)
+                user
+                opts))
+  (define (parse str)
+    (and-let* ((ret1 (if (string? str)
+                         (string-split str "\n")
+                         '("")))
+               (col (if (equal? '("") (take-right ret1 1))
+                        (drop-right ret1 1)
+                        ret1))
+               (ret2 (map (lambda (s)
+                            (and-let* ((ret (string-split s "\t"))
+ (low (if (equal? '("") (take-right ret 1))
+                                                (drop-right ret 1)
+                                              ret)))
+                                      low))
+                          col)))
+              (car ret2)))
+  (let* ((user (if (string=? social-ime-user "")
+                   ""
+ (format "&user=~a" (http:encode-uri-string social-ime-user))))
+         (proxy (and (eq? http-proxy-setting 'user)
+ (make-http-proxy http-proxy-hostname http-proxy-port)))
+         (ret (http:get social-ime-server (make-query user) 80 proxy)))
+    (if (string? ret)
+        (parse ret)
+        (list str))))

 (define (social-ime-lib-init)
   #t)
 (define (social-ime-lib-alloc-context)
-  #t)
+  (social-ime-internal-context-new-internal))
 (define (social-ime-lib-get-nth-candidate sc seg nth)
   (let* ((sc-ctx (social-ime-context-sc-ctx sc))
          (cand (social-ime-internal-context-candidates sc-ctx)))
@@ -162,13 +195,12 @@
     #t))
 (define (social-ime-lib-begin-conversion sc str)
   (let* ((cand (social-ime-conversion str ""))
-         (sc-ctx (social-ime-internal-context-new-internal)))
+         (sc-ctx (social-ime-context-sc-ctx sc)))
     (social-ime-internal-context-set-str! sc-ctx str)
     (social-ime-internal-context-set-candidates! sc-ctx cand)
     (social-ime-internal-context-set-seg-cnts!
      sc-ctx
      (make-list (length cand) 0))
-    (social-ime-context-set-sc-ctx! sc sc-ctx)
     (length cand)))
 (define (social-ime-lib-commit-segments sc delta)
   (let* ((sc-ctx (social-ime-context-sc-ctx sc))
@@ -178,6 +210,21 @@
     #t))
 (define (social-ime-lib-reset-conversion sc)
   #f)
+(define (social-ime-lib-set-prediction-src-string sc str)
+  (let ((sc-ctx (social-ime-context-sc-ctx sc))
+       (cands (social-ime-predict str "")))
+    (social-ime-internal-context-set-prediction-candidates! sc-ctx cands)
+    (social-ime-internal-context-set-prediction-nr! sc-ctx (length cands)))
+  #f)
+(define (social-ime-lib-get-nr-predictions sc)
+  (let ((sc-ctx (social-ime-context-sc-ctx sc)))
+    (social-ime-internal-context-prediction-nr sc-ctx)))
+(define (social-ime-lib-get-nth-prediction sc nth)
+  (let* ((sc-ctx (social-ime-context-sc-ctx sc))
+ (cands (social-ime-internal-context-prediction-candidates sc-ctx)))
+    (list-ref cands nth)))
+(define (social-ime-lib-commit-nth-prediction sc nth)
+  #f)


 (define social-ime-init-lib-ok? #f)
@@ -408,12 +455,15 @@
     (list 'state              #f)
     (list 'transposing        #f)
     (list 'transposing-type    0)
+    (list 'predicting         #f)
     (list 'sc-ctx             ()) ;; social-ime-internal-context
     (list 'preconv-ustr              #f) ;; preedit strings
     (list 'rkc                ())
     (list 'segments          #f) ;; ustr of candidate indices
     (list 'candidate-window   #f)
     (list 'candidate-op-count 0)
+    (list 'prediction-window  #f)
+    (list 'prediction-index   #f)
     (list 'kana-mode          social-ime-type-hiragana)
     (list 'alnum             #f)
     (list 'alnum-type        social-ime-type-halfwidth-alnum)
@@ -545,9 +595,12 @@
   (ustr-clear! (social-ime-context-segments sc))
   (social-ime-context-set-transposing! sc #f)
   (social-ime-context-set-state! sc #f)
-  (if (social-ime-context-candidate-window sc)
+  (if (or
+       (social-ime-context-candidate-window sc)
+       (social-ime-context-prediction-window sc))
       (im-deactivate-candidate-selector sc))
   (social-ime-context-set-candidate-window! sc #f)
+  (social-ime-context-set-prediction-window! sc #f)
   (social-ime-context-set-candidate-op-count! sc 0))

 (define (social-ime-begin-input sc key key-state)
@@ -602,7 +655,9 @@
                              (social-ime-context-transposing-state-preedit sc)
                              (if (social-ime-context-state sc)
                                  (social-ime-compose-state-preedit sc)
-                                 (social-ime-input-state-preedit sc)))
+                                 (if (social-ime-context-predicting sc)
+                                     (social-ime-predicting-state-preedit sc)
+                                     (social-ime-input-state-preedit sc))))
                          ())))
        (context-update-preedit sc segments))
       (social-ime-context-set-commit-raw! sc #f)))
@@ -856,6 +911,176 @@
           (social-ime-flush sc)
           (social-ime-proc-input-state sc key key-state))))))))

+(define (social-ime-move-prediction sc offset)
+  (let* ((nr (social-ime-lib-get-nr-predictions sc))
+         (idx (social-ime-context-prediction-index sc))
+         (n (if (not idx)
+               0
+               (+ idx offset)))
+         (compensated-n (cond
+                        ((>= n nr)
+                         0)
+                        ((< n 0)
+                         (- nr 1))
+                        (else
+                         n))))
+    (im-select-candidate sc compensated-n)
+    (social-ime-context-set-prediction-index! sc compensated-n)))
+
+(define (social-ime-move-prediction-in-page sc numeralc)
+  (let* ((nr (social-ime-lib-get-nr-predictions sc))
+        (p-idx (social-ime-context-prediction-index sc))
+        (n (if (not p-idx)
+               0
+               p-idx))
+        (cur-page (if (= social-ime-nr-candidate-max 0)
+                      0
+                      (quotient n social-ime-nr-candidate-max)))
+        (pageidx (- (numeric-ichar->integer numeralc) 1))
+        (compensated-pageidx (cond
+                              ((< pageidx 0) ; pressing key_0
+                               (+ pageidx 10))
+                              (else
+                               pageidx)))
+        (idx (+ (* cur-page social-ime-nr-candidate-max) compensated-pageidx))
+        (compensated-idx (cond
+                          ((>= idx nr)
+                           #f)
+                          (else
+                           idx)))
+        (selected-pageidx (if (not p-idx)
+                              #f
+                              (if (= social-ime-nr-candidate-max 0)
+                                  p-idx
+                                  (remainder p-idx
+                                             social-ime-nr-candidate-max)))))
+    (if (and
+        compensated-idx
+        (not (eqv? compensated-pageidx selected-pageidx)))
+       (begin
+         (social-ime-context-set-prediction-index! sc compensated-idx)
+         (im-select-candidate sc compensated-idx)
+         #t)
+       #f)))
+
+(define (social-ime-prediction-select-non-existing-index? sc numeralc)
+  (let* ((nr (social-ime-lib-get-nr-predictions sc))
+        (p-idx (social-ime-context-prediction-index sc))
+        (cur-page (if (= social-ime-nr-candidate-max 0)
+                      0
+                      (quotient p-idx social-ime-nr-candidate-max)))
+        (pageidx (- (numeric-ichar->integer numeralc) 1))
+        (compensated-pageidx (cond
+                              ((< pageidx 0) ; pressing key_0
+                               (+ pageidx 10))
+                              (else
+                               pageidx)))
+        (idx (+ (* cur-page social-ime-nr-candidate-max) compensated-pageidx)))
+    (if (>= idx nr)
+        #t
+        #f)))
+
+(define (social-ime-prediction-keys-handled? sc key key-state)
+  (cond
+   ((social-ime-next-prediction-key? key key-state)
+    (social-ime-move-prediction sc 1)
+    #t)
+   ((social-ime-prev-prediction-key? key key-state)
+    (social-ime-move-prediction sc -1)
+    #t)
+   ((and
+     social-ime-select-prediction-by-numeral-key?
+     (ichar-numeric? key))
+    (social-ime-move-prediction-in-page sc key))
+   ((and
+     (social-ime-context-prediction-index sc)
+     (social-ime-prev-page-key? key key-state))
+    (im-shift-page-candidate sc #f)
+    #t)
+   ((and
+     (social-ime-context-prediction-index sc)
+     (social-ime-next-page-key? key key-state))
+    (im-shift-page-candidate sc #t)
+    #t)
+   (else
+    #f)))
+
+(define (social-ime-proc-prediction-state sc key key-state)
+  (cond
+   ;; prediction index change
+   ((social-ime-prediction-keys-handled? sc key key-state))
+
+   ;; cancel
+   ((social-ime-cancel-key? key key-state)
+    (if (social-ime-context-prediction-index sc)
+       (social-ime-reset-prediction-window sc)
+       (begin
+         (social-ime-reset-prediction-window sc)
+         (social-ime-proc-input-state sc key key-state))))
+
+   ;; commit
+   ((and
+     (social-ime-context-prediction-index sc)
+     (social-ime-commit-key? key key-state))
+    (social-ime-do-commit-prediction sc))
+   (else
+    (if (and
+        social-ime-use-implicit-commit-prediction?
+        (social-ime-context-prediction-index sc))
+       (cond
+        ((or
+          ;; check keys used in social-ime-proc-input-state-with-preedit
+          (social-ime-begin-conv-key? key key-state)
+          (social-ime-backspace-key? key key-state)
+          (social-ime-delete-key? key key-state)
+          (social-ime-kill-key? key key-state)
+          (social-ime-kill-backward-key? key key-state)
+          (and
+           (not (social-ime-context-alnum sc))
+           (social-ime-commit-as-opposite-kana-key? key key-state))
+          (social-ime-transpose-as-hiragana-key? key key-state)
+          (social-ime-transpose-as-katakana-key? key key-state)
+          (social-ime-transpose-as-halfkana-key? key key-state)
+          (and
+ (not (= (social-ime-context-input-rule sc) social-ime-input-rule-kana))
+           (or
+            (social-ime-transpose-as-halfwidth-alnum-key? key key-state)
+            (social-ime-transpose-as-fullwidth-alnum-key? key key-state)))
+          (social-ime-hiragana-key? key key-state)
+          (social-ime-katakana-key? key key-state)
+          (social-ime-halfkana-key? key key-state)
+          (social-ime-halfwidth-alnum-key? key key-state)
+          (social-ime-fullwidth-alnum-key? key key-state)
+          (and
+           (not (social-ime-context-alnum sc))
+           (social-ime-kana-toggle-key? key key-state))
+          (social-ime-alkana-toggle-key? key key-state)
+          (social-ime-go-left-key? key key-state)
+          (social-ime-go-right-key? key key-state)
+          (social-ime-beginning-of-preedit-key? key key-state)
+          (social-ime-end-of-preedit-key? key key-state)
+          (and
+           (modifier-key-mask key-state)
+           (not (shift-key-mask key-state))))
+         ;; go back to unselected prediction
+         (social-ime-reset-prediction-window sc)
+         (social-ime-check-prediction sc))
+        ((and
+          (ichar-numeric? key)
+          social-ime-select-prediction-by-numeral-key?
+          (not (social-ime-prediction-select-non-existing-index? sc key)))
+         (social-ime-context-set-predicting! sc #f)
+         (social-ime-context-set-prediction-index! sc #f)
+         (social-ime-proc-input-state sc key key-state))
+        (else
+         ;; implicit commit
+         (social-ime-do-commit-prediction sc)
+         (social-ime-proc-input-state sc key key-state)))
+       (begin
+         (social-ime-context-set-predicting! sc #f)
+         (social-ime-context-set-prediction-index! sc #f)
+         (social-ime-proc-input-state sc key key-state))))))
+
 (define (social-ime-proc-input-state-with-preedit sc key key-state)
   (let ((preconv-str (social-ime-context-preconv-ustr sc))
        (raw-str (social-ime-context-raw-ustr sc))
@@ -865,6 +1090,7 @@
     (cond
      ;; begin conversion
      ((social-ime-begin-conv-key? key key-state)
+      (social-ime-reset-prediction-window sc)
       (social-ime-begin-conv sc))

      ;; backspace
@@ -916,6 +1142,7 @@
           (or
            (social-ime-transpose-as-halfwidth-alnum-key? key key-state)
            (social-ime-transpose-as-fullwidth-alnum-key? key key-state))))
+      (social-ime-reset-prediction-window sc)
       (social-ime-proc-transposing-state sc key key-state))

      ((social-ime-hiragana-key? key key-state)
@@ -1084,10 +1311,41 @@
                (ustr-insert-elem! preconv-str residual-kana)
                (rk-flush rkc)))))))

+(define (social-ime-reset-prediction-window sc)
+  (if (social-ime-context-prediction-window sc)
+      (im-deactivate-candidate-selector sc))
+  (social-ime-context-set-predicting! sc #f)
+  (social-ime-context-set-prediction-window! sc #f)
+  (social-ime-context-set-prediction-index! sc #f))
+
+(define (social-ime-check-prediction sc)
+  (if (and
+       (not (social-ime-context-state sc))
+       (not (social-ime-context-transposing sc))
+       (not (social-ime-context-predicting sc)))
+      (let ((preconv-str
+ (social-ime-make-whole-string sc #t (social-ime-context-kana-mode sc))))
+       (if (not (string=? preconv-str ""))
+           (begin
+             (social-ime-lib-set-prediction-src-string sc preconv-str)
+             (let ((nr (social-ime-lib-get-nr-predictions sc)))
+               (if (and
+                    nr
+                    (> nr 0))
+                   (begin
+                     (im-activate-candidate-selector
+                      sc nr social-ime-nr-candidate-max)
+                     (social-ime-context-set-prediction-window! sc #t)
+                     (social-ime-context-set-predicting! sc #t))
+                   (social-ime-reset-prediction-window sc))))
+           (social-ime-reset-prediction-window sc)))))
+
 (define (social-ime-proc-input-state sc key key-state)
   (if (social-ime-has-preedit? sc)
       (social-ime-proc-input-state-with-preedit sc key key-state)
-      (social-ime-proc-input-state-no-preedit sc key key-state)))
+      (social-ime-proc-input-state-no-preedit sc key key-state))
+  (if social-ime-use-prediction?
+      (social-ime-check-prediction sc)))

 (define social-ime-separator
   (lambda (sc)
@@ -1174,6 +1432,14 @@
                "???") ;; FIXME
            "????")))))) ;; shouldn't happen

+(define (social-ime-predicting-state-preedit sc)
+  (if (or
+       (not social-ime-use-implicit-commit-prediction?)
+       (not (social-ime-context-prediction-index sc)))
+      (social-ime-input-state-preedit sc)
+      (let ((cand (social-ime-get-prediction-string sc)))
+       (list (cons (bitwise-ior preedit-reverse preedit-cursor) cand)))))
+
 (define (social-ime-compose-state-preedit sc)
   (let* ((segments (social-ime-context-segments sc))
         (cur-seg (ustr-cursor-pos segments))
@@ -1244,6 +1510,22 @@
     (social-ime-reset-candidate-window sc)
     (social-ime-flush sc))

+(define (social-ime-get-prediction-string sc)
+  (social-ime-lib-get-nth-prediction
+   sc
+   (social-ime-context-prediction-index sc)))
+
+(define (social-ime-learn-prediction-string sc)
+  (social-ime-lib-commit-nth-prediction
+   sc
+   (social-ime-context-prediction-index sc)))
+
+(define (social-ime-do-commit-prediction sc)
+  (im-commit sc (social-ime-get-prediction-string sc))
+  (social-ime-learn-prediction-string sc)
+  (social-ime-reset-prediction-window sc)
+  (social-ime-flush sc))
+
 (define social-ime-correct-segment-cursor
   (lambda (segments)
     (if (ustr-cursor-at-end? segments)
@@ -1462,7 +1744,9 @@
               (social-ime-proc-transposing-state sc key key-state)
               (if (social-ime-context-state sc)
                   (social-ime-proc-compose-state sc key key-state)
-                  (social-ime-proc-input-state sc key key-state)))
+                 (if (social-ime-context-predicting sc)
+                     (social-ime-proc-prediction-state sc key key-state)
+                     (social-ime-proc-input-state sc key key-state))))
          (social-ime-proc-raw-state sc key key-state)))
   (social-ime-update-preedit sc))

@@ -1482,13 +1766,19 @@
 ;;;
 (define (social-ime-get-candidate-handler sc idx ascel-enum-hint)
   (let* ((cur-seg (ustr-cursor-pos (social-ime-context-segments sc)))
-        (cand (social-ime-lib-get-nth-candidate
-               sc cur-seg idx)))
+        (cand (if (social-ime-context-state sc)
+                  (social-ime-lib-get-nth-candidate sc cur-seg idx)
+                  (social-ime-lib-get-nth-prediction sc idx))))
     (list cand (digit->string (+ idx 1)) "")))

 (define (social-ime-set-candidate-index-handler sc idx)
-  (ustr-cursor-set-frontside! (social-ime-context-segments sc) idx)
-  (social-ime-update-preedit sc))
+  (cond
+   ((social-ime-context-state sc)
+    (ustr-cursor-set-frontside! (social-ime-context-segments sc) idx)
+    (social-ime-update-preedit sc))
+   ((social-ime-context-predicting sc)
+    (social-ime-context-set-prediction-index! sc idx)
+    (social-ime-update-preedit sc))))

 (define (social-ime-proc-raw-state sc key key-state)
   (if (not (social-ime-begin-input sc key key-state))

Reply via email to