Hammerspoon – Powerful automation of OS X with Lua
hammerspoon.org
hammerspoon.org
I also have it iMessage me when it's removed. In case someone else grabs it when I'm not near it.
I also have it wake up the screen when I plug it in, combined with Knock I can get in and out of my computer quickly and easily.
In the original post, I left out that I also have a usb LED sign [1] that I also have programmed, so people know when they can and cannot interrupt me. Again controlled with hammerspoon and my yubikey.
- Drag to the left or right to cover that half of the screen. - Drag to the top for maximise - Drag to a corner for corner snap - Control + Option + Arrow to snap to left or right of screen, maximise or center - Control + Option + Command + Arrow to snap to corner of screen
https://gist.github.com/spartanatreyu/850788a0441e1c5565668a...
Spectacle just didn't have the window options and wasn't being actively developed to add the options that everyone was asking for.
It's the oldest issue (3 years) on the project:
Use it nonstop all day to snap stuff half-screen right/left/up/down, no to mention (finally!) full screen.
Intrigued by Hammerspoon.
Recently I've made this hammerspoon "plugin": https://github.com/selectnull/hammerspoon-alttab
I would love to have feedback, if anyone is interested (it's not perfect, i'm aware of few bugs, but it solves my problem most of the time).
Let me know if you make something.
"HammerSpoon"
It perfectly conveys what an elegant kludge it is.
As we added feature after feature to Mjolnir, and it grew to a monolithic collection of barely-related modules (APIs), I realized that it didn't make a lot of sense for users to keep upgrading to "newer" versions of Mjolnir, when in reality it was just the modules bundled with Mjolnir that were new or changed, and Mjolnir itself wasn't changed at all.
So I made the decision to decentralize the APIs. Instead of being bundled into Mjolnir itself, users would be able to download Mjolnir and then download or upgrade modules independently of Mjolnir.
This was pretty unpopular, because it meant Mjolnir was no longer "batteries included", so Hammerspoon was forked by the portion of the community that preferred that batteries included approach. Honestly, I don't even know how much of the community (if any) continued to use Mjolnir.
They forked it because of a difference of opinion: I believe that separation of the core app and the modules into separate projects is ultimately better, and they don't.
When they're separate projects, there's a lot of potential for really interesting tools to be built around them, between them, or bridging them together.
Imagine having a GUI app that manages third party modules for you, installing and loading them at a single click. Or a plugin that centralizes plugin settings into a unified single GUI window. These are the kinds of things that this separation was meant to allow and encourage.
But when it's a batteries-included app, every single aspect of it needs to be built into the app. It becomes monolithic. Every feature anyone could ever want needs to be bundled into it, and even though this is more convenient at first, it ends up bloated. It also doesn't allow for any competition between features in the same domain.
The authors behind Hammerspoon prefer the batteries-included approach. They're not wrong, it's not a matter of right or wrong. It's just a difference of opinion. People who want that approach will prefer Hammerspoon. People who want to build tools around their existing tools will probably prefer Mjolnir.
In this case, mjolnir, the lean mean core, then the various subprojects, and finally the "distro", containing a curated set of popular modules that people can download as a turnkey system. Then, if you want your own custom setup, minus the bloat, you can set up your own distro. If you just want to use the damn thing and don't care about how the sausage is made, use the "recommended" distro.
Have a centralized repository containing pointers to all available modules. Module creators can publish to this repository. Cocoapods does this rather nicely, and uses github for the centralized repo.
Then have a tool inside mjolnir that allows administration of the repo (request adding your module, publish a new version of your module, etc).
Then have a "distro" format that lists what modules are included in your distro. This is doubly cool because if you have to install another machine, you just call upon your distro, it installs everything and you're good to go. It also makes upgrading to the latest and greatest modules a breeze.
I guarantee that 90% of your users will just go with the "recommended" distro, but the developers will love you for making it a lot easier to contribute. It's all about lowering friction, for users, power users, and devs.
Suggestions for filling in the blank, are welcome :)
I've played around with Lua in Codea -- really liked it: https://github.com/TwoLivesLeft/Codea-Runtime
see also: https://itunes.apple.com/us/app/codea/id439571171?mt=8
Check out the really gentle follow-along tutorial:
I think we made some terrible API decisions, but we'll fix them up eventually!
(Also for those following along at home, sdegutis is the author of a long line of OS X automation tooling, up to and including Mjolnir, which we forked to make Hammerspoon. He is awesome)
Phoneix lives on as Phoenix 2.2 https://github.com/kasper/phoenix
It's useful both for general window management as well as system hackery. It's the closest OS X users can get to the power of Linux.
> It has a very low false negative rate, but often has false positives.
Seems like it would get triggered constantly around noises like A/C, or wind, or the inevitable coworker who quietly hisses behind you while you've got your headphones on.
(It would be me. I would 100% be that coworker.)
The answer is that all the false positives I encounter are human-triggered so if you are alone and not doing anything else except reading, they aren't much of an issue.
You can also buy super directional headsets that don't pick up anything else, even other people making the noises standing next to you. I have one and it works great, just not as convenient as the tiny mike on my earbuds.
[1] https://live.gnome.org/GnomeShell/Extensions [2] https://live.gnome.org/GObjectIntrospection [3] https://developer.gnome.org/gnome-devel-demos/unstable/ [4] https://developer.gnome.org/platform-overview/stable/ [5] https://extensions.gnome.org/
Another seemingly great product for Apple not by Apple. I just downloaded the app Continous to my iPad Pro, and I am programming happily in F# on it. It has cut into my Pythonista time, another non-Apple made app.
Maybe Apple's focus more on hardware, and leaving software a bit behind is working out for them. It seems users are stepping up and creating some really productive software.
I almost never use Dock, Spotlight or Finder now. It's great!
Wrap it all in a personal Cask, and you're good to go! https://github.com/Jeppesen-io/homebrew-hammerspoon
Thankfully, tools like you've discovered address this behaviour and add a lot of other useful window management features anyway.
It seems like the Option+Click on the streetlight is kind of like a toggle of the last two previous sizes, but not always - sometimes it stretches to the top, sometimes it doesn't do anything.
I've been a dedicated OS X user since 10.3 - and, despite spending 15-20 minutes at a stretch every year or so (such as tonight) - I've never really understood what the green button is supposed to do. I kind of find it amazing that such a horribly inconsistent user interface control has persisted for 15+ years.
But yet - Magnet (much like Spectacle before it) does exactly what I want. Ctrl+Option+Enter = Maximize window (which is exactly what I bet 99% of people want the Green Button to do)
For example, you could make text editing (in apps that use the Cocoa text editor libraries and input fields etc..., which are most of them) act like Vim or Emacs, or Windows, or whatever you want.
Awesome work! (And if you haven't already, check out some of Steven's other projects. Very fun/interesting code.)
Im going to change the events to activated/deactived so that I can leave the app on, but only change the screensaver when in use.
You can trigger any action based on app events as well. So anytime an app is launched, quit, hidden, unhidden, etc. - you can then take any other action.
Also, I created a 'modal' set of shortcuts for my machine. By pressing a leader, I switch to 'normal' mode and every letter has a binding. Very powerful.
Here's my configuration: https://github.com/pstadler/dotfiles/blob/master/hammerspoon...
I'm pretty fluent in Lua, so being able to leverage ability like Hammerspoon does would be great.
Look at emmet if you do anything involving html.
Maybe setup a process that watches a folder and builds/compiles anything placed in there.
If you need to do a job 10 times that takes 5 hours to do each time and you can automate that job in 30 hours so each job now only takes 1 hour each then you've saved 10 hours of time.
At my work I've made an enewsletter editor app (turned 2 week job down to 3 days job) and a language file editor for the content we output (turned 1 week job into 1 day job)
All that extra time gives you more breathing room between projects, more polish time for those projects or more time to learn new things.
This (https://github.com/Linell/hammerspoon-config) is my configuration, which is about as basic as it gets. The documentation has a billion other, cooler things that can be done.
Edit: After binding a hotkey to hs.alert.show(_VERSION), it seems to be Lua 5.3.
Edit 2: Oh Hammerspoon has an interactive console. Typing _VERSION in there would have been slightly simpler.
At http://www.hammerspoon.org/go/#colonsyntax it mentions the following calls are identical:
win:frame()
hs.window.frame(win)
My Lua knowledge is a bit rusty but should the second line not be:
win.frame(win) ?
local win = hs.window.focusedWindow()
local f = win:frame()
win is presumable a copy ("instance") of the table hs.window created by focusedWindow().Meaning hs.window.focusedWindow() returns a copy of the hs.window table.
With that being said, win.frame(win) would just be hs.window.frame(win), so you're also correct. It's just a poorly worded example explaining Lua's colon syntax feature.
As for JavaScript, my opinion is that Lua is everything JavaScript should have been: A clean, minimal, sanely designed, language. JavaScript on the other hand is nothing but mistakes piled upon mistakes. It's really disheartening to see JavaScript get shoved into places Lua fits better, like as Gnome Shell's scripting language. Oh well.
Then I can just put a Lua file in my dotfiles.
Can people give some real world examples of what they are using this for?
CAPS + 1 = Bring up Bash
CAPS + 2 = Bring up IntelliJ
CAPS + 3 = Bring up Chrome
CAPS + 4 = Bring up Geany
CAPS + 5 = Bring up SourceTree
CAPS + F1 = Chat software
CAPS + F2 = Email
CAPS + F = Full screen the current app (But not really fullscreen - it's like option + green button, except width too)
CAPS + W = Cycle the wifi
CAPS + V = Paste text from the clipboard by typing it in, accounting for tab indentations. This is useful for copying things from Outlook into Confluence. Stupid Confluence.
https://github.com/victorso/.hammerspoon/blob/master/tools/c...
cmd+alt+control+k emaKs cmd+alt+control+T Trello cmd+alt+control+M chroMe
And I have cmd+alt+control+/ print this bubble message onto the screen to help remember them all: https://fetchh--captured.s3.amazonaws.com/2016-07-15_135709....
I was a bit surprised, but cmd+fx doesn't seem to override any useful app builtin shortcuts either for the apps I use.
2. Site specific apps (e.g. trello)
3. Custom browser chooser per URL
4. Clipboard manager
5. Downloader manager
6. Various system information displays
7. Pomodoro timer
8. Various utilities.
Here (https://github.com/Linell/hammerspoon-config) is my configuration, although it's nothing fancy.
Hammerspoon is the only utility that could give me what I wanted: Window columns sized ⅓ ⅔ on the left monitor, and ⅔ ⅓ on the right monitor.