macOS 输入法状态管理

尴尬

前言

经常在多个应用之间切换,然后手速比较快,就总会遇到类似上面这样的问题:

我输入的是python, 因为不知道当前的输入法是中文,所以出现了上面的结果,我得按4次删除键来清除错误的输入。

为了解决这个问题,试过很多办法,目前综合了各种方案,终于有了一个比较满意的方案。

这个方案主要解决的问题有:

  • 应用软件切换时提示输入法的状态

  • 手动中英文切换时提示

  • 自动根据运行软件切换输入法

基本有了以上功能,就可以无障碍的在各个应用软件之间输入文字了。为了达到上面的目的需要使用下面几个软件:

  • Karabiner

  • Hammerspoon

  • Squirrel

实现方式

输入法配置

首先输入法使用的是:Squirrel(鼠须管), 系统ABC,鼠须管关闭了英文模式,使用Karabinershift键映射为:ctrl+space

本来鼠须管也有自己的英文输入,但是别的程序无法获取它的中英文状态,所以只使用了它的中文输入。修改shift映射是因为习惯了用它来切换中英文的状态,因为系统设置里面的输入法切换的快捷键没办法改为shift

鼠须管以及Karabiner的配置可以参考了这篇) 文章

手动中英文切换时提示

因为切换时用的是快捷键,所以可以用监听键盘按键的方式来进行提示,主要的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  hs.eventtap.new({hs.eventtap.event.types.keyUp}, function(event)
-- print(event:getKeyCode())
-- print(hs.inspect.inspect(event:getFlags()))

if event:getKeyCode() == 49 and event:getFlags().ctrl then
showInputMethod(true)
end
end):start()

function showInputMethod(reverse)
-- 用于保存当前输入法
local currentSourceID = hs.keycodes.currentSourceID()
local tag
print(currentSourceID)
hs.alert.closeSpecific(showUUID)

if (currentSourceID == "com.apple.keylayout.ABC") then
if reverse then
tag = '中'
else
tag = 'A'
end
else
if reverse then
tag = 'A'
else
tag = '中'
end
end
showUUID = hs.alert.show(tag, screens)
end

应用软件切换时提示输入法的状态

主要是通过hs.application.watcher来监听应用是否激活,然后根据应用的名字来进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function updateFocusAppInputMethod(appName, eventType, appObject)
if (eventType == hs.application.watcher.activated) then
local default = true
for index, app in pairs(key2App) do
if app[1] == appObject:path() then
default = false
if app[2] == 'Chinese' then
Chinese()
else
English()
end
end
end
if default then
English()
end
end
showInputMethod()
end

appWatcher = hs.application.watcher.new(updateFocusAppInputMethod)
appWatcher:start()

自动根据运行软件切换输入法

第二步中一起做了

效果展示

效果

完整的代码在github, 参考了这个Karabiner配置。

问题

  • 在iTerm中切换输入法有时候不会触发keyUp的消息,就没有状态提示了,重起后正常
坚持原创技术分享,您的支持将鼓励我继续创作!