从最开始使用外置输入法到使用内置输入法 pyim ,越来越感受到内置输入法的便利,其中最让人中毒的就是通过探针函数的设置,在不同的位置或模式自动切换中英文,几乎不用手工切换,打字真如行云流水一般。
pyim 是一款非常优秀的内置输入法,是它坚定了我从外置输入法转为内置输入法的决心。但是这是一款从拼音起家的输入法,虽然早已加入了对五笔等方案的支持,但对五笔远没有像拼音方案那样进行优化,所以用起来总感觉有点儿不尽如意。
我在系统中用的是 rime 输入法, pyim 也可以把 rime 作为后端进行调用,经过一段时间的试用,发现 pyim 对 rime 的调用不太完全,而且 pyim 用自家的缓存对 rime 取出的候选词进行干预,这样就无法保持与外置 rime 输入法的一致体验了。
正在此时, emacs-china 上有大佬发布了一新的内置输入法 emacs-rime 。严格的说,这不是一个输入法,而是相当于是 rime 输入法在 emacs 里的一个前端,所有的输入都原封不动的发送给 rime后端,由 rime 处理完后把数据再返回并在 emacs 里展现。
经过几天的试用和调整,今天终于决定把输入法切换到 emacs-rime 了,理由有两点:
- 几乎与外置输入法一致的输入体验;
- 谦虚而活跃的作者,作者曾经连续花几个小时和我一起定位一个 issue 。
配置如下 (doom-emacs 配置格式) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| ;; packages.el
(package! liberime
:recipe (:host github :repo "DogLooksGood/liberime" :files ("CMakeLists.txt" "Makefile" "src" "*.el")))
(package! rime
:recipe (:host github :repo "DogLooksGood/emacs-rime" :files ("rime.el")))
;; config.el
(use-package! liberime-config
:init
(setenv "RIME_PATH" "~/repos/librime")
(setq liberime-shared-data-dir (file-truename "~/Library/Rime")
liberime-user-data-dir (file-truename "~/.local/liberime"))
:hook
('after-init . (lambda ()
(when (fboundp 'liberime-sync-user-data)
(liberime-sync))))
('liberime-after-start . (lambda ()
(liberime-select-schema "wubi86_jidian"))))
(use-package! rime
:after liberime-config
:after-call after-find-file pre-command-hook
:custom
(default-input-method "rime")
(rime-show-candidate 'posframe)
:config
(defadvice! +rime--posframe-display-result-a (args)
"给 `rime--posframe-display-result' 传入的字符串加一个全角空
格,以解决 `posframe' 偶尔吃字的问题。"
:filter-args #'rime--posframe-display-result
(cl-destructuring-bind (result) args
(let ((newresult (if (string-blank-p result)
result
(concat result " "))))
(list newresult))))
(load! "+rime-probe-english"))
|
pyim 里的探针函数非常好用, emacs-rime 里也提供了几个,我从 pyim 里移植了一个觉得好用的,另外又写了两个自用的探针,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| ;;; +rime-probe-english.el -*- lexical-binding: t; -*-
;;
;; Some functions copied from `pyim', thanks for tumashu@github.com .
;;
(defun +rime--char-before-to-string (num)
"得到光标前第 `num' 个字符,并将其转换为字符串。"
(let* ((point (point))
(point-before (- point num)))
(when (and (> point-before 0)
(char-before point-before))
(char-to-string (char-before point-before)))))
(defun +rime--string-match-p (regexp string &optional start)
"与 `string-match-p' 类似,如果 REGEXP 和 STRING 是非字符串时,
不会报错。"
(and (stringp regexp)
(stringp string)
(string-match-p regexp string start)))
(defun +rime--probe-auto-english ()
"激活这个探针函数后,使用下面的规则自动切换中英文输入:
1. 当前字符为英文字符(不包括空格)时,输入下一个字符为英文字符
2. 当前字符为中文字符或输入字符为行首字符时,输入的字符为中文字符
3. 以单个空格为界,自动切换中文和英文字符
即,形如 `我使用 emacs 编辑此函数' 的句子全程自动切换中英输入法
"
(let ((str-before-1 (+rime--char-before-to-string 0))
(str-before-2 (+rime--char-before-to-string 1)))
(unless (string= (buffer-name) " *temp*")
(if (> (point) (save-excursion (back-to-indentation)
(point)))
(or (if (+rime--string-match-p " " str-before-1)
(+rime--string-match-p "\\cc" str-before-2)
(not (+rime--string-match-p "\\cc" str-before-1))))))))
(defun +rime--beancount-p ()
"当前为`beancount-mode',且光标在注释或字符串当中。"
(when (derived-mode-p 'beancount-mode)
(not (or (nth 3 (syntax-ppss))
(nth 4 (syntax-ppss))))))
(defun +rime--evil-mode-p ()
"检测当前是否在 `evil' 模式下。"
(or (evil-normal-state-p)
(evil-visual-state-p)
(evil-motion-state-p)
(evil-operator-state-p)))
(defun +rime-english-prober()
"自定义英文输入探针函数,用于在不同mode下使用不同的探针列表"
(let ((use-en (or (button-at (point))
(+rime--evil-mode-p))))
(if (derived-mode-p 'telega-chat-mode)
(setq use-en (or use-en
(+rime--probe-auto-english)))
(when (derived-mode-p 'text-mode)
(setq use-en (or use-en
(+rime--probe-auto-english))))
(when (derived-mode-p 'prog-mode 'conf-mode)
(setq use-en (or use-en
(rime--after-alphabet-char-p))))
(setq use-en (or use-en
(rime--prog-in-code-p)
(+rime--beancount-p))))
use-en))
(setq rime-disable-predicates '(+rime-english-prober))
|
刚刚给作者提了点小建议,得到了非常积极的响应,非常感谢 DogLooksGood 的贡献。 emacs-rime 还在不断完善中,希望 emacs-rime 越做越好,造福更多的 emacer 。
另外,再次感谢 pyim 和 posframe 的大神 tumashu ,造了那么多优秀的轮子。