Smart Open Xcode
August 2, 2023
If you’re like me, you often have multiple versions of Xcode installed. One or two beta versions, a stable version, and maybe another version in case the most recent stable version has something weird about it.
I also really like mapping my Caps Lock key to something more useful, and after reading Brett Terspstra’s excellent article on making a Hyper key many years ago, I’ve gotten used to hitting Caps Lock + X to jump to Xcode thanks to Karabiner Elements and Alfred. It works a lot like Command + Tab, but doesn’t require hitting Tab until you find it. It basically maps Caps Lock to holding down Command, Option, Control, and Shift all at once, a modifier that is very unlikely to conflict with anything else.
Anyway, this setup works by mapping a hotkey to a specific app, which works great 99% of the time, but if you’re working in a beta version of Xcode, and you have that keyboard shortcut mapped to the stable version, it opens the wrong app and can even sometimes get Xcode confused about accessing a file in multiple locations. Not good!
So, we need a smarter version rather than just hardcoding the app. Lots of options exist, like AppleScript (had a small delay though) and Keyboard Maestro, probably Shortcuts too, but I like a little Lua scripting utility called Hammerspoon. Just download it and drop it in your Applications folder.
At that point, we can add a short script to our init.lua
file that uses Hammerspoon’s find()
API to, well, find the version of Xcode that’s currently running, and open that, rather than a hardcoded one. Nice! (If you keep multiple versions of Xcode open at once, I don’t know what to tell you, weirdo.)
hs.hotkey.bind({"cmd", "alt", "ctrl", "shift"}, "X", function()
-- Use the bundle ID rather than just 'Xcode' to prevent it from trying to open utility apps like 'Xcodes'
local xcode = hs.application.find("com.apple.dt.Xcode")
-- If nothing is found then just alert the user to open one, it would be very hard to guess which one they want if none are open!
if xcode == nil then
hs.notify.new({title="Xcode is not open! 🫨", informativeText="Manually launch an Xcode instance and then I’ll be able to work!"}):send()
return
end
--- If not the frontmost app, make it the frontmost! If it already is, hide it (makes it more toggle-y).
if xcode:isFrontmost() then
xcode:hide()
else
xcode:activate()
end
end)
Voilà! Works like a charm. Here’s an addition that you can add as well that extends it to Simulators:
hs.hotkey.bind({"cmd", "alt", "ctrl", "shift"}, "A", function()
-- Use the bundle ID rather than just 'Simulator' to prevent it from trying to open random background processes, and yes 'iphonesimulator' works for iPads as well
local simulator = hs.application.find("com.apple.iphonesimulator")
-- If nothing is found then just alert the user to open one, it would be very hard to guess which one they want if none are open!
if simulator == nil then
hs.notify.new({title="Simulator is not open! 🫨", informativeText="Run your project in Xcode to launch it in a simulator, then I'll know what to open!"}):send()
return
end
--- If not the frontmost app, make it the frontmost! If it already is, hide it (makes it more toggle-y).
if simulator:isFrontmost() then
simulator:hide()
else
simulator:activate()
end
end)