Commit 500fd323 authored by Yuanle Song's avatar Yuanle Song
Browse files

build-candidates add fetch-size support;

- handle fetch more in page down function.
- let build-candidates sync version support fetch-size param.
- adjusted some debug log
- tested zero-pinyin and sync and async mode, both works. I can't feel the
  difference.
parent 1ac8945b
......@@ -96,13 +96,13 @@ if item is not in lst, return nil"
;;; concrete input method should define these functions and set them in the
;;; corresponding *-func variable.
(defun zero-build-candidates-default (_preedit-str) nil)
(defun zero-build-candidates-default (_preedit-str _fetch-size) nil)
(defun zero-can-start-sequence-default (_ch) nil)
(defun zero-get-preedit-str-for-panel-default () zero-preedit-str)
(defvar zero-build-candidates-func 'zero-build-candidates-default
"contains a function to build candidates from preedit-str. The function accepts param preedit-str, returns candidate list.")
"contains a function to build candidates from preedit-str. The function accepts param preedit-str, fetch-size, returns candidate list.")
(defvar zero-build-candidates-async-func 'zero-build-candidates-async-default
"contains a function to build candidates from preedit-str. The function accepts param preedit-str, and a complete-func that should be called on returned candidate list.")
"contains a function to build candidates from preedit-str. The function accepts param preedit-str, fetch-size, and a complete-func that should be called on returned candidate list.")
(defvar zero-can-start-sequence-func 'zero-can-start-sequence-default
"contains a function to decide whether a char can start a preedit sequence")
(defvar zero-handle-preedit-char-func 'zero-handle-preedit-char-default
......@@ -152,6 +152,12 @@ otherwise, next single quote insert close quote")
"how many candidates to show on each page"
:group 'zero)
(defvar zero-current-page 0 "current page number. count from 0")
(defvar zero-initial-fetch-size 20
"how many candidates to fetch for the first call to GetCandidates")
;; zero-fetch-size is reset to 0 when preedit-str changes.
;; zero-fetch-size is set to fetch-size in build-candidates-async complete-func
;; lambda.
(defvar zero-fetch-size 0 "last GetCandidates call's fetch-size")
(defvar zero-previous-page-key ?\- "previous page key")
(defvar zero-next-page-key ?\= "next page key")
......@@ -192,23 +198,23 @@ if t, `zero-debug' will output debug msg in *zero-debug* buffer")
(destructuring-bind (x y) (zero-get-point-position)
(zero-panel-move x y))))
(defun zero-build-candidates (preedit-str)
(defun zero-build-candidates (preedit-str fetch-size)
"build candidates list synchronously"
(zero-debug "build candidates list synchronously")
(if (functionp zero-build-candidates-func)
(funcall zero-build-candidates-func preedit-str)
(error "`zero-build-candidates-func' is not a function")))
;; (zero-debug "zero-build-candidates\n")
(unless (functionp zero-build-candidates-func)
(signal 'wrong-type-argument (list 'functionp zero-build-candidates-func)))
(prog1 (funcall zero-build-candidates-func preedit-str fetch-size)
(setq zero-fetch-size fetch-size)))
(defun zero-build-candidates-complete (candidates)
"called when `zero-build-candidates-async' returns"
(setq zero-candidates candidates)
(setq zero-current-page 0)
(zero-show-candidates candidates))
(defun zero-build-candidates-async-default (preedit-str complete-func)
(defun zero-build-candidates-async-default (preedit-str fetch-size complete-func)
"build candidate list, when done show it via `zero-show-candidates'"
(zero-debug "building candidate list asynchronously\n")
(let ((candidates (zero-build-candidates preedit-str)))
;; (zero-debug "zero-build-candidates-async-default\n")
(let ((candidates (zero-build-candidates preedit-str fetch-size)))
;; update cache to make SPC and digit key selection possible.
(funcall complete-func candidates)))
......@@ -278,12 +284,27 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
(setq zero-current-page (1- zero-current-page))
(zero-show-candidates)))
(defun zero-just-page-down ()
"just page down using existing candidates"
(let ((len (length zero-candidates)))
(when (> len (* zero-candidates-per-page (1+ zero-current-page)))
(setq zero-current-page (1+ zero-current-page))
(zero-show-candidates))))
(defun zero-page-down ()
"if there is still candidates to be displayed, show candidates on next page."
(let ((len (length zero-candidates)))
(when (> len (* zero-candidates-per-page (1+ zero-current-page)))
(setq zero-current-page (1+ zero-current-page))
(zero-show-candidates))))
(let ((len (length zero-candidates))
(new-fetch-size (* zero-candidates-per-page (+ 2 zero-current-page))))
(if (and (< len new-fetch-size)
(< zero-fetch-size new-fetch-size))
(funcall zero-build-candidates-async-func
zero-preedit-str
new-fetch-size
(lambda (candidates)
(zero-build-candidates-complete candidates)
(setq zero-fetch-size new-fetch-size)
(zero-just-page-down)))
(zero-just-page-down))))
(defun zero-handle-preedit-char-default (ch)
"hanlde character insert in `*zero-state-im-preediting*' state"
......@@ -333,7 +354,9 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
(defun zero-preedit-str-changed ()
"called when preedit str is changed and not empty. update and show candidate list"
(funcall zero-build-candidates-async-func zero-preedit-str 'zero-build-candidates-complete))
(setq zero-fetch-size 0)
(setq zero-current-page 0)
(funcall zero-build-candidates-async-func zero-preedit-str zero-initial-fetch-size 'zero-build-candidates-complete))
(defun zero-backspace-default ()
"handle backspace key in `*zero-state-im-preediting*' state"
......@@ -424,23 +447,21 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
;; minor mode
;;============
;; TODO when zero-framework is stable, move default value to defvar.
;; this will allow user to customize the keymap.
(defvar zero-mode-map nil "zero-mode keymap")
(setq zero-mode-map
'(keymap
(escape . zero-reset)
(13 . zero-return)
;; C-.
(67108910 . zero-cycle-punctuation-level)
(remap keymap
(self-insert-command . zero-self-insert-command)
;; (forward-char . zero-forward-char)
;; (backward-char . zero-backward-char)
;; (forward-word . zero-forward-word)
;; (backward-word . zero-backward-word)
;; (delete-char . zero-delete-char)
)))
(defvar zero-mode-map
'(keymap
(escape . zero-reset)
(13 . zero-return)
;; C-.
(67108910 . zero-cycle-punctuation-level)
(remap keymap
(self-insert-command . zero-self-insert-command)
;; (forward-char . zero-forward-char)
;; (backward-char . zero-backward-char)
;; (forward-word . zero-forward-word)
;; (backward-word . zero-backward-word)
;; (delete-char . zero-delete-char)
))
"zero-mode keymap")
(define-minor-mode zero-mode
"a Chinese input method framework written as an emacs minor mode.
......@@ -466,6 +487,7 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
(set (make-local-variable 'zero-candidates) nil)
(make-local-variable 'zero-candidates-per-page)
(make-local-variable 'zero-current-page)
(make-local-variable 'zero-fetch-size)
(make-local-variable 'zero-im)
(make-local-variable 'zero-build-candidates-func)
(make-local-variable 'zero-can-start-sequence-func)
......
......@@ -20,8 +20,6 @@
"accompany `zero-candidates', marks how many preedit-str chars are used for each candidate")
(defvar zero-pinyin-pending-str "")
(defvar zero-pinyin-pending-preedit-str "")
(defvar zero-pinyin-initial-fetch-size 20
"how many candidates to fetch for the first call to GetCandidates")
;;=====================
;; key logic functions
......@@ -40,21 +38,27 @@
(defvar zero-pinyin--build-candidates-use-test-data nil
"if t, `zero-pinyin-build-candidates' will use `zero-pinyin-build-candidates-test'")
(defun zero-pinyin-build-candidates (preedit-str)
(defun zero-pinyin-build-candidates (preedit-str fetch-size)
"zero-pinyin-build-candidates synchronous version"
(if zero-pinyin--build-candidates-use-test-data
(zero-pinyin-build-candidates-test preedit-str)
(let ((result (zero-pinyin-service-get-candidates preedit-str zero-pinyin-initial-fetch-size)))
(progn
(zero-pinyin-build-candidates-test preedit-str)
(setq zero-fetch-size fetch-size))
(zero-debug "zero-pinyin building candidate list synchronously\n")
(let ((result (zero-pinyin-service-get-candidates preedit-str fetch-size)))
(setq zero-fetch-size fetch-size)
(setq zero-pinyin-used-preedit-str-lengths (second result))
(first result))))
(defun zero-pinyin-build-candidates-async (preedit-str complete-func)
(defun zero-pinyin-build-candidates-async (preedit-str fetch-size complete-func)
"build candidate list, when done call complete-func on it"
(zero-debug "building candidate list async\n")
(zero-debug "zero-pinyin building candidate list asynchronously\n")
(zero-pinyin-service-get-candidates-async
preedit-str
zero-pinyin-initial-fetch-size
fetch-size
(lambda (candidates matched_preedit_str_lengths)
(setq zero-pinyin-used-preedit-str-lengths matched_preedit_str_lengths)
(setq zero-fetch-size fetch-size)
;; Note: with dynamic binding, this command result in (void-variable
;; complete-func) error.
(funcall complete-func candidates))))
......@@ -77,7 +81,9 @@
(should-not (zero-pinyin-can-start-sequence ?v)))
(defun zero-pinyin-pending-preedit-str-changed ()
(zero-pinyin-build-candidates-async zero-pinyin-pending-preedit-str 'zero-build-candidates-complete))
(setq zero-fetch-size 0)
(setq zero-current-page 0)
(zero-pinyin-build-candidates-async zero-pinyin-pending-preedit-str zero-initial-fetch-size 'zero-build-candidates-complete))
(defun zero-pinyin-commit-nth-candidate (n)
"commit nth candidate and return true if it exists, otherwise, return false"
......@@ -141,6 +147,23 @@ otherwise, just return nil"
t))
(t (error "Unexpected zero-pinyin-state: %s" zero-pinyin-state))))))
(defun zero-pinyin-page-down ()
"handle page down for zero-pinyin.
This is different from zero-framework because I need to support partial commit"
(let ((len (length zero-candidates))
(new-fetch-size (* zero-candidates-per-page (+ 2 zero-current-page))))
(if (and (< len new-fetch-size)
(< zero-fetch-size new-fetch-size))
(let ((preedit-str (if (eq zero-pinyin-state *zero-pinyin-state-im-partial-commit*) zero-pinyin-pending-preedit-str zero-preedit-str)))
(zero-pinyin-build-candidates-async
preedit-str
new-fetch-size
(lambda (candidates)
(zero-build-candidates-complete candidates)
(zero-just-page-down))))
(zero-just-page-down))))
(defun zero-pinyin-handle-preedit-char (ch)
"hanlde character insert in `*zero-state-im-preediting*' state. overrides `zero-handle-preedit-char-default'"
(cond
......@@ -154,9 +177,10 @@ otherwise, just return nil"
(unless (zero-pinyin-commit-nth-candidate (mod (- (- ch ?0) 1) 10))
(zero-append-char-to-preedit-str ch)
(setq zero-pinyin-state nil)))
((or (= ch zero-previous-page-key)
(= ch zero-next-page-key))
((= ch zero-previous-page-key)
(zero-handle-preedit-char-default ch))
((= ch zero-next-page-key)
(zero-pinyin-page-down))
(t (let ((str (zero-convert-punctuation ch)))
(if str
(when (zero-pinyin-commit-first-candidate-in-full)
......@@ -186,7 +210,8 @@ otherwise, just return nil"
(zero-register-im
'pinyin
'((:build-candidates . zero-pinyin-build-candidates)
(:build-candidates-async . zero-pinyin-build-candidates-async)
;; comment to use sync version, uncomment to use async version.
;; (:build-candidates-async . zero-pinyin-build-candidates-async)
(:can-start-sequence . zero-pinyin-can-start-sequence)
(:handle-preedit-char . zero-pinyin-handle-preedit-char)
(:get-preedit-str-for-panel . zero-pinyin-get-preedit-str-for-panel)
......
......@@ -27,7 +27,7 @@
should sort before rhs."
(string< (car lhs) (car rhs)))
(defun zero-table-build-candidates (preedit-str)
(defun zero-table-build-candidates (preedit-str &optional _fetch-size)
(mapcar 'cdr (sort (cl-remove-if-not (lambda (pair) (string-prefix-p preedit-str (car pair))) zero-table-table) 'zero-table-sort-key)))
(ert-deftest zero-table-build-candidates ()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment