Loading operational +100 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,106 @@ complete registered im symbols. ** 2019-10-23 checkdoc and package-lint can't ignore some non-issues. I can't run them in git pre-commit hook. * done :entry: ** 2020-02-02 zero-el: 如果输入“。”之前和之后输入的是数字,则自动将"。"转换为小数点"."。 (setq zero-input-auto-fix-dot-between-numbers t) enabled by default. - is it easy to implement in elisp? try it in self-insert-command hook. post-self-insert-hook (add-hook 'post-self-insert-hook #'t1-replace-chinese-dot-maybe nil t) see ~/lisp/elisp/testing-only/auto-fix-typing-via-self-insert-command-hook.el it works. when I type 1a3 it will insert 1.3. - I think this can probably work outside zero-input. nope. zero doesn't use self-insert-command for inserting Chinese dot. what does it use? zero-input-pinyin-handle-preedit-char it should be easy to implement the same thing there. - when commit digit, just also add digit in a ring buffer. and check whether there is a Chinese dot to be replaced. - when commit Chinese dot, add Chinese dot in a ring buffer. // These digits and Chinese dot is not part of key IM logic. // zero-input-can-start-sequence will return false for them. // I don't even need to change zero-input-commit-text. - put the feature under a flag. zero-input-auto-fix-dot-between-numbers - problems - how to get last insert char? - how to get last 3 char from a string? (equal (substring "abcde" -3) "cde") (equal (substring "abc" -3) "abc") (equal (substring "ab" -3) "ab") how to loop characters over a string? (mapcar (lambda (ch) ch) "abc") - in elisp, use #'(lambda (x) x) or (lambda (x) x)? Anonymous Functions - GNU Emacs Lisp Reference Manual https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html use #' is better. it is short for (function (lambda (x) ...)). - DONE return key should also insert ?\n to ring buffer. bug reproduce: type 25。<ret> 6 it is converted to 25。.6 where is return key handled when not in preedit mode? debug log: user typed: . cannot start sequence, state=IM_WAITING_INPUT press <ret> doesn't get any debug output. ret is handled here: (define-key zero-input-mode-map (kbd "RET") 'zero-input-return) (define-key zero-input-mode-map (kbd "RET") nil) When not in preedit-mode, I use system default self-insert-command binding for RET key. So I still need the hook. (add-hook 'post-self-insert-hook #'zero-input-post-self-insert nil t) - when I do this, digit key press will insert twice into ring. fixed. only use post-self-insert-hook, drop my explicit call. - when type 。 it is not added to ring buf. // it is added, just doesn't have debug log. because it uses mapc to add ch // to ring. The hook function should handle auto fix Chinese dot in digits. now it works. - WONTFIX backspace should update ring buffer. Oh, I can't restore old char. just remove the newest item in the ring buffer. e.g. 1<backspace>。6 should not be converted to ".6". (define-key zero-input-mode-map (kbd "<backspace>") 'zero-input-backspace) // I don't do anything here. auto fix doesn't work with preedit mode. (define-key zero-input-mode-map (kbd "<backspace>") nil) backspace doesn't run self-insert-command in many major modes. There is nothing I can do. Is there a hook I can use? delete-char - DONE only do auto fix when zero-input-mode is on. - DONE when zero is off, clear the ring buffer. do it in zero-input-reset. ** 2020-02-04 zero-input-pinyin, allow switch between sync and async mode in runtime. title was: zero-input-pinyin.el why sometimes it uses sync call and sometimes it uses async call? Loading zero-input-framework.el +53 −11 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ ;; dependencies ;;============== (eval-when-compile (require 'cl-lib)) (eval-when-compile (require 'cl-lib) (require 'cl-macs)) (require 'ring) (require 's) (require 'zero-input-panel) Loading Loading @@ -132,7 +133,7 @@ If item is not in lst, return nil." ;; zero-input-el version (defvar zero-input-version nil "Zero package version.") (setq zero-input-version "2.1.0") (setq zero-input-version "2.2.0") ;; FSM state (defconst zero-input--state-im-off 'IM-OFF) Loading Loading @@ -186,6 +187,15 @@ Otherwise, next double quote insert close quote.") Used when converting single quote to Chinese quote. If nil, next single quote insert open quote. Otherwise, next single quote insert close quote.") (defvar-local zero-input-recent-insert-chars (make-ring 3) "Store recent insert characters. Used to handle Chinese dot in digit input. e.g. 1。3 could be converted to 1.3.") (defcustom zero-input-auto-fix-dot-between-numbers t "Non-nil means zero should change 1。3 to 1.3." :group 'zero :type 'boolean) (defvar-local zero-input-preedit-str "") (defvar-local zero-input-candidates nil) (defcustom zero-input-candidates-per-page 10 Loading Loading @@ -269,6 +279,12 @@ STRING and OBJECTS are passed to `format'" ;; (zero-input-debug "msg3: %s\n" 24) ;; (zero-input-debug "msg4: %s %s\n" 24 1) (defun zero-input-add-recent-insert-char (ch) "Insert CH to `zero-input-recent-insert-chars'." ;; (cl-assert (and (characterp ch) (not (stringp ch)))) (zero-input-debug "add char to recent chars ring: %s\n" ch) (ring-insert zero-input-recent-insert-chars ch)) (defun zero-input-enter-preedit-state () "Config keymap when enter preedit state." (zero-input-enable-preediting-map) Loading Loading @@ -385,6 +401,7 @@ If there is no full-width char for CH, return it unchanged." (when zero-input-full-width-p (let ((full-width-ch (zero-input-convert-ch-to-full-width ch))) (insert full-width-ch) (zero-input-add-recent-insert-char full-width-ch) full-width-ch))) (defun zero-input-convert-punctuation-basic (ch) Loading Loading @@ -437,6 +454,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (let ((str (zero-input-convert-punctuation ch))) (when str (insert str) (mapc #'zero-input-add-recent-insert-char str) t))) (defun zero-input-append-char-to-preedit-str (ch) Loading Loading @@ -480,7 +498,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) Loading Loading @@ -554,7 +572,7 @@ N is the argument passed to `self-insert-command'." (let ((new-fetch-size (zero-input-get-initial-fetch-size))) (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) (zero-input-show-candidates candidates))))) Loading Loading @@ -582,6 +600,9 @@ N is the argument passed to `self-insert-command'." "Commit given TEXT, reset preedit str, hide candidate list." (zero-input-debug "commit text: %s\n" text) (insert text) ;; insert last 3 characters (if possible) to zero-input-recent-insert-chars (mapc #'zero-input-add-recent-insert-char (if (>= (length text) 3) (substring text -3) text)) (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) Loading Loading @@ -629,6 +650,8 @@ N is the argument passed to `self-insert-command'." (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) (while (not (ring-empty-p zero-input-recent-insert-chars)) (ring-remove zero-input-recent-insert-chars)) (zero-input-hide-candidate-list)) (defun zero-input-focus-in () Loading Loading @@ -707,8 +730,27 @@ Otherwise, show Zero." (add-hook 'focus-in-hook 'zero-input-focus-in) (add-hook 'focus-out-hook 'zero-input-focus-out) (setq zero-input-buffer (current-buffer)) (add-hook 'post-self-insert-hook #'zero-input-post-self-insert-command nil t) (add-hook 'buffer-list-update-hook 'zero-input-buffer-list-changed)) (defun zero-input-post-self-insert-command (&optional ch) "Run after a regular `self-insert-command' is run by zero-input. Argument CH the character that was inserted." ;; `zero-input-auto-fix-dot-between-numbers' is the only feature that ;; requires this ring, so for now if it is nil, no need to maintain the ring ;; for `self-insert-command'. (if (and zero-input-mode zero-input-auto-fix-dot-between-numbers) (let ((ch (or ch (elt (this-command-keys-vector) 0)))) (zero-input-add-recent-insert-char ch) ;; if user typed digit “。” digit, auto convert “。” to “.” (cl-flet ((my-digit-char-p (ch) (and (>= ch ?0) (<= ch ?9)))) (when (and (my-digit-char-p (ring-ref zero-input-recent-insert-chars 0)) (equal ?。 (ring-ref zero-input-recent-insert-chars 1)) (my-digit-char-p (ring-ref zero-input-recent-insert-chars 2))) (delete-char -2) (insert "." (car (ring-elements zero-input-recent-insert-chars)))))))) ;;================== ;; IM developer API ;;================== Loading zero-input-pinyin.el +12 −11 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ ;; dependencies ;;============== (require 'ring) (require 'zero-input-framework) (require 'zero-input-pinyin-service) Loading Loading @@ -67,7 +68,7 @@ You can find the xml file locally at (defvar zero-input-pinyin-pending-str "") (defvar zero-input-pinyin-pending-preedit-str "") (defvar zero-input-pinyin-pending-pinyin-indices nil "Stores `zero-input-pinyin-pending-str' corresponds pinyin indices.") "Store `zero-input-pinyin-pending-str' corresponds pinyin indices.") ;;===================== ;; key logic functions Loading Loading @@ -123,7 +124,7 @@ COMPLETE-FUNC the callback function when async call completes. it's called with (zero-input-pinyin-service-get-candidates-async preedit-str fetch-size (lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) #'(lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max fetch-size (length candidates))) (setq zero-input-pinyin-used-preedit-str-lengths matched_preedit_str_lengths) Loading Loading @@ -268,7 +269,7 @@ This is different from zero-input-framework because I need to support partial co (zero-input-pinyin-build-candidates-unified preedit-str new-fetch-size (lambda (_candidates) #'(lambda (_candidates) (zero-input-just-page-down)))) (zero-input-debug "won't fetch more candidates\n") (zero-input-just-page-down)))) Loading zero-input-table.el +2 −2 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ (defun zero-input-table-build-candidates (preedit-str &optional _fetch-size) "Build candidates by looking up PREEDIT-STR in `zero-input-table-table'." (mapcar 'cdr (sort (cl-remove-if-not (lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) (mapcar 'cdr (sort (cl-remove-if-not #'(lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) ;; (defun zero-input-table-build-candidates-async (preedit-str) ;; "build candidate list, when done show it via `zero-input-table-show-candidates'" Loading Loading @@ -92,7 +92,7 @@ To use demo data, you can call: (\"address\" . \"123 Happy Street\")))" (setq zero-input-table-table alist) (setq zero-input-table-sequence-initials (delete-dups (mapcar (lambda (pair) (substring (car pair) 0 1)) (delete-dups (mapcar #'(lambda (pair) (substring (car pair) 0 1)) zero-input-table-table)))) (provide 'zero-input-table) Loading zero-input.el +69 −25 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ ;; See the License for the specific language governing permissions and ;; limitations under the License. ;; Version: 2.1.0 ;; Version: 2.2.0 ;; URL: https://gitlab.emacsos.com/sylecn/zero-el ;; Package-Requires: ((emacs "24.3") (s "1.2.0")) Loading Loading @@ -51,7 +51,10 @@ ;;; Code: (require 'dbus) (eval-when-compile (require 'cl-lib)) (eval-when-compile (require 'cl-lib) (require 'cl-macs)) (require 'ring) (require 's) ;; body of zero-input-panel.el Loading Loading @@ -243,7 +246,7 @@ If item is not in lst, return nil." ;; zero-input-el version (defvar zero-input-version nil "Zero package version.") (setq zero-input-version "2.1.0") (setq zero-input-version "2.2.0") ;; FSM state (defconst zero-input--state-im-off 'IM-OFF) Loading Loading @@ -297,6 +300,15 @@ Otherwise, next double quote insert close quote.") Used when converting single quote to Chinese quote. If nil, next single quote insert open quote. Otherwise, next single quote insert close quote.") (defvar-local zero-input-recent-insert-chars (make-ring 3) "Store recent insert characters. Used to handle Chinese dot in digit input. e.g. 1。3 could be converted to 1.3.") (defcustom zero-input-auto-fix-dot-between-numbers t "Non-nil means zero should change 1。3 to 1.3." :group 'zero :type 'boolean) (defvar-local zero-input-preedit-str "") (defvar-local zero-input-candidates nil) (defcustom zero-input-candidates-per-page 10 Loading Loading @@ -380,6 +392,12 @@ STRING and OBJECTS are passed to `format'" ;; (zero-input-debug "msg3: %s\n" 24) ;; (zero-input-debug "msg4: %s %s\n" 24 1) (defun zero-input-add-recent-insert-char (ch) "Insert CH to `zero-input-recent-insert-chars'." ;; (cl-assert (and (characterp ch) (not (stringp ch)))) (zero-input-debug "add char to recent chars ring: %s\n" ch) (ring-insert zero-input-recent-insert-chars ch)) (defun zero-input-enter-preedit-state () "Config keymap when enter preedit state." (zero-input-enable-preediting-map) Loading Loading @@ -496,6 +514,7 @@ If there is no full-width char for CH, return it unchanged." (when zero-input-full-width-p (let ((full-width-ch (zero-input-convert-ch-to-full-width ch))) (insert full-width-ch) (zero-input-add-recent-insert-char full-width-ch) full-width-ch))) (defun zero-input-convert-punctuation-basic (ch) Loading Loading @@ -548,6 +567,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (let ((str (zero-input-convert-punctuation ch))) (when str (insert str) (mapc #'zero-input-add-recent-insert-char str) t))) (defun zero-input-append-char-to-preedit-str (ch) Loading Loading @@ -591,7 +611,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) Loading Loading @@ -665,7 +685,7 @@ N is the argument passed to `self-insert-command'." (let ((new-fetch-size (zero-input-get-initial-fetch-size))) (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) (zero-input-show-candidates candidates))))) Loading Loading @@ -693,6 +713,9 @@ N is the argument passed to `self-insert-command'." "Commit given TEXT, reset preedit str, hide candidate list." (zero-input-debug "commit text: %s\n" text) (insert text) ;; insert last 3 characters (if possible) to zero-input-recent-insert-chars (mapc #'zero-input-add-recent-insert-char (if (>= (length text) 3) (substring text -3) text)) (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) Loading Loading @@ -740,6 +763,8 @@ N is the argument passed to `self-insert-command'." (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) (while (not (ring-empty-p zero-input-recent-insert-chars)) (ring-remove zero-input-recent-insert-chars)) (zero-input-hide-candidate-list)) (defun zero-input-focus-in () Loading Loading @@ -818,8 +843,27 @@ Otherwise, show Zero." (add-hook 'focus-in-hook 'zero-input-focus-in) (add-hook 'focus-out-hook 'zero-input-focus-out) (setq zero-input-buffer (current-buffer)) (add-hook 'post-self-insert-hook #'zero-input-post-self-insert-command nil t) (add-hook 'buffer-list-update-hook 'zero-input-buffer-list-changed)) (defun zero-input-post-self-insert-command (&optional ch) "Run after a regular `self-insert-command' is run by zero-input. Argument CH the character that was inserted." ;; `zero-input-auto-fix-dot-between-numbers' is the only feature that ;; requires this ring, so for now if it is nil, no need to maintain the ring ;; for `self-insert-command'. (if (and zero-input-mode zero-input-auto-fix-dot-between-numbers) (let ((ch (or ch (elt (this-command-keys-vector) 0)))) (zero-input-add-recent-insert-char ch) ;; if user typed digit “。” digit, auto convert “。” to “.” (cl-flet ((my-digit-char-p (ch) (and (>= ch ?0) (<= ch ?9)))) (when (and (my-digit-char-p (ring-ref zero-input-recent-insert-chars 0)) (equal ?。 (ring-ref zero-input-recent-insert-chars 1)) (my-digit-char-p (ring-ref zero-input-recent-insert-chars 2))) (delete-char -2) (insert "." (car (ring-elements zero-input-recent-insert-chars)))))))) ;;================== ;; IM developer API ;;================== Loading Loading @@ -1007,7 +1051,7 @@ if IM-NAME is nil, use default empty input method" (defun zero-input-table-build-candidates (preedit-str &optional _fetch-size) "Build candidates by looking up PREEDIT-STR in `zero-input-table-table'." (mapcar 'cdr (sort (cl-remove-if-not (lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) (mapcar 'cdr (sort (cl-remove-if-not #'(lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) ;; (defun zero-input-table-build-candidates-async (preedit-str) ;; "build candidate list, when done show it via `zero-input-table-show-candidates'" Loading Loading @@ -1049,7 +1093,7 @@ To use demo data, you can call: (\"address\" . \"123 Happy Street\")))" (setq zero-input-table-table alist) (setq zero-input-table-sequence-initials (delete-dups (mapcar (lambda (pair) (substring (car pair) 0 1)) (delete-dups (mapcar #'(lambda (pair) (substring (car pair) 0 1)) zero-input-table-table)))) (provide 'zero-input-table) Loading Loading @@ -1198,7 +1242,7 @@ You can find the xml file locally at (defvar zero-input-pinyin-pending-str "") (defvar zero-input-pinyin-pending-preedit-str "") (defvar zero-input-pinyin-pending-pinyin-indices nil "Stores `zero-input-pinyin-pending-str' corresponds pinyin indices.") "Store `zero-input-pinyin-pending-str' corresponds pinyin indices.") ;;===================== ;; key logic functions Loading Loading @@ -1254,7 +1298,7 @@ COMPLETE-FUNC the callback function when async call completes. it's called with (zero-input-pinyin-service-get-candidates-async preedit-str fetch-size (lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) #'(lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max fetch-size (length candidates))) (setq zero-input-pinyin-used-preedit-str-lengths matched_preedit_str_lengths) Loading Loading @@ -1399,7 +1443,7 @@ This is different from zero-input-framework because I need to support partial co (zero-input-pinyin-build-candidates-unified preedit-str new-fetch-size (lambda (_candidates) #'(lambda (_candidates) (zero-input-just-page-down)))) (zero-input-debug "won't fetch more candidates\n") (zero-input-just-page-down)))) Loading Loading
operational +100 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,106 @@ complete registered im symbols. ** 2019-10-23 checkdoc and package-lint can't ignore some non-issues. I can't run them in git pre-commit hook. * done :entry: ** 2020-02-02 zero-el: 如果输入“。”之前和之后输入的是数字,则自动将"。"转换为小数点"."。 (setq zero-input-auto-fix-dot-between-numbers t) enabled by default. - is it easy to implement in elisp? try it in self-insert-command hook. post-self-insert-hook (add-hook 'post-self-insert-hook #'t1-replace-chinese-dot-maybe nil t) see ~/lisp/elisp/testing-only/auto-fix-typing-via-self-insert-command-hook.el it works. when I type 1a3 it will insert 1.3. - I think this can probably work outside zero-input. nope. zero doesn't use self-insert-command for inserting Chinese dot. what does it use? zero-input-pinyin-handle-preedit-char it should be easy to implement the same thing there. - when commit digit, just also add digit in a ring buffer. and check whether there is a Chinese dot to be replaced. - when commit Chinese dot, add Chinese dot in a ring buffer. // These digits and Chinese dot is not part of key IM logic. // zero-input-can-start-sequence will return false for them. // I don't even need to change zero-input-commit-text. - put the feature under a flag. zero-input-auto-fix-dot-between-numbers - problems - how to get last insert char? - how to get last 3 char from a string? (equal (substring "abcde" -3) "cde") (equal (substring "abc" -3) "abc") (equal (substring "ab" -3) "ab") how to loop characters over a string? (mapcar (lambda (ch) ch) "abc") - in elisp, use #'(lambda (x) x) or (lambda (x) x)? Anonymous Functions - GNU Emacs Lisp Reference Manual https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html use #' is better. it is short for (function (lambda (x) ...)). - DONE return key should also insert ?\n to ring buffer. bug reproduce: type 25。<ret> 6 it is converted to 25。.6 where is return key handled when not in preedit mode? debug log: user typed: . cannot start sequence, state=IM_WAITING_INPUT press <ret> doesn't get any debug output. ret is handled here: (define-key zero-input-mode-map (kbd "RET") 'zero-input-return) (define-key zero-input-mode-map (kbd "RET") nil) When not in preedit-mode, I use system default self-insert-command binding for RET key. So I still need the hook. (add-hook 'post-self-insert-hook #'zero-input-post-self-insert nil t) - when I do this, digit key press will insert twice into ring. fixed. only use post-self-insert-hook, drop my explicit call. - when type 。 it is not added to ring buf. // it is added, just doesn't have debug log. because it uses mapc to add ch // to ring. The hook function should handle auto fix Chinese dot in digits. now it works. - WONTFIX backspace should update ring buffer. Oh, I can't restore old char. just remove the newest item in the ring buffer. e.g. 1<backspace>。6 should not be converted to ".6". (define-key zero-input-mode-map (kbd "<backspace>") 'zero-input-backspace) // I don't do anything here. auto fix doesn't work with preedit mode. (define-key zero-input-mode-map (kbd "<backspace>") nil) backspace doesn't run self-insert-command in many major modes. There is nothing I can do. Is there a hook I can use? delete-char - DONE only do auto fix when zero-input-mode is on. - DONE when zero is off, clear the ring buffer. do it in zero-input-reset. ** 2020-02-04 zero-input-pinyin, allow switch between sync and async mode in runtime. title was: zero-input-pinyin.el why sometimes it uses sync call and sometimes it uses async call? Loading
zero-input-framework.el +53 −11 Original line number Diff line number Diff line Loading @@ -34,7 +34,8 @@ ;; dependencies ;;============== (eval-when-compile (require 'cl-lib)) (eval-when-compile (require 'cl-lib) (require 'cl-macs)) (require 'ring) (require 's) (require 'zero-input-panel) Loading Loading @@ -132,7 +133,7 @@ If item is not in lst, return nil." ;; zero-input-el version (defvar zero-input-version nil "Zero package version.") (setq zero-input-version "2.1.0") (setq zero-input-version "2.2.0") ;; FSM state (defconst zero-input--state-im-off 'IM-OFF) Loading Loading @@ -186,6 +187,15 @@ Otherwise, next double quote insert close quote.") Used when converting single quote to Chinese quote. If nil, next single quote insert open quote. Otherwise, next single quote insert close quote.") (defvar-local zero-input-recent-insert-chars (make-ring 3) "Store recent insert characters. Used to handle Chinese dot in digit input. e.g. 1。3 could be converted to 1.3.") (defcustom zero-input-auto-fix-dot-between-numbers t "Non-nil means zero should change 1。3 to 1.3." :group 'zero :type 'boolean) (defvar-local zero-input-preedit-str "") (defvar-local zero-input-candidates nil) (defcustom zero-input-candidates-per-page 10 Loading Loading @@ -269,6 +279,12 @@ STRING and OBJECTS are passed to `format'" ;; (zero-input-debug "msg3: %s\n" 24) ;; (zero-input-debug "msg4: %s %s\n" 24 1) (defun zero-input-add-recent-insert-char (ch) "Insert CH to `zero-input-recent-insert-chars'." ;; (cl-assert (and (characterp ch) (not (stringp ch)))) (zero-input-debug "add char to recent chars ring: %s\n" ch) (ring-insert zero-input-recent-insert-chars ch)) (defun zero-input-enter-preedit-state () "Config keymap when enter preedit state." (zero-input-enable-preediting-map) Loading Loading @@ -385,6 +401,7 @@ If there is no full-width char for CH, return it unchanged." (when zero-input-full-width-p (let ((full-width-ch (zero-input-convert-ch-to-full-width ch))) (insert full-width-ch) (zero-input-add-recent-insert-char full-width-ch) full-width-ch))) (defun zero-input-convert-punctuation-basic (ch) Loading Loading @@ -437,6 +454,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (let ((str (zero-input-convert-punctuation ch))) (when str (insert str) (mapc #'zero-input-add-recent-insert-char str) t))) (defun zero-input-append-char-to-preedit-str (ch) Loading Loading @@ -480,7 +498,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) Loading Loading @@ -554,7 +572,7 @@ N is the argument passed to `self-insert-command'." (let ((new-fetch-size (zero-input-get-initial-fetch-size))) (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) (zero-input-show-candidates candidates))))) Loading Loading @@ -582,6 +600,9 @@ N is the argument passed to `self-insert-command'." "Commit given TEXT, reset preedit str, hide candidate list." (zero-input-debug "commit text: %s\n" text) (insert text) ;; insert last 3 characters (if possible) to zero-input-recent-insert-chars (mapc #'zero-input-add-recent-insert-char (if (>= (length text) 3) (substring text -3) text)) (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) Loading Loading @@ -629,6 +650,8 @@ N is the argument passed to `self-insert-command'." (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) (while (not (ring-empty-p zero-input-recent-insert-chars)) (ring-remove zero-input-recent-insert-chars)) (zero-input-hide-candidate-list)) (defun zero-input-focus-in () Loading Loading @@ -707,8 +730,27 @@ Otherwise, show Zero." (add-hook 'focus-in-hook 'zero-input-focus-in) (add-hook 'focus-out-hook 'zero-input-focus-out) (setq zero-input-buffer (current-buffer)) (add-hook 'post-self-insert-hook #'zero-input-post-self-insert-command nil t) (add-hook 'buffer-list-update-hook 'zero-input-buffer-list-changed)) (defun zero-input-post-self-insert-command (&optional ch) "Run after a regular `self-insert-command' is run by zero-input. Argument CH the character that was inserted." ;; `zero-input-auto-fix-dot-between-numbers' is the only feature that ;; requires this ring, so for now if it is nil, no need to maintain the ring ;; for `self-insert-command'. (if (and zero-input-mode zero-input-auto-fix-dot-between-numbers) (let ((ch (or ch (elt (this-command-keys-vector) 0)))) (zero-input-add-recent-insert-char ch) ;; if user typed digit “。” digit, auto convert “。” to “.” (cl-flet ((my-digit-char-p (ch) (and (>= ch ?0) (<= ch ?9)))) (when (and (my-digit-char-p (ring-ref zero-input-recent-insert-chars 0)) (equal ?。 (ring-ref zero-input-recent-insert-chars 1)) (my-digit-char-p (ring-ref zero-input-recent-insert-chars 2))) (delete-char -2) (insert "." (car (ring-elements zero-input-recent-insert-chars)))))))) ;;================== ;; IM developer API ;;================== Loading
zero-input-pinyin.el +12 −11 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ ;; dependencies ;;============== (require 'ring) (require 'zero-input-framework) (require 'zero-input-pinyin-service) Loading Loading @@ -67,7 +68,7 @@ You can find the xml file locally at (defvar zero-input-pinyin-pending-str "") (defvar zero-input-pinyin-pending-preedit-str "") (defvar zero-input-pinyin-pending-pinyin-indices nil "Stores `zero-input-pinyin-pending-str' corresponds pinyin indices.") "Store `zero-input-pinyin-pending-str' corresponds pinyin indices.") ;;===================== ;; key logic functions Loading Loading @@ -123,7 +124,7 @@ COMPLETE-FUNC the callback function when async call completes. it's called with (zero-input-pinyin-service-get-candidates-async preedit-str fetch-size (lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) #'(lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max fetch-size (length candidates))) (setq zero-input-pinyin-used-preedit-str-lengths matched_preedit_str_lengths) Loading Loading @@ -268,7 +269,7 @@ This is different from zero-input-framework because I need to support partial co (zero-input-pinyin-build-candidates-unified preedit-str new-fetch-size (lambda (_candidates) #'(lambda (_candidates) (zero-input-just-page-down)))) (zero-input-debug "won't fetch more candidates\n") (zero-input-just-page-down)))) Loading
zero-input-table.el +2 −2 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ (defun zero-input-table-build-candidates (preedit-str &optional _fetch-size) "Build candidates by looking up PREEDIT-STR in `zero-input-table-table'." (mapcar 'cdr (sort (cl-remove-if-not (lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) (mapcar 'cdr (sort (cl-remove-if-not #'(lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) ;; (defun zero-input-table-build-candidates-async (preedit-str) ;; "build candidate list, when done show it via `zero-input-table-show-candidates'" Loading Loading @@ -92,7 +92,7 @@ To use demo data, you can call: (\"address\" . \"123 Happy Street\")))" (setq zero-input-table-table alist) (setq zero-input-table-sequence-initials (delete-dups (mapcar (lambda (pair) (substring (car pair) 0 1)) (delete-dups (mapcar #'(lambda (pair) (substring (car pair) 0 1)) zero-input-table-table)))) (provide 'zero-input-table) Loading
zero-input.el +69 −25 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ ;; See the License for the specific language governing permissions and ;; limitations under the License. ;; Version: 2.1.0 ;; Version: 2.2.0 ;; URL: https://gitlab.emacsos.com/sylecn/zero-el ;; Package-Requires: ((emacs "24.3") (s "1.2.0")) Loading Loading @@ -51,7 +51,10 @@ ;;; Code: (require 'dbus) (eval-when-compile (require 'cl-lib)) (eval-when-compile (require 'cl-lib) (require 'cl-macs)) (require 'ring) (require 's) ;; body of zero-input-panel.el Loading Loading @@ -243,7 +246,7 @@ If item is not in lst, return nil." ;; zero-input-el version (defvar zero-input-version nil "Zero package version.") (setq zero-input-version "2.1.0") (setq zero-input-version "2.2.0") ;; FSM state (defconst zero-input--state-im-off 'IM-OFF) Loading Loading @@ -297,6 +300,15 @@ Otherwise, next double quote insert close quote.") Used when converting single quote to Chinese quote. If nil, next single quote insert open quote. Otherwise, next single quote insert close quote.") (defvar-local zero-input-recent-insert-chars (make-ring 3) "Store recent insert characters. Used to handle Chinese dot in digit input. e.g. 1。3 could be converted to 1.3.") (defcustom zero-input-auto-fix-dot-between-numbers t "Non-nil means zero should change 1。3 to 1.3." :group 'zero :type 'boolean) (defvar-local zero-input-preedit-str "") (defvar-local zero-input-candidates nil) (defcustom zero-input-candidates-per-page 10 Loading Loading @@ -380,6 +392,12 @@ STRING and OBJECTS are passed to `format'" ;; (zero-input-debug "msg3: %s\n" 24) ;; (zero-input-debug "msg4: %s %s\n" 24 1) (defun zero-input-add-recent-insert-char (ch) "Insert CH to `zero-input-recent-insert-chars'." ;; (cl-assert (and (characterp ch) (not (stringp ch)))) (zero-input-debug "add char to recent chars ring: %s\n" ch) (ring-insert zero-input-recent-insert-chars ch)) (defun zero-input-enter-preedit-state () "Config keymap when enter preedit state." (zero-input-enable-preediting-map) Loading Loading @@ -496,6 +514,7 @@ If there is no full-width char for CH, return it unchanged." (when zero-input-full-width-p (let ((full-width-ch (zero-input-convert-ch-to-full-width ch))) (insert full-width-ch) (zero-input-add-recent-insert-char full-width-ch) full-width-ch))) (defun zero-input-convert-punctuation-basic (ch) Loading Loading @@ -548,6 +567,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (let ((str (zero-input-convert-punctuation ch))) (when str (insert str) (mapc #'zero-input-add-recent-insert-char str) t))) (defun zero-input-append-char-to-preedit-str (ch) Loading Loading @@ -591,7 +611,7 @@ Return CH's Chinese punctuation if CH is converted. Return nil otherwise." (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) Loading Loading @@ -665,7 +685,7 @@ N is the argument passed to `self-insert-command'." (let ((new-fetch-size (zero-input-get-initial-fetch-size))) (funcall zero-input-build-candidates-async-func zero-input-preedit-str new-fetch-size (lambda (candidates) #'(lambda (candidates) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max new-fetch-size (length candidates))) (zero-input-show-candidates candidates))))) Loading Loading @@ -693,6 +713,9 @@ N is the argument passed to `self-insert-command'." "Commit given TEXT, reset preedit str, hide candidate list." (zero-input-debug "commit text: %s\n" text) (insert text) ;; insert last 3 characters (if possible) to zero-input-recent-insert-chars (mapc #'zero-input-add-recent-insert-char (if (>= (length text) 3) (substring text -3) text)) (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) Loading Loading @@ -740,6 +763,8 @@ N is the argument passed to `self-insert-command'." (setq zero-input-preedit-str "") (setq zero-input-candidates nil) (setq zero-input-current-page 0) (while (not (ring-empty-p zero-input-recent-insert-chars)) (ring-remove zero-input-recent-insert-chars)) (zero-input-hide-candidate-list)) (defun zero-input-focus-in () Loading Loading @@ -818,8 +843,27 @@ Otherwise, show Zero." (add-hook 'focus-in-hook 'zero-input-focus-in) (add-hook 'focus-out-hook 'zero-input-focus-out) (setq zero-input-buffer (current-buffer)) (add-hook 'post-self-insert-hook #'zero-input-post-self-insert-command nil t) (add-hook 'buffer-list-update-hook 'zero-input-buffer-list-changed)) (defun zero-input-post-self-insert-command (&optional ch) "Run after a regular `self-insert-command' is run by zero-input. Argument CH the character that was inserted." ;; `zero-input-auto-fix-dot-between-numbers' is the only feature that ;; requires this ring, so for now if it is nil, no need to maintain the ring ;; for `self-insert-command'. (if (and zero-input-mode zero-input-auto-fix-dot-between-numbers) (let ((ch (or ch (elt (this-command-keys-vector) 0)))) (zero-input-add-recent-insert-char ch) ;; if user typed digit “。” digit, auto convert “。” to “.” (cl-flet ((my-digit-char-p (ch) (and (>= ch ?0) (<= ch ?9)))) (when (and (my-digit-char-p (ring-ref zero-input-recent-insert-chars 0)) (equal ?。 (ring-ref zero-input-recent-insert-chars 1)) (my-digit-char-p (ring-ref zero-input-recent-insert-chars 2))) (delete-char -2) (insert "." (car (ring-elements zero-input-recent-insert-chars)))))))) ;;================== ;; IM developer API ;;================== Loading Loading @@ -1007,7 +1051,7 @@ if IM-NAME is nil, use default empty input method" (defun zero-input-table-build-candidates (preedit-str &optional _fetch-size) "Build candidates by looking up PREEDIT-STR in `zero-input-table-table'." (mapcar 'cdr (sort (cl-remove-if-not (lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) (mapcar 'cdr (sort (cl-remove-if-not #'(lambda (pair) (string-prefix-p preedit-str (car pair))) zero-input-table-table) 'zero-input-table-sort-key))) ;; (defun zero-input-table-build-candidates-async (preedit-str) ;; "build candidate list, when done show it via `zero-input-table-show-candidates'" Loading Loading @@ -1049,7 +1093,7 @@ To use demo data, you can call: (\"address\" . \"123 Happy Street\")))" (setq zero-input-table-table alist) (setq zero-input-table-sequence-initials (delete-dups (mapcar (lambda (pair) (substring (car pair) 0 1)) (delete-dups (mapcar #'(lambda (pair) (substring (car pair) 0 1)) zero-input-table-table)))) (provide 'zero-input-table) Loading Loading @@ -1198,7 +1242,7 @@ You can find the xml file locally at (defvar zero-input-pinyin-pending-str "") (defvar zero-input-pinyin-pending-preedit-str "") (defvar zero-input-pinyin-pending-pinyin-indices nil "Stores `zero-input-pinyin-pending-str' corresponds pinyin indices.") "Store `zero-input-pinyin-pending-str' corresponds pinyin indices.") ;;===================== ;; key logic functions Loading Loading @@ -1254,7 +1298,7 @@ COMPLETE-FUNC the callback function when async call completes. it's called with (zero-input-pinyin-service-get-candidates-async preedit-str fetch-size (lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) #'(lambda (candidates matched_preedit_str_lengths candidates_pinyin_indices) (setq zero-input-candidates candidates) (setq zero-input-fetch-size (max fetch-size (length candidates))) (setq zero-input-pinyin-used-preedit-str-lengths matched_preedit_str_lengths) Loading Loading @@ -1399,7 +1443,7 @@ This is different from zero-input-framework because I need to support partial co (zero-input-pinyin-build-candidates-unified preedit-str new-fetch-size (lambda (_candidates) #'(lambda (_candidates) (zero-input-just-page-down)))) (zero-input-debug "won't fetch more candidates\n") (zero-input-just-page-down)))) Loading