macos
Sierra
karabiner-Elements
Hammerspoon

Hammerspoon と Karabiner-Elements でアプリケーションごとにキーマッピングを変更する

More than 1 year has passed since last update.

Sierra より前の OSX で動作していた Karabiner はアプリケーションごとにキーマッピングを変更できたが、Sierra で動作する Karabiner-Elements ではその機能がなくなってしまった。Hammerspoon と Karabiner-Elements を組み合わせて Sierra でもそれを実現する。

背景

Sierra より前の OSX ではキーマッピングを以下のように設定していた(US 配列のキーボードを利用)。

  • Caps lockCommand に変更: Mac のシステム環境設定で設定
  • ターミナルでは左の CommandControl に変更: ↑で設定したものを更に iTerm2 で設定
  • MacVim でも左の CommandControl に変更: Karabiner でアプリケーションごとに設定を変更して対応

しかし冒頭に書いた理由で MacVim の設定が実現できなくなり、とても困っていた。

手順

  • Karabiner-Elements に複数のプロファイルを用意
  • Hammerspoon でアプリケーションごとにプロファイルを変更

こちらの記事でキーボードごとに設定変更していたので、それをアプリケーションごとに変更できるようにした)

Karabiner-Elements に複数のプロファイルを用意

Karabiner-Elements の Profiles から作成する。今回は名前を MacVim とした。

K-1.png

作成したプロファイルを [Select] してから Simple Modifications でキーマッピングを追加する。

K-2.png

Karabiner-Elements は ~/.config/karabiner/karabiner.json に設定を保存している。profiles 以下はこのようになっているはず。

~/.config/karabiner/karabiner.json(抜粋)
{
  "profiles": [
    {
      "name": "Default",
      "selected": true,
      "simple_modifications": {}
    },
    {
      "name": "MacVim",
      "selected": false,
      "simple_modifications": {
        "caps_lock": "left_control"
      }
    }
  ]
}

Hammerspoon でアプリケーションごとにプロファイルを変更

Hammerspoon で利用中のアプリケーションを取得して、プロファイル変更スクリプトを実行する。

~/.hammerspoon/init.lua
local home = os.getenv("HOME")

local function handleGlobalEvent(name, event, app)
    if event == hs.application.watcher.activated then
        -- hs.alert.show(name)
        if name == "MacVim" then
            hs.execute(home .. '/.hammerspoon/karabiner-switcher 1')
        else
            hs.execute(home .. '/.hammerspoon/karabiner-switcher 0')
        end
    end
end

watcher = hs.application.watcher.new(handleGlobalEvent)
watcher:start()

プロファイル変更スクリプト(実行権を付与すること):

~/.hammerspoon/karabiner-switcher
#!/usr/bin/env ruby

require 'json'

select = ARGV[0].to_i

filename = "#{ENV["HOME"]}/.config/karabiner/karabiner.json"
file = File.open(filename)
data = JSON.parse(file.read)
file.close

data["profiles"][0]["selected"] = select == 0
data["profiles"][1]["selected"] = select == 1

json = JSON.generate(data)

file = File.new(filename, "w")
file.write(json)
file.close

これで通常時は profiles[0] # Default が、MacVim 利用時には profiles[1] # MacVim が有効になる。
MiscShow profile name in menu bar をONにすると動作確認ができて便利。

h1.png
h2.png

その他

僕の場合は Karabiner-Element を入れると Mac のシステム環境設定で設定した修飾キー変更が効かなくなってしまったので、Default プロファイルに caps_lockleft_command にする設定を入れた。

まとめ

最終的に以下のように設定することになった。

  • Caps lockCommand に変更: Karabiner-Elements の Default プロファイル
  • ターミナルでは左の CommandControl に変更: ↑で設定したものを更に iTerm2 で設定
  • MacVim では左の Caps lockControl に変更: Karabiner-Elements の MacVim プロファイル

参考にしたWebページ