在 macOS 中利用 Hammerspoon 自动切换输入法。
因为 Rime 目前的中英切换不是特别好用:
- 不能 Shift 全局切换中英:是否有可能将中英文输入状态作全局管理? #145
- Rime 的自动切换仍然会记住上一次的状态:请问如何设置打开某app始终切换到英文模式? #164
- 菜单栏不能显示中英状态
Rime 全局状态功能的进展:global input session, state shared by all client apps #294
我希望的是:无论当前是什么输入法,切换到 iTerm,就是英文,离开 iTerm,回到我原先的输入法。
类似于 Alfred 目前的功能(高级设置中的 Force Keyboard 设置为 ABC)。
我在 Typora 写中文,呼出 Alfred,变成英文输入法,用完了回到 Typora,变回中文输入法。
代码参考于:ibreathebsb/hammerspoon自动切换输入法.lua
使用方法:放到 ~/.hammerspoon/init.lua
重新部署就可以了。
可以用 Cmd + Ctrl + .
来查看当前窗口的 name 或 path;
可以在 Hammerspoon 的控制台输入 hs.keycodes.currentSourceID()
来查看当前输入法的 ID。
做的修改:
- 以 App name 作为参数,看起来舒服点
- 退出指定的程序后,恢复到原先的输入法
-- 当选中某窗口按下 ctrl+command+. 时会显示应用的路径、名字等信息
hs.hotkey.bind({'ctrl', 'cmd'}, ".", function()
hs.pasteboard.setContents(hs.window.focusedWindow():application():path())
hs.alert.show("App path: " .. hs.window.focusedWindow():application():path() .. "\n" .. "App name: " ..
hs.window.focusedWindow():application():name() .. "\n" .. "IM source id: " ..
hs.keycodes.currentSourceID(), hs.alert.defaultStyle, hs.screen.mainScreen(), 3)
end)
-- 这里指定中文和英文输入法的 ID
local function Chinese()
hs.keycodes.currentSourceID("im.rime.inputmethod.Squirrel.Rime")
end
local function English()
hs.keycodes.currentSourceID("com.apple.keylayout.ABC")
end
-- 指定程序
local appInputMethod = {
iTerm2 = English,
['EuDic LightPeek'] = English,
Bitwarden = English,
SnippetsLab = English,
['微信'] = Chinese,
}
-- activated 时切换到指定的输入法,deactivated 时恢复之前的状态
currentID = ""
function applicationWatcher(appName, eventType, appObject)
if (eventType == hs.application.watcher.activated) then
for app, fn in pairs(appInputMethod) do
if app == appName then
currentID = hs.keycodes.currentSourceID()
fn()
end
end
end
if eventType == hs.application.watcher.deactivated then
for app, fn in pairs(appInputMethod) do
if app == appName then
hs.keycodes.currentSourceID(currentID)
currentID = hs.keycodes.currentSourceID()
end
end
end
end
appWatcher = hs.application.watcher.new(applicationWatcher):start()
-- 输入法切换提示
-- hs.keycodes.inputSourceChanged(function()
-- if hs.keycodes.currentMethod() == nil then
-- hs.alert.show("ABC", hs.alert.defaultStyle, hs.screen.mainScreen(), 2)
-- else
-- hs.alert.show("拼音", hs.alert.defaultStyle, hs.screen.mainScreen(), 2)
-- end
-- end)
小问题:
无法识别 Alfred 的窗口,不过 Alfred 自带这个功能,和本配置功能一样。
本来想弄个提示的,但是每次切换时都会产生意料之外的多次切换,比如「ABC → ABC → ABC」或「ABC → 拼音 → ABC」,不知为何中间发生了多次切换,这导致菜单栏的输入法图标发生了一阵短暂而急促的抖动,不过好在结果都是正确的。
我看 Alfred 自己的功能也有这个问题,不知道有没有可能是 macOS 的 Bug。
最后只好注释掉 hs.alert.show
的提示了。