Skip to content

Instantly share code, notes, and snippets.

@cleverdevil
Created December 14, 2017 18:05
Show Gist options
  • Save cleverdevil/fd3e5f9eea3215547ea2c6492c0d3ee0 to your computer and use it in GitHub Desktop.
Save cleverdevil/fd3e5f9eea3215547ea2c6492c0d3ee0 to your computer and use it in GitHub Desktop.
Current hammerspoon configuration
-- -----------------
-- Setup environment
-- -----------------
-- Animation off, mofo
hs.window.animationDuration = 0
-- Get list of screens and refresh that list whenever screens are (un)plugged
local screens = hs.screen.allScreens()
local screenwatcher = hs.screen.watcher.new(function()
screens = hs.screen.allScreens()
end)
screenwatcher:start()
-- Modifier shortcuts
local hyper = {"⌥", "⇧"}
local pushkey = {"⌃", "⌘"}
-- Tracking variables
local pressed = {
up = false,
down = false,
left = false,
right = false
}
-- Full screen sizes
local fullScreenSizeIndex = 0
local fullScreenSizes = {
{ x = 0.00, y = 0.00, w = 1.0, h = 1.0 },
{ x = 0.05, y = 0.05, w = 0.9, h = 0.9 },
{ x = 0.10, y = 0.10, w = 0.8, h = 0.8 },
{ x = 0.15, y = 0.15, w = 0.7, h = 0.7 },
{ x = 0.20, y = 0.20, w = 0.6, h = 0.6 },
{ x = 0.25, y = 0.25, w = 0.5, h = 0.5 }
}
-- ----------------
-- Helper functions
-- ----------------
-- Resize window for chunk of screen.
-- For x and y: use 0 to expand fully in that dimension, 0.5 to expand halfway
-- For w and h: use 1 for full, 0.5 for half
function push(x, y, w, h)
local win = hs.window.focusedWindow()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()
f.x = max.x + (max.w*x)
f.y = max.y + (max.h*y)
f.w = max.w*w
f.h = max.h*h
win:setFrame(f)
end
-- Shortcuts for pushing to top, bottom, left, right in every combination
function pushT() push(0.0, 0.0, 1.0, 0.5) end
function pushB() push(0.0, 0.5, 1.0, 0.5) end
function pushL() push(0.0, 0.0, 0.5, 1.0) end
function pushR() push(0.5, 0.0, 0.5, 1.0) end
function pushTL() push(0.0, 0.0, 0.5, 0.5) end
function pushTR() push(0.5, 0.0, 0.5, 0.5) end
function pushBL() push(0.0, 0.5, 0.5, 0.5) end
function pushBR() push(0.5, 0.5, 0.5, 0.5) end
-- Move to monitor x. Checks to make sure monitor exists, if not moves to last monitor that exists
function moveToMonitor(x)
local win = hs.window.focusedWindow()
local newScreen = nil
while not newScreen do
newScreen = screens[x]
x = x-1
end
win:moveToScreen(newScreen)
end
-- -----------------
-- Window management
-- -----------------
-- Push to left (including top left and bottom left)
hs.hotkey.bind(pushkey, "left", function()
pressed.left = true
if pressed.up then
pushTL()
elseif pressed.down then
pushBL()
else
pushL()
end
end, function ()
pressed.left = false
end)
-- Push to right (including top right and bottom right)
hs.hotkey.bind(pushkey, "right", function()
pressed.right = true
if pressed.up then
pushTR()
elseif pressed.down then
pushBR()
else
pushR()
end
end, function()
pressed.right = false
end)
-- Push to top (including top right and top left)
hs.hotkey.bind(pushkey, "up", function()
pressed.up = true
if pressed.left then
pushTL()
elseif pressed.right then
pushTR()
else
pushT()
end
end, function()
pressed.up = false
end)
-- Push to bottom (including bottom left and bottom right)
hs.hotkey.bind(pushkey, "down", function()
pressed.down = true
if pressed.left then
pushBL()
elseif pressed.right then
pushBR()
else
pushB()
end
end, function()
pressed.down = false
end)
-- Center window with some room to see the desktop
hs.hotkey.bind(pushkey, "m", function() push(0.05,0.05,0.9,0.9) end)
-- Move a window between monitors
hs.hotkey.bind(pushkey, "1", function() moveToMonitor(1) end) -- Move to first monitor
hs.hotkey.bind(pushkey, "2", function() moveToMonitor(2) end) -- Move to second monitor
-- Tile windows on current screen
hs.hotkey.bind({'cmd', 'ctrl'}, 't', function()
local wins = hs.window.filter.new():setCurrentSpace(true):getWindows()
local screen = hs.screen.mainScreen():currentMode()
local rect = hs.geometry(0, 0, screen['w'], screen['h'])
hs.window.tiling.tileWindows(wins, rect)
end)
-- -------------
-- "Full" screen
-- -------------
-- Cycle through "full" screen sizes
hs.hotkey.bind(pushkey, "f", function()
fullScreenSizeIndex = fullScreenSizeIndex + 1
if fullScreenSizeIndex > #fullScreenSizes then fullScreenSizeIndex = 1 end
size = fullScreenSizes[fullScreenSizeIndex]
push(size.x, size.y, size.w, size.h)
end)
-- Watch for focus changes to reset the full screen size cycling
allwindows = hs.window.filter.new(nil)
allwindows:subscribe(hs.window.filter.windowUnfocused, function () fullScreenSizeIndex = 0 end)
-- ---------------------
-- Application shortcuts
-- ---------------------
appmode = hs.hotkey.modal.new({"cmd"}, "E")
appmode:bind({}, "B", function() hs.application.launchOrFocus("Safari") appmode:exit() end)
appmode:bind({}, "T", function() hs.application.launchOrFocus("iTerm") appmode:exit() end)
appmode:bind({}, "M", function() hs.application.launchOrFocus("Mail") appmode:exit() end)
appmode:bind({}, "S", function() hs.application.launchOrFocus("Slack") appmode:exit() end)
appmode:bind({}, "R", function() hs.application.launchOrFocus("Tweetbot") appmode:exit() end)
appmode:bind({}, "I", function() hs.application.launchOrFocus("Messages") appmode:exit() end)
-- -----------------------
-- Configuration reloading
-- -----------------------
function reloadConfig(files)
doReload = false
for _,file in pairs(files) do
if file:sub(-4) == ".lua" then
doReload = true
end
end
if doReload then
hs.reload()
end
end
hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start()
hs.alert.show("Config loaded")
@lucasprag
Copy link

Thank you very much for sharing this gist 👍

Not all hero wear capes =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment