Commit 1013e01e authored by Yuanle Song's avatar Yuanle Song
Browse files

v1.2.0 zero-framework supports full-width mode

user can toggle full-width mode via C-c , .
or they can set zero-full-width-mode in buffer or use setq-default to
set default value for all buffers.
parent ab606397
Loading
Loading
Loading
Loading
+70 −22
Original line number Diff line number Diff line
@@ -12,15 +12,15 @@ cd ~/lisp/elisp/zero/
  implemented in zero-framework.el

  | Imp | state            | action                                              | next state       | trigger action                                                                                          |
  |-----+------------------+-----------------------------------------------------+------------------+---------------------------------------------------------------------|
  |-----+------------------+-----------------------------------------------------+------------------+---------------------------------------------------------------------------------------------------------|
  | Y   | IM_OFF           | M-x zero-on or zero-toggle                          | IM_WAITING_INPUT | turn on minor mode                                                                                      |
  | Y   | IM_WAITING_INPUT | type M-x zero-off or zero-toggle                    | IM_OFF           | turn off minor mode                                                                                     |
  | Y   | IM_WAITING_INPUT | type character that can start a sequence            | IM_PREEDITING    | update preedit str, show candidate list                                                                 |
  | Y   | IM_WAITING_INPUT | type character that can not start a sequence        | IM_WAITING_INPUT | insert character                                                    |
  | Y   | IM_WAITING_INPUT | type [,.?!\]                                        | IM_WAITING_INPUT | insert Chinese punctuation character                                |
  | Y   | IM_WAITING_INPUT | type character that can not start a sequence        | IM_WAITING_INPUT | insert character (full-width aware)                                                                     |
  | Y   | IM_WAITING_INPUT | type [,.?!\]                                        | IM_WAITING_INPUT | insert Chinese punctuation character (full-width aware)                                                 |
  | Y   | IM_PREEDITING    | type character (that is not SPC, digit keys)        | IM_PREEDITING    | update preedit str, update and show candidate list                                                      |
  | Y   | IM_PREEDITING    | type RET                                            | IM_WAITING_INPUT | commit preedit str, hide candidate list, reset preedit str          |
  | Y   | IM_PREEDITING    | type SPC                                            | IM_WAITING_INPUT | commit first candidate or preedit str, reset preedit str            |
  | Y   | IM_PREEDITING    | type RET                                            | IM_WAITING_INPUT | commit preedit str (full-width aware), hide candidate list, reset preedit str                           |
  | Y   | IM_PREEDITING    | type SPC                                            | IM_WAITING_INPUT | commit first candidate or preedit str (full-width aware), reset preedit str                             |
  | Y   | IM_PREEDITING    | type digit keys                                     | IM_WAITING_INPUT | commit nth candidate if it exists, otherwise, append to preedit str                                     |
  |     | IM_PREEDITING    | type C-g                                            | IM_WAITING_INPUT | reset IM (reset preedit str, hide candidate list)                                                       |
  | Y   | IM_PREEDITING    | type M-x zero-off or zero-toggle                    | IM_OFF           | reset IM, turn off minor mode                                                                           |
@@ -28,7 +28,7 @@ cd ~/lisp/elisp/zero/
  | Y   | IM_PREEDITING    | type <backspace>, when preedit str is length 1      | IM_WAITING_INPUT | reset IM                                                                                                |
  | Y   | IM_PREEDITING    | focus in                                            | IM_PREEDITING    | show candidat list                                                                                      |
  | Y   | IM_PREEDITING    | focus out                                           | IM_PREEDITING    | hide panel                                                                                              |
  | Y   | IM_PREEDITING    | type [,.?!\]                                        | IM_WAITING_INPUT | commit first candidate or preedit str, insert Chinese punctuation   |
  | Y   | IM_PREEDITING    | type [,.?!\]                                        | IM_WAITING_INPUT | commit first candidate or preedit str (full-width aware), insert Chinese punctuation (full-width aware) |
  | Y   | IM_PREEDITING    | type -/=                                            | IM_PREEDITING    | candiate page up/down                                                                                   |
  |     |                  |                                                     |                  |                                                                                                         |

@@ -80,6 +80,7 @@ cd ~/lisp/elisp/zero/
* later                                                               :entry:
* current                                                             :entry:
** 
* done                                                                :entry:
** 2019-10-08 support full-width characters and symbols.
全角 半角

@@ -107,8 +108,17 @@ cd ~/lisp/elisp/zero/

    FSM table:
    move from gtk-im-module-zero operational file.
  - 
  - updated FSM.
    so it's only a few changes.
    - when insert character that can't start a sequence, insert char should be
      full-width aware.

      zero-self-insert-command
      DONE zero-commit-preedit-str
      DONE zero-convert-punctuation

    - when commit preedit str, insert should be full-width aware.
    - when insert Chinese punctuation character, insert should be full-width aware.
- problems
  - where is the GB standard file?
  - docs
@@ -148,5 +158,43 @@ cd ~/lisp/elisp/zero/
    how to add C-c , as prefix key and add binding for those two commands?
    it works.

* done                                                                :entry:
  - elisp how to convert unicode hex to char?
    1. Non-ASCII Characters
    https://ftp.gnu.org/old-gnu/Manuals/elisp-manual-21-2.8/html_chapter/elisp_33.html#SEC541

    FF01 to FF65    only 65 chars. I will just type it.
    "\uff01" !

    char to code point:
    (split-char ?\)(unicode 0 255 1)

    # FF01
    (split-char ?\!)(unicode 0 255 1)
    (insert (make-char 'unicode 0 255 1))
    (split-char ?\!)(ascii 33)
    # FF5A
    (split-char ?\z)(unicode 0 255 90)
    (insert (make-char 'unicode 0 255 90))
    (split-char ?\z)(ascii 122)
    # FF65
    (split-char ?\・)(unicode 0 255 101)
    (insert (make-char 'unicode 0 255 101))

    ascii [33, 122]
    map to
    unicode 0 255 [1, 101].

    then pick a few others if they are of importance.

  - commit preedit str in full-width mode didn't work.
    it still commit half-width str.

    is zero-commit-preedit-str called at all? there is no debug message.
    that is for commit preedit-str when there is no candidate.

    when I press RET, the code is in zero-return.

  - type = will insert both full-width char and half-width char.
    fixed.

* wontfix                                                             :entry:
+62 −10
Original line number Diff line number Diff line
@@ -17,6 +17,17 @@

;; zero-framework is a Chinese input method framework for emacs, implemented
;; as an emacs minor mode.
;;
;; You can cycle zero-punctuation-level by C-c , ,
;; You can change default Chinese punctuation level:
;;
;;   (setq-default zero-punctuation-level *zero-punctuation-level-full*)
;;
;; You can toggle full-width mode by C-c , .
;; You can enable full-width mode by default:
;;
;;   (setq-default zero-full-width-mode t)
;;

;;; Code:

@@ -127,7 +138,7 @@ if item is not in lst, return nil"

;; zero-el version
(defvar zero-version nil "zero-el package version")
(setq zero-version "1.1.0")
(setq zero-version "1.2.0")

;; FSM state
(defconst *zero-state-im-off* 'IM-OFF)
@@ -313,15 +324,53 @@ enough elements, return lst as it is."
    ;; update cache to make SPC and digit key selection possible.
    (funcall complete-func candidates)))

(defvar zero-full-width-char-map
  ;; ascii 33 to 126 map to
  ;; unicode FF01 to FF5E
  (cl-loop
   for i from 33 to 126
   collect (cons (make-char 'ascii i) (make-char 'unicode 0 255 (- i 32))))
  "an alist that map half-width char to full-width char")

(defun zero-convert-ch-to-full-width (ch)
  (let ((pair (assoc ch zero-full-width-char-map)))
    (if pair (cdr pair) ch)))

(ert-deftest zero-convert-ch-to-full-width ()
  (should (= (zero-convert-ch-to-full-width ?\!) ?\!)))

(defun zero-convert-str-to-full-width (s)
  "convert each char in s to their full-width char if there is one"
  (concat (mapcar 'zero-convert-ch-to-full-width s)))

(ert-deftest zero-convert-str-to-full-width ()
  (should (string-equal "!" (zero-convert-str-to-full-width "!")))
  (should (string-equal "(" (zero-convert-str-to-full-width "(")))
  (should (string-equal "(:)" (zero-convert-str-to-full-width "(:)")))
  (should (string-equal "ABab" (zero-convert-str-to-full-width "ABab")))
  (should (string-equal "hehe" (zero-convert-str-to-full-width "hehe")))
  (should (string-equal "(A)" (zero-convert-str-to-full-width "(A)"))))

(defun zero-convert-str-to-full-width-maybe (s)
  "if in zero-full-width-mode, convert char in s to their full-width char; otherwise, return s unchanged."
  (if zero-full-width-mode (zero-convert-str-to-full-width s) s))

(defun zero-insert-full-width-char (ch)
  "if in zero-full-width-mode, insert full-width char for given ch and return true, otherwise just return nil."
  (when zero-full-width-mode
    (let ((full-width-ch (zero-convert-ch-to-full-width ch)))
      (insert full-width-ch)
      full-width-ch)))

(defun zero-convert-punctuation-basic (ch)
  "convert punctuation for *zero-punctuation-level-basic*
return ch's Chinese punctuation if ch is converted. return nil otherwise"
  (cl-case ch
    (?, ",")
    (?. "。")
    (?. "。")				; 0x3002
    (?? "?")
    (?! "!")
    (?\\ "、")
    (?\\ "、")				; 0x3001
    (?: ":")
    (otherwise nil)))

@@ -330,12 +379,12 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
return ch's Chinese punctuation if ch is converted. return nil otherwise"
  (cl-case ch
    (?_ "——")
    (?< "《")
    (?> "》")
    (?< "《")				;0x300A
    (?> "》")				;0x300B
    (?\( "(")
    (?\) ")")
    (?\[ "【")
    (?\] "】")
    (?\[ "【")				;0x3010
    (?\] "】")				;0x3011
    (?^ "……")
    (?\" (setq zero-double-quote-flag (not zero-double-quote-flag))
	 (if zero-double-quote-flag "“" "”"))
@@ -343,6 +392,7 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
	 (if zero-single-quote-flag "‘" "’"))
    (?~ "~")
    (?\; ";")
    (?$ "¥")
    (t (zero-convert-punctuation-basic ch))))

(defun zero-convert-punctuation (ch)
@@ -444,7 +494,8 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
	    (zero-append-char-to-preedit-str ch))
	(zero-debug "cannot start sequence, state=IM_WAITING_INPUT\n")
	(unless (zero-handle-punctuation ch)
	  (self-insert-command n))))
	  (unless (zero-insert-full-width-char ch)
	    (self-insert-command n)))))
     ((eq zero-state *zero-state-im-preediting*)
      (zero-debug "still preediting\n")
      (funcall zero-handle-preedit-char-func ch))
@@ -493,7 +544,7 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
    (error "zero-return called in non preediting state"))
  (zero-debug "zero-return\n")
  (zero-set-state *zero-state-im-waiting-input*)
  (zero-commit-text zero-preedit-str))
  (zero-commit-text (zero-convert-str-to-full-width-maybe zero-preedit-str)))

(defun zero-commit-nth-candidate (n)
  "commit nth candidate and return true if it exists, otherwise, return false"
@@ -507,7 +558,7 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"

(defun zero-commit-preedit-str ()
  (zero-set-state *zero-state-im-waiting-input*)
  (zero-commit-text zero-preedit-str))
  (zero-commit-text (zero-convert-str-to-full-width-maybe zero-preedit-str)))

(defun zero-commit-first-candidate-or-preedit-str ()
  "commit first candidate if there is one, otherwise commit preedit str"
@@ -593,6 +644,7 @@ return ch's Chinese punctuation if ch is converted. return nil otherwise"
  (make-local-variable 'zero-state)
  (zero-set-state  *zero-state-im-off*)
  (make-local-variable 'zero-punctuation-level)
  (make-local-variable 'zero-full-width-mode)
  (make-local-variable 'zero-double-quote-flag)
  (make-local-variable 'zero-single-quote-flag)
  (set (make-local-variable 'zero-preedit-str) "")
+4 −2
Original line number Diff line number Diff line
@@ -112,8 +112,10 @@ fetch-size try to fetch this many candidates or more"
(ert-deftest zero-pinyin-service-get-candidates ()
  (cl-destructuring-bind (cs ls &rest rest)
      (zero-pinyin-service-get-candidates "liyifeng" 1)
    (should (equal (car cs) "李易峰"))
    (should (= (car ls) 8)))
    (should (or (and (equal (car cs) "李易峰")
		     (= (car ls) 8))
		(and (equal (car cs) "利益")
		     (= (car ls) 4)))))
  (cl-destructuring-bind (cs ls &rest rest)
      (zero-pinyin-service-get-candidates "wenti" 1)
    (should (equal (car cs) "问题"))