Skip to content

Instantly share code, notes, and snippets.

@jjrussell
Created November 21, 2022 15:30
Show Gist options
  • Save jjrussell/c1349f416a28c030ac4e58f91dac8822 to your computer and use it in GitHub Desktop.
Save jjrussell/c1349f416a28c030ac4e58f91dac8822 to your computer and use it in GitHub Desktop.
-- NOTE: IN order to move around windows mjolnir must have access to Accessibility
-- This can be set in Security & Privacy properties
-- local files
dofile(package.searchpath("utils", package.path))
-- adds some functionality to bg.grid
dofile(package.searchpath("grid", package.path))
local log = hs.logger.new('jjr-init','info')
log.i('Initializing')
--------------------------------------------------------------
---
--- Auto updates
---
--------------------------------------------------------------
-- save the time when updates are checked
function checkforupdates()
updates.check()
settings.set('lastcheckedupdates', os.time())
end
--------------------------------------------------------------
---
--- Keybindings
---
--------------------------------------------------------------
local minimash = {"alt", "ctrl"}
local mash = {"cmd", "alt", "ctrl"}
local mashshift = {"ctrl", "alt", "shift"}
-- hs.hotkey.bind(mash, 'X', logger.show)
-- hs.hotkey.bind(mash, "R", repl.open)
hs.hotkey.bind(mash, "c", hs.console.getConsole) -- doesn't work
hs.hotkey.bind(mash, "e", "Reloading Hammerspoon Config", hs.reload )
-- App keybindings
-- return a function to bind to hs.hotkey for launching the specified app
local function launch_fn(app)
return function() hs.application.launchOrFocus(app) end
end
hs.hotkey.bind({"alt"}, '1', launch_fn("iTerm"))
-- editors
hs.hotkey.bind({"alt"}, '2', launch_fn("Emacs"))
hs.hotkey.bind({"alt", "shift"}, '2', launch_fn("IntelliJ IDEA Community Edition"))
hs.hotkey.bind({"ctrl", "shift"}, '2', launch_fn("IntelliJ IDEA Community Edition"))
hs.hotkey.bind({"alt"}, '3', launch_fn("Finder"))
hs.hotkey.bind({"alt"}, '4', launch_fn("Slack"))
-- hs.hotkey.bind({"alt", "shift"}, '4', launch_fn("Pulse SMS"))
hs.hotkey.bind({"alt", "shift"}, '4', launch_fn("Android Messages"))
hs.hotkey.bind({"alt"}, '5', launch_fn("Todoist"))
hs.hotkey.bind({"alt", "shift"}, '5', launch_fn("TogglDesktop"))
hs.hotkey.bind({"alt"}, '6', launch_fn("zoom.us"))
hs.hotkey.bind({"alt"}, '7', launch_fn("Google Chrome"))
-- firefox starts in safe mode if alt is pressed on launch so this happens because I have my key repeat set really fast
hs.hotkey.bind({"alt"}, '8', launch_fn("Brave Browser"))
hs.hotkey.bind({"alt"}, '9', launch_fn("Cubase 12"))
hs.hotkey.bind({"alt", "shift"}, '9', launch_fn("Kontakt"))
hs.hotkey.bind({"alt"}, '0', launch_fn("Idagio"))
hs.hotkey.bind({"alt", "shift"}, '0', launch_fn("YouTube Music"))
-- https://gist.github.com/lancethomps/a5ac103f334b171f70ce2ff983220b4f
hs.hotkey.bind(mash, '0', launch_fn("Notification Dismisser"))
hs.hotkey.bind({"control", "shift", "command"}, 'q',
function()
os.execute('pmset sleepnow')
end)
-- puts display to sleep
hs.hotkey.bind(mash, 'l',
function()
os.execute('pmset displaysleepnow')
end
)
-- Just use cmd-ctrl-Q on the mac
-- hs.hotkey.bind(mashshift, 'l',
-- function()
-- hs.caffeinate.lockScreen()
-- end
-- )
--------------------------------------------------------------
---
--- Grid and window movement
---
--------------------------------------------------------------
-- use the whole screen
hs.grid.setMargins(hs.geometry(0,0))
hs.grid.setGrid("2x2")
hs.hotkey.bind(minimash, ';', hs.grid.show)
hs.hotkey.bind(minimash, 'U', hs.grid.maximizeWindow)
hs.hotkey.bind(minimash, 'J', hs.grid.pushWindowDown)
hs.hotkey.bind(minimash, 'K', hs.grid.pushWindowUp)
hs.hotkey.bind(mash, 'K', hs.grid.pushWindowTopHalf)
hs.hotkey.bind(mash, 'J', hs.grid.pushWindowBottomHalf)
-- hs.hotkey.bind(minimash, 'H', hs.grid.pushWindowLeftAndResize)
-- hs.hotkey.bind(minimash, 'L', hs.grid.pushWindowRightAndResize)
hs.hotkey.bind(mash, 'H', hs.grid.pushWindowLeftHalf)
hs.hotkey.bind(mash, 'L', hs.grid.pushWindowRightHalf)
hs.hotkey.bind(minimash, 'H', hs.grid.pushWindowLeft)
hs.hotkey.bind(minimash, 'L', hs.grid.pushWindowRight)
hs.hotkey.bind(minimash, 'P', hs.grid.pushWindowTopRight)
hs.hotkey.bind(minimash, '.', hs.grid.pushWindowBottomRight)
hs.hotkey.bind(minimash, 'Y', hs.grid.pushWindowTopLeft)
hs.hotkey.bind(minimash, 'B', hs.grid.pushWindowBottomLeft)
function myLayoutComms()
local mainScreen = hs.screen.allScreens()[1]
local secondScreen = hs.screen.allScreens()[2]
if secondScreen then
hs.application.launchOrFocus("Firefox")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,1,2), secondScreen)
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(1,0,1,2), secondScreen)
hs.application.launchOrFocus("Slack")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(1,0,1,2), mainScreen)
hs.application.launchOrFocus("Todoist")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,1,2), mainScreen)
else
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.pushWindowLeftHalf()
hs.application.launchOrFocus("Slack")
os.execute("sleep .2")
hs.grid.pushWindowTopRight()
hs.application.launchOrFocus("Todoist")
os.execute("sleep .2")
hs.grid.pushWindowBottomRight()
end
end
function myLayoutFrontEndDevelopment()
local mainScreen = hs.screen.allScreens()[1]
local secondScreen = hs.screen.allScreens()[2]
if secondScreen then
hs.application.launchOrFocus("Emacs")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(1,0,1,2), secondScreen)
hs.application.launchOrFocus("iTerm")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,1,2), secondScreen)
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,2,2), mainScreen)
else
hs.application.launchOrFocus("Emacs")
os.execute("sleep .2")
hs.grid.pushWindowLeftHalf()
hs.application.launchOrFocus("iTerm")
os.execute("sleep .2")
hs.grid.pushWindowLeftHalf()
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.pushWindowRightHalf()
end
end
function myLayoutDebugging()
local mainScreen = hs.screen.allScreens()[1]
local secondScreen = hs.screen.allScreens()[2]
if secondScreen then
hs.application.launchOrFocus("iTerm")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,1,2), secondScreen)
intellijWindows = hs.application.allWindows(hs.application("Intellij IDEA"))
for k, v in pairs(intellijWindows) do
os.execute("sleep .2")
hs.grid.set(v, hs.geometry(1,0,1,2), secondScreen)
hs.application.launchOrFocus("IntelliJ IDEA")
end
-- hs.application.launchOrFocus("IntelliJ IDEA CE")
-- os.execute("sleep .2")
-- hs.grid.set(hs.window.focusedWindow(), hs.geometry(1,0,1,2), secondScreen)
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,2,2), mainScreen)
else
hs.application.launchOrFocus("iTerm")
os.execute("sleep .2")
hs.grid.pushWindowLeftHalf()
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.pushWindowRightHalf()
end
end
function myLayoutBackEndDevelopment()
local mainScreen = hs.screen.allScreens()[1]
local secondScreen = hs.screen.allScreens()[2]
if secondScreen then
hs.application.launchOrFocus("Emacs")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,1,2), secondScreen)
hs.application.launchOrFocus("iTerm")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(1,0,1,2), secondScreen)
intellijWindows = hs.application.allWindows(hs.application("Intellij IDEA"))
for k, v in pairs(intellijWindows) do
os.execute("sleep .2")
hs.grid.set(v, hs.geometry(0,0,2,2), mainScreen)
hs.application.launchOrFocus("IntelliJ IDEA CE")
end
else
hs.application.launchOrFocus("iTerm")
os.execute("sleep .2")
hs.grid.pushWindowLeftHalf()
hs.application.launchOrFocus("IntelliJ IDEA CE")
os.execute("sleep .2")
hs.grid.pushWindowRightHalf()
end
hs.execute('/usr/local/bin/emacsclient -e "(progn (delete-other-windows) (switch-to-buffer \\\"*scratch*\\\"))"')
end
function myLayoutGeneralTesting()
local mainScreen = hs.screen.allScreens()[1]
local secondScreen = hs.screen.allScreens()[2]
if secondScreen then
hs.application.launchOrFocus("Iterm")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,1,2), secondScreen)
intellijWindows = hs.application.allWindows(hs.application("Intellij IDEA"))
for k, v in pairs(intellijWindows) do
os.execute("sleep .2")
hs.grid.set(v, hs.geometry(1,0,1,2), secondScreen)
hs.application.launchOrFocus("IntelliJ IDEA CE")
end
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.set(hs.window.focusedWindow(), hs.geometry(0,0,2,2), mainScreen)
else
intellijWindows = hs.application.allWindows(hs.application("Intellij IDEA"))
for k, v in pairs(intellijWindows) do
os.execute("sleep .2")
hs.grid.set(v, hs.geometry(1,0,1,2), secondScreen)
hs.application.launchOrFocus("IntelliJ IDEA CE")
end
hs.application.launchOrFocus("Google Chrome")
os.execute("sleep .2")
hs.grid.pushWindowRightHalf()
end
end
function myZoomLayoutTesting(app)
local mainScreen = hs.screen.allScreens()[1]
local secondScreen = hs.screen.allScreens()[2]
local screen = mainScreen
if secondScreen then
screen = secondScreen
end
if not app then
app = hs.application.launchOrFocus("zoom.us")
os.execute("sleep .2")
end
zoomWindows = app:allWindows()
for k, v in pairs(zoomWindows) do
log.i("moving zoom window")
os.execute("sleep .2")
hs.grid.set(v, hs.geometry(0,0,2,2), screen)
end
end
-- function appEventHandler(appName, eventType, application)
--
-- if appName == "zoom.us" then
-- log.i("app launch handler " .. appName .. " event " .. eventType)
-- log.i("activated=" .. hs.application.watcher.activated .. " deactivated=" .. hs.application.watcher.deactivated .. " hidden=" .. hs.application.watcher.hidden .. " launched=" .. hs.application.watcher.launched .. " launching=" .. hs.application.watcher.launching .. " terminated=" .. hs.application.watcher.terminated .. " unhidden=" .. hs.application.watcher.unhidden)
-- if eventType == hs.application.watcher.activated then
-- log.i("handling zoom event")
-- myZoomLayoutTesting(application)
-- end
-- end
-- end
-- hs.hotkey.bind(minimash, 'D', defaultBigDisplaySetup)
hs.hotkey.bind(minimash, 'F', myLayoutFrontEndDevelopment)
hs.hotkey.bind(minimash, 'C', myLayoutComms)
hs.hotkey.bind(minimash, 'V', myLayoutBackEndDevelopment)
hs.hotkey.bind(minimash, 'D', myLayoutDebugging)
hs.hotkey.bind(minimash, 'T', myLayoutGeneralTesting)
-- hs.hotkey.bind(minimash, 'Z', myZoomLayoutTesting)
-- hs.application.watcher.new(appEventHandler):start()
--------------------------------------------------------------
---
--- Expose
---
--------------------------------------------------------------
-- set up your instance(s)
-- expose = hs.expose.new(nil,{showThumbnails=true}) -- default windowfilter, no thumbnails
-- expose_app = hs.expose.new(nil,{onlyActiveApplication=true}) -- show windows for the current application
-- expose_browsers = hs.expose.new{'Safari','Google Chrome', 'Firefox'} -- specialized expose using a custom windowfilter
-- for your dozens of browser windows :)
-- then bind to a hotkey
-- hs.hotkey.bind('ctrl-cmd-shift','e','Expose',function()expose:toggleShow()end)
--------------------------------------------------------------
---
--- SPOOOOOOOOOOOOOONS
---
--------------------------------------------------------------
-- hs.loadSpoon("CircleClock")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment