Skip to content

Instantly share code, notes, and snippets.

@mattvh
Created July 27, 2015 06:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattvh/e6984932c2ae5368bce4 to your computer and use it in GitHub Desktop.
Save mattvh/e6984932c2ae5368bce4 to your computer and use it in GitHub Desktop.
Hammerspoon NudgeMode module
-- Window nudging and resizing with modal shortcuts
-- Initialize with desired mode keybind:
-- windowmode.init({"cmd", "alt", "ctrl", "shift"}, "m")
-- Nudge window with arrows, resize with shift and arrows
-- HJKL is also supported
-- Space or return exits nudge mode
-- ------------------------------------------------------
-- http://github.com/mattvh
local function module_init(mod, key)
local mode = hs.hotkey.modal.new(mod, key)
local modeUIOutline = {}
--
-- Enter mode
--
function mode:entered()
hs.alert.show('Nudge Mode')
local screens = hs.screen.allScreens()
for index, screen in pairs(screens) do
local id = screen:id()
modeUIOutline[id] = hs.drawing.rectangle(screen:frame())
modeUIOutline[id]:setStrokeColor({["red"]=0,["blue"]=0,["green"]=1,["alpha"]=0.8})
modeUIOutline[id]:setFill(false)
modeUIOutline[id]:setStrokeWidth(3)
modeUIOutline[id]:show()
end
end
--
-- Exit mode
--
function mode:exited()
for id, outline in pairs(modeUIOutline) do
outline:delete()
modeUIOutline[id] = nil
end
end
--
-- Nudge windows
--
function nudge(x, y)
local s = hs.screen.mainScreen():frame()
local win = hs.window.focusedWindow()
local f = win:frame()
-- Update window frame
f.x = f.x + x
f.y = f.y + y
-- Apply changes and snap the window to screen edges
win:setFrame(f)
win:ensureIsInScreenBounds()
end
--
-- Resize windows
--
function resize(x, y)
local win = hs.window.focusedWindow()
local f = win:frame()
f.w = f.w + x
f.h = f.h + y
win:setFrame(f)
end
--
-- Keybinds
--
mode:bind({}, 'escape', function() mode:exit() end)
mode:bind({}, 'return', function() mode:exit() end)
mode:bind({}, 'left', function() nudge(-50, 0) end)
mode:bind({}, 'right', function() nudge(50, 0) end)
mode:bind({}, 'up', function() nudge(0, -50) end)
mode:bind({}, 'down', function() nudge(0, 50) end)
mode:bind({}, 'h', function() nudge(-50, 0) end)
mode:bind({}, 'l', function() nudge(50, 0) end)
mode:bind({}, 'k', function() nudge(0, -50) end)
mode:bind({}, 'j', function() nudge(0, 50) end)
mode:bind({'shift'}, 'left', function() resize(-50, 0) end)
mode:bind({'shift'}, 'right', function() resize(50, 0) end)
mode:bind({'shift'}, 'up', function() resize(0, -50) end)
mode:bind({'shift'}, 'down', function() resize(0, 50) end)
mode:bind({'shift'}, 'h', function() resize(-50, 0) end)
mode:bind({'shift'}, 'l', function() resize(50, 0) end)
mode:bind({'shift'}, 'k', function() resize(0, -50) end)
mode:bind({'shift'}, 'j', function() resize(0, 50) end)
end
return {
init = module_init
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment