Created
February 23, 2020 08:05
-
-
Save DogLooksGood/e4ae3f04ab12b023631a373b5b197b2d to your computer and use it in GitHub Desktop.
Try to implement a minimal emacs rime input method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defface rime-preedit-face | |
'((((class color) (background dark)) | |
(:underline t)) | |
(((class color) (background light)) | |
(:underline t))) | |
"Face for preedit string" | |
:group 'rime) | |
(defvar rime--preedit-overlay nil) | |
(defvar rime--backspace-fallback nil) | |
(make-variable-buffer-local 'rime--backspace-fallback) | |
(defun rime--show-candidates (context) | |
(let ((candidates (alist-get 'candidates (alist-get 'menu context))) | |
(idx 1) | |
(result "")) | |
(dolist (c candidates) | |
(setq result | |
(concat result (format "%d. %s " idx c))) | |
(setq idx (1+ idx))) | |
(message result))) | |
(defun rime--create-preedit (&rest args) | |
(let ((context (liberime-get-context))) | |
(when context | |
(when-let ((preedit (or (alist-get 'commit-text-preview context) | |
(alist-get 'preedit context)))) | |
(let ((beg (point))) | |
(insert preedit) | |
(setq rime--preedit-overlay | |
(make-overlay beg (point) (current-buffer))) | |
(overlay-put rime--preedit-overlay 'face 'rime-preedit-face)))))) | |
(defun rime--remove-preedit () | |
(when (overlayp rime--preedit-overlay) | |
(let ((beg (overlay-start rime--preedit-overlay)) | |
(end (overlay-end rime--preedit-overlay))) | |
(delete-overlay rime--preedit-overlay) | |
(setq rime--preedit-overlay nil) | |
(save-mark-and-excursion | |
(delete-region beg end))))) | |
(defun rime--backspace () | |
(interactive) | |
(let ((context (liberime-get-context))) | |
(if (not context) | |
(call-interactively rime--backspace-fallback) | |
(liberime-process-key 65288) | |
(rime--show-candidates (liberime-get-context))))) | |
(defun rime-input-method (key) | |
(liberime-process-key key) | |
(with-silent-modifications | |
(rime--remove-preedit) | |
(let ((context (liberime-get-context)) | |
(commit (liberime-get-commit))) | |
(rime--show-candidates context) | |
(cond | |
((and (not context) (not commit)) | |
(liberime-clear-composition) | |
(list key)) | |
(commit | |
(mapcar 'identity commit)))))) | |
(defun rime-activate (name) | |
(interactive) | |
(setq input-method-function 'rime-input-method | |
deactivate-current-input-method-function #'rime-deactivate) | |
(liberime-clear-composition) | |
(setq-local rime--backspace-fallback (key-binding (kbd "DEL"))) | |
(setq-local rime--space-fallback (key-binding (kbd "SPC"))) | |
(local-set-key (kbd "DEL") 'rime--backspace) | |
(message "Rime activate")) | |
(defun rime-deactivate () | |
"When quit the input method, we preserve the preedit, remove the overlay." | |
(when (overlayp rime--preedit-overlay) | |
(delete-overlay rime--preedit-overlay) | |
(setq rime--preedit-overlay nil)) | |
(local-unset-key (kbd "DEL"))) | |
(register-input-method "rime" "euc-cn" 'rime-activate "中") | |
(provide 'the-rime) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment