Hammerspoon 一个 Mac OS 上的自动化工具。

这篇文章介绍使用 Hammerspoon 实现移动窗口和改变窗口大小的功能。市面上有挺多同类软件,比如付费的 Sizeup、Moom,免费开源的 Spectacle,Hammerspoon。最开始我用的是 Slate,但由于在新系统有内存泄漏等性能问题,最近换上了 Hammerspoon,同时发现有比其它软件优秀的地方。

创建 Hammerspoon 配置需要一点点 Lua 语言的知识,花几分钟阅读《X分钟速成Y》,了解一点基本的语法就可以动手了,当然也可以直接在前人的基础上改。

Part 1 是希望能复现我之前使用 Slate 的一些操作,并且把 Spectacle 的部分功能抄过来。

安装

Hammerspoon 网站下载 App 或者使用 brew 安装,先不启动软件。之后新建 ~/.hammerspoon 目录,并且在 .hammerspoon 下新建 init.lua 文件。

添加初始化内容:

-- reload config
function reloadConfig(files) -- `files` available in pathwatcher
  hs.reload()
  hs.notify.new({title="Hammerspoon config reloaded", informativeText="By user operation"}):send()
end

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "R", reloadConfig)
hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start()

上面的代码主要用于检测配置文件变更并且自动更新,或者手动 Ctrl + Alt + Command + R 可以手动载入配置。现在启动 Hammerspoon.app,会自动载入这个配置。

添加下面的内容在 init.lua 之后:

hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'Left', function()
  local win = hs.window.focusedWindow()
  local f = win:frame() -- the co-ordinates of the top left corner of the window and its width and height
  local screen = win:screen()
  local max = screen:frame()

  f.x = max.w * 0
  f.y = max.h * 0
  f.w = max.w * 0.5
  f.h = max.h * 1
  win:setFrame(f, 0)
end
)

现在就可以在激活的窗口,按下 Ctrl + Alt + Command + Left 就可以让窗口靠左边收缩。

配置简单的窗口快捷键

接下来打算添加几个常用的快捷键:

  • Ctrl + Alt + Command + Left 靠左,半边窗口
  • Ctrl + Alt + Command + Right 靠右, 半边窗口
  • Ctrl + Alt + Command + Up 靠上,半边窗口
  • Ctrl + Alt + Command + Down 靠下, 半边窗口

最大化、居中

  • Ctrl + Alt + Command + M 最大化,铺满屏幕
  • Ctrl + Alt + Command + C 缩小,居中屏幕

三分之一、三分之二 (虽然看起来按键复杂,是一遍就觉得亲切了)

  • Ctrl + Command + Left 靠左,三分之一窗口
  • Ctrl + Command + Right 靠右,三分之一窗口
  • Alt + Command + Shift + left 靠左,三分之二窗口
  • Alt + Command + Shift + Right 靠右,三分之二窗口

代码实现如下:

function baseMove(x, y, w, h)
    return function()
        local win = hs.window.focusedWindow()
        local f = win:frame()
        local screen = win:screen()
        local max = screen:frame()

        -- add max.x so it stays on the same screen, works with my second screen
        f.x = max.w * x + max.x
        f.y = max.h * y
        f.w = max.w * w
        f.h = max.h * h
        win:setFrame(f, 0)
    end
end

hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'Left', baseMove(0, 0, 0.5, 1))
hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'Right', baseMove(0.5, 0, 0.5, 1))
hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'Down', baseMove(0, 0.5, 1, 0.5))
hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'Up', baseMove(0, 0, 1, 0.5))

hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'M', hs.grid.maximizeWindow)
hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, 'C', baseMove(0.25, 0.25, 0.5, 0.5))

hs.hotkey.bind({'ctrl', 'cmd'}, 'Left', baseMove(0, 0, 1/3, 1))
hs.hotkey.bind({'ctrl', 'cmd'}, 'Right', baseMove(2/3, 0, 1/3, 1))
hs.hotkey.bind({'alt', 'shift', 'cmd'}, 'Left', baseMove(0, 0, 2/3, 1))
hs.hotkey.bind({'alt', 'shift', 'cmd'}, 'Right', baseMove(1/3, 0, 2/3, 1))

保存并且重载配置后,就可以使用快捷键管理窗口啦。如果想自定义更加冷门的快捷键,可以参考官方提供的 按键映射表

最后

当然提供现成的代码,仓库地址: yantze/dotfiles/hammerspoon