落格输入法 macOS 是如何处理 ascii 0x01 的兼容问题的-macOS 输入法如何正确设置 buffer

早在去年,落格输入法的用户就有报告说落格输入法 macOS 在 有道云笔记 的 MarkDown 模式下无法正常键入中文,经过测试证明确实如此,体现为打中文字的时候,buffer的刷新会奇怪的删除掉光标前的一个字符——对,不多不少,就删一个。

捣鼓了很久未果,最后我没招了打印出了所有内容,发现了谜团:

当我把输入法获取到的光标左边的文字打印出来后,我发现文字的后边被追加了一个奇怪的字符:

奇怪的红色问号,表示这个字符无法表达。

你可能看不见,它实际上也是一个无法表达的字符,一般来说文本编辑器都用来表示一个坏掉的字符。不过,经过字符编码转换后,我还是找到了它的原本,这是一个 ASCII 字符,编码是  0x01 ……嗯,无法表达的字符——那么答案就明显了,显然是在系统在设定 buffer 的时候判断到了这个字符的数量(也就是1),但在替换的时候这个字符没了,于是把末尾的字给替换了。

于是,我就根据有道云笔记的 BundleID 进行判断,一旦找到这个字符,那说明就是在它的 MarkDown 模式里,然后在键入 buffer 之前,手动把这个字符给它补回去——好吧它至少真的管用:

不过好景不长,时隔半年,在另一个 app, Quiver 中又遇到了这个问题,这次就没那么容易解决了,同样的办法会导致无限递归……好吧,是时候使用真正的技术了。

经过询问大佬(是的是问出来的……),macOS 的  InputMethodKit 中  public func setMarkedText(_ string: Any!, selectionRange: NSRange, replacementRange: NSRange)  这个方法,虽然在 Swift 中声明的是接收  Any 类型,也就是说不论是 String 还是 NSAttributedString 均可(声明中也是如此说明),但实际上它需要的是后者,很简单,生成一个 NSAttributedString 再写入 buffer ,问题解决。

同时,细心的我还发现了一个有趣的问题,落格输入法的 buffer 下划线总是比系统的下划线要粗那么一点(这里我用 QIM 做比较):

落格输入法的 buffer 下划线很粗
QIM 的下划线就比较细,和系统的一样。

原来, IMKInputController 中是有这么一个方法的:

它可以返回一个包含富文本标签的字典,这个字典可以标记某条 buffer,从而让系统认识这个 buffer。

那么大概用法是这样:

然后把这个属性附加到设置 buffer 时生成的  NSAttributedString 即可,这才是 macOS 输入法正确设置 buffer 的姿势:

这样,输入法的 buffer 区域就和系统的一模一样了:

落格输入法 macOS 改正后的 buffer 下划线很细

发表评论

电子邮件地址不会被公开。 必填项已用*标注