推荐 macOS 自动化工具 Hammerspoon 配置

最近花时间重写了 awesome-hammerspoon 配置。写完个人觉得还挺满意 :no_mouth: 估计论坛里也有不少 Mac 党,就发出来给大家看看。

如果你不清楚这是啥东东,额,它利用 Hammerspoon 来实现桌面 widgets、窗口管理、应用启动、词典翻译、aria2 前端等等功能。配置的一大特色是使用了模式化按键绑定,以解决需要不停地按 cmd + opt + shift + l 这样组合键的问题。配置自带了 15 个模块,介绍在这里:The built in Spoons · ashfinal/awesome-hammerspoon Wiki · GitHub

个人觉得比较不错的:窗口管理 awesome-hammerspoon-winresize

桌面 widgets

欢迎大家使用,提意见,共同改进……神马的 :grin:

11 个赞

确实不错的一款软件 https://github.com/jixiuf/dotfiles/tree/master/mac/hammerspoon 配合https://github.com/tekezo/Karabiner-Elements https://github.com/jixiuf/dotfiles/blob/master/mac/karabiner/karabiner.json 最喜欢的功能 比如 按下空格键单按为空格 ,组合按为cmd键,等 等, mammerspoon最喜欢的功能是一键 显隐窗口 比如cmd+f 显隐safari 借楼分享一下

哈哈 貌似两者组合用的人挺多。你可以考虑把你的配置用 Spoon 格式包一下,发给官方 repo 共享出来。

我个人没在用 Karabiner。用的是类似按键序列的东东,opt + r ,然后按单键 hjklyuioq 等等。当要处理的情形多时,会比较有用。比如窗口操作:上下左右半屏,1/4 屏,窗口移动/调整,移到其它监视器等等…… 一堆。反正按完 opt + r 后都是一个按键,个人觉得挺好用的 :smile:

在 Linux 上用过 CLFSWM 以后感觉不会再爱 macOS 的图形界面了。

2 个赞

可以录个动图什么的 大家有直观了解。

https://common-lisp.net/project/clfswm/#tutorial

这里有一整页的骚操作。

虽然默认的界面朴素了点,但是可以另外支持透明窗口和阴影的。

之前因为它还不支持sierra就入了Keyboard Masetro的坑。。

Karabiner设置右Command为ESC/Hyper 谁用谁知道 (新macbook就不说了,旧款的ESC也是小的我很难按。。换了之后再也不用伸手去function-key row了)

1 个赞

@ztlevi 然后发现 Maestro 其实做不到 Karabiner 的功能?:joy:

@fuxialexander 现在基本没人按 esc 键了吧?除了偶尔手忙脚乱时按一下一锤定音。

Emacs、Vim、Sublime Text、Atom 下我都用的 jk,ctrl + ] 也算不错的选择。

上面一排 function 键除了调亮度、声音等外,真的用不着。

1 个赞

好吧…我是能用一个键就绝不用俩的懒癌…

1 个赞

jk 的好处是完全融于文字编辑的过程中,不必离开主键位去按别的键。

刚看了下你用的右 cmd 也是挺顺手的。不过我个人对 Karabiner 这种调用私有 API 的软件不太敢用,上游稍微动一下就挂了,还是不要太依赖的好。

1 个赞

这倒是😂之前就有一段时间用不了。。想炸了Apple🌚

这是入魔的先兆

正在试用 Hammerspoon 中,我一直不明白 Mac 上究竟怎么最大化一个窗口,最好还能取消最大化,类似别的桌面环境或者 Emacs 的 M-x toggle-frame-maximized。有人知道如何用 Hammerspoon 实现吗?

if 未最大化 {
  保存窗口的位置和大小
  最大化
} else {
  恢复窗口的位置和大小
}

我目前能做到最大化,不知道怎么恢复:

hs.hotkey.bind({"ctrl", "cmd"}, "up", function()
      local win = hs.window.focusedWindow()
      win:maximize()
end)

这种用alfred或者bettertouchtool其实更方便设置

awesome-hammerspoon 有一个简陋的 undo(只保存最后一个窗口最后一步操作),快捷键是 \ 。 有时候手快,把一个不规则窗体最大化了,就可以按这个键恢复过来。

这个 undo 其实可以改进:保留所有窗口最后一步操作。这样你随便切到一个窗口,都能恢复到之前的位置和大小。也就涵盖了你说的 toggle 窗口最大化。

具体操作是维护一个全局字典,用 window id 做 key,frame 数组做 value。每次 undo 的时候到字典里找 window id,找到了就调用 :setFrame 方法(恢复之前的 frame)。

最大化就不要用 :maximize 方法了,统一使用 :frame() 存储位置大小以及 :setFrame(frame)。

获取屏幕大小(以最大化) cscreen = hs.screen.mainScreen() scrframe = cscreen:fullFrame()

全局字典 history = {} 存入一组数据 history[cid] = cwinframe

遍历字典 for key, value in pairs(history) do print(key, value) end

涉及到的知识点大概就这几点。你可以自己试着实现下,晚上我把这个 undo 完善下推上去。

— 对了,这个全局字典最好限制一下最大长度,把没用的 window id 及时清掉,以防止列表无限膨胀。

刚刚又发现了 lushscsh。我感觉 Lisp Machine 要在我的电脑上重现了

1 个赞

这到是,之前看过一篇帖子说Karabiner改的是底层的,KM改键是表层的,所以速度没karabiner快

先完成个小目标,切换窗口最大化。不行明天再搞 undo 吧……

window_history = {}

function toggleWindowMaximized()
    local cscreen = hs.screen.mainScreen()
    local cres = cscreen:fullFrame() -- 获取当前屏幕大小
    local cwin = hs.window.focusedWindow()
    local cframe = cwin:frame() -- 获取焦点窗口大小
    local cid = cwin:id() -- 窗口 ID
    -- 如果面积已经占到屏幕的 95%,就认为已经最大化了。area 变量访问请参看 hs.geometry
    if cframe.area > 0.95 * cres.area then
        -- 已经最大化了。在 history 里找之前是否保存过该窗口
        if window_history[cid] then
            -- 找到了就恢复到之前的位置和大小
            cwin:setFrame(window_history[cid])
        else
            print("该窗口一启动就是全屏的")
        end
    else
        window_history[cid] = cframe -- 老窗口要保存的,以便恢复
        cwin:setFrame(cres) -- 最大化窗口
    end
end

hs.hotkey.bind({"ctrl","cmd"}, "up", toggleWindowMaximized)

Dock 栏自动隐藏之后,会在屏幕边缘(Dock 一侧)留下 4px 的空隙,窗口最大化的时候能看出来,Hammerspoon 有处理吗?