From cb1ef55c1a4b5694c907f2ad7a12dcddde957c1b Mon Sep 17 00:00:00 2001 From: Yuanle Song Date: Tue, 4 Feb 2020 23:29:04 +0800 Subject: [PATCH] =?UTF-8?q?v2.2.1=20support=20auto=20convert=201=E3=80=823?= =?UTF-8?q?=20to=201.3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - support auto convert 1。3 to 1.3. This feature is enabled by default. To turn off this feature, (setq zero-input-auto-fix-dot-between-numbers nil) - bugfix: should call (zero-input-pinyin-register-im) once when the code is moved into a function. --- zero-input.el | 96 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 25 deletions(-) diff --git a/zero-input.el b/zero-input.el index e4016a5..167cc74 100644 --- a/zero-input.el +++ b/zero-input.el @@ -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.1 ;; URL: https://gitlab.emacsos.com/sylecn/zero-el ;; Package-Requires: ((emacs "24.3") (s "1.2.0")) @@ -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 @@ -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.1") ;; FSM state (defconst zero-input--state-im-off 'IM-OFF) @@ -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 @@ -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) @@ -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) @@ -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) @@ -591,11 +611,11 @@ 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) - (setq zero-input-candidates candidates) - (setq zero-input-fetch-size (max new-fetch-size - (length candidates))) - (zero-input-just-page-down)))) + #'(lambda (candidates) + (setq zero-input-candidates candidates) + (setq zero-input-fetch-size (max new-fetch-size + (length candidates))) + (zero-input-just-page-down)))) (zero-input-just-page-down)))) (defun zero-input-handle-preedit-char-default (ch) @@ -665,10 +685,10 @@ 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) - (setq zero-input-candidates candidates) - (setq zero-input-fetch-size (max new-fetch-size (length candidates))) - (zero-input-show-candidates candidates))))) + #'(lambda (candidates) + (setq zero-input-candidates candidates) + (setq zero-input-fetch-size (max new-fetch-size (length candidates))) + (zero-input-show-candidates candidates))))) (defun zero-input-backspace-default () "Handle backspace key in `zero-input--state-im-preediting' state." @@ -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) @@ -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 () @@ -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 ;;================== @@ -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'" @@ -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) @@ -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 @@ -1254,14 +1298,14 @@ 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) - (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) - (setq zero-input-pinyin-candidates-pinyin-indices candidates_pinyin_indices) - ;; Note: with dynamic binding, this command result in (void-variable - ;; complete-func) error. - (funcall complete-func candidates)))) + #'(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) + (setq zero-input-pinyin-candidates-pinyin-indices candidates_pinyin_indices) + ;; Note: with dynamic binding, this command result in (void-variable + ;; complete-func) error. + (funcall complete-func candidates)))) (defun zero-input-pinyin-can-start-sequence (ch) "Return t if char CH can start a preedit sequence." @@ -1399,8 +1443,8 @@ 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) - (zero-input-just-page-down)))) + #'(lambda (_candidates) + (zero-input-just-page-down)))) (zero-input-debug "won't fetch more candidates\n") (zero-input-just-page-down)))) @@ -1497,6 +1541,8 @@ DIGIT 0 means delete 10th candidate." (:preedit-start . zero-input-pinyin-preedit-start) (:preedit-end . zero-input-pinyin-preedit-end))))) +(zero-input-pinyin-register-im) + ;;============ ;; public API ;;============ -- GitLab