mcpField
H
hammerspoon

hammerspoon

github.com/plinde生产力842 次安装28 周前更新
代码仓库

关于 hammerspoon

Hammerspoon 将 Lua 脚本与 macOS 桌面控制结合,适合希望自动化窗口、应用、快捷键和系统事件的用户。它支持以 Spoons 插件扩展功能。

主要功能

  1. 01使用 Lua 自动化 macOS
  2. 02管理窗口与应用
  3. 03绑定键盘快捷键
  4. 04通过 Spoons 扩展功能
  5. 05使用 hs 命令行执行 Lua

适用场景

  1. 01平铺和调整窗口位置
  2. 02启动或切换到应用
  3. 03通过快捷键或命令行重载配置
  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)

加载后,可以通过 spoon.SpoonName 访问 Spoons。

CLI 用法(hs 命令)

前置条件: 将 require("hs.ipc") 添加到 init.lua,然后手动重新加载一次。

# 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

修复方法: 将 require("hs.ipc") 添加到 init.lua,然后通过菜单栏手动重新加载。

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 - 添加 require("hs.ipc") 以支持 CLI
  2. 使用 Spoons - 不要重复实现窗口管理功能
  3. 使用版本控制 - 使用 git 跟踪 ~/.hammerspoon/
  4. 保存对象到变量 - 未存储在变量中的对象会被垃圾回收
  5. 检查控制台 - 出现错误时首先查看这里

参考资料

评论

支持 Markdown