关于业火输入法临时英文模式的思考、设计和实现

关于业火输入法临时英文模式的由来、思考、设计、开发和总结。

临时半角符号

我刚开始只是经常输错半角和全角符号,所以我刚开始的想法是需要一种能在中文输入模式下也能快速输入半角符号的方案。

所以我的初始方案是在中文输入模式下,当输入分号时,并不直接输入全角的分号,而是进入拼词模式,唤出候选窗。然后在拼词模式下输入对应的符号,就自动把半角符号输入输入框中,并退出拼词模式。比如输入 “;, = 半角,”、 “ ;.=.”,如下图。那么如何输入全角的分号呢?我也考虑到了,在拼词模式下,再输入分号,就输出全角分号。其实写到这里,已经能感觉不太对了,主要是一致性的问题,分号+其它的符号输出半角符号,但是分号 + 分号竟然是全角符号,这里的两个输入逻辑是一致的,但是两种输出不一致。然而当时我并没有意识到这个问题,直到按我上面的思路去着手实现的时候才反应过来。

临时半角符号

为什么使用分号作为触发按键

解释一下为什么使用分号键来承载触发词。从萌芽这个想法开始,我的第一反应就是应该用分号键来承载,然后我意识到我实际上是受了清歌输入法的影响,因为用过,所以隐约记得清歌输入法是用分号键承载了什么能力,所以我才会有那样的第一反应。然后反应过来后再回看,发现这个分号按键真的很妙,因为和它对称的shift键大多数用来切换中英文,而分号键用来临时切回半角符号,有一种对称的美感。

临时英文模式

然后再回到上面在着手实现时发现了不一致的问题,因为有珠玉在前,所以我转头去看了一下清歌输入法,清歌输入法是用分号键作为临时英文触发按键,按下分号键,再按下字母和符号键(一个或多个),再敲空格键,即可输出英文字母和半角符号。

受到清歌输入法的启发,我开始思考我是否需要临时英文输入?考虑之下,我发现其实是有的,比如说“关于 IMKInputCotroller 的碎碎念”这句话,其中有中文有英文,经常会在输入英文时忘记当前是中文输入模式,或者输入完英文后忘记切换输入模式去输入中文。除了中英文的输入外,还有全角半角符号的转换也经常会输错。当这种事频繁发生并打断我的思路的时候,我意识到我确实需要临时英文来提高输入效率。

业火的临时英文模式与清歌有所不同—中文输入模式下,按下分号键,进入临时英文模式,唤起候选框,半角分号作为第一个原码,之后按下多个英文字母或标点符号,把分号之后的所有的英文字母和标点符号按输入顺序作为第一个候选词,按空格,输出第一个候选词。具体的用流程图表示如下,基本上是把清歌的回车换成了空格:

业火输入法临时英文输入

可以看出,虽然仍然会有分号后+其它符号或分号表现最终输出不一致的问题,但是除了这一点这外,还有一个空格确认的区别,所以最终反而不会有太多的不协调了。

具体实现

关于具体的实现,只要理清了逻辑,其实没什么难点,只是有几个点需要注意一下。

  1. 按下分号键时,要有临时英文的提示和一些操作提示
  2. 当“五笔的四码唯一自动上屏”开启时,会和临时英文的唯一候选词冲突

处理提示的显示问题

最初候选词 Candidate 的结构为:

1
2
3
4
5
struct Candidate: Hashable {
let code: String
let text: String
let type: CandidateType
}

候选词的显示和候选词的实际内容是一致的,取的是 text 字段。如果这次也这样处理,那最终在英文输入时候选窗是类似这样的。

候选窗样式

可以看到太多重复的内容了,一边是重复的内容,一边是要显示提示,最终的答案也就呼之欲出了——把候选词的显示和实际内容分开,最终调整 Candidate 的结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Candidate: Hashable {
let code: String
let text: String
let type: CandidateType
let label: String

init(code: String, text: String, type: CandidateType, label: String? = nil) {
self.code = code
self.text = text
self.type = type
self.label = label ?? text
}

}

候选窗中实际显示 label 字段,输出时使用 text 字段,这样即可解决第一个问题。最终显示效果如下:

临时英文的提示

处理自动上屏和临时英文的冲突

这里目前的实现是扩展了一个 CandidateType 的枚举,原来的 Candidate 的枚举定义如下:

1
2
3
4
5
6
enum CandidateType: String {
case wb // 五笔
case py // 拼音
case user // 用户词库
case tip // 显示提示
}

然后在自动上屏的逻辑中判断过滤了一下这个 CandidateType

但是目前来看,感觉或许扩展一个 Candidate 结构字段 canAutoCompose 字段更合适一些。

关于临时英文的适用场景

这里主要解释一下,为什么拼音输入法没有临时英文模式。因为拼音输入法下,用户需要手动去选(输入1,2,3…或空格键),才会把字或词输出出来,在这种情况下,如果不选词,直接按回车键,一般都是输出原码,也就是英文,所以拼音输入法用回车键就天生自带临时英文模式。

同样的道理,如果五笔输入法,不开启四码唯一上屏选项,那就和拼音输入是一样的,也不需要临时英文模式,但是临时半角仍然是需要的。