个性化

输入方案管理

启用、排序、导入与导出方案,理解方案文件结构,并从零创建自定义方案

清风输入法采用方案驱动架构:一个方案 = 一种输入方式,由 TOML 方案文件定义。内置全拼、双拼、五笔 86、五笔拼音四种,另有英文等特殊方案,可随时启用、排序、导入新方案。

配置分工:全局行为 + 方案固定参数

用户可配的引擎行为(上屏策略、调频、造词、模糊音等)是全局配置,同类方案共享;方案文件只包含引擎的固定参数(引擎类型、码长、词库、双拼布局等)。单方案的差异化通过 schema_overrides 覆盖。所以下文提到的行为开关多在全局配置里调整,方案文件一般无需手动修改。

启用、停用与排序

在设置工具(Ctrl + Shift + ])的「方案」页,方案列表展示所有方案,每个显示名称与引擎类型徽章(码表 / 拼音 / 混输 / 英文)。已启用的排在前、未启用的排在后;勾选「隐藏未启用」只看已启用项。

列表上方工具栏对选中方案提供操作:

操作说明
↑ / ↓调整已启用方案的顺序,「切换输入方案」快捷键按此顺序循环
设置打开方案设置对话框(切换热键引导键码表配置、双拼布局、附加词库开关)
删除删除用户方案(内置方案不可删除),同时清理其词库数据与未被共享的资源文件
刷新重新加载方案列表
导入 / 导出见下文导入与导出方案

方案设置对话框没有独立的保存按钮

里面的改动——切换热键、引导键、码表配置、双拼布局、附加词库——关闭对话框后由底栏的「应用设置 / 保存并退出」统一提交,与设置界面其它页面完全一致。

它们背后写两个地方(热键这类进 config.toml,码表配置与词库开关进 schema_overrides\<方案id>.toml),但你不需要关心分别:一个保存入口全部落地。可以连着配好几个方案再一次性保存。

「重新加载」会连同这些尚未提交的改动一并丢弃。

也可以直接编辑 %APPDATA%\WindInput\config.toml

[schema]
active = "wubi86"               # 当前使用的方案
# 可切换的方案列表(顺序决定 Ctrl + Shift + E 的循环顺序)
available = ["wubi86", "wubi86_pinyin"]

如需启用拼音 / 双拼,把对应 id 加入 available 并重启。按 Ctrl + Shift + E 在已启用方案间循环切换。

方案切换热键 0.114 新增

Ctrl + Shift + E 是循环切换,方案多了要按好几次。可以给单个方案绑一个直达热键,按下直接切过去:选中方案 → 设置 → 进入方式 → 切换热键

两种模式下都生效——切到英文方案之后还得能按键切回来,所以它不像其它快捷键那样限定中文模式。配置键是 keys.schema_hotkeys

不必先启用:直达热键可以切到没加入 available 的方案。英文方案的典型用法就是这样——不占循环切换的位置,用热键切过去打一段,再用循环键或另一个热键切回来。首次切过去时会现加载词库,可能有短暂停顿,之后就缓存住了。

特殊方案 0.114 新增

英文、快符这类方案默认不在列表里——它们对多数用户是噪音。勾选列表上方的「显示特殊方案」即可看到并启用。已启用的特殊方案恒显示,不受这个开关影响。

特殊方案还可以配引导键选中方案 → 设置 → 进入方式 → 引导键。与切换热键不同,引导键是在中文输入中途按下即临时进入,打完一段自动退回原方案——适合快符这种「插一个符号就走」的用法。配置落在 schema.special_modes,条目的其余字段(进入即展示候选、候选窗布局等)目前仍需手写 config.toml

快符这类特殊方案本质就是码表方案,只是靠引导键进入。所以它同样有用户词库、词频调整、候选调整,也同样能单独设一套上屏行为——见下方方案级码表配置

其中英文方案可以像五笔、拼音那样切换:启用后用循环键或直达热键切过去,输入字母出英文候选(词库补全)。它和 Shift 切换的英文半角不是一回事——后者是按键原样透传、不出候选。

英文方案的调频、上屏后自动加空格等设置在方案 → 全局方案配置 → 英文方案配置,配置段是 schema.english,与码表互不影响。

英文方案与临时英文的区别

「切过去打一整段英文,再切回中文」用英文方案;「中文输入中途插几个英文单词」用临时英文。临时英文的大小写变形、符号数字入码等选项目前只作用于临时英文模式,英文方案走的是常规输入路径,不受那些开关影响。

方案级码表配置 0.114 新增

码表方案默认跟随全局码表配置(方案 → 全局方案配置 → 上屏行为)——改一次,所有码表方案一起变。想让某个方案单独一套,在 选中方案 → 设置 → 码表配置 打开「自定义码表配置」,再点旁边的「设置」。

里面的项与全局那份逐条相同(顶码上屏、精确匹配、词频调整等),改的只是作用范围。

开与关的含义

  • (默认):该方案不写任何行为字段,跟随基线。普通方案的基线是全局配置,特殊方案的基线是内置默认值(特殊方案不继承全局
  • :从当前生效值起步,逐项写进该方案。此后改全局配置对这个方案不再有影响

关掉即恢复跟随,之前写的值会被清掉。

最典型的用法是给快符表单独开词频调整:小符号表的顺序往往是作者精心排过的,全局开了调频未必适合它;反过来想让快符学习使用频率、又不想动五笔的调频,也只能靠这里。

落盘位置是用户覆盖层 schema_overrides/<方案id>.toml,不改方案文件本身,方案后续更新不受影响。手写的写法见引导键特殊模式 · 自动上屏策略

方案文件写死的值不受这个开关控制

若方案作者在 <方案id>.schema.toml 里显式写了某项,它属于方案定义的一部分——关掉「自定义码表配置」只清除你在设置里改的那层,方案文件里的值仍然生效。

主方案设置

选项说明
主码表方案主力码表方案(如五笔 86);拼音方案的反查 / 编码提示基于此方案的码表
主拼音方案混输 / 临时拼音使用的拼音方案;码表方案的临时拼音使用此方案

配置项参考

主方案、全局引擎行为等的确切配置键、取值与默认值见方案与引擎配置

导入与导出方案

方案以方案包.zip)形式分发,便于备份或分享社区码表方案(如 WindInputCodeTable 收集的第三方码表)。在「方案」页工具栏:

  • 导入 —— 选择 .zip 后先预览包内方案信息,确认后选择合并替换导入
  • 导出 —— 将选中方案连同其引用的资源文件打包导出为方案包(文件名带方案版本)

方案包为零层级结构:根目录直接放方案文件与词库,可附可选的 package.toml 元信息。导入方自动预览包内容并选择合并 / 替换。

方案文件结构

方案文件为 TOML 格式,位于 %APPDATA%\WindInput\schemas\ 目录,命名为 <方案ID>.schema.toml;方案引用的词库文件(.dict.yaml)为 Rime YAML 格式。内置方案对应文件:

文件方案
pinyin.schema.toml全拼
shuangpin.schema.toml双拼
wubi86.schema.toml五笔 86
wubi86_pinyin.schema.toml五笔拼音混输

方案文件的最小结构:

[schema]
id = "my_schema"        # 方案 ID,须与文件名前缀一致
name = "我的方案"
icon_label = "我"       # 模式指示 / 状态气泡的图标短称(可选)
version = "1.0"
author = "作者"
description = "方案说明"

[engine]
type = "codetable"      # 引擎类型:pinyin / codetable / mixed

引擎类型

三种引擎各有一段固定参数(行为开关不写在这里):

# 拼音引擎(全拼 / 双拼)
[engine.pinyin]
scheme = "full"                 # full(全拼)/ shuangpin(双拼)
unigram_path = "pinyin/unigram.txt"  # 长句打分用语言模型(可选)
[engine.pinyin.shuangpin]
layout = "xiaohe"               # xiaohe / ziranma / mspy / sogou / abc / ziguang

# 码表引擎(五笔等)
[engine.codetable]
max_code_length = 4             # 最大码长(0 = 回退 4)
base_sort = "weight"            # 基础排序维度,见下文「排序配置」
input_chars = ""                # 码元字符集(空 = a-z),见下文「码元字符集」
leading_chars = ""              # 可作第一码的字符(空 = 同 input_chars)

# 混合引擎(五笔优先、拼音兜底)
[engine.mixed]
primary_schema = "wubi86"       # 主方案(码表)
secondary_schema = "pinyin"     # 辅助方案(拼音)
codetable_weight_boost = 10000000  # 码表精确匹配提权基线(0 = 回退 10_000_000)

码元字符集 0.114 新增

默认只有 26 个字母算「输入码」,按别的键就走标点、选词或直接上屏。方案的编码里若含别的字符, 用 input_chars 声明:

[engine.codetable]
input_chars = "a-x"     # 五笔严格集:y、z 不进编码
input_chars = "a-x/"    # 再加一个 /,供 /test 这类词条
input_chars = "a-z0-9"  # 字母加数字,词库里有 Win10 这类词条时需要

写法是范围 + 字面的组合,大小写不敏感;- 写在首位或末位时作字面字符(a-z-)。 不在集内的字符按下时会终结当前编码:先上屏当前候选,再输出该字符本身。

数字通常要配 leading_chars。数字键在空编码时是选词键,直接让它作码元会把这个用法整个占掉:

[engine.codetable]
input_chars = "a-z0-9"
leading_chars = "a-z"   # 数字能作码元,但不能起头

这样 win10 里的 10 正常进编码,而空编码时按数字键仍是选词或输出数字。

码元会从原有功能手里抢走按键

编码输入期间,码元字符优先于选词键、翻页键、以词定字键和数字选词。把 ; 配成码元后, 编码输入时按 ; 就是打码而非选第二个候选。

写进 leading_chars 的字符连空编码时也归码表,以它作引导键的功能(快捷输入、临时拼音/英文、 特殊模式)便进不去了。想两者共存,把它排除出 leading_chars——它就只在编码输入途中作码元。 有冲突时启动日志会逐条告警并给出改法。

字符集写错(如 z-a 逆序、含空格)不会让方案失灵,会回落默认 a-z 并记录告警。 完整字段说明见配置参考

词库配置

每个方案的 dictionaries 数组列出所有词库,分两类:主词库仅 1 个(default = true,始终启用),附加词库任意多个(可被用户独立开关)。

[[dictionaries]]
id = "wubi86_main"
label = "极点五笔主词库"
path = "wubi86/wubi86_jidian.dict.yaml"
type = "rime_codetable"
default = true

[[dictionaries]]
id = "wubi86_emoji"
label = "Emoji 表情"
path = "wubi86/wubi86_jidian_emoji.dict.yaml"
type = "rime_codetable"
default_enabled = true          # 方案默认启用

[[dictionaries]]
id = "wubi86_district"
label = "行政区域"
path = "wubi86/wubi86_jidian_district.dict.yaml"
type = "rime_codetable"
base_order = 1                  # 排在主库(0)之后
default_weight = 500            # 该库无权重列,整库定档 500

常用字段:

字段说明
id词库 ID,全局唯一
labelUI 显示名,留空回退 id
description设置工具开关下方的小字说明
path词库文件路径,相对 schemas\ 目录;用户数据目录下的同名文件优先于程序 data\,见同结构覆盖机制
typerime_codetable / rime_pinyin / english(空 = 回退 rime_codetable
default是否为主词库;每方案有且仅一个
default_enabled附加词库的方案默认启用状态;省略视为未启用
enabled用户覆盖启用状态,由设置工具写入;未设时继承 default_enabled
base_order该库的层级基序档位,见下文排序配置
default_weight整库权重硬覆盖,见下文排序配置

启用判定优先级:enabled > default_enabled > 主词库始终启用

weight_spec 尚未接线

方案文件里可能出现 [dictionaries.weight_spec]median / max / mode 等)。它当前不被读取,仅作为词库权重分布的事实记录供方案作者查阅。跨库权重归一化尚未实现,现阶段用 default_weight + base_order 手工校准。

词库文件(.dict.yaml)

词库文件沿用 Rime 的 .dict.yaml 外形,但解析器是本输入法自己的,与 librime 并不等价。理解下面这几条能避免绝大多数「词库加载了却不生效」的问题。

YAML 头只有两个键被读取

除 columns / import_tables 外,头部所有键一律被忽略——包括 name

解析器逐行扫描头部,只认 columns:(全部词库类型)与 import_tables:(仅 type = "rime_pinyin" 的词库)。其余键既不报错也不告警,直接跳过。

这意味着 name: 写什么都不影响任何行为——词库的显示名来自方案文件的 [[dictionaries]].label,不是 YAML 头里的 name。同理 versionuse_preset_vocabularyvocabulary 等 Rime 键在这里全是装饰。

sort: 是个特例:它会被读取,但只用来打一条日志告警,不影响排序。词库生成工具甚至会主动清洗掉这个键。要控制排序请用下文的排序配置四件套

---
name: my_dict          # 被忽略(显示名取方案文件的 label)
version: "1.0"         # 被忽略
sort: by_weight        # 读取,但只触发一条 WARN 日志,不生效
columns:               # ← 真正生效的键
  - text
  - code
  - weight
...
你好	nihao	1000

分隔行:... 必需,--- 可选

正文的起点是首个恰好等于 ... 的行--- 只是头部里的一行普通内容,写不写都行。

缺少 `...` 会让整个词库静默变成零条目

找不到 ... 时解析器按零条目处理,只在日志里留一条 WARN。词库看起来"加载成功"但一个候选都没有——这是最常见的自制词库失效原因。

columns 支持的列名

columns 只认三个名字,两种 YAML 写法(块序列 - text 与流式 [text, code, weight])都支持:

列名必需性缺失后果
text必需整个词库被跳过并记 ERROR
code必需整个词库被跳过并记 ERROR
weight可选全库权重按 0 处理

其他列名(如 Rime 的 stem语法合法但不取用,只作占位——占位会顺延其后各列的下标,所以必须写全,不能省略中间列。

不写 columns 会走启发式猜测

省略 columns: 时,解析器会采样正文(最多 200 行 / 攒够 32 票)投票判断列序:逐列检查是否"像编码"(全部字符属于 a-z0-9 及少数符号),恰有一列像码才计一票。

  • 平票或零票 → 回退 text code weight
  • 无论投票结果如何,权重恒取第 3 列
  • 每次走启发式都会记 WARN,日志里带票数与建议写法

始终显式写 columns

纯 ASCII 词条(符号库里的 @、命令直通车的 $CC(...))会让投票判错,把词条当成编码列。列序是文件级属性、判定一次全文固定,一旦判反整个词库的编码与词条就是对调的。显式声明 columns 可以完全绕开这套启发式。

其他正文规则

  • # no comment 指令 —— 整行恰好等于它时,其后所有 # 开头的行按数据而非注释解析
  • 只剥行尾空白,保留行首 —— 因为全角空格 U+3000 属于 Unicode 空白,用常规 trim 会把「全角空格」这个词条本身削掉
  • 空 text 或空 code 的行被跳过
  • 权重解析失败记为 0 —— Rime 的 50% 相对权重语法未实现,会落到这里

排序配置四件套

base_sortbase_orderdefault_weightsort 名字相近但分属三个不同的文件层,作用点完全不同。这是方案定制里最容易混淆的一组:

名字写在哪作用
base_sort方案文件 [engine.codetable]选定全局排序维度
base_order方案文件 [[dictionaries]]词库层间档位
default_weight方案文件 [[dictionaries]]整库权重硬覆盖
sort词库 .dict.yaml 头部死键,只触发告警

base_sort —— 选定排序维度

只对码表引擎生效,写在拼音方案里无效。

取值比较链
weight(默认,留空同)权重降序 → base_order 升序 → 库内出现序 → …
naturalbase_order 升序 → 库内出现序 → …(权重完全不参与

natural 即"字根序 / 文件原序",适合按编码规则天然有序的码表。

不接受 Rime 的 by_weight / original 拼法

这两个 librime 写法被明确列为非法值而非别名。填入任何未知取值都会回退到 weight 并记一条告警——刻意不做兼容,是为了避免两套排序词汇被误当等价。

base_order —— 词库之间的硬分档

小整数档位,排序时作为独立层级参与,位置在权重之后、库内出现序之前

它存在的理由是:库内出现序是每个词库各自从 0 起的局部序号。没有 base_order 时跨库直接比较,会让小词库靠前的词条反超主词库深处的词条。给扩展库配 base_order = 1 就能让它整体排在主库(0)之后。

系统词库建议取 >= 0

用户词、临时词等非系统层有默认的负档位(逻辑层 -4、用户层 -3 等)。系统词库若配负值会与这些层交错,产生难以预料的顺序。

default_weight —— 整库权重硬覆盖

设置后无条件替换该词库每一条词条的权重,词库自身的权重信息完全丢弃。

用途是没有权重列的附加库:不设时全库 weight = 0,在权重模式下会整体沉底。给行政区域库配 default_weight = 500 就能让它落在设计者选定的档位。

有真实权重的库绝不要配

Emoji 库靠 200/199/198… 递减权重表达展示顺序,抹平就毁了它的排列;扩展词库带真实词频,抹平会丢掉词频信息。

另外注意两个相互作用:整库同权会让库内自动退化为文件原序(等价 Rime 的 sort: original);而 base_sort = "natural" 时权重根本不参与比较,此时配 default_weight 完全没有意义。

优先级串联

base_sort 选定比较器
  ├─ weight  → 权重降序 → base_order 升序 → 库内出现序 → …
  └─ natural → base_order 升序 → 库内出现序 → …(权重不参与)

其中权重的值 = default_weight(若配置)或词库原始权重
                └─ 覆盖发生在更早的取数层,不是排序层

差异化覆盖(schema_overrides)

全局引擎配置是所有同类方案的基线;当某个方案需要与全局值不同的行为时,用 schema_overrides\<方案ID>.toml 只覆盖个别项,未覆盖项跟随全局值。方案设置对话框中的附加词库开关、双拼布局等也写入这个文件(由设置工具维护,一般无需手改)。它不会被安装包升级覆盖。

与「整份替换方案文件」的区别

schema_overrides\逐项深合并,只表达差异;而在用户数据目录 schemas\ 下放一个与内置方案同名的 .schema.toml整份替换——内置那份完全不参与。两条路都不会被升级覆盖,但前者能让方案文件的后续更新继续透传。详见同结构覆盖机制

覆盖采用深合并,但有两条例外:

  • 数组整体替换 —— 如 encoder.rules 写了就是整份替换,不会逐条合并
  • [[dictionaries]] 按 id 稀疏合并,且只接受 enabled 一个字段 —— pathlabelbase_orderdefault_weight 等永远以方案文件为准,覆盖层改不了

第二条是刻意的:它保证用户层的词库开关不会把整份词库定义冻结成快照,否则方案升级后新增或改路径的词库都会失效。

从零创建自定义方案

普通用户通过设置工具即可完成配置,无需手动编辑方案文件。若要创建自定义方案,按以下步骤:

  1. 准备方案文件 —— 建议先在「方案」页导出一个内置方案作模板,在其基础上修改;方案 ID 必须与文件名前缀一致(如 my_schema.schema.toml 的 ID 为 my_schema
  2. 放置文件 —— 方案文件存入 %APPDATA%\WindInput\schemas\;引用的词库文件(.dict.yaml)放在用户数据目录 schemas\ 下,或复用 data\ 下的内置词库路径
  3. 登记方案 —— 在 config.tomlschema.available 中加入方案 ID
  4. 生效 —— 重启输入法或切换方案;附加词库开关等热重载项除外

码表方案通常还需编码器为词组自动生成编码:

[encoder]
max_word_length = 10

[[encoder.rules]]
length_equal = 2                # 二字词
formula = "AaAbBaBb"            # 第一字前两码 + 第二字前两码

[[encoder.rules]]
length_equal = 3
formula = "AaBaCaCb"

[[encoder.rules]]
length_in_range = [4, 10]       # 四字及以上
formula = "AaBaCaZa"

公式语法:A / B / C / Z = 第 1、2、3、末个字;a / b = 该字的第 1、2 个编码(如 Aa = 第 1 字第 1 码)。

行为参数在全局配置

上屏策略、调频、造词、模糊音、临时拼音等行为都是全局配置,集中在 config.toml[schema.codetable] / [schema.pinyin] / [schema.mix],不写在方案文件里。自定义短语也是全局共享的,通过设置工具添加,见自定义短语

拆字配置(engine.chaizi)

形码方案可挂拆字库,在候选悬停提示里显示构字信息。整段配置写在方案文件的 [engine.chaizi] 下,路径相对 data\schemas\

[engine.chaizi]
db_path = "wubi86/wubi86_chaizi.txt"   # 拆字库(字\t字根\t编码)
font_path = "wubi86/HeiTiZiGen.ttf"    # 字根字体 TTF(可选,仅参与导入导出打包)
font_family = "黑体字根"               # 字根字体的 DirectWrite 家族名(可选,实际渲染依据)
必填说明
db_path拆字库文件,制表符分隔的三列:字\t字根\t编码
font_path字根字体 TTF;只用于导入导出打包,不参与渲染
font_family字根字体的 DirectWrite 家族名;渲染时的实际依据

字根字体:font_path 与 font_family

两个字体项的分工与直觉不同,注意区分:

  • font_path —— 在 Windows 上不会被直接加载渲染。它只在方案的导入/导出时起作用:导出时把这个 TTF 一并打包进方案压缩包,导入时随方案一起落到用户数据目录。要让字体真正可用,必须把该字体文件手动安装到系统(双击 TTF → 安装,或右键「为所有用户安装」)。
  • font_family —— 决定渲染时实际使用哪套字体,必须填写字体安装到 Windows 后的家族名,而不是文件名或文件路径。家族名可在「设置 → 个性化 → 字体」或双击字体文件的预览窗口中查看。

字体没装,字根就退回默认字体显示

若字体未安装到系统,或 font_family 与系统中的家族名不一致,DirectWrite 找不到对应字体,拆字提示会静默回退到默认字体渲染——不会报错,但字根形状是错的。排查时优先核对系统字体列表里的名称拼写(含全角/半角、空格差异)。

本页目录