frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Open in hackernews

Hammerspoon

https://github.com/Hammerspoon/hammerspoon
79•tosh•2h ago

Comments

golem14•2h ago
Has anyone worked on making a config replicating aerospace?

Hammerspoon seems like a superset and it’s probably better to just have one, instead of two tools warring about who gets the keypresses?

hirvi74•51m ago
What features are you trying to replicate from Aerospace?
golem14•35m ago
Well, a tiling window and workspace manager. But as I am typing this, I’m realizing they hammerspoon can probably do some of the window placement, but maybe not handling workspaces and global state.

I was hoping I could be lazy and ask, and a not-lazy person could give a ready made answer :)

pjm331•1h ago
here is my entire config

    hs.hotkey.bind({"ctrl"}, "D", function()
      hs.grid.show()
    end)
i've tried all of the other fancy window managers and for me nothing has ever beat the ease of use of just

(1) ctrl-d to see the grid, (2) type the letter where you want the top left corner of your window to be, (3) type the letter where you want the bottom right corner to be

window resized

stackghost•1h ago
Not that I insert EOFs very often, but does that conflict with CTRL+D in the terminal?
xyzzy_plugh•1h ago
I use EOF all the time to end terminal sessions.
commandertso•37m ago
Great handle, btw.
pjm331•48m ago
yeah the CTRL+D definitely gives me problems from time to time but thus far i have been too lazy to fix it
elAhmo•1h ago
This is amazing! I have a slightly more elaborate setup that allows me to resize from one or another side, similar to what Apple added recently but with more flexibility, but this is super interesting, thanks for sharing!
hrmtst93837•29m ago
Neat until you need to sync configs or keep multiple machines in harmony, at which point dotfile headaches stack up with Hammerspoon and Lua. Adding complex logic like window rules, app-specific behavior, or handling monitor changes strips away some of that hotkey simplicity and leads to endless tweaking. Still, for avoiding the mouse, it's one of the few flexible options left on macOS that doesn't feel ancient. Tradeoffs everywhere but nowhere else really compares in control.
john-tells-all•1h ago
I'd love to have a global "toggle Teams mute" button.
hirvi74•48m ago
What do you mean? Like muting the entire application so no sound comes from Teams or muting yourself while on a call? For the latter, I thought 'Option + Space' worked (or used to)?
roxolotl•29m ago
```

hs.loadSpoon("MicMute")

binding = { toggle = { {"ctrl", "alt"}, "m" } }

spoon.MicMute:bindHotkeys(binding)

```

You'll have to add the MicMute spoon which just mean downloading the zip here, unzipping, and opening the .spoon. https://www.hammerspoon.org/Spoons/MicMute.html

jjmiv•1h ago
is there a particular reason this was shared?

otherwise I'm slowly working on a Spoon that figures out if there is an active meeting in Zoom, Teams, Huddle, Google Meet and will allow for muting, video enable/disable and screen sharing etc

rolymath•1h ago
Is paperwm jittery for everyone?
trjordan•1h ago
I utterly love Hammerspoon.

It's fun to combine with qmk [0], which gives you a bunch more options for hotkeys on your keyboard via layers. I've ended up with a layer where half the keyboard is Hammerspoon shortcuts directly to apps (e.g. go to Slack, to Chrome, etc.) and half of it is in-app shortcuts (like putting cmd-number on the home row, for directly addressing chrome tabs).

Between this and one of the tiling window manager-adjacent tools (I use Sizeup), I can do all my OS-level navigation directly. "Oh I want to go to Slack and go to this DM" is a few keystrokes away, and not dependent on what else I was doing.

[0] https://qmk.fm/

incanus77•1h ago
Hammerspoon is the glue that holds my Mac together. For a starter list of things to do with this app, a partial list of the things that I'm using it for:

  - Dumping all open Safari tabs to an Obsidian doc
  - Adding 'hyper' (Ctrl-Opt-Cmd) keybinds to pop a new window for:
    - Safari
    - Finder
    - Terminal / Ghostty
    - VS Code
    - Notes
    - Editing Hammerspoon/AeroSpace/Sketchybar config
    - Reloading Hammerspoon config
    - Reloading Sketchybar
    - Quitting all Dock apps except Finder
    - Screen lock
    - System sleep
    - Opening front Finder folder in VS Code
    - Opening front Safari URL on Archive.today
    - Showing front Safari window tab count
    - Showing front app bundle ID
    - Posting notification about current Music track
    - Controlling my Logi Litra light (various color temps/brightnesses)
    - Starting/stopping a client work timer
  - Tying it to AeroSpace for:
    - Pushing a window to another monitor
    - Performing a two-up window layout
    - Swapping those two windows
    - Closing all other workspace windows
    - Gathering all windows to first workspace
  - Ensuring some background apps stay running if they crash
  - Prompting to unmount disk images if trashed
  - Binding into Skim to jump to specific sections of spec PDFs using terse Markdown URLs
mwagstaff•59m ago
Can't live without Hammerspoon on Mac.

Can't live without AutoHotkey on Windows.

Thanks to everyone who contributed to both!

hirvi74•56m ago
I have fond memories of this app. However, after many years, I have moved on. I am in the process of writing my own replacement for some of the various use cases that Hammerspoon once provided me. Though, Hammerspoon will always be a source of great inspiration.
weitzj•54m ago
I love hammerspoon. That's it :D

It's lua, so you can get creative with https://fennel-lang.org/

hmokiguess•49m ago
what's your favourite spoon?
zdw•48m ago
I fake a tiling window manager on Mac with Hammerspoon, resizing to fit in specific corners/sizes:

     -- resize based on ratios
    function ratioResize(xr, yr, wr, hr)
      return function ()
        local win = hs.window.focusedWindow()
        win:moveToUnit({x=xr,y=yr,w=wr,h=hr})
      end
    end

    -- 4 corners, different sizes
    hs.hotkey.bind({"cmd", "ctrl"}, "w", ratioResize(0,     0, 2/5, 2/3))
    hs.hotkey.bind({"cmd", "ctrl"}, "e", ratioResize(2/5,   0, 3/5, 2/3))
    hs.hotkey.bind({"cmd", "ctrl"}, "s", ratioResize(0,   2/3, 2/5, 1/3))
    hs.hotkey.bind({"cmd", "ctrl"}, "d", ratioResize(2/5, 2/3, 3/5, 1/3))
And to throw windows to other monitors:

    -- send to next screen
    hs.hotkey.bind({"cmd", "ctrl"}, ";", function()
      local win = hs.window.focusedWindow()
      local screen = win:screen()
      local next_screen = screen:next()

      win:moveToScreen(next_screen)
    end)
comboy•19m ago
I highly recommend Aerospace[1], went through a few approaches, I cared about not completely compromising security either, it works really well if you come from something like i3

1. https://github.com/nikitabobko/AeroSpace

jmcguckin•46m ago
I use it to give me focus-follows-mouse and to have a large circle surrounding the mouse when i move it, to aid finding it.
juancn•41m ago
I use it to hide Zoom's screen sharing controls so they don't come back when pressing Esc:

    -- Hide Zoom's "share" windows so it doesn't come back on ESC keypress
    local zoomWindow = nil
    local originalFrame = nil
    
    hs.hotkey.bind({"cmd", "ctrl", "alt"}, "H", function()
      print("> trying to hide zoom")
      if not zoomWindow then
        print(">  looking for window")
        zoomWindow = hs.window.find("zoom share statusbar window")
      end
    
      if zoomWindow then
        print(">  found window")
        if originalFrame then
          print(">    restoring")
          zoomWindow:setFrame(originalFrame)
          originalFrame = nil
          zoomWindow = nil
        else
          print(">    hiding")
          originalFrame = zoomWindow:frame()
          local screen = zoomWindow:screen()
          local frame = zoomWindow:frame()
          frame.x = screen:frame().w + 99000
          frame.y = screen:frame().h + 99000
          zoomWindow:setFrame(frame)
        end
      else
        print(">  window not found")
      end
    end)
overflowy•39m ago
I use this to remap app keys:

    local appHotkeys = {}

    local function remapAppHotkey(appName, fromMods, fromKey, toMods, toKey, delay)
        if not appHotkeys[appName] then
            appHotkeys[appName] = {}
        end
        local hotkey = hs.hotkey.new(fromMods, fromKey, function()
            hs.eventtap.keyStroke(toMods, toKey, delay or 0)
        end)
        table.insert(appHotkeys[appName], hotkey)
    end
    
    local appWatcher = hs.application.watcher.new(function(appName, eventType)
        local hotkeys = appHotkeys[appName]
        if not hotkeys then return end
        for _, hotkey in ipairs(hotkeys) do
            if eventType == hs.application.watcher.activated then
                hotkey:enable()
            elseif eventType == hs.application.watcher.deactivated then
                hotkey:disable()
            end
        end
    end)
    
    appWatcher:start()

    -- Remap app hotkeys
    remapAppHotkey("Finder", { "cmd" }, "q", { "cmd" }, "w", 0.5)
    ... etc ...
alexfortin•32m ago
I use it to enable/disable the wifi when I disconnec/connect the macbook to a specific usb hub with ethernet connection:

  local usbWatcher = hs.usb.watcher.new(function(device)
    if device.productName == "EMEET SmartCam C960" then
      if device.eventType == "added" then
        hs.execute("networksetup -setairportpower en0 off")
        hs.notify.new({title="Wi-Fi", informativeText="Disabled (USB device connected)"}):send()
      elseif device.eventType == "removed" then
        hs.execute("networksetup -setairportpower en0 on")
        hs.notify.new({title="Wi-Fi", informativeText="Re-enabled (USB device removed)"}):send()
      end
    end
  end)
  usbWatcher:start()
swiftcoder•30m ago
I always confuse "hammerspoon" and "rowhammer"
selectnull•12m ago
Love hammerspoon. I use it to map double CMD to swap between the terminal and the browser.
theshrike79•6m ago
[delayed]

Show HN: Channel Surfer – Watch YouTube like it’s cable TV

https://channelsurfer.tv
234•kilroy123•2d ago•95 comments

Can I run AI locally?

https://www.canirun.ai/
567•ricardbejarano•7h ago•143 comments

Hammerspoon

https://github.com/Hammerspoon/hammerspoon
84•tosh•2h ago•30 comments

Stanford researchers report first recording of a blue whale's heart rate (2019)

https://news.stanford.edu/stories/2019/11/first-ever-recording-blue-whales-heart-rate
19•eatonphil•1h ago•4 comments

Qatar helium shutdown puts chip supply chain on a two-week clock

https://www.tomshardware.com/tech-industry/qatar-helium-shutdown-puts-chip-supply-chain-on-a-two-...
222•johnbarron•8h ago•213 comments

Mouser: An open source alternative to Logi-Plus mouse software

https://github.com/TomBadash/MouseControl
25•avionics-guy•2h ago•9 comments

Show HN: Context Gateway – Compress agent context before it hits the LLM

https://github.com/Compresr-ai/Context-Gateway
35•ivzak•2h ago•24 comments

Elon Musk pushes out more xAI founders as AI coding effort falters

https://www.ft.com/content/e5fbc6c2-d5a6-4b97-a105-6a96ea849de5
108•merksittich•4h ago•95 comments

New 'negative light' technology hides data transfers in plain sight

https://www.unsw.edu.au/newsroom/news/2026/03/New-negative-light-technology-hides-data-transfers-...
11•wjSgoWPm5bWAhXB•1d ago•0 comments

Parallels confirms MacBook Neo can run Windows in a virtual machine

https://www.macrumors.com/2026/03/13/macbook-neo-runs-windows-11-vm/
99•tosh•6h ago•120 comments

TUI Studio – visual terminal UI design tool

https://tui.studio/
465•mipselaer•10h ago•258 comments

Using Thunderbird for RSS

https://rubenerd.com/using-thunderbird-for-rss/
24•ingve•3d ago•1 comments

Your phone is an entire computer

https://medhir.com/blog/your-phone-is-an-entire-computer
149•medhir•2h ago•144 comments

Launch HN: Captain (YC W26) – Automated RAG for Files

https://www.runcaptain.com/
39•CMLewis•4h ago•14 comments

John Carmack about open source and anti-AI activists

https://twitter.com/id_aa_carmack/status/2032460578669691171
131•tzury•2h ago•191 comments

The Wyden Siren Goes Off Again: We'll Be "Stunned" by NSA Under Section 702

https://www.techdirt.com/2026/03/12/the-wyden-siren-goes-off-again-well-be-stunned-by-what-the-ns...
247•cf100clunk•4h ago•86 comments

Launch HN: Spine Swarm (YC S23) – AI agents that collaborate on a visual canvas

https://www.getspine.ai/
73•a24venka•7h ago•59 comments

Bucketsquatting is finally dead

https://onecloudplease.com/blog/bucketsquatting-is-finally-dead
283•boyter•12h ago•148 comments

Lost Doctor Who Episodes Found

https://www.bbc.co.uk/news/articles/c4g7kwq1k11o
153•edent•15h ago•43 comments

The wild six weeks for NanoClaw's creator that led to a deal with Docker

https://techcrunch.com/2026/03/13/the-wild-six-weeks-for-nanoclaws-creator-that-led-to-a-deal-wit...
36•wateroo•1h ago•1 comments

Source code of Swedish e-government services has been leaked

https://darkwebinformer.com/full-source-code-of-swedens-e-government-platform-leaked-from-comprom...
172•tavro•10h ago•162 comments

How do you capture WHY engineering decisions were made, not just what?

18•zain__t•55m ago•15 comments

Meta Platforms: Lobbying, dark money, and the App Store Accountability Act

https://github.com/upper-up/meta-lobbying-and-other-findings
1093•shaicoleman•10h ago•464 comments

Hyperlinks in terminal emulators

https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
73•nvahalik•17h ago•47 comments

Digg is gone again

https://digg.com/
48•hammerbrostime•1h ago•27 comments

The Accidental Room (2018)

https://99percentinvisible.org/episode/the-accidental-room/
16•blewboarwastake•2h ago•1 comments

Okmain: How to pick an OK main colour of an image

https://dgroshev.com/blog/okmain/
210•dgroshev•4d ago•41 comments

Militaries are scrambling to create their own Starlink

https://www.newscientist.com/article/2517766-why-the-worlds-militaries-are-scrambling-to-create-t...
50•mooreds•3h ago•79 comments

E2E encrypted messaging on Instagram will no longer be supported after 8 May

https://help.instagram.com/491565145294150
322•mindracer•7h ago•168 comments

Who Goes Nazi? (1941)

https://harpers.org/archive/1941/08/who-goes-nazi/
18•Anon84•45m ago•2 comments