Hammerspoonで英かな切り替えやEmacsキーバインドの設定


USキーボードを使っているのでKarabiner-Elementsで左右コマンドキーで英語と日本語入力の切り替えをやっていたんですが、M1ではKarabinerが動作しないっぽいのでググったところHammerspoonで代用できそうなことがわかった

https://www.hammerspoon.org/

導入

インストール

$ brew install hammerspoon --cask

luaを利用するので入ってなければインストールする

$ brew install lua

設定ファイル作成

$ touch ~/.hammerspoon/init.lua

この設定ファイル内に好みのキーバインドの設定を書いてメニューの Reload Config をクリックすると有効化される

左右コマンドキーで英語、日本語入力を切り替える(入力ソースはどちらもGoogle)

~/.hammerspoon/init.lua
local simpleCmd = false
local map = hs.keycodes.map
local function eikanaEvent(event)
  local c = event:getKeyCode()
  local f = event:getFlags()
  if event:getType() == hs.eventtap.event.types.keyDown then
    if f['cmd'] then
      simpleCmd = true
    end
  elseif event:getType() == hs.eventtap.event.types.flagsChanged then
    if not f['cmd'] then
      if simpleCmd == false then
        if c == map['cmd'] then
          hs.keycodes.setMethod('Alphanumeric (Google)')
        elseif c == map['rightcmd'] then
          hs.keycodes.setMethod('Hiragana (Google)')
        end
      end
      simpleCmd = false
    end
  end
end

eikana = hs.eventtap.new({hs.eventtap.event.types.keyDown, hs.eventtap.event.types.flagsChanged}, eikanaEvent)
eikana:start()

参考

https://zenn.dev/hiracky16/articles/mac_m1_input_method
https://mac-ra.com/hammerspoon-command-eikana02/

ここで一つハマってしまったのが最初日本語はGoogleで英語はデフォルトで入っているU.S.で切り替えをしようとしていて

~/.hammerspoon/init.lua
if c == map['cmd'] then
  -- setLayoutに変える必要がある
  hs.keycodes.setLayout("U.S.")
    elseif c == map['rightcmd'] then
  hs.keycodes.setMethod('Hiragana (Google)')

と設定していてコマンドキーの押下でメニューバー上では切り替えができていたがなぜか日本語入力の方はできず、入力するフォームなどを移動するタイミングで切り替えの有効化がされていたようでハマってしまった。
理由はよくわからないが別にU.S.にしている理由もなかったのでGoogleの英数に変更すると問題なく動作した。

これで最初の目的はできたけど、Google検索で検索候補や履歴が ctrl + N, P で移動できず矢印キーを押さないといけないのは地味に煩わしかったのでついでに設定した

Emacs風キーバインドの設定

~/.hammerspoon/init.lua
fbpn = hs.eventtap.new({hs.eventtap.event.types.keyDown}, function(e)
    if e:getFlags().ctrl then
    if e:getKeyCode() == 35 then
      hs.eventtap.event.newKeyEvent({}, 'up', true):post(); return true;
    elseif e:getKeyCode() == 11 then
      hs.eventtap.event.newKeyEvent({}, 'left', true):post(); return true;
    elseif e:getKeyCode() == 45 then
      hs.eventtap.event.newKeyEvent({}, 'down', true):post(); return true;
    elseif e:getKeyCode() == 3 then
      hs.eventtap.event.newKeyEvent({}, 'right', true):post(); return true;
    end
  end

  return false
end)
fbpn:start()

上記を追記してリロードするとどこでも ctrl + F, B, P, N でカーソルが上下左右移動できるできるようになりました!HHKB使いなのでめっちゃ快適になった!

参考

https://kumamotone.hatenadiary.jp/entry/2018/02/25/225939