上周在折腾 Hammerspoon 时回看以前写的脚本,在一个关于输入法的模块中发现一段代码,看起来是用于提示当前输入法。一顿操作之后(直接拷贝),发现有一个非常大的 BUG,这很正常,但问题在于我对这个(BUG)一点印象都没,这就不科学了。

在正文之前

说实话自用 macOS 以来,就如何在输入时知道当前输入法状态问题尝试过无数的方案,至今也没有找到完美的解决方法,以至于我一度放弃。不过好在终于有了这个可以说是接近完美的方法,而且还是用 Hammerspoon 实现,不用再另外安装第三方软件,如 isHuD 或 ShowyEdge。

下面是之前写的代码:

hs.keycodes.inputSourceChanged(function()

    if hs.keycodes.currentMethod() == nil then
        hs.alert.show("ABC")
    else
        hs.alert.show("拼音")
    end

end)

功能没什么问题,inputSourceChanged 可以检测到输入源的每次改变,包括手动切换和切换窗口时,甚至在 Excel 中双击时,都会提示。虽然频繁,但也还能(并不能)接受,不过就前文所说有个 BUG,即每次提示都会显示两遍,当你操作很快时,屏幕中间就会出现一片提示。

下面就来修复这个问题,不过在正文开始之前,先对代码做点小修改,一是为了能重复利用,二是增强扩展性:

hs.keycodes.inputSourceChanged(function()

    -- 用于保存当前输入法
    local currentSourceID = hs.keycodes.currentSourceID()

    -- 这里以系统自带的 ABC 和简体双拼为例
    if (currentSourceID == "com.apple.keylayout.ABC") then
        hs.alert.show("ABC")
    elseif (currentSourceID == "com.apple.inputmethod.SCIM.Shuangpin") then
        hs.alert.show("双拼")
    end

end)

功能和开始的基本相同,不过修改后的代码,可以用于两个输入源以上的提示,增加的变量也便于后面的修改。

另外,如果想查看当前输入法的 ID,在 Hammerspoon 中的 Console 输入 hs.keycodes.currentSourceID() 即可。

正文开始

早先的方法有两个缺点:

  1. 提示重复显示两次;
  2. 提示太过频繁;

首先解决第二个问题,而且可以顺便也把第二个问题也一起解决了,在源代码不变的情况下,再增加四行代码即可:

hs.keycodes.inputSourceChanged(function()

   -- 用于保存当前输入法
    local currentSourceID = hs.keycodes.currentSourceID()

    -- 如果当前输入法和上一个输入法相同,则直接返回
    if currentSourceID == lastSourceID then 
        return
    end

    -- 这里以系统自带的 ABC 和简体双拼为例
    if (currentSourceID == "com.apple.keylayout.ABC") then
        hs.alert.show("ABC")
    elseif (currentSourceID == "com.apple.inputmethod.SCIM.Shuangpin") then
        hs.alert.show("双拼")
    end

    -- 保存最后一个输入法源名称
    lastSourceID = currentSourceID
end)

这样一来就解决了重复提示和提示频繁的问题,但会有另一个问题存在,当在不同应用切换时如果两边的输入源是相同的,一样也不会提示。

方法二

第二个方法是借用 Hammerspoon 中的另一个 API closeSpecific

hs.keycodes.inputSourceChanged(function()
    
    local currentSourceID = hs.keycodes.currentSourceID()

    -- 关闭重复提示
    hs.alert.closeSpecific(showUUID)

    -- 提示当前输入法,注意这里增加了变量
    if (currentSourceID == "com.apple.keylayout.ABC") then
        showUUID = hs.alert.show("ABC", 0.8)
    elseif (currentSourceID == "com.apple.inputmethod.SCIM.Shuangpin") then
        showUUID = hs.alert.show("双拼", 0.8)
    end

end)

这个方法可以解决重复提醒两次的问题,而且只要是输入源有变动,便会显示提示。

注:如果频繁使用 Workflowy 或 Excel 之类应用,最好不要考虑使用这个方法。

最后

两个方法各有优缺点,如何取舍就看使用习惯了。

最后的最后:本文代码主要参考了附录中的链接,感谢原作者。

附录

版本

  • macOS:macOS Catalina 10.15.1
  • Hammerspoon:Version 0.9.76 (5104)
  • 输入法
    • ABC
    • 简体双拼

参考