前言
Rime 本身是一套高度可定制的输入法框架。除了常规的拼音输入、词库管理和候选排序之外,还可以通过 Lua 扩展实现动态内容生成。
一个比较实用的例子,是输入特定拼音后直接生成当前日期、当前时间、星期等内容。例如:
riqi
xianzai
shijian
xingqi
可以分别得到类似:
2026-08-23
2026/08/23
20260823
2026-08-23 21:10:35
21:10:35
星期日
这些内容不是提前写进词典的静态词条,而是在输入时调用系统时间动态产生。
这一功能最初在 Linux 环境下完成并稳定使用。之后需要将同样的能力迁移到 Windows 上的 Rime,也就是小狼毫 Weasel。
实际迁移过程并不是简单复制一个文件即可完成。Linux 与 Windows 的 Rime 前端、用户目录以及部署行为都存在差异,尤其是在 Windows 上还遇到了重新部署后 build 内容没有正确刷新的情况。
经过多轮检查和最小化修改,最终成功在 Windows 上完整复现了 Linux 下的动态日期时间输入功能。
一、Linux 下的实现结构
Linux 环境使用 Fcitx5 + Rime。
实际生效的 Rime 用户目录位于:
~/.local/share/fcitx5/rime/
动态日期时间功能主要由三个部分构成:
rime.lua
lua/date_time.lua
luna_pinyin_simp.custom.yaml
完整调用链可以概括为:
用户输入关键字
↓
Rime Schema Translator
↓
lua_translator@date_time_translator
↓
rime.lua
↓
require("date_time")
↓
lua/date_time.lua
↓
os.date(...)
↓
动态生成候选
这说明该功能本质上是一个 Rime Lua Translator。
二、rime.lua:注册 Lua 模块
Rime 会通过用户目录中的 rime.lua 加载 Lua 扩展。
核心逻辑类似:
local ok, date_time = pcall(require, "date_time")
if ok then
date_time_translator = date_time
end
这里完成两个动作:
- 加载
date_timeLua 模块; - 将模块暴露为
date_time_translator。
之后 Schema 就可以通过:
lua_translator@date_time_translator
调用这个模块。
使用 pcall() 的好处是,即使模块加载失败,也不至于直接因为 Lua 异常破坏整个 Rime 初始化流程。
三、date_time.lua:真正生成日期和时间
主要逻辑位于:
lua/date_time.lua
这个 Lua Translator 会检查用户当前输入的字符串。
例如:
riqi
date
可以映射到当前日期。
Lua 中通常使用:
os.date(...)
获取系统当前时间。
例如:
os.date("%Y-%m-%d")
产生:
2026-08-23
而:
os.date("%Y/%m/%d")
产生:
2026/08/23
还可以进一步组合不同格式。
四、支持的动态关键字
实际实现中包含几组常用关键字。
日期
例如:
riqi
date
可以产生:
2026-08-23
2026/08/23
20260823
也可以生成中文日期以及星期信息。
当前日期时间
例如:
xianzai
riqishijian
datetime
可以产生:
2026-08-23 21:10:35
以及中文日期时间等格式。
时间
例如:
shijian
time
可以产生当前时间。
星期
例如:
xingqi
week
可以产生:
星期日
最大的优势在于,这些值不是词库里的固定文本。
每次调用:
os.date(...)
读取的都是系统当前时间。
五、Schema 才是让 Lua Translator 真正生效的关键
仅仅存在 rime.lua 和 Lua 文件还不够。
还必须让当前输入方案的 engine/translators 调用 Lua Translator。
对应的自定义配置文件为:
luna_pinyin_simp.custom.yaml
其核心逻辑是:
patch:
"engine/translators/@before 3": lua_translator@date_time_translator
也就是说,在原有 Translator 列表中插入:
lua_translator@date_time_translator
因此真正的运行链是:
Schema
→ lua_translator
→ rime.lua
→ date_time.lua
缺少任何一环,功能都不会工作。
六、Linux 下如何确认功能确实来自 Lua
排查过程中,一个重要问题是:
riqi和xianzai究竟是词库里的静态词条,还是 Lua 动态生成的?
不能只看到候选结果就下结论。
可以从几个层面确认。
首先搜索:
riqi
xianzai
date_time
os.date
lua_translator
如果关键字只存在于 Lua 代码而不是词典文件,已经是很强的证据。
其次检查编译后的 Schema:
build/luna_pinyin_simp.schema.yaml
其中应存在:
lua_translator@date_time_translator
最后,如果 Rime Lua 日志能够看到类似:
translator called: xianzai
以及动态生成的当前时间候选,则基本可以确认完整链路。
这比单纯看到输入结果更加可靠。
七、迁移到 Windows
Windows 使用的是小狼毫 Weasel。
其用户 Rime 目录通常位于:
%APPDATA%\Rime
展开后类似:
C:\Users\<USER>\AppData\Roaming\Rime
迁移时并没有复制整个 Linux Rime 用户目录。
这是非常重要的一点。
Linux 与 Windows 之间存在:
- 前端差异;
- 部署环境差异;
- 默认配置差异;
- 用户目录差异;
- 编译产物差异。
因此最安全的方式是:
只迁移实现目标功能所需要的最小文件。
八、Windows 需要迁移的文件
最终只需要复制或创建:
Rime\rime.lua
Rime\lua\date_time.lua
Rime\luna_pinyin_simp.custom.yaml
结构如下:
Rime
├── rime.lua
├── luna_pinyin_simp.custom.yaml
└── lua
└── date_time.lua
其中:
rime.lua负责加载 Lua 模块;date_time.lua负责生成动态内容;luna_pinyin_simp.custom.yaml负责把 Lua Translator 插进 Schema。
这是整个功能最核心的最小集合。
九、第一次遇到的问题:Weasel 部署没有刷新 build
按正常逻辑,在修改用户配置后执行 Rime 部署,应该重新生成:
Rime\build\
Windows 下也尝试调用了 Weasel 的部署程序。
然而实际出现了一个比较特殊的情况:
部署命令虽然执行了,但编译后的 Schema 并没有真正刷新。
检查:
build\luna_pinyin_simp.schema.yaml
之后发现其中仍然没有:
lua_translator@date_time_translator
这意味着:
用户 custom.yaml 已正确
并不等于:
当前运行中的 build schema 已正确
这是整个 Windows 迁移过程中最关键的排查点之一。
十、为什么一定要检查 build Schema
Rime 的用户配置与实际运行配置之间存在编译过程。
可以简单理解成:
用户配置
↓
部署
↓
build
↓
Rime 实际运行
因此:
luna_pinyin_simp.custom.yaml
只是配置来源。
真正需要确认的是:
build\luna_pinyin_simp.schema.yaml
其中最终是否已经出现:
lua_translator@date_time_translator
如果没有,那么即使源配置写得完全正确,也可能依然没有生效。
十一、最终采用的最小修复方式
由于正常部署没有刷新对应 build 文件,最终采用了非常有限的手动修复。
首先备份:
build\luna_pinyin_simp.schema.yaml
备份命名可以采用:
原文件名.YYYYMMDD-HHMMSS
例如:
luna_pinyin_simp.schema.yaml.20260823-211000
随后发现目标 build 文件带有 Windows 的只读属性。
因此操作顺序是:
备份
↓
临时去掉 Read-only
↓
进行最小修改
↓
加入 lua_translator@date_time_translator
↓
恢复 Read-only 属性
没有改动其他 Schema 内容。
最终在:
build\luna_pinyin_simp.schema.yaml
中确认:
lua_translator@date_time_translator
已经存在。
十二、重新加载 Weasel
修改完成之后,需要重新启动 Weasel 服务进程。
这样可以让当前桌面输入法重新读取已经修正的配置。
验证至少包括:
riqi
xianzai
并可以进一步验证:
shijian
xingqi
最终桌面环境中确认:
riqi可以动态生成当前日期;xianzai可以动态生成当前日期时间;- Lua Translator 工作正常。
至此,Windows 端复现成功。
十三、随后复制到另一套 Windows 系统
在第一套 Windows 环境成功之后,另一套 Windows 系统也需要部署相同功能。
这次就不再需要重新分析 Linux 实现。
已经验证成功的 Windows 环境可以直接作为标准源。
迁移关系因此变为:
已验证 Windows
↓
另一套 Windows
而不是:
Linux
↓
重新研究
↓
Windows
这极大降低了不确定性。
需要复制的依然只是:
rime.lua
lua\date_time.lua
luna_pinyin_simp.custom.yaml
之后检查:
build\luna_pinyin_simp.schema.yaml
如果正常部署没有正确生成 Lua Translator,则按照前一次已经验证的方法进行相同的最小修复。
最终第二套 Windows 环境也成功实现了:
riqi
xianzai
shijian
xingqi
等动态输入。
十四、为什么不应该直接复制整个 Rime 目录
跨系统迁移输入法配置时,很容易想到:
把整个 Rime 目录复制过去
但这种方式风险较高。
一个完整 Rime 用户目录中可能同时存在:
- 输入方案;
- 用户词典;
- 编译后的 build;
- OpenCC 数据;
- 缓存;
- 用户同步数据;
- 前端相关设置;
- Lua 扩展;
- 操作系统特定配置。
Linux 与 Windows 的运行环境并不完全相同。
直接整体覆盖可能导致:
为了复制一个小功能
→ 连带覆盖大量无关配置
→ 引入新的问题
因此这次实践采用的原则是:
先找到功能的真正依赖链,再只迁移依赖链。
最终确认真正需要的是:
rime.lua
↓
date_time.lua
↓
lua_translator
↓
schema patch
其他配置都不需要碰。
十五、这次排查中最有价值的方法
1. 不通过文件名猜实现
发现一个叫:
date_time.lua
的文件,并不能证明它真的被调用。
必须继续检查:
谁 require 它?
然后检查:
谁调用这个 Lua Translator?
最后再检查:
编译后的 Schema 中是否真正存在?
这才是一条完整证据链。
2. 区分源配置和运行配置
Rime 中尤其要注意:
custom.yaml
和:
build/*.schema.yaml
不是同一个层级。
前者代表:
希望 Rime 如何配置
后者代表:
当前实际编译出了什么
排查“配置明明写了为什么不生效”时,检查 build 往往非常关键。
3. 动态功能不要写进静态词库
日期和时间本质上是动态数据。
如果使用词典硬编码:
riqi 2026-08-23
第二天就会失效。
Lua Translator 的优势就在于:
os.date(...)
每次输入时实时生成。
因此特别适合:
- 日期;
- 时间;
- 星期;
- 时间戳;
- 格式化年月日;
- 其他根据当前环境计算的内容。
4. Windows 和 Linux 不必完全配置一致
跨平台配置的目标不应该是:
两边目录中的每一个文件都相同。
真正应该追求的是:
两边实现相同的用户功能。
只要最终都能形成:
Schema
→ lua_translator
→ Lua 模块
→ 动态候选
那么底层文件组织存在少量平台差异是完全可以接受的。
十六、推荐的迁移流程
如果以后需要迁移类似 Rime Lua 功能,可以按照下面的顺序处理。
第一步:在源系统建立完整证据链
确认:
触发关键字
↓
Schema
↓
Lua Translator
↓
Lua 模块
↓
动态生成函数
第二步:找出最小依赖文件
不要复制整个 Rime 用户目录。
第三步:检查目标系统已有配置
尤其避免覆盖已有:
*.custom.yaml
rime.lua
lua/
第四步:修改前备份
尤其是已有文件。
第五步:正常重新部署
优先让 Rime 自己生成 build。
第六步:检查 build
不要只检查源配置。
第七步:必要时才修改 build
只有在正常部署明确失败,并且已经知道应该生成什么内容时,才考虑这种方式。
第八步:重载输入法前端
例如重启 Weasel。
第九步:桌面实际输入验证
最终验证应当发生在真实输入环境,而不只是文件层面。
十七、最终结构
整个功能最终可以抽象为一个非常简单的结构:
输入:
riqi
xianzai
shijian
xingqi
↓
luna_pinyin_simp
↓
lua_translator@date_time_translator
↓
rime.lua
↓
lua/date_time.lua
↓
os.date(...)
↓
动态候选
最初这一方案只存在于 Linux。
经过逐层确认调用关系、识别最小依赖、处理 Windows Rime 部署差异,并验证编译后的 Schema,最终在多套 Windows 环境中成功复现。
总结
这次 Rime 日期时间功能迁移最有价值的地方,并不是复制了几个配置文件,而是完整理清了 Rime 一个扩展功能从源代码到最终候选之间的运行链。
最终得到的几个关键结论是:
- 动态日期和时间适合通过 Lua Translator 实现。
rime.lua负责加载模块。date_time.lua负责通过os.date()动态生成内容。- Schema 必须显式加载
lua_translator。 custom.yaml正确不代表部署后的build一定正确。- Windows 上遇到异常时,应检查最终编译出的 Schema。
- 跨平台迁移应采用最小依赖复制,而不是整个用户目录覆盖。
- 第一套 Windows 验证成功后,可以将其作为后续 Windows 系统的标准模板。
- 文件层验证完成后,最终仍应通过真实桌面输入进行端到端确认。
最终结果是,一套最初在 Linux 环境构建的 Rime Lua 动态输入方案,被完整、稳定地复现在 Windows 环境中,同时保留了原有输入法配置,并且没有为了实现一个小功能而进行不必要的整体迁移或重构。