/emacs-rime

RIME ㄓ in Emacs

Primary LanguageEmacs LispGNU General Public License v3.0GPL-3.0

Emacs Rime

https://melpa.org/packages/rime-badge.svg https://stable.melpa.org/packages/rime-badge.svg

Document in English

https://i.imgur.com/jHpk7BT.gif

一、基本安装与使用方法

基本安装与使用方法

二、Rime:方案配置与词库

切换折叠

设置输入中发送到 Rime 的组合键

通过变量 rime-translate-keybindings 可以设置哪些组合键将发送至 Rime 。可以用来配合方案中的设置完成光标移动和选字等功能。 支持 Control (C-), Meta (M-), Shift (S-)的组合键。

;; 默认值
(setq rime-translate-keybindings
  '("C-f" "C-b" "C-n" "C-p" "C-g" "<left>" "<right>" "<up>" "<down>" "<prior>" "<next>" "<delete>"))

指定 Rime 共享目录和用户目录

共享目录即 rime-share-data-dir 是 Rime 安装后放置配置(包括输入方案)的目录, 例如 Linux 上默认为 /usr/share/rime-data ,通常使用默认值即可。 如果使用其它的位置,可以配置该值。 例如对于 fcitx5-rime 可能要使用 ~/.local/share/fcitx5/rime

用户目录即 rime-user-data-dir 为 emacs-rime 布署的位置(包括词频等)。 默认为 ~/.emacs.d/rime ,如果需要其它位置,可以配置该值。

不建议 ~emacs-rime~ 与 ~fcitx-rime~ 共用用户数据目录 。 以地球拼音方案在 fcitx-rime 与 emacs-rime 中使用为例,若设置

(setq rime-user-data-dir "~/.config/fcitx/rime/")

,则在 emacs-rime 初次部署后,将会生成新的 terra_pinyin.userdb/ 文件夹,原有 fcitx-rime 使用记录将会被移动到 terra_pinyin.userdb.old/ ,此时新的 terra_pinyin.userdb.txt 中词频为空。

打开 Rime 的配置文件

使用 rime-open-configuration 打开自定义配置文件。

使用 rime-open-schema 打开一个方案的自定义配置文件。

重新部署

切换折叠

emacs-rime 的配置文件更新之后,与 RIME 一样,都需要重新部署才可生效。

以添加 地球拼音(terra_pinyin) 为例。

找到 emacs-rime 配置所在路径,或使用 M-x rime-open-configuration 打开文件 default.custom.yaml ,在 patch:schema_list 中添加 - schema: terra_pinyin ,需要 M-x rime-deploy 重新部署才可启用地球拼音方案,重新部署成功后按 C-` 选择输入方案。

示例如下:

patch:
  schema_list:
    - schema: luna_pinyin
    - schema: pinyin_simp
    - schema: terra_pinyin
  menu/page_size: 7 # 每页显示7个候选字词。
  switcher:
    hotkeys:
      - Control+grave # 激活RIME选单的快捷键,某些版本的RIME支持<F4>为快捷键,容易与其他软件冲突。

重新部署后原有个人词库丢失?

这很可能是 emacs-rimefcitx-rime 共用用户数据文件夹导致的。

如何找回:(依然以地球拼音为例)设置 emacs-rime 用户数据目录到其他文件夹,删除 terra_pinyin.userdb/ 并将 terra_pinyin.userdb.old/ 重命名为前者,再次同步或部署, terra_pinyin.userdb.txt 亦将恢复。

同步词库

切换折叠

M-x rime-sync 可对 RIME 输入方案和词库进行同步与备份,每次同步双向进行,词库生成的备份文件为 sync/ins_id/schema.userdb.txt ,其本身是文件夹 schema.userdb/ 中词库与词频使用记录的纯文本形式,方便用户跨平台、多设备使用。

所谓双向同步,即当前设备中的词频或用户自造词( schema.userdb/ 中)与备份文件( sync/ins_id/schema.userdb.txt 中)所记录的词库会被 RIME 合并,其 并集 将会继续记录在 schema.userdb/ 中,同时生成一份新的备份文件,仍名为 sync/ins_id/schema.userdb.txt ,并(在不询问用户的情况下)将旧的覆盖。

上述路径中 sync 文件夹与配置文件 default.custom.yaml 在同一目录, ins_id 对应的是 installation.yaml 文件中 installation_id 的值,默认值为随机生成,可自定义为其他字符串。

以添加 地球拼音(terra_pinyin) 后同步为例。启用该方案后,在 RIME 数据目录下会产生名为 terra_pinyin.userdb 的文件夹,其中为使用频率与自造词的记录,不可随意修改。同步前先修改 installation.yaml 中内容为自定义的 installation_id: "hesperus" ,之后 M-x rime-sync ,将会在 sync/hesperus/ 生成文件 terra_pinyin.userdb.txt (词库)与 terra_pinyin.schema.yaml (输入方案)。

若在其他设备或系统中有个人积累的词库,想继续使用。则先在旧系统中进行同步,将生成的 terra_pinyin.userdb.txt 复制到当前系统的 sync/hesperus/ 下,再进行同步或部署,此时旧系统中备份的词库将会被合并到当前系统的 terra_pinyin.userdb/ ,新的并集也将会被同时导出,并覆盖 terra_pinyin.userdb.txt

词库同步失败?

切换折叠

(以地球拼音方案使用为例。)

建议将不同设备或系统中的 ~installation_id~ 设为同一值 。若其不同,则可能同步失败,即从旧系统同步并复制的 terra_pinyin.userdb.txt 中的词频记录不会被纳入到当前的 terra_pinyin.userdb/ 。 此时该文件中词频不为空,但其中 user_id 等不同,修改此值后再次同步仍可能不生效。

三、样式设置

切换折叠

候选框展示风格

设置 rime-show-candidate

可选值说明
nil不展示
minibuffer在 minibuffer 中展示, 推荐使用的方式
message直接使用 message 输出,兼容控制 minibuffer 内容的插件
popup使用 popup.el 展示跟随的候选
posframe使用 posframe 展示跟随的候选,在不可用的时候会用 popup
sidewindow使用 sidewindow 展示跟随的候选

候选样式

Face说明
rime-default-face默认的前景色和背景色(仅 posframe)
rime-code-face编码的颜色
rime-candidate-num-face候选序号颜色
rime-comment-face编码提示颜色

posframe/popup/sidewindow 候选版式

设置 rime-posframe-stylerime-popup-style 或者 rime-sidewindow-style 可选值有

可选值说明
simple单行
horizontal水平,默认
vertical垂直

posframe 的其它属性

设置 rime-posframe-properties, 其中颜色的设置使用 rime-default-face.

(setq rime-posframe-properties
 (list :font "sarasa ui sc"
       :internal-border-width 10))

支持的内容参照 posframe

sidewindow 的其它屬性

设置 rime-sidewindow-style ,可选值有 top, bottom, left, right ,分别指 sidewindow 出现的位置位于上下左右。

设置 rime-sidewindow-keep-window ,为 t 时可保持 sidewindow 为开启状态。

彩色指示标志

可用 (rime-lighter) 得到彩色指示标志 . 可将其放在 modeline 等任意地方。

可用 rime-titlerime-indicator-facerime-indicator-dim-face 来自定义。

设置软光标的样式

默认使用 | 字符做为软光标,可以通过如下方式修改。

(setq rime-cursor "˰")

颜色可通过 rime-cursor-face 设置。

设置嵌入文本的样式

可通过 rime-preedit-face 设置。

编码的展示形式

设置 rime-show-preedit, 可选值有

可选值说明
t展示在菜单中
inline替换上屏预览
nil不展示

注意:使用 inlinenil 将不再展示软光标。

四、自动化设置

切换折叠

临时英文模式

切换折叠

如果使用模式编辑,或是在一些特定的场景下需要自动使用英文,可以设 置~rime-disable-predicates~ , rime-disable-predicates 的值是一个断言列表, 当其中有任何一个断言的值 **不是** nil 时,会自动使用英文。

一个在 evil-normal-state 中、在英文字母后面以及代码中自动使用英文的例子。

(setq rime-disable-predicates
      '(rime-predicate-evil-mode-p
        rime-predicate-after-alphabet-char-p
        rime-predicate-prog-in-code-p))

目前可用的断言函数

切换折叠
  • rime-predicate-after-alphabet-char-p

    在英文字符串之后(必须为以字母开头的英文字符串)

  • rime-predicate-after-ascii-char-p

    任意英文字符后

  • rime-predicate-prog-in-code-p

    prog-modeconf-mode 中除了注释和引号内字符串之外的区域

  • rime-predicate-in-code-string-p

    在代码的字符串中,不含注释的字符串。

  • rime-predicate-evil-mode-p

    evil-mode 的非编辑状态下

  • rime-predicate-ace-window-p

    激活 ace-window-mode

  • rime-predicate-hydra-p

    如果激活了一个 hydra keymap

  • rime-predicate-current-input-punctuation-p

    当要输入的是符号时

  • rime-predicate-punctuation-after-space-cc-p

    当要在中文字符且有空格之后输入符号时

  • rime-predicate-punctuation-after-ascii-p

    当要在任意英文字符之后输入符号时

  • rime-predicate-punctuation-line-begin-p

    在行首要输入符号时

  • rime-predicate-space-after-ascii-p

    在任意英文字符且有空格之后

  • rime-predicate-space-after-cc-p

    在中文字符且有空格之后

  • rime-predicate-current-uppercase-letter-p

    将要输入的为大写字母时

  • rime-predicate-tex-math-or-command-p

    在 (La)TeX 数学环境中或者输入 (La)TeX 命令时

可提示临时英文状态的提示符

使用函数 (rime-lighter) 返回一个用于展示的 符号。 可以通过 rime-indicator-facerime-indicator-dim-face 设置样式。

如下设置可替换输入法的符号,使其用颜色提示当前的临时英文状态。

;;; 具体参考 mode-line-mule-info 默认值,其中可能有其它有用信息
(setq mode-line-mule-info '((:eval (rime-lighter))))

基于 Rime inline ascii 模式的临时英文

设置 rime-inline-predicates ,结构与 rime-disable-predicates 相同,具有较低优先级。

这个功能主要用来实现输入带空格的临时英文的场景。

由于当前实现限制,如果 Rime 配置中没有使用默认的 Shift_L 切换 inline ascii 模式,需要在 emacs-rime 中指定。 两边配置相同才能正常激活。

;;; support shift-l, shift-r, control-l, control-r
(setq rime-inline-ascii-trigger 'shift-l)

在有编码的状态下使用 rime-inline-ascii 命令可以切换状态。

(define-key rime-active-mode-map (kbd "M-j") 'rime-inline-ascii)

临时英文中阻止标点直接上屏

(setq rime-inline-ascii-holder ?x)      ; Any single character that not trigger auto commit

断言成立时的强制中文模式

使用 rime-force-enable 来临时强制使用强制中文模式(即无视 rime-disable-predicates 中的规则), 在 一次输入行为取消输入 之后会自动关闭强制中文模式。

你可能需要给这个命令绑定一个按键来使用。

(define-key rime-mode-map (kbd "M-j") 'rime-force-enable)

Commit1 自动上屏

emacs-rime 内置了 rime-commit1 函数,其作用是在输入状态下将候选框中的首项自动上屏。

这对于不注重(或几乎不需要)选重、且码长可不固定(即简码)的输入方案,如纯形码、音形码等(尤其是顶功类方案)而言,非常有用。

此函数不是针对单独使用的,而主要是为了配合自定义其它函数,以适应个人的各种使用场景。

实例:在切换输入法时首项自动上屏

在切换输入法时首项自动上屏,这是 fcitx5-rime 等所支持的功能。 这里就以在 emacs-rime 中实现相同功能为例,说明如何使用 rime-commit1 函数。

基本思路是,先自定义一个函数,功能是先使得首项自动上屏,再切换输入法; 再将这个函数绑定到某个按键组合上,来替代原本 toggle-input-method 的功能。

示例配置如下:

(defun rime-commit1-and-toggle-input-method ()
  "Commit the 1st item if exists, then toggle input method."
  (interactive)
  (ignore-errors (rime-commit1))
  (toggle-input-method))

(global-set-key (kbd "C-;") #'rime-commit1-and-toggle-input-method)

这里使用了 ignore-errors 来防止在初次切换输入法时 rime-commit1 未被加载而报错。 在此配置生效后,按 C-; 即可使首项自动上屏并切换输入法。

对任意无关函数首项自动上屏

若你有很多函数需要在其执行前首项自动上屏,而又不想对它们一个个进行自定义函数与绑定的配置,你可以设置对任意与 emacs-rime 无关函数的首项自动上屏。

机制:

  • 在 emacs-rime 的输入状态下,若执行与 emacs-rime 无关的函数,默认会触发 rime--clear-state 清空候选框。
  • 若设置变量 rime-commit1-forall 为一非 nil 值,则会将触发的函数改为 rime-commit1 即首项自动上屏。

示例配置如下:

(setq rime-commit1-forall t)

按 ESC 时首项自动上屏

上述全局设置,不能使得在输入时按 ESC 时首项也自动上屏,这里给出针对性的配置方法。

机制:在 emacs-rime 的输入状态下,ESC 被绑定到了 rime--escape 函数上,此函数显然不是“与 emacs-rime 无关的函数”。

实例:以 evil 插件为例,若要使得 ESC 能自动上屏并切换到 evil 的 normal state,可以先自定义函数,并将此函数绑定到 ESC 上。 (注:至少对于 evil 插件而言, C-[ESC 被 emacs 当作同一按键,所以不需要对 C-[ 另行绑键。)

示例配置如下:

(defun rime-commit1-and-evil-normal ()
  "Commit the 1st item if exists, then go to evil normal state."
  (interactive)
  (rime-commit1)
  (evil-normal-state))
(define-key rime-active-mode-map (kbd "<escape>") 'rime-commit1-and-evil-normal)

在 minibuffer 使用后自动关闭输入法

默认行为为自动关闭,设置 rime-deactivate-when-exit-minibuffer 为 nil 取消该行为。

结合 evil-escape 一起使用

切换折叠

以下代码可能有性能问题

在你的配置中添加如下内容,即可在当前没有输入内容(没有 preedit overlay)的情况 下,用evil-escape的按键回到 normal 模式。

(defun rime-evil-escape-advice (orig-fun key)
  "advice for `rime-input-method' to make it work together with `evil-escape'.
        Mainly modified from `evil-escape-pre-command-hook'"
  (if rime--preedit-overlay
      ;; if `rime--preedit-overlay' is non-nil, then we are editing something, do not abort
      (apply orig-fun (list key))
    (when (featurep 'evil-escape)
      (let (
            (fkey (elt evil-escape-key-sequence 0))
            (skey (elt evil-escape-key-sequence 1))
            )
        (if (or (char-equal key fkey)
                (and evil-escape-unordered-key-sequence
                     (char-equal key skey)))
            (let ((evt (read-event nil nil evil-escape-delay)))
              (cond
               ((and (characterp evt)
                     (or (and (char-equal key fkey) (char-equal evt skey))
                         (and evil-escape-unordered-key-sequence
                              (char-equal key skey) (char-equal evt fkey))))
                (evil-repeat-stop)
                (evil-normal-state))
               ((null evt) (apply orig-fun (list key)))
               (t
                (apply orig-fun (list key))
                (if (numberp evt)
                    (apply orig-fun (list evt))
                  (setq unread-command-events (append unread-command-events (list evt))))))
              )
          (apply orig-fun (list key)))))))

(advice-add 'rime-input-method :around #'rime-evil-escape-advice)

五、杂项

切换折叠

打开 Rime 菜单

假设你为菜单使用 C-~

switcher:
  caption: 〔方案選單〕
  hotkeys:
    - Control+grave

你可用函数 rime-send-keybinding 将此按键绑定到 rime-mode-map

(use-package
  ...

  :bind
  (:map rime-mode-map
        ("C-`" . 'rime-send-keybinding))
  ...
  )

六、FAQ

切换折叠

在 isearch 中的使用

目前在 isearch 中不能正常工作,但是可以使用 phi-search.

候选框最后一项不显示?

切换折叠

极少数用户下会偶尔出现最后一个候选词不显示的情况,可以确定跟 `posframe` 有关,但 目前尚未找到原因,有一个暂时的解决办法,就是给候选词列表最后附加一个全角空格,这 样即使出现“吃字”的情况也只是把末尾的全角空格“吃”掉,不会影响候选词的显示。 代码如下:

  (defun +rime--posframe-display-content-a (args)
    "`rime--posframe-display-content' 传入的字符串加一个全角空
格,以解决 `posframe' 偶尔吃字的问题。"
    (cl-destructuring-bind (content) args
      (let ((newresult (if (string-blank-p content)
                           content
                         (concat content " "))))
        (list newresult))))

  (if (fboundp 'rime--posframe-display-content)
      (advice-add 'rime--posframe-display-content
                  :filter-args
                  #'+rime--posframe-display-content-a)
    (error "Function `rime--posframe-display-content' is not available."))

无需 librime 纯 Emacs 实现的输入法?

你可能需要 pyim.

终、感谢所有的 Contributor