中文输入不是「能打出汉字」就算完成
砚最开始就要读中文 Markdown,也要输入中文。这个需求如果等界面都搭完才补,后面会不断在坐标、删除和撤销上返工。
"能输入你好"只覆盖了很小的一部分。按词移动、选区替换、全角标点、组合字符、候选框位置,以及组字时突然切换标签,都在这条链路里。
先把三个坐标系分开
一个汉字的 UTF-8 字节数,不等于它在终端里占的格数;一个用户看见的字符,也未必只含一个 Unicode 码点。
所以砚内部的字节偏移、字素边界和显示宽度各有职责:文本修改用字节,光标移动与删除尊重字素,布局计算显示宽度。终端布局尽量和 tcell 使用相同的宽度规则,减少两边对同一字符算出不同位置。
即便如此,实际终端的设置仍然要验证。尤其是中英文混排、弯引号、省略号、破折号这些内容,不能只用 ASCII 的测试文件判断光标没问题。
终端输入法与窗口输入法是两条链路
终端版里,组字和候选界面主要由终端及系统输入法负责。砚需要把真实终端光标放到插入点,并处理最终送来的文本。
这也解释了为什么"画一个像光标的色块"不够。用户看到的插入点和系统认识的光标位置如果不同,候选框就可能跑偏。
窗口版则会接到组字过程里的事件。砚接入 MyGo 后,把预编辑和正式提交分开:组字中的文字不直接当作正式编辑记录,提交时使用 OriginIME,一次组字对应一个撤销步骤。
最初 Gio 方案讨论过临时事务模型;当前 MyGo 路径已经不同。不能把旧方案里"如何处理预编辑"的描述原封不动贴到现在的实现上。
一个不容易想到的情况:组字时换标签
假设正在 A 文件里输入拼音,文字还没提交,这时切到了 B。紧接着系统发来了输入法提交事件。
如果事件处理只读取"当前标签",这段文字就会跑到 B 里。
现在的处理是记录开始组字时的输入目标。提交仍然回到那个目标;如果原标签已关闭,显示提示,而不是悄悄写进另一个文件。
这种错误未必每天遇到,但编辑器一旦发生,用户很难相信自己刚才看见了什么。和简单的输入测试相比,它更值得成为一个固定回归用例。
输入法测试也要写清楚测到了哪一层
当前发布报告记录了模拟 MyGo 组字事件的覆盖:预编辑不正式写入、提交、取消、替换选区、一次提交一次撤销、组字中切标签。
这些验证的是应用如何处理事件。系统拼音是否在真实窗口里给出正确候选位置,微信输入法、搜狗、Rime 是否行为一致,仍然需要真实输入法来测。
alpha.1 的发布报告明确把真实键盘和系统拼音窗口体验列为未验证项。后续功能变多,也不会自动让这项变成通过。
这篇我愿意把边界写得具体一点:砚已经为中文处理建立了内核约定和模拟测试,但还不能说所有输入法、所有输入框、所有位置都已验证完成。
对我最有用的经验
中文支持应该从文本模型开始,一直延伸到系统事件和真实设备。把最后一屏截图里出现汉字当成验收,很容易漏掉最影响使用的部分。
下次再做文本输入相关的工具,我会更早准备混合文本和操作场景:行尾组字、滚动后组字、选区覆盖、连续提交再撤销。这些场景比单纯多准备几句中文,更容易找到问题。