Created
April 5, 2016 05:35
-
-
Save BrianGilbert/5484ada044c0e54a872a6794f83feb69 to your computer and use it in GitHub Desktop.
Hammerspoon Config
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 alert = require "hs.alert" | |
local application = require "hs.application" | |
local fnutils = require "hs.fnutils" | |
local grid = require "hs.grid" | |
local hotkey = require "hs.hotkey" | |
local mjomatic = require "hs.mjomatic" | |
local window = require "hs.window" | |
grid.MARGINX = 0 | |
grid.MARGINY = 0 | |
grid.GRIDHEIGHT = 13 | |
grid.GRIDWIDTH = 13 | |
local mash = {"cmd", "alt", "ctrl"} | |
local mashshift = {"cmd", "alt", "ctrl", "shift"} | |
-- | |
-- replace caffeine | |
-- | |
local caffeine = hs.menubar.new() | |
function setCaffeineDisplay(state) | |
local result | |
if state then | |
result = caffeine:setIcon("caffeine-on.pdf") | |
else | |
result = caffeine:setIcon("caffeine-off.pdf") | |
end | |
end | |
function caffeineClicked() | |
setCaffeineDisplay(hs.caffeinate.toggle("displayIdle")) | |
end | |
if caffeine then | |
caffeine:setClickCallback(caffeineClicked) | |
setCaffeineDisplay(hs.caffeinate.get("displayIdle")) | |
end | |
hs.hotkey.bind(mash, "/", function() caffeineClicked() end) | |
-- | |
-- /replace caffeine | |
-- | |
-- | |
-- function to adjust window size | |
-- | |
hs.window.animationDuration = 0 | |
local function adjust(x, y, w, h) | |
return function() | |
local win = hs.window.focusedWindow() | |
if not win then return end | |
local f = win:frame() | |
local max = win:screen():frame() | |
f.w = math.floor(max.w * w) | |
f.h = math.floor(max.h * h) | |
f.x = math.floor((max.w * x) + max.x) | |
f.y = math.floor((max.h * y) + max.y) | |
win:setFrame(f) | |
end | |
end | |
-- | |
-- /function to adjust window size | |
-- | |
-- | |
-- toggle push window to edge and restore to screen | |
-- | |
-- somewhere to store the original position of moved windows | |
local origWindowPos = {} | |
-- cleanup the original position when window restored or closed | |
local function cleanupWindowPos(_,_,_,id) | |
origWindowPos[id] = nil | |
end | |
-- function to move a window to edge or back | |
local function movewin(direction) | |
local win = hs.window.focusedWindow() | |
local res = hs.screen.mainScreen():frame() | |
local id = win:id() | |
if not origWindowPos[id] then | |
-- move the window to edge if no original position is stored in | |
-- origWindowPos for this window id | |
local f = win:frame() | |
origWindowPos[id] = win:frame() | |
-- add a watcher so we can clean the origWindowPos if window is closed | |
local watcher = win:newWatcher(cleanupWindowPos, id) | |
watcher:start({hs.uielement.watcher.elementDestroyed}) | |
if direction == "left" then f.x = (res.w - (res.w * 2)) + 10 end | |
if direction == "right" then f.x = (res.w + res.w) - 10 end | |
if direction == "down" then f.y = (res.h + res.h) - 10 end | |
win:setFrame(f) | |
else | |
-- restore the window if there is a value for origWindowPos | |
win:setFrame(origWindowPos[id]) | |
-- and clear the origWindowPos value | |
cleanupWindowPos(_,_,_,id) | |
end | |
end | |
hs.hotkey.bind(mash, "A", function() movewin("left") end) | |
hs.hotkey.bind(mash, "D", function() movewin("right") end) | |
hs.hotkey.bind(mash, "S", function() movewin("down") end) | |
-- | |
-- /toggle push window to edge and restore to screen | |
-- | |
-- -- | |
-- -- Open Applications | |
-- -- | |
-- local function openchrome() | |
-- application.launchOrFocus("Google Chrome") | |
-- end | |
-- local function openff() | |
-- application.launchOrFocus("FirefoxDeveloperEdition") | |
-- end | |
-- local function openmail() | |
-- application.launchOrFocus("Airmail") | |
-- end | |
-- hotkey.bind(mash, 'F', openff) | |
-- hotkey.bind(mash, 'C', openchrome) | |
-- hotkey.bind(mash, 'M', openmail) | |
-- -- | |
-- -- /Open Applications | |
-- -- | |
-- -- | |
-- -- Window management | |
-- -- | |
-- --Alter gridsize | |
-- hotkey.bind(mashshift, '=', function() grid.adjustHeight( 1) end) | |
-- hotkey.bind(mashshift, '-', function() grid.adjustHeight(-1) end) | |
-- hotkey.bind(mash, '=', function() grid.adjustWidth( 1) end) | |
-- hotkey.bind(mash, '-', function() grid.adjustWidth(-1) end) | |
--Resize windows to specific sizes | |
hotkey.bind(mash, "J", adjust(0, 0, 0.5, 1)) --1/2 left | |
hotkey.bind(mash, "U", adjust(0, 0, 0.5, 0.5)) --1/4 top left | |
hotkey.bind(mash, "I", adjust(0, 0, 1, 0.5)) --1/2 top | |
hotkey.bind(mash, "O", adjust(0.5, 0, 0.5, 0.5)) --1/4 top right | |
hotkey.bind(mash, "L", adjust(0.5, 0, 0.5, 1)) --1/2 right | |
hotkey.bind(mash, ".", adjust(0.5, 0.5, 0.5, 0.5)) --1/4 bottom right | |
hotkey.bind(mash, ",", adjust(0, 0.5, 1, 0.5)) --1/2 bottom | |
hotkey.bind(mash, "M", adjust(0, 0.5, 0.5, 0.5)) --1/4 bottom left | |
hotkey.bind(mash, "K", adjust(0, 0, 1, 1)) --full screen | |
hotkey.bind(mashshift, "K", adjust(0.25, 0.25, 0.5, 0.5)) | |
--Snap windows | |
hotkey.bind(mash, ';', function() grid.snap(window.focusedWindow()) end) | |
hotkey.bind(mash, "'", function() fnutils.map(window.visibleWindows(), grid.snap) end) | |
-- hotkey.bind(mashshift, 'H', function() window.focusedWindow():focusWindowWest() end) | |
-- hotkey.bind(mashshift, 'L', function() window.focusedWindow():focusWindowEast() end) | |
-- hotkey.bind(mashshift, 'K', function() window.focusedWindow():focusWindowNorth() end) | |
-- hotkey.bind(mashshift, 'J', function() window.focusedWindow():focusWindowSouth() end) | |
--Move windows | |
hotkey.bind(mash, 'DOWN', grid.pushWindowDown) | |
hotkey.bind(mash, 'UP', grid.pushWindowUp) | |
hotkey.bind(mash, 'LEFT', grid.pushWindowLeft) | |
hotkey.bind(mash, 'RIGHT', grid.pushWindowRight) | |
--resize windows | |
hotkey.bind(mashshift, 'UP', grid.resizeWindowShorter) | |
hotkey.bind(mashshift, 'DOWN', grid.resizeWindowTaller) | |
hotkey.bind(mashshift, 'RIGHT', grid.resizeWindowWider) | |
hotkey.bind(mashshift, 'LEFT', grid.resizeWindowThinner) | |
hotkey.bind(mash, 'N', grid.pushWindowNextScreen) | |
hotkey.bind(mash, 'P', grid.pushWindowPrevScreen) | |
-- hotkey.bind(mashshift, 'M', grid.maximizeWindow) | |
-- -- | |
-- -- /Window management | |
-- -- | |
-- | |
-- Screen resolution management | |
-- | |
local function setres(direction) | |
local screen = hs.screen.mainScreen() | |
local modes = screen:availableModes() | |
local currentMode = screen:currentMode() | |
local currentKey = tonumber(currentMode.w .. '.' .. currentMode.h) | |
alert.closeAll() | |
local modes_rekeyed = {} | |
for key, values in pairs(modes) do | |
new_key = tonumber(values.w .. '.' .. values.h) | |
modes_rekeyed[new_key] = values | |
end | |
local ordered_keys = {} | |
for k in pairs(modes_rekeyed) do | |
table.insert(ordered_keys, k) | |
end | |
table.sort(ordered_keys); | |
local last = nil | |
for i = 1, #ordered_keys do | |
local k, v = ordered_keys[i], modes_rekeyed[ordered_keys[i]] | |
if direction == 'up' and currentKey == last then | |
screen:setMode(v.w, v.h, v.scale) | |
alert.show(v.w .. ' x ' .. v.h) | |
break | |
elseif direction == 'down' and currentKey == k then | |
v = modes_rekeyed[last] | |
screen:setMode(v.w, v.h, v.scale) | |
alert.show(v.w .. ' x ' .. v.h) | |
break | |
end | |
last = k | |
end | |
end | |
hotkey.bind(mash, "=", function() setres('up') end) | |
hotkey.bind(mash, "-", function() setres('down') end) | |
-- | |
-- /Screen resolution management | |
-- | |
-- | |
-- Focus Follows Mouse | |
-- | |
--hs.eventtap.event.types["mouseMoved"] | |
--hs.window:focus() | |
-- | |
-- Focus Follows Mouse | |
-- | |
-- | |
-- Monitor and reload config when required | |
-- | |
function reload_config(files) | |
caffeine:delete() | |
hs.reload() | |
end | |
hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reload_config):start() | |
hs.alert.show("Config loaded") | |
-- | |
-- /Monitor and reload config when required | |
-- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment