进阶专题

制作定制版

用 data_custom 目录把清风改造成自己的发行版:换默认方案、改默认配置、删掉不需要的内置内容,主程序升级零冲突

v0.126.0
0.120 新增

这一页是给二次定制的作者看的:你想把清风改造成「虎码版」「小鹤音形版」再分发给自己的用户,而不是自己一个人换套方案用。终端用户不需要读这一页——个人调整走设置界面就够了。

定制层要解决的问题

以前做定制只能直接改发布包里的 data\ 目录:删掉不要的方案、换掉 config.toml、塞进自己的词库。主程序一发新版,data\ 整个被覆盖,你得把上一版的改动逐个文件 diff 回来——每次发版都重来一遍。

定制层的目标只有一句:把你的全部定制内容放进 data_custom\,一个字节都不碰 data\,主程序升级时你的定制毫发无伤。

三层,各管一段

层位置谁维护装什么
出厂层安装目录 data\主程序,升级时整个覆盖内置方案、主题、词库、默认配置
定制层安装目录 data_custom\你,程序只读不写你这个发行版的方案、主题、默认配置
用户层%APPDATA%\WindInput\终端用户用户自己的个人设置

优先级 出厂 < 定制 < 用户。也就是说:

  • 你能盖掉任何出厂值;
  • 但你永远盖不过终端用户自己的设置。定制版是「换一套出厂配置」,不是「替用户做决定」。用户改过的项,装了你的包也仍然是他改的那个值。

data_custom\ 与 data\ 必须同级。

第一步:放一个 custom.toml

程序判定「这是定制版」的依据是 data_custom\custom.toml 在场且能解析,不是目录存在。文件内容:

[custom]
id = "huma-edition"        # 稳定标识,日志、关于页、用户报障时用
name = "虎码定制版"          # 显示名
version = "1.2"            # 你这个定制包自己的版本
base_version = "0.119.0"   # 基于哪个主程序版本定制的

[schemas]
hide = ["wubi86", "wubi86_pinyin"]

[themes]
hide = ["msime"]

[settings]
hide = ["key:input.temp_english.*", "feature:wizard"]

清单只负责两件事:身份([custom])与减法(hide)。加东西、换东西都不用在这里声明。

清单读不出来,整层就当不存在

custom.toml 缺失、语法错、或者用记事本存成了 GBK,后果不是「少了 hide 清单」,而是你的方案、主题、配置全部回落到原版——而程序一切正常,日志里连一条警告都没有。这是最难自查的一种故障,所以打包前请务必跑一次体检。

段名 [schemas] / [themes] / [settings] 都是复数。写成 [schema] 能解析通过,但一个字都不起作用。

你能做的四件事

加 / 换:把文件放进对应位置

data_custom\ 与 data\ 目录结构同构。把文件放到对应位置就生效,不需要在清单里声明任何东西。

你放什么覆盖粒度
config.toml按键深合并——你只写想改的键,其余仍取出厂值
schemas\<id>.schema.toml、schemas\<id>\ 下的词库等逐文件覆盖;出厂没有的 id 就是新增方案
themes\<名>\、opencc\*.octrie按名逐文件覆盖,同名的用你的,没放的用出厂的
compat.toml按进程名条目合并
pinyin_map.txt、system.*.toml、schemas\common_chars.txt整表替换:放了就完全替代出厂那份

config.toml 只写差异键

机制上你可以整份复制出厂 config.toml 再改几处,但别这么做。与出厂值相同的键现在看不出区别,可将来主程序调整那个默认值时,你这份旧值会把新默认顶住——本该跟着升级改善的行为,在你的用户那里被冻结了。差异越小,跨版本存活率越高。

删:写进 hide

删掉不需要的内置方案或主题,只能靠清单里的 hide——你没法「删掉」出厂目录里的文件。

[schemas]
hide = ["wubi86", "wubi86_pinyin"]

[themes]
hide = ["msime"]

hide 是绝对的:被 hide 的 id 在任何层都不存在,包括终端用户自己在 %APPDATA%\WindInput\schemas\ 里放的同名文件。所以只 hide 你确实想从这个发行版里移除的内置 id。

如果你只是想让某个方案不出现在切换列表里、但仍然可用(比如英文方案、快符表),那是方案文件里的 hidden,两者不是一回事。

hide 掉的东西不能还被引用着

把 wubi86 hide 了,却在 config.toml 里让 schema.active = "wubi86"、或者混输成员、特殊模式里还引用着它,程序起来就没有可用方案。体检会把这类引用当错误报出来。

藏:精简设置界面 0.126 新增

定制版通常已经替用户选好了方案、调好了参数,设置界面里有一大片对你的用户没用、或者不希望他们乱动的项。把它们写进 [settings] hide,设置程序就不再显示:

[settings]
hide = [
  "key:input.temp_english.*",            # 前缀匹配:所有以 input.temp_english. 开头的设置项
  "key:input.english_case_cycle_key",    # 精确匹配单个设置项
  "key:schema.pinyin.fuzzy.*",           # 拼音方案配置里的整块「模糊音」
  "feature:wizard",                      # 设置向导:不自动弹出,侧栏也不显示入口
]
  • key:<配置键>:按设置项的配置键选,以 * 结尾时按前缀匹配。配置键见配置文件参考。一张卡片里的项全被藏掉后,整张卡连同左侧的二级导航一起消失。
  • feature:<名称>:不对应某个配置键的界面元素。目前只有 wizard(设置向导)。向导会按「五笔 / 拼音」推荐预设改写用户设置,盖掉你在定制层调好的值,主方案已经定好的定制版建议关掉它。

隐藏只影响设置界面,功能照常生效——值仍取你在 data_custom\config.toml 里写的(或出厂值)。要关掉一个功能,先在 config.toml 里把它设成关,再在这里把它藏起来;只藏不改,功能还开着,只是用户找不到开关了。这一点与上面的 [schemas] hide(「这个方案不存在」)完全不同。

终端用户可以在设置「高级 → 定制版」里打开「显示定制版隐藏的设置」,重新打开设置窗口后就能看到全部设置。这个开关只在你藏了东西时才会出现。

一张卡片里的项不一定同一个前缀

卡片是按界面分组的,不按配置键前缀:比如「临时英文」卡里还有一项 input.english_case_cycle_key。只写 key:input.temp_english.*,卡片里会剩下这一项。写错或漏掉的选择器不会报错——设置程序会在自己的日志里记一条「没有命中任何设置项」的警告,装好后打开一次设置、看一眼界面最直接。模糊音那块以总开关为准整块显隐:藏总开关(key:schema.pinyin.fuzzy.enabled,或整组 key:schema.pinyin.fuzzy.*)就藏掉整块,只藏其中几格不生效。互斥的两项(比如「启用简入繁出」与「启用繁入简出」)要成对隐藏:只藏一个,用户打开另一个时界面没法联动关掉被藏的那个,两者可能同时生效。

打包前跑一次体检

wind_input config check --custom D:\build\data_custom --data D:\build\data

--data 省略时会自动找 --custom 同级的 data\。这条命令全程离线:不连服务、不读用户配置、一个字节都不写盘,你把安装包解开就能跑,不必先把输入法装起来。

它会替你查出来:

  • 清单本身——缺失、语法错、段名/键名拼错、身份字段没填、base_version 与当前主程序差了几个版本、[settings] hide 的选择器写法(是否命中设置项要看设置程序的日志)
  • 配置键——已经被移除或从来不存在的键、类型不符、值超出合法范围、把一整段写成了标量
  • 真加载一遍——按运行时同样的方式把你的定制层加载一次,光看配置表看不出来的坏值(映射表里的值、越界的整数)在这里现形
  • 引用面——hide 掉的 id 是否还被别处引用着、hide 的目标在盘上是否真的存在
  • 几个不会报错的静默陷阱——见下

退出码:0 没问题、1 查出了错误、2 命令用法不对。警告不影响退出码,可以直接接进打包脚本。

三个不报错但会坑到用户的写法

这几条的共同点是:程序照常工作、不报错、日志里也没有,但你的用户会遇到怪事。体检都会替你查出来,这里说清楚为什么。

  1. 定制层里不要声明 [keys] key_actions(input.temp_pinyin.trigger_keys、input.temp_english.trigger_keys 同理)。首次启动时程序会把按键绑定一次性物化进终端用户的个人配置并打上完成标记。此后你在定制包里再改这些绑定,对已经装过旧版包的用户永远不生效——只有全新安装的用户才拿得到新绑定。

  2. data_custom\opencc\ 里的文件名必须与出厂目录逐字相同,含大小写。 简繁转换按文件名跨层取,只放一两本是正常用法(没放的自动用出厂的)。但名字完全对不上(MyDict.octrie)的那本在任何平台上都永远取不到;只差大小写(stphrases.octrie)在 Windows 和 macOS 上现在能取到,可那是在赌文件系统大小写不敏感,换到区分大小写的环境就失效。届时的现象是「同一个包在这台机器上换了词表、在那台上一个字都没变」。

  3. 映射表的值是数组,不是单个值。 [input.punct.custom_mappings] 要写 "," = [","] 而不是 "," = ",";[ui.font.scripts] 同理(latin = ["Consolas"])。写错的后果是那一整段配置在加载时被丢掉换成出厂默认,每个用户、每次启动都会踩到。

分发与升级

data_custom\ 不在官方安装包里,官方安装包也不会删它。所以:

  • 分发——由你自己把 data_custom\ 放进安装目录:可以让用户装完官方包后解压一个压缩包进去,也可以做你自己的安装脚本。
  • 升级——用户装新版官方包时,data\ 被整个覆盖,data_custom\ 原样保留,你的定制立即在新版上继续生效。这正是这套机制存在的意义。
  • 改定制内容——只需要重新分发 data_custom\,不用重打整个安装包。

装好之后确认一下清单真被读到了

在装了你的定制版的机器上,不带参数跑一次 wind_input config check。它会自动找本机的定制层——如果回你「本机不是定制版」,说明清单没被读到,此刻整个定制层是没生效的。

启动日志里也会有对应的一行:定制版 huma-edition「虎码定制版」1.2(基于 0.119.0)。

对这篇文档有疑问,或发现内容有误?

欢迎到文档仓库提 issue,写明问题时附上本页链接即可。

去提 issue →

本页目录