Last active
September 30, 2016 20:29
-
-
Save jeffpamer/0eb3aa6ddefae4b55064 to your computer and use it in GitHub Desktop.
~/.hammerspoon/init.lua
This file contains 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
local benqDisplay = "BenQ LCD" | |
local defaultDisplay = "Color LCD" | |
local padding = 20 | |
-- disable animation | |
hs.window.animationDuration = 0 | |
-- Quick if/else helper function | |
function fif(condition, if_true, if_false) | |
if condition then return if_true else return if_false end | |
end | |
function applyLayouts() | |
-- Initialize some common window size vars | |
local screen = hs.screen.allScreens()[1] | |
local frame = screen:frame() | |
local width = frame.w - padding * 2 | |
local height = frame.h - padding * 2 | |
local halfWidth = frame.w / 2 - padding * 1.5 | |
local halfHeight = frame.h / 2 - padding * 1.5 | |
local largeHeight = height * 0.8 - padding / 2 | |
local smallHeight = height * 0.2 - padding / 2 | |
local midWidth = halfWidth + padding * 2 | |
local midHeight = halfHeight + padding | |
-- Setup geometry vars for commonly used screen spaces | |
local fullScreen = hs.geometry.rect(0, 0, frame.w, frame.h) | |
local leftHalf = hs.geometry.rect(padding, padding, halfWidth, height) | |
local rightHalf = hs.geometry.rect(padding * 2 + halfWidth, padding, halfWidth, height) | |
local right75 = hs.geometry.rect(padding * 2 + halfWidth / 1.5, padding, halfWidth * 1.3333, height) | |
local left25 = hs.geometry.rect(padding, padding, halfWidth * 0.6666, height) | |
local topRight = hs.geometry.rect(padding * 2 + halfWidth, padding, halfWidth, halfHeight) | |
local largeTopRight = hs.geometry.rect(padding * 2 + halfWidth, padding, halfWidth, largeHeight) | |
local smallBottomRight = hs.geometry.rect(midWidth, largeHeight + padding * 2, halfWidth, smallHeight) | |
local bottomRight = hs.geometry.rect(midWidth, halfHeight + padding * 2, halfWidth, halfHeight) | |
-- Find the 'main' window (if any) of all the applications we care about | |
local chrome = hs.application.find("Google Chrome") and hs.application.find("Google Chrome"):mainWindow() | |
local atom = hs.application.find("Atom") and hs.application.find("Atom"):mainWindow() | |
local emacs = hs.application.find("Emacs") and hs.application.find("Emacs"):mainWindow() | |
local term = hs.application.find("iTerm2") and hs.application.find("iTerm2"):focusedWindow() | |
local hyperterm = hs.application.find("HyperTerm") and hs.application.find("HyperTerm"):focusedWindow() | |
local slack = hs.application.find("Slack") and hs.application.find("Slack"):mainWindow() | |
local itunes = hs.application.find("iTunes") and hs.application.find("iTunes"):mainWindow() | |
local spotify = hs.application.find("Spotify") and hs.application.find("Spotify"):mainWindow() | |
local messages = hs.application.find("Messages") and hs.application.find("Messages"):mainWindow() | |
local largeLayout = screen:name() == benqDisplay | |
-- Establish desired layouts for each application depending on which screen is being used | |
local expectedFrames = { | |
["chrome"] = {chrome, fif(largeLayout, leftHalf, fullScreen)}, | |
["atom"] = {atom, fif(largeLayout, largeTopRight, fullScreen)}, | |
["emacs"] = {emacs, fif(largeLayout, rightHalf, right75)}, | |
["term"] = {term, fif(largeLayout, rightHalf, fullScreen)}, | |
["hyperterm"] = {hyperterm, fif(largeLayout, smallBottomRight, fullScreen)}, | |
["slack"] = {slack, leftHalf}, | |
["itunes"] = {itunes, topRight}, | |
["spotify"] = {spotify, topRight}, | |
["messages"] = {messages, bottomRight} | |
} | |
-- Iterate through each window and apply the expected layout if the current bounds don't already match | |
for key,value in pairs(expectedFrames) do | |
local app = value[1] | |
local expectedFrame = value[2] | |
if app and (app:frame() ~= expectedFrame) then | |
app:setFrame(expectedFrame) | |
end | |
end | |
end | |
-- Shortcut to manually reset layout | |
hs.hotkey.bind({"cmd", "alt"}, ";", function() | |
applyLayouts() | |
end) | |
-- VIM-esque keybindings to focus windows using canrdinal directions. | |
hs.hotkey.bind({"cmd", "alt"}, "K", function() | |
hs.window.focusedWindow():focusWindowNorth(nil, true, true) | |
end) | |
hs.hotkey.bind({"cmd", "alt"}, "L", function() | |
hs.window.focusedWindow():focusWindowEast(nil, true, true) | |
end) | |
hs.hotkey.bind({"cmd", "alt"}, "J", function() | |
hs.window.focusedWindow():focusWindowSouth(nil, true, true) | |
end) | |
hs.hotkey.bind({"cmd", "alt"}, "H", function() | |
hs.window.focusedWindow():focusWindowWest(nil, true, true) | |
end) | |
hs.hotkey.bind({"cmd", "alt"}, "P", function() | |
hs.spotify.playpause() | |
end) | |
-- Watch for space/screen changes to re-apply layouts | |
hs.spaces.watcher.new(applyLayouts):start() | |
hs.screen.watcher.new(applyLayouts):start() | |
-- Confirm load | |
hs.alert.show("Config loaded") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment