进阶

命令直通车

让短语与词库条目在选中时执行动作——打开网址、启动程序、模拟按键、切换输入法状态

命令直通车(Command Bar)把短语 / 用户词库 / 系统词库的条目从"展开成文本"升级为"执行带副作用的动作":打开 URL、启动程序、模拟按键、写入剪贴板、加词到用户库、切换输入法状态等,让输入法兼作快捷命令启动器。

如何触发

命令用一段英文字母编码触发:输入编码 → 候选区出现命令条目 → 选中即执行。

输入选中后
cobd用默认浏览器打开 baidu.com
cojk输出 「」,光标停在中间,可用跳出键越过
coac把剪贴板内容加入用户词库
coen切换中英文模式

系统短语包已内置一批以 co 开头的示例命令,可在 设置 → 词库 → 短语 中浏览、开关或仿写。

触发码只能是英文字母

数字键会被"选中第 N 候选"逻辑吃掉,中文标点在按键阶段就被转换,二者都进不了短语层。因此触发码只能用 ASCII 字母(如 cobd),既不能含数字,也不能用中文标点。想携带查询内容时,用 clip() / last() 等数据源,而不是把词跟在编码后面。

编写位置

命令短语可放在三处,都会自动解析:

位置作用范围入口
快捷短语全局,跨方案有效设置 → 词库 → 短语
用户词库仅当前方案设置 → 词库 → 方案 → 用户词库
系统词库仅当前方案设置 → 词库 → 方案 → 系统词库

推荐放快捷短语

绝大部分命令放快捷短语,拼音 / 五笔 / 混输下都可用。只有方案专属的命令才放用户词库。

四种标记

短语与词库条目共用一个 text 字段,靠内容形式区分类型。命令能力通过以 $ 开头的标记触发。

标记含义前缀输入时完整编码时
$CC(显示名, 动作...)命令,仅精确匹配不显示显示
$CC1(显示名, 动作...)命令,精确 + 前缀都显示显示显示
$AA(组名, 字符串)字符组显示组名导航展开为 N 个单字符
$SS(组名, 元素...)数组(字符组的一般形式)显示组名导航展开为 N 个成员
cobd = $CC("打开百度", open("https://baidu.com"))
cobd = $CC1("打开百度", open("https://baidu.com"))
zzbd = $AA("标点", "、。·ˉˇ¨〃々—~‖…")
zzgo = $SS("常用站点", $CC("百度", open("https://baidu.com")), $CC("GitHub", open("https://github.com")))

$AA$SS 的字符串简写:$AA 自动按字符拆开,$SS 显式列举每个元素,元素既可是字符串(选中上屏),也可是嵌入的 $CC(...)(选中执行动作)。输入前缀(如 zz)看到组名导航条目,选中后自动补全到完整码进入二级选择;输入完整码(如 zzbd)直接展开为成员候选。

表达式语法

$CC / $CC1 内部是表达式,只有三种形态:

形态例子
字面量"hello"423.14
标识符lastnowcode(等价零参调用)
函数调用open("https://...")clip.copy("x")key.tap("Enter")
  • 字符串内插:字符串中用 {expr} 内插子表达式,如 $CC("百度搜 {clip()}", open("https://baidu.com/s?wd={url(clip())}"))
  • $$ 转义:要输出字面 $ 就写 $$,否则 $M 之类会被当模板变量替换。例如 text = "工资: $$M" 显示 工资: $M
  • . 仅作命名空间. 只用于函数名分隔(clip.copykey.tap),不能取属性或索引。用 last(1) 而非 last.1,用 len(code) 而非 code.length
  • 具名参数:部分函数接受 名字=值 形式的可选参数(目前是 proc.runcwd / verb / showproc.shellcwd,以及 ime.pairjump),如 proc.run("dict.exe", cwd="D:\\Dict")。规则三条:必须写在所有位置参数之后、同一个名字不能写两次、名字必须是该函数登记过的(写错会报错,不会被当没写过)。值和普通参数一样可以内插,如 cwd="{clip()}"

`k=v` 与 `{k: v}` 不是一回事

k=v函数的参数,管这一次调用;$CC(..., {prefix: false}) 那种花括号是短语的修饰符,管这条候选怎么显示。两者位置和作用对象都不同,写错地方会直接报错而不是悄悄生效。

路径里的反斜杠要写两个

字符串里的 \转义引导符,写 Windows 路径时必须写成 \\

# ✅ 正确
cotmp = $CC("[打开临时目录]", open("D:\\notes\\temp"))

# ❌ 错误:`\n` 被当成换行、`\t` 被当成 Tab
cotmp = $CC("[打开临时目录]", open("D:\notes\temp"))

被吃掉的是这几个:\n \t \r 分别变成换行、Tab、回车,\\ \" \' \{ \} \( \) \$ 变成对应的单个字符。其余组合(如 \我\x)原样保留反斜杠——这正是坑人的地方D:\我的文档 恰好能用,于是很容易以为单反斜杠没问题,直到某天路径里出现 \notes\tools\report,才发现路径被截断成了带换行/Tab 的怪字符串,而且看不出哪里错了。

别靠「试出来能用」判断

路径写单反斜杠时能否工作,取决于下一个字母恰好是不是转义字母。同一条短语换个目录名就可能失效,且失败时只弹一句「命令执行失败」,不会告诉你是反斜杠的问题。统一写 \\,不要逐条去试。

内部目录变量

不想硬编码安装位置或用户名(换台机器、换个盘符就失效),可以用 ${变量名} 引用输入法自己的目录:

变量指向典型位置
${APP_DIR}程序安装目录(wind_input.exe 所在目录)C:\Program Files\WindInput
${USER_DATA}漫游用户数据目录%APPDATA%\WindInput
${LOCAL_DATA}本机用户数据目录(不随漫游同步)%LOCALAPPDATA%\WindInput
# 打开安装目录
coad = $CC("[打开安装目录]", open("${APP_DIR}"))

# 上屏安装目录路径
cotd = $CC("[输出安装目录]", type("${APP_DIR}"))

# 拼接子目录 —— 反斜杠同样要写两个
colg = $CC("[打开日志]", open("${LOCAL_DATA}\\logs"))

变量在解析阶段就被替换成绝对路径,可用在任何字符串位置(动作参数、显示名、拼接片段)。这三个变量与 CLI 的路径参数完全一致,写法可以互相照搬。

不认识的 ${...} 会原样保留

只有上表三个是内部目录变量。写错名字(如 ${APPDIR})不会报错,而是原样留下字面的 ${APPDIR} ——因为 ${YC} 这类短语模板变量也用同样的写法,命令栏不能把它们当错误吞掉。所以路径打不开时,先核对变量名拼写。

若你确实想输出字面的 $ 且后面紧跟 {,写 \${...}

常用示例

# 打开网址
cobd = $CC("打开百度", open("https://baidu.com"))
cogh = $CC("打开 GitHub", open("https://github.com"))

# 搜索剪贴板 / 上次上屏内容
cobs = $CC("百度搜 · {clip()}", search("baidu", clip()))
cozd = $CC("汉典 · {last()}", open("https://www.zdic.net/hans/{url(last())}"))

# 配对符号(光标落两段之间,可用跳出键越过右段)
cojk = $CC("「」", ime.pair("「", "」"))

# 删除当前行
codl = $CC("[删行]", key.seq("Home", "Shift+End", "Backspace"))

# 启动程序
cono = $CC("打开记事本", proc.run("notepad.exe"))

# 加词到用户库(编码自动生成)
coac = $CC("加词 · {clip()}", dict.add(clip()))

# 计算剪贴板表达式
coca = $CC("={calc(clip())}", type(calc(clip())))

# 切换输入法状态
coen = $CC("切中英", ime.toggle("cn-en"))
cots = $CC("切主题", ime.theme_cycle())

# 字符组
zzbd = $AA("标点", "、。·ˉˇ¨〃々—~‖…")
zzsx = $AA("数学", "+-<=>±×÷∈∏∑")

内置函数参考

所有函数都返回字符串,动作函数返回空串。记号:s 字符串、n 整数、参数后 ? 表示可选。

取值函数(纯函数)

函数说明
code() / code(n)触发编码(第 n 字符起到末尾)
tail(s, n)字符串 s 从第 n 字符起到末尾
last() / last(n)最近 / 倒数第 n 次上屏文本
clip()当前剪贴板文本
clip(n)剪贴板历史第 n 条——尚未实现,参数被忽略,等同 clip()
app() / title() / sel()前台进程名 / 窗口标题 / 选中文本——Windows 上均返回空串(仅 macOS 上报)
date(fmt) / date(fmt, offset)日期,offset 形如 "+1d""-2w""+3M""-1y"
time() / time(fmt)时间,默认 "HH:mm:ss"
now()等价 date("YYYY-MM-DD HH:mm:ss")
env(name)环境变量,如 env("USERNAME")
config.get(key)读取配置项当前值

文本处理(纯函数)

函数说明
len(s)字符数(按 rune)
upper(s) / lower(s)转大写 / 小写
trim(s) / trim(s, chars)去首尾空白 / 指定字符
sub(s, start) / sub(s, start, end)切片,索引 1 起,双闭区间,支持负数
replace(s, old, new)字面替换
regex(s, pat, rep)正则替换(RE2 语法)
split(s, sep, n)拆分取第 n 段(1 起,支持负数)
concat(...)拼接
reverse(s)反转(按 rune)
url(s) / html(s) / json(s) / base64(s)URL / HTML / JSON / Base64 编码
default(s, fallback)s 为空时返回 fallback

计算与内省

函数说明
calc(expr)数学表达式求值,支持 + - * / % ( )、浮点
num(s, base)进制转换(2/8/10/16),如 num("0xff", 10)"255"
help(name)返回指定函数的简介

以下函数已注册但尚未实现

调用它们不会报错,但拿不到预期结果,请勿写进日常短语:

  • t2s(s) / s2t(s) / pinyin(s) —— 占位实现,原样返回输入
  • ask(prompt) / pick(...) —— 交互式弹窗,未实现
  • clip(n) 的历史查询、proc.shell 的 flags 参数

动作函数(有副作用)

部分函数有等价别名(run = proc.runshell = proc.shellsearch = web.searchdict.addword = dict.addime.setting = setting.open),推荐写规范名。

函数副作用
type(s)经 TSF 上屏文本,不污染剪贴板
open(target)打开 URL / 文件 / 程序(http(s) 走浏览器,其他走 ShellExecute)
proc.run(cmd, ...args, cwd?, verb?, show?)异步启动进程,三个具名参数见下
proc.shell(cmdline, flags?, cwd?)执行 shell 命令,flags 见下、cwd 见下
key.tap(combo) / key.seq(...combos)单次按键 / 按键序列
key.hold(combo) / key.release(combo)按下 / 抬起(须成对使用)
key.type(text)Unicode 直输,绕过键盘布局(走 SendInput,非 TSF)
clip.copy(s) / clip.paste()写入剪贴板 / 模拟 Ctrl+V
dict.add(s) / dict.add(s, code)加词到用户库(编码自动推导或指定)
ime.toggle(target)切换状态:cn-en / fullshape / layout / candwin / s2t / preedit / toolbar
ime.schema(id)切换并持久化方案,如 "wubi86" / "pinyin"
ime.theme(name) / ime.theme_cycle(dir?)切换主题 / 循环切换(dirnext / prev
ime.undo_commit()撤销上屏:删除最近一次上屏的内容,见下文
ime.pair(left, right, jump?)上屏配对符号:光标落两段之间,可用跳出键越过右段,见下文
setting.open(page, args?) / setting.web(page, args?)打开设置的指定页(page 见下;args 为附加命令行参数;setting.web 已废弃,等价于 setting.open
web.search(engine, q)打开搜索页,enginebaidu / bing / google / zdic
config.set(key, value) / config.toggle(key)写入配置 / 循环切换枚举或翻转布尔(返回新值)
wind.cli(...)调用命令行子命令,见下文

proc.shell 的 flags 暂未区分

term / pwsh 等 flag 参数当前被忽略,一律走默认 shell(Windows 为 cmd /C)。写了不报错,但不会得到可见 console 或 PowerShell。

工作目录:cwd=

被启动的程序总有一个确定的工作目录,规则如下:

写法工作目录
proc.run("D:\\Dict\\dict.exe")D:\Dict(程序自己所在的目录)
proc.run("notepad.exe")用户主目录(%USERPROFILE%
proc.run("x.exe", cwd="D:\\Data")D:\Data
proc.shell("dict -q 词")用户主目录
proc.shell("dict -q 词", cwd="D:\\Dict")D:\Dict

不写 cwd 时,proc.run 默认取被启动程序所在的目录——等同于你在资源管理器里双击它。靠相对路径找数据文件的程序(各类词典、绿色版工具)正是按这个前提写的,所以多数情况下不需要写 cwd

proc.shell 是把整条命令行交给 shell,认不出目标程序,所以默认只能落到主目录。命令里带相对路径就必须显式写 cwd

cwd 支持内部目录变量,也支持内插:

# 用输入法自己的目录
cotool = $CC("[跑工具]", proc.run("${APP_DIR}\\tools\\t.exe", cwd="${APP_DIR}\\tools"))

# 查词:词库在程序目录下,靠相对路径加载
codc = $CC("查 {last(1)}", proc.run("D:\\Dict\\dict.exe", "{last(1)}", cwd="D:\\Dict"))

`cwd` 写了个不存在的目录会被忽略

此时程序仍会启动,但工作目录退回默认值,只在日志里留一条警告。之所以不直接失败,是因为你的目的是启动程序而不是校验路径——但这也意味着 cwd 路径写错时表面上一切正常,只是程序又找不到它的数据了。排查这类问题先检查路径拼写和反斜杠

管理员运行与窗口状态:verb= show=

只对 proc.run 有效,且只在 Windows 生效(macOS 会忽略并在日志留一条说明)。

verb效果
省略该文件类型的默认动作
open打开
runas以管理员身份运行(会弹 UAC 提示)
edit / print编辑 / 打印
explore / properties在资源管理器中浏览 / 打开属性对话框
show效果
省略 / normal正常窗口
min最小化启动,且不抢焦点
max最大化启动
hidden不显示窗口
# 以管理员身份跑一个维护脚本
coadm = $CC("[管理员运行]", proc.run("D:\\tools\\fix.exe", verb="runas"))

# 后台静默启动,不打断当前打字
cobg = $CC("[后台同步]", proc.run("D:\\tools\\sync.exe", show="hidden", cwd="D:\\tools"))

取值必须是上表里的小写词,写错(含大小写不符,如 verb="RUNAS")会直接报错并列出合法取值——这个校验在所有平台一致,所以在 macOS 上写错也会当场发现,不会等到换台 Windows 机器才炸。

`hidden` 不会让程序变成后台服务

它只是不显示窗口。程序本身如果会弹对话框或自己创建窗口,照样会出现;反过来,一个需要你操作的程序设了 hidden 就变成了看不见摸不着的进程,只能去任务管理器结束。

打开设置页:setting.open(page)

page 是目标页的规范 id,直接跳到对应标签页:

page页面
schema方案
input输入
keys按键
ui外观
dict词库
advanced高级
about关于
""(空串)默认页
cost = $CC("打开设置", setting.open(""))
codc = $CC("词库管理", setting.open("dict"))

未知 id 会被设置端忽略并落到默认页。setting.web(page) 是等价别名(旧 Web 版设置已废弃)。

附加参数:setting.open(page, args) 0.113 新增

第二个参数是原样直通给设置工具的命令行参数串,写法与设置工具的命令行参数完全一致。最常用的是直接落到某个方案的某类词库数据:

codw = $CC("五笔用户词库", setting.open("dict", "--schema=wubi86 --type=user-dict"))
cods = $CC("五笔候选调整", setting.open("dict", "--schema=wubi86 --type=shadow"))
copy = $CC("拼音词频", setting.open("dict", "--schema=pinyin --type=freq"))

输入法只负责转交,不解析这串参数——设置工具支持什么就能写什么,新版本加的参数无需等输入法跟进。参数不认识或方案不存在时,设置工具会退到最接近的位置并给出提示,不会打不开。

含空格的值要自己加引号

参数串会被重新切分成多个参数,--text=你 好 会断在空格处。含空格的值请写成 --text="你 好"

配对符号:ime.pair(left, right, jump?)

上屏 left + right、光标落在两段之间,并把这一层压入配对状态——之后按跳出键(在设置里配的 Tab / Enter)就能越过右段,和自动配对打出来的括号完全一样。

cojk = $CC("「」", ime.pair("「", "」"))
cozs = $CC("注释", ime.pair("<!--", "-->"))

两段都可以是任意文本,不限于单个符号:

输入后:  <!--|-->
按 Tab:  <!---->|

jump:跳出时光标右移的格数。 省略时按右段的字符数推导("-->" → 3),一般不用写。它存在是因为跳出靠合成方向键,而"一次右键越过多少内容"是宿主行为——多数宿主一次跨整个 emoji,少数按编码单元走。若在某个程序里发现跳出后光标位置差了几格,用它手动校准:

cozs = $CC("注释", ime.pair("<!--", "-->", jump=3))

分级跳出:同一条词条里写多个 ime.pair 即可,无需额外语法。后写的是内层,跳出时也先出内层:

cokh = $CC("(【】)", ime.pair("(", ")"), ime.pair("【", "】"))

输入后:  (【|】)
按 Tab:  (【】|)     ← 出内层
按 Tab:  (【】)|     ← 出外层

受「标点配对」总开关约束

ime.pair 跟着设置 → 标点配对的开关走(中文模式看中文配对、英文模式看英文配对)。关掉时它退化为纯上屏:整串照常上屏,但光标落在末尾、也不能跳出。

另外,「输入右符号跳出」对它不生效——那条路径只认单个标点按键。ime.pair 压入的配对只能用 Tab / Enter 跳出。

撤销上屏:ime.undo_commit()

按上屏历史删除最近一次上屏的内容——记录上屏了几个字符,就往前删几个。连续触发可逐条回退。

coun = $CC("撤销上屏", ime.undo_commit())

配合快捷键使用更顺手:把这条短语绑一个好按的编码,或用 config.set 给它挂全局热键。

行为细节:

  • 正在打字时不动作 —— 输入缓冲非空(组合区有内容)时直接忽略,不会误删
  • 无上屏历史时删除 1 个字符
  • 每撤销一次就从历史中弹出一条,推送失败会回滚该条记录

撤销不校验光标前的内容

它只按历史记录的字符数往前删,不检查光标前实际是什么。上屏后如果你在输入法之外移动过光标、或改过文本,撤销会删错位置的内容。

另外计数按 UTF-16 单位,在使用退格兜底的宿主里遇到 emoji 可能多删。

调用命令行:wind.cli(...)

命令行工具的任意子命令挂到短语上,用主程序自身执行。两种传参形式:

# 单参形式:按空白拆分
cocr = $CC("重建词库缓存", wind.cli("schema rebuild"))
codf = $CC("停用辅码库", wind.cli("schema dict disable wubi86 fl"))

# 多参形式:逐个原样传递,用于含空格的路径
cobk = $CC("备份", wind.cli("backup", "create", "D:\\我的 备份\\wind.zip"))

# 配合内部目录变量,免去硬编码路径
cobu = $CC("备份到用户目录", wind.cli("backup", "create", "${USER_DATA}\\backups\\wind.zip"))

含空格的参数(尤其是文件路径)必须用多参形式,否则会被空白拆散成多个参数。路径里的反斜杠仍按短语字符串规则写成 \\(见路径里的反斜杠要写两个)——这一层与 CLI 无关,是短语先解析、再把结果交给 CLI。

发射后不管,错误对你不可见

wind.cli 启动子进程后不回收输出与退出码。命令失败时没有任何提示——短语看起来正常执行了,实际可能什么都没做。

调试新命令时,请先在终端里手动跑一遍确认无误,再写进短语。

从短语调用时输入法服务必然在线,所以 schema / dict / phrase / backup 这些需要在线的子命令都能正常连上。

改配置优先用 config.set,不要绕 wind.cli

config.set(key, value)wind.cli("config set ...") 效果相同,但前者在进程内直接生效并能拿到错误,后者是发射后不管。改配置一律用 config.set / config.toggle

按键 combo 格式

key.* 的 combo 为 [修饰键+]...主键,大小写不敏感,+ 分隔。修饰键:CtrlShiftAltWin(各有别名如 Control / Menu / Super)。主键支持常见控制键(EnterTabEscapeHomeEndUp 等)、功能键 F1F24、字母数字键,以及标点键(CommaPeriodSlash 等)。

key.tap("Ctrl+C")                       # 复制
key.tap("Alt+F4")                       # 关闭窗口
key.seq("Home", "Shift+End", "Delete")  # 删除整行
key.type("Hello, 世界")                  # Unicode 直输

未列出的特殊键用 vk: 前缀指定 Windows 虚拟键值,0x 前缀为十六进制、无前缀为十进制,有效范围 0x010xFF

key.tap("vk:0x5D")    # 右键菜单键(VK_APPS)
key.tap("vk:0x60")    # 数字小键盘 0
key.tap("Shift+vk:0x5D")

标点键 VK 码基于美式布局

标点符号键的 VK 码按美式 US 键盘布局定义,非 US 布局下物理键位可能不同,此时改用 vk: 数值码指定精确虚拟键值。

行为细节

  • 权重:命令短语与普通短语一样默认权重 1000。命令用的精确英文编码极少与自然候选撞码,默认值通常已足够靠前;拼音方案下更应选一个不与自然词碰撞的编码,而非堆高 weight。
  • 自动上屏 / 顶码:纯文本命令(只产出文本)与短语一样可自动上屏、顶码上屏;含副作用的命令不自动上屏,始终等待手动选择,被顶屏时异步执行动作。只有短语的编码(如 date)不参与顶码,也不会被"满码空码清空"误清。
  • 不污染历史last() 只记录真正上屏的文本。有 type() 的命令进入历史;仅副作用命令(open / proc.run 等)不进入,避免显示文字污染下一次 last()
  • 副作用会求值两次$CC 的显示名和动作里的表达式都会被求值。若在两处各写一次 config.toggle 会切换两次(净效果为零)。想"切一次并显示新状态",让显示名用 config.get、动作用 config.toggle

临时拼音下不查快捷短语

进入临时拼音模式后不查询快捷短语层,输 zzbd 得到的是拼音候选而非字符组导航。但词库条目内嵌的 $ 语法在临拼下仍会正常展开与执行。

相关阅读

本页目录