Hammerspoon と Karabiner Elements でキーカスタマイズした

新しいMacBook Proが届いたんだけど、Karabiner(旧 KeyRemapForMacBook)が動かない。そこで、Karabiner 使えない対策: Hammerspoon で macOS の修飾キーつきホットキーのキーリマップを実現する - Qiitaを参考にしながら、以前のMacBookでおこなっていた「Vim のインサートモードから抜ける時にIMEを英数に切り替える」というのをHammerspoonとKarabiner Elementsで実現した。

Karabiner Elementsで、EscをF13にリマップした後に、以下のHammerspoonのluaスクリプトを書いた。Control + Shift + ; はGoogle日本語入力で英数に切り替えるショートカット。

local function keyCode(key, modifiers)
   modifiers = modifiers or {}
   return function()
      hs.eventtap.event.newKeyEvent(modifiers, string.lower(key), true):post()
      hs.timer.usleep(1000)
      hs.eventtap.event.newKeyEvent(modifiers, string.lower(key), false):post()      
   end
end

local function keyCodeSet(keys)
   return function()
      for i, keyEvent in ipairs(keys) do
         keyEvent()
      end
   end
end

local function remapKey(modifiers, key, keyCode)
   hs.hotkey.bind(modifiers, key, keyCode, nil, keyCode)
end

remapKey({}, 'f13', keyCodeSet({
    keyCode('escape', {}),
    keyCode(';', {'ctrl', 'shift'})
}))

気持ちよく作業するために致し方ないのだけど、なんか面倒くさいね... Hammerspoon、luaスクリプトを書くことでウィンドウをリサイズしたり、メニューバーに何か出したりとか、結構色々なことが実現できるようなので、時間があったらもうちょっと遊んでみたい。

おまけで、上のスクリプトを書くために、入力しているキーを調べたくなって、以下のようなluaスクリプトも書いたので乗っけておく。モードを用意して、そのモードに切り替えると入力したキーの内容がアラートとして表示される。

local function showKeyPress(tapEvent)
    local charactor = hs.keycodes.map[tapEvent:getKeyCode()]
    hs.alert.show(charactor, 1.5)
end

local keyTap = hs.eventtap.new(
  {hs.eventtap.event.types.keyDown},
  showKeyPress
)

k = hs.hotkey.modal.new({"cmd", "shift", "ctrl"}, 'P')
function k:entered()
  hs.alert.show("Enabling Keypress Show Mode", 1.5)
  keyTap:start()
end
function k:exited()
  hs.alert.show("Disabling Keypress Show Mode", 1.5)
end
k:bind({"cmd", "shift", "ctrl"}, 'P', function()
    keyTap:stop()
    k:exit()
end)