Last active
October 7, 2024 13:22
-
-
Save furquanuddin94/802a1153978c0622d8bd16eb09b5fc3f to your computer and use it in GitHub Desktop.
Lua script for hammerspoon for easy switching between apps.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
— Define your hyper key | |
local hyper = {"ctrl", "alt", "cmd", "shift"} | |
— Define a table of applications with their bundle identifiers and hotkeys | |
local apps = { | |
{key = "C", bundleID = "com.todesktop.230313mzl4w4u92"}, — Cursor App | |
{key = "B", bundleID = "com.google.Chrome"}, — Google Chrome | |
{key = "P", bundleID = "com.postmanlabs.mac"}, — Postman | |
{key = "I", bundleID = "com.jetbrains.intellij"}, — IntelliJ | |
{key = "T", bundleID = "com.googlecode.iterm2"}, — iTerm | |
{key = "S", bundleID = "com.tinyspeck.slackmacgap"}, — Slack | |
{key = "M", bundleID = "com.microsoft.teams2"}, — Microsoft Teams | |
{key = "O", bundleID = "com.microsoft.Outlook"} — Outlook | |
} | |
— Command to find the bundle ID of an app | |
— osascript -e 'id of app "YourAppName"' | |
— Table to store the previously focused window for each app | |
local previousWindows = {} | |
— Table to store the last focused window within the app for cycling | |
local lastFocusedWindows = {} | |
— Function to switch to the next window of the specified app | |
local function switchAppWindow(bundleID) | |
— Get the application object | |
local app = hs.application.get(bundleID) | |
— If the app is not running, launch it | |
if not app then | |
hs.application.launchOrFocusByBundleID(bundleID) | |
return | |
end | |
— Get all windows of the app | |
local windows = app:allWindows() | |
— If no windows are found, launch the app | |
if #windows == 0 then | |
hs.application.launchOrFocusByBundleID(bundleID) | |
return | |
end | |
— Sort windows to ensure consistent order | |
table.sort(windows, function(a, b) return a:id() < b:id() end) | |
— Get the currently focused window | |
local currentWindow = hs.window.focusedWindow() | |
— Check if the current window belongs to the app | |
local isCurrentWindowInApp = false | |
for _, window in ipairs(windows) do | |
if window == currentWindow then | |
isCurrentWindowInApp = true | |
break | |
end | |
end | |
— Handle single window toggle | |
if #windows == 1 then | |
if isCurrentWindowInApp then | |
— Toggle back to the previous window | |
if previousWindows[bundleID] and previousWindows[bundleID]:isVisible() then | |
previousWindows[bundleID]:focus() | |
previousWindows[bundleID] = nil | |
else | |
previousWindows[bundleID] = currentWindow | |
windows[1]:focus() | |
end | |
else | |
— Focus on the app's window and store the current window | |
previousWindows[bundleID] = currentWindow | |
windows[1]:focus() | |
end | |
return | |
end | |
— Handle multiple windows cycling | |
if not isCurrentWindowInApp then | |
— Focus on the last focused window within the app or the first window | |
if lastFocusedWindows[bundleID] and lastFocusedWindows[bundleID]:isVisible() then | |
lastFocusedWindows[bundleID]:focus() | |
else | |
windows[1]:focus() | |
end | |
previousWindows[bundleID] = currentWindow | |
return | |
end | |
— Find the index of the last focused window within the app | |
local lastFocusedIndex = 1 | |
if lastFocusedWindows[bundleID] then | |
for i, window in ipairs(windows) do | |
if window == lastFocusedWindows[bundleID] then | |
lastFocusedIndex = i | |
break | |
end | |
end | |
end | |
— Move to the next window in the list | |
local nextIndex = lastFocusedIndex % #windows + 1 | |
windows[nextIndex]:focus() | |
— Update the last focused window | |
lastFocusedWindows[bundleID] = windows[nextIndex] | |
end | |
— Bind the function to the hyper key + specified key for each app | |
for _, app in ipairs(apps) do | |
hs.hotkey.bind(hyper, app.key, function() switchAppWindow(app.bundleID) end) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment