中文输入不是「能打出汉字」就算完成

中文输入不是「能打出汉字」就算完成

砚最开始就要读中文 Markdown,也要输入中文。这个需求如果等界面都搭完才补,后面会不断在坐标、删除和撤销上返工。

"能输入你好"只覆盖了很小的一部分。按词移动、选区替换、全角标点、组合字符、候选框位置,以及组字时突然切换标签,都在这条链路里。

先把三个坐标系分开

一个汉字的 UTF-8 字节数,不等于它在终端里占的格数;一个用户看见的字符,也未必只含一个 Unicode 码点。

所以砚内部的字节偏移、字素边界和显示宽度各有职责:文本修改用字节,光标移动与删除尊重字素,布局计算显示宽度。终端布局尽量和 tcell 使用相同的宽度规则,减少两边对同一字符算出不同位置。

即便如此,实际终端的设置仍然要验证。尤其是中英文混排、弯引号、省略号、破折号这些内容,不能只用 ASCII 的测试文件判断光标没问题。

终端输入法与窗口输入法是两条链路

终端版里,组字和候选界面主要由终端及系统输入法负责。砚需要把真实终端光标放到插入点,并处理最终送来的文本。

这也解释了为什么"画一个像光标的色块"不够。用户看到的插入点和系统认识的光标位置如果不同,候选框就可能跑偏。

窗口版则会接到组字过程里的事件。砚接入 MyGo 后,把预编辑和正式提交分开:组字中的文字不直接当作正式编辑记录,提交时使用 OriginIME,一次组字对应一个撤销步骤。

最初 Gio 方案讨论过临时事务模型;当前 MyGo 路径已经不同。不能把旧方案里"如何处理预编辑"的描述原封不动贴到现在的实现上。

一个不容易想到的情况:组字时换标签

假设正在 A 文件里输入拼音,文字还没提交,这时切到了 B。紧接着系统发来了输入法提交事件。

如果事件处理只读取"当前标签",这段文字就会跑到 B 里。

现在的处理是记录开始组字时的输入目标。提交仍然回到那个目标;如果原标签已关闭,显示提示,而不是悄悄写进另一个文件。

这种错误未必每天遇到,但编辑器一旦发生,用户很难相信自己刚才看见了什么。和简单的输入测试相比,它更值得成为一个固定回归用例。

输入法测试也要写清楚测到了哪一层

当前发布报告记录了模拟 MyGo 组字事件的覆盖:预编辑不正式写入、提交、取消、替换选区、一次提交一次撤销、组字中切标签。

这些验证的是应用如何处理事件。系统拼音是否在真实窗口里给出正确候选位置,微信输入法、搜狗、Rime 是否行为一致,仍然需要真实输入法来测。

alpha.1 的发布报告明确把真实键盘和系统拼音窗口体验列为未验证项。后续功能变多,也不会自动让这项变成通过。

这篇我愿意把边界写得具体一点:砚已经为中文处理建立了内核约定和模拟测试,但还不能说所有输入法、所有输入框、所有位置都已验证完成。

对我最有用的经验

中文支持应该从文本模型开始,一直延伸到系统事件和真实设备。把最后一屏截图里出现汉字当成验收,很容易漏掉最影响使用的部分。

下次再做文本输入相关的工具,我会更早准备混合文本和操作场景:行尾组字、滚动后组字、选区覆盖、连续提交再撤销。这些场景比单纯多准备几句中文,更容易找到问题。


相关推荐
Patrick_Wilson2 小时前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言
Patrick_Wilson3 小时前
从文本输出理解 Go 方法与接口
后端·go·编程语言
Patrick_Wilson8 小时前
读懂一个 Go JSON 处理函数:从输入数据追踪结构体、校验与错误返回
go·json·编程语言
Patrick_Wilson8 小时前
第一次读 Go 项目:从两个源码文件弄清 package、import 和 go.mod
后端·go·编程语言
Patrick_Wilson8 小时前
执行 go build . 后,Go 怎样找到代码并生成程序
后端·go·编程语言
Patrick_Wilson9 小时前
Go 变量不赋值时,为什么也有值
后端·go·编程语言
Patrick_Wilson9 小时前
读 Go 项目里的命令:run、build、test 分别做了什么
后端·go·编程语言
vipxieliang13 小时前
Go GC 性能优化实践:从 GOGC、GOMEMLIMIT 到分配热点定位
go
孔令飞14 小时前
很多人想学AI Infra,今天推荐一个 AI Agent / AI Infra 学习路线
云原生·go·ai编程
我不会起名字3221 天前
Redis 从 0 到 1(十七):订单 30 分钟不支付自动关闭——ZSet 延迟队列 Go 实现
redis·go·延迟队列·zset·订单