AgentSkillsCN

hammerspoon-api

Hammerspoon macOS 自动化 API 参考。适用于为 Hammerspoon 编写 Lua 脚本、查找 hs.* 模块,或通过键盘快捷键、窗口管理,或系统事件实现 macOS 自动化时使用。

SKILL.md
--- frontmatter
name: hammerspoon-api
description: "Hammerspoon macOS automation API reference. Use when writing Lua scripts for Hammerspoon, looking up hs.* modules, or automating macOS with keyboard shortcuts, window management, or system events."

Hammerspoon API Overview

Hammerspoon bridges macOS system APIs into Lua for desktop automation.

Configuration

  • Config file: ~/.hammerspoon/init.lua
  • Reload config: hs.reload() or menu bar → Reload Config
  • Console: menu bar → Console (for testing)

Core Patterns

Hotkey Binding

lua
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "W", function()
  hs.alert.show("Hello!")
end)

Variable Lifecycle

Objects must be stored in global variables to avoid garbage collection:

lua
-- WRONG: will be garbage collected
hs.pathwatcher.new(...):start()

-- CORRECT: survives until reload
myWatcher = hs.pathwatcher.new(...):start()

Colon Syntax

Use : for method calls (passes self), . for static functions:

lua
local win = hs.window.focusedWindow()  -- static function
local f = win:frame()                   -- method call

Key Modules

Window Management

ModulePurpose
hs.windowGet/manipulate windows
hs.window.filterFilter/watch windows by criteria
hs.screenScreen info and geometry
hs.layoutMulti-window layouts
hs.gridGrid-based window positioning
lua
-- Move window to left half
local win = hs.window.focusedWindow()
local screen = win:screen():frame()
win:setFrame({x=screen.x, y=screen.y, w=screen.w/2, h=screen.h})

Input Events

ModulePurpose
hs.hotkeyGlobal keyboard shortcuts
hs.hotkey.modalModal shortcut environments
hs.eventtapLow-level input events
hs.mouseMouse position/control
hs.keycodesKey string/code conversion

System Control

ModulePurpose
hs.caffeinatePrevent sleep, lock screen
hs.audiodeviceVolume, input/output devices
hs.brightnessDisplay brightness
hs.batteryPower/battery info
hs.spacesmacOS Spaces control

Applications

ModulePurpose
hs.applicationLaunch, focus, control apps
hs.application.watcherApp launch/quit events
hs.appfinderFind apps/windows by name
lua
-- React to app activation
appWatcher = hs.application.watcher.new(function(name, event, app)
  if event == hs.application.watcher.activated and name == "Finder" then
    app:selectMenuItem({"Window", "Bring All to Front"})
  end
end):start()

Watchers (Event Handlers)

ModulePurpose
hs.pathwatcherFile/directory changes
hs.wifi.watcherWiFi network changes
hs.usb.watcherUSB device connect/disconnect
hs.caffeinate.watcherSleep/wake events
hs.screen.watcherDisplay changes
hs.battery.watcherPower state changes

UI Elements

ModulePurpose
hs.alertOn-screen text alerts
hs.notifymacOS notifications
hs.menubarMenu bar icons
hs.chooserSpotlight-like picker
hs.dialogDialog boxes, file pickers
hs.canvasDraw on screen

Data & Network

ModulePurpose
hs.httpHTTP requests
hs.jsonJSON encode/decode
hs.pasteboardClipboard access
hs.settingsPersist Lua values
hs.socketTCP/UDP sockets
hs.websocketWebSocket client

Scripting

ModulePurpose
hs.applescriptRun AppleScript
hs.osascriptAppleScript/JavaScript
hs.taskRun shell commands
hs.urleventHandle hammerspoon:// URLs

Spoons (Plugins)

Spoons are pre-made plugins installed to ~/.hammerspoon/Spoons/.

lua
-- Load and use a Spoon
hs.loadSpoon("ReloadConfiguration")
spoon.ReloadConfiguration:start()

-- Access Spoon methods
hs.loadSpoon("AClock")
spoon.AClock:toggleShow()

Browse available Spoons: https://www.hammerspoon.org/Spoons/

Common Recipes

Auto-reload Config

lua
configWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", function(files)
  for _, file in pairs(files) do
    if file:sub(-4) == ".lua" then hs.reload() end
  end
end):start()

Window Layout

lua
hs.layout.apply({
  {"Safari", nil, "Built-in Display", hs.layout.left50, nil, nil},
  {"Mail", nil, "Built-in Display", hs.layout.right50, nil, nil},
})

Menu Bar Item

lua
menuItem = hs.menubar.new()
menuItem:setTitle("🔴")
menuItem:setClickCallback(function() hs.alert.show("Clicked!") end)

Defeat Paste Blocking

lua
hs.hotkey.bind({"cmd", "alt"}, "V", function()
  hs.eventtap.keyStrokes(hs.pasteboard.getContents())
end)

API Documentation

Full API docs: https://www.hammerspoon.org/docs/

Look up specific modules by reading:

  • https://www.hammerspoon.org/docs/hs.<module>.html

Example: For hs.windowhttps://www.hammerspoon.org/docs/hs.window.html