mcpField
H
hammerspoon

hammerspoon

github.com/plinde生産性842 回インストール28 週間前に更新
リポジトリ

hammerspoon について

HammerspoonはLuaスクリプトとmacOSのデスクトップ操作を結ぶ自動化環境です。ウィンドウ、アプリ、ホットキー、システムイベントを自動化したいユーザー向けで、Spoonsで機能を拡張できます。

主な機能

  1. 01LuaによるmacOS自動化
  2. 02ウィンドウとアプリの管理
  3. 03キーボードショートカットの登録
  4. 04Spoonsによる機能拡張
  5. 05hs CLIからLuaを実行

活用シーン

  1. 01ウィンドウのタイル配置と移動
  2. 02アプリの起動や切り替え
  3. 03ショートカットやCLIから設定を再読み込み
  4. 04アラートとシステム通知の表示

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/plinde/claude-plugins --skill hammerspoon

インストール後、Claude Code で/hammerspoonを入力して読み込まれたか確認します。

詳細

Hammerspoon による macOS の自動化

Hammerspoon は macOS と Lua スクリプトを連携させ、強力なデスクトップ自動化を実現します。

ディレクトリ構成

~/.hammerspoon/
├── init.lua              # Main entry point (always loaded on startup)
├── Spoons/               # Plugin directory
│   └── *.spoon/          # Individual Spoon packages
│       └── init.lua      # Spoon entry point
└── .gitignore

設定の基本

init.lua - エントリーポイント

Hammerspoon は起動時に常に ~/.hammerspoon/init.lua を読み込みます。

-- Enable CLI support (required for hs command)
require("hs.ipc")

-- Load a Spoon
hs.loadSpoon("SpoonName")

-- Configure the Spoon
spoon.SpoonName:bindHotkeys({...})
Spoons の読み込み
-- Load and auto-init (default)
hs.loadSpoon("MySpoon")

-- Load without global namespace
local mySpoon = hs.loadSpoon("MySpoon", false)

読み込むと、Spoons は spoon.SpoonName からアクセスできます。

CLI の使い方(hs コマンド)

前提条件: init.lua に require("hs.ipc") を追加し、手動で一度再読み込みしてください。

# Reload configuration
hs -c 'hs.reload()'

# Show alert on screen
hs -c 'hs.alert("Hello from CLI")'

# Run any Lua code
hs -c 'print(hs.host.locale.current())'

# Get focused window info
hs -c 'print(hs.window.focusedWindow():title())'

ShiftIt によるウィンドウ管理

ShiftIt は、ウィンドウのタイル配置に使われる人気の Spoon です。

インストール
# Download from https://github.com/peterklijn/hammerspoon-shiftit
# Extract to ~/.hammerspoon/Spoons/ShiftIt.spoon/
設定
require("hs.ipc")
hs.loadSpoon("ShiftIt")

spoon.ShiftIt:bindHotkeys({
    -- Halves
    left = { { 'ctrl', 'cmd' }, 'left' },
    right = { { 'ctrl', 'cmd' }, 'right' },
    up = { { 'ctrl', 'cmd' }, 'up' },
    down = { { 'ctrl', 'cmd' }, 'down' },

    -- Quarters
    upleft = { { 'ctrl', 'cmd' }, '1' },
    upright = { { 'ctrl', 'cmd' }, '2' },
    botleft = { { 'ctrl', 'cmd' }, '3' },
    botright = { { 'ctrl', 'cmd' }, '4' },

    -- Other
    maximum = { { 'ctrl', 'cmd' }, 'm' },
    toggleFullScreen = { { 'ctrl', 'cmd' }, 'f' },
    center = { { 'ctrl', 'cmd' }, 'c' },
    nextScreen = { { 'ctrl', 'cmd' }, 'n' },
    previousScreen = { { 'ctrl', 'cmd' }, 'p' },
    resizeOut = { { 'ctrl', 'cmd' }, '=' },
    resizeIn = { { 'ctrl', 'cmd' }, '-' },
})
修飾キー
キーLua 名
Command'cmd'
Control'ctrl'
Option/Alt'alt'
Shift'shift'

ホットキーの割り当て(Spoons を使わない場合)

-- Simple hotkey
hs.hotkey.bind({'cmd', 'alt'}, 'R', function()
    hs.reload()
end)

-- Hotkey with message
hs.hotkey.bind({'cmd', 'shift'}, 'H', function()
    hs.alert.show('Hello!')
end)

よく使うモジュール

hs.window - ウィンドウ管理
-- Get focused window
local win = hs.window.focusedWindow()

-- Move/resize
win:moveToUnit('[0,0,0.5,1]')  -- Left half
win:maximize()
win:centerOnScreen()

-- Get all windows
local allWindows = hs.window.allWindows()
hs.application - アプリの制御
-- Launch or focus app
hs.application.launchOrFocus('Safari')

-- Get running app
local app = hs.application.get('Finder')
app:activate()
hs.alert - 画面上のメッセージ
hs.alert.show('Message')
hs.alert.show('Message', nil, nil, 3)  -- 3 second duration
hs.notify - システム通知
hs.notify.new({title='Title', informativeText='Body'}):send()
hs.caffeinate - スリープ/スリープ解除
-- Prevent sleep
hs.caffeinate.set('displayIdle', true)

-- Watch for sleep/wake events
hs.caffeinate.watcher.new(function(event)
    if event == hs.caffeinate.watcher.systemWillSleep then
        print('Going to sleep')
    end
end):start()

Spoons

Spoon とは?

標準的な構成を持つ、自己完結型の Lua プラグインです。

MySpoon.spoon/
└── init.lua     # Required: exports a table with methods
公式 Spoon リポジトリ
SpoonInstall - パッケージマネージャー
hs.loadSpoon("SpoonInstall")

-- Install from official repo
spoon.SpoonInstall:andUse("ReloadConfiguration", {
    start = true
})

-- Install from custom repo
spoon.SpoonInstall.repos.Custom = {
    url = "https://github.com/user/repo",
    desc = "Custom spoons",
    branch = "main",
}
spoon.SpoonInstall:andUse("CustomSpoon", { repo = "Custom" })

設定の再読み込み

手動で再読み込み
  • メニューバーのアイコンをクリック -> 「Reload Config」
  • または、ホットキーを割り当てます:
hs.hotkey.bind({'cmd', 'alt', 'ctrl'}, 'R', function()
    hs.reload()
end)
ファイル変更時の自動再読み込み
hs.loadSpoon("ReloadConfiguration")
spoon.ReloadConfiguration:start()

または手動で実行します:

local configWatcher = hs.pathwatcher.new(os.getenv('HOME') .. '/.hammerspoon/', function(files)
    for _, file in pairs(files) do
        if file:sub(-4) == '.lua' then
            hs.reload()
            return
        end
    end
end):start()
CLI での再読み込み
hs -c 'hs.reload()'

注:init.lua に require("hs.ipc") が必要です。

トラブルシューティング

IPC が動作しない
error: can't access Hammerspoon message port

解決方法: init.lua に require("hs.ipc") を追加し、メニューバーから手動で再読み込みしてください。

Spoon が読み込まれない
  1. パスを確認します:~/.hammerspoon/Spoons/Name.spoon/init.lua
  2. Spoon の init.lua の Lua 構文を確認します
  3. Hammerspoon のコンソールでエラーを確認します(メニューバー -> Console)
ホットキーが動作しない
  1. システムのショートカットと競合していないか確認します
  2. 修飾キー名が小文字の文字列であることを確認します
  3. コンソールで割り当てに関するエラーを確認します

コンソールとデバッグ

-- Print to console
print('Debug message')

-- Inspect objects
hs.inspect(someTable)

-- Open console
hs.openConsole()

コンソールを開くには:メニューバーのアイコン -> Console(または、割り当てている場合は Cmd+Alt+C)

ベストプラクティス

  1. 常に IPC を使う - CLI を使えるように require("hs.ipc") を追加します
  2. Spoons を使う - ウィンドウ管理を一から作り直さないようにします
  3. バージョン管理 - ~/.hammerspoon/ を git で管理します
  4. 変数に保持する - 変数に保存されていないオブジェクトはガベージコレクションされます
  5. コンソールを確認する - エラーが発生したときに最初に確認する場所です

参考資料

コメント