关于Emacs集成Rime的一些建议

特意录了一个视频,主要是关于上屏的一些问题和对RIME方案更好的支持。 因为看到最近有专门的针对RIME的Emacs输入法,但是自己用的方案一直得不到很好的支持。

https://www.bilibili.com/video/av91187023

开头有些废话可以略过。

2 个赞

最近谈这个话题的很多,我自己也在折腾

这里说一句离题的话,狗哥的桌面和Emacs配置的很好看啊。

1 个赞
;; 看了一下你这个视频,感觉功能有一点类似 pyim-autoselector 机制。

;; 在 pyim 中,autoselector 机制是这样子的,假如你已经输入 nihao,
;; 并且当前输入一个 m, 这个过程中就有可能触发 autoselector 机制,

;; 1. nihao 已经处理完成,得到的候选词放到 pyim-candidates 变量中,
;; 2. 如果 pyim-candidates 变量存在,并且 autoselector 返回 t, 则
;;    pyim 会将 m 推到 emacs 的 unread-command-events 变量中。并将
;;    nihao 对应的 pyim-candidates 的第一个词条“你好”上屏,然后关闭选词框等。
;; 3. 由于 m 被缓存到 unread-command-events 中, emacs 内置的机制会
;;    再次将 m 提出来,开始新一轮的输入。

;; 和 rime 集成的过程中,最绕脑袋的是 autoselector 的向前预判机制:
;; 假如已经输入 nihao, 当前输入的是m,pyim 已经处理 nihao 并保存到 pyim-autoselector
;; 中,现在 autoselector 需要判断的是: nihaom 有没有触发pyim 的自动上屏机制,
;; 来决定 nihao 要不要自动上屏。可能的方式是

(defun pyim-autoselector-rime (&rest args)
  "适用于RIME的自动上屏器."
  (let* ((scheme-name (pyim-scheme-name))
         (class (pyim-scheme-get-option scheme-name :class)))
    (when (and (eq class 'rime) (functionp 'liberime-get-commit))
      (liberime-clear-composition)
      ;; 预判是否踩雷
      (liberime-search (concat (pyim-entered-get) (char-to-string last-command-event)))
      (let ((x (liberime-get-commit)))
        (> (length x) 0)))))

这个代码暂时还不能使用,因为其依赖的东西还没有到 melpa

;; requirement
1. https://github.com/tumashu/pyim/tree/new-rime
2. https://github.com/tumashu/liberime/tree/liberime-search

(liberime-select-schema "wubi86")

(defun pyim-autoselector-rime (&rest args)
  "适用于RIME的自动上屏器."
  (let* ((scheme-name (pyim-scheme-name))
         (class (pyim-scheme-get-option scheme-name :class))
         (entered (pyim-entered-get)))
    (when (and (eq class 'rime) (functionp 'liberime-get-commit))
      ;; 向前预判
      (liberime-search
              (concat entered (char-to-string last-command-event))
              2)
      (let* ((context (liberime-get-context))
             (composition (alist-get 'composition context))
             (preedit (alist-get 'preedit composition))
             x)
        ;; 用 liberime-get-commit 判断自动上屏,好像不太靠谱,但不知道
        ;; 什么原因。
        ;; 
        ;; 这里暂时使用 preedit 的长度来判断,自动上屏后,preedit
        ;; 的长度会变成1, 肯定小于 entered.
        (< (length preedit) (length entered))))))

(push 'pyim-autoselector-rime pyim-autoselector)

我觉得这个逻辑是有一点问题的,因为m是否导致nihao被上屏,应该是由rime来决定的,不应该在emacs中判断出来是否上屏,有一些输入法在rime中上屏的规则是和码表相关,也就是说nihaom会不会顶nihao上去取决于码表。

在我的这个方案里面,在我这个demo里面,有编码时,get-commit总是能给我对的结果,似乎拼音和形码都是正确的。只有空码时情况不对,可能是需要特别处理的地方。

做决策的当然是 rime, 但上屏的操作肯定是 pyim 或者 erime,这个是肯定的

有存在顶屏后preedit长度不为1的输入法,有一类叫24顶的方案是这样的。

erime这个还有点问题,呼叫 @QiangF ,有空帮忙看下哈 ~

只要preedit是减少的,就可以,按理说不应该出现自动上屏后preedit增加的情况吧?

我用get-commit的时候,也遇到一些奇怪的担心,还没找到是什么原因,不过关键是怎么能判断是否发生了自动上屏

这个应该是可性的,上屏后preedit应该是减少。commit的话,会出现什么样的问题呢?我感觉挺可靠的啊。

get-commit 会遇到类似上次commit未清理的问题,我也搞不清楚到底是哪块的问题

听起来像是某个字符会触发上屏,就没有发送给liberime,于是就留下了旧的preedit。我用了一天了发现没有遇到这样的问题,我这个实现方式也可以支持拼音。

嗯,我们慢慢研究吧

求分享 rime 配制

现在问题的关键还是 liberime 提供的函数太有限了,如果能提供一个实时查看 composition 状态的函数,无论你顶屏还是像全拼输入 iii 没有返回 context 都比较好处理,代码就一个按键转发,也没必要那么复杂。这里提了一个

一行 c 代码顶十行 lisp。

1 个赞

@DogLooksGood https://github.com/QiangF/liberime

已经更新,可能支持顶屏了你试试

能不能分享一下你的顶屏方案设置

1 个赞

今天更改了一下 autoselector 的逻辑, 相对来说更好理解了, 现在采用 踩雷回退的方式,而不是原来的测试机制。吐槽一下,我发现有状态的集成能搞死人。。。。

稍后我尝试一下。

我先把我用的方案放上来,这个输入法的行为模式能代表了一批。

星空两笔单字

三个xklbdz开头的yaml文件就是了。

用于测试的编码 ykyoctsdead_bcompa_


有个错误

let: Symbol’s function definition is void: erime-prompt--format-prompt