解决了我在 MacOS 下输入法和 Vim Mode 的烦恼

175 天前
 jerommix

MacOS 下切换输入法一直很恼人,特别是在 vim mode 下。

利用 Harmmerspoon 今天终于达到自己满意的效果了,实现逻辑 AppGroup1 默认开启英文输入法,AppGroup2 在 ESC 或 Ctrl [ 后切换为英文输入。参考实现如下:


local function switchToABC()
    hs.keycodes.currentSourceID("com.apple.keylayout.ABC")
end

local targetAppsGroup1 = {
    "com.runningwithcrayons.Alfred",
    "com.apple.finder",
    "org.hammerspoon.Hammerspoon",
    "com.apple.Safari",
    "com.mitchellh.ghostty",
    "com.todesktop.230313mzl4w4u92", -- Cursor
    "com.microsoft.VSCode",
    "com.apple.dt.Xcode",
    "com.apple.Terminal",
    "org.vim.MacVim",
}

local targetAppsGroup2 = { -- 在这些应用中按下 Esc 或 Ctrl+[ 时切换为 ABC
    "com.apple.Terminal",
    "com.apple.dt.Xcode",
    "com.jetbrains.intellij",
    "com.microsoft.VSCode",
    "com.mitchellh.ghostty",
    "com.todesktop.230313mzl4w4u92", -- Cursor
    "org.vim.MacVim",
}

-- 监听应用切换事件
local function handleAppSwitch(appName, eventType, app)
    if eventType == hs.application.watcher.activated then
        local bundleID = app:bundleID()
        -- 检查是否在 Group 1 中
        for _, appID in ipairs(targetAppsGroup1) do
            if bundleID == appID then
                switchToABC()
                break
            end
        end
    end
end

-- 创建应用切换监听器
local appWatcher = hs.application.watcher.new(handleAppSwitch)
appWatcher:start()

-- 监听键盘事件( Esc 和 Ctrl+[)
local eventTap = hs.eventtap.new({hs.eventtap.event.types.keyDown}, function(event)
    local keyCode = event:getKeyCode()
    local modifiers = event:getFlags()
    local isEsc = (keyCode == hs.keycodes.map.escape) -- Esc 键
    local isCtrlOpenBracket = (keyCode == hs.keycodes.map["["] and modifiers.ctrl) -- Ctrl+[

    if isEsc or isCtrlOpenBracket then
        local frontmostApp = hs.application.frontmostApplication()
        local bundleID = frontmostApp:bundleID()
        -- 检查是否在 Group 2 中
        for _, appID in ipairs(targetAppsGroup2) do
            if bundleID == appID then
                switchToABC() -- 切换输入法
                break
            end
        end
    end

    return false -- 允许事件继续传递
end)

eventTap:start() -- 启动监听

1295 次点击
所在节点    程序员
6 条回复
shinonome
175 天前
挺好的, 不过小狼毫有 vim_mode 也能满足
jerommix
175 天前
@shinonome 鼠须管用户折腾了一圈发现不太完美 😄
jqtmviyu
175 天前
我在用 rime, 但 macos 版缺少查询当前中英文状态的 api
jerommix
175 天前
@jqtmviyu 是的,所以粗暴一些,切换应用或按下 esc 时 fallback 回英文状态。
jqtmviyu
175 天前
@jerommix #4 哈哈, 刚看了眼 Karabiner 配置, 其实有相同困扰的 v2exer 不少, https://www.v2ex.com/t/565667

这个 19 年的帖子也是解决同样的问题. shift 轮换输入法, esc 切换英文.
dbing
127 天前
我的解决方案是中文只用鼠须管,英文用系统自带的 ABC ,使用是 karabiner 将 caps lock 映射成超级按键,单独按下切换式鼠须管或者 ABC ,这个按键配合其他键 用于实现其他功能

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1117345

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX