Initial commit of Hammerspoon config
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
-- ~/.hammerspoon/bump.lua
|
||||
|
||||
local bump = {}
|
||||
|
||||
-- Persistence and State
|
||||
_G.BumpState = _G.BumpState or {
|
||||
gridSize = "3x2", -- 3 columns, 2 rows
|
||||
enabled = true
|
||||
}
|
||||
|
||||
-- Cleanup existing resources
|
||||
if _G.BumpResources then
|
||||
for _, item in ipairs(_G.BumpResources) do
|
||||
if item.stop then item:stop() end
|
||||
if item.delete then item:delete() end
|
||||
end
|
||||
end
|
||||
_G.BumpResources = {}
|
||||
|
||||
-- ~~~~~~~~~~ MANUAL BUMP LOGIC ~~~~~~~~~~
|
||||
local bentoWatcher = hs.window.filter.new()
|
||||
|
||||
bentoWatcher:subscribe(hs.window.filter.windowMoved, function(newWin)
|
||||
if not _G.BumpState.enabled then return end
|
||||
|
||||
local f1 = newWin:frame()
|
||||
local screen = newWin:screen()
|
||||
local maxW = screen:frame().w
|
||||
local allWindows = hs.window.visibleWindows()
|
||||
|
||||
-- Calculate how wide one "slot" is (e.g., 1/3 of screen)
|
||||
local cols = tonumber(_G.BumpState.gridSize:sub(1,1))
|
||||
local slotWidth = maxW / cols
|
||||
|
||||
for _, oldWin in ipairs(allWindows) do
|
||||
if oldWin:id() ~= newWin:id() and oldWin:screen() == screen and oldWin:isStandard() then
|
||||
local f2 = oldWin:frame()
|
||||
|
||||
-- Manual Intersection check
|
||||
local dx = math.max(0, math.min(f1.x + f1.w, f2.x + f2.w) - math.max(f1.x, f2.x))
|
||||
local dy = math.max(0, math.min(f1.y + f1.h, f2.y + f2.h) - math.max(f1.y, f2.y))
|
||||
|
||||
-- If they overlap significantly
|
||||
if (dx * dy) > (f1.w * f1.h * 0.4) then
|
||||
local newX = f2.x + slotWidth
|
||||
|
||||
-- If pushing right stays on screen, move it.
|
||||
-- Otherwise, move it to the start of the next row (y + height)
|
||||
if (newX + 50) > maxW then
|
||||
oldWin:setFrame({x = 0, y = f2.y + f2.h, w = f2.w, h = f2.h})
|
||||
else
|
||||
oldWin:setFrame({x = newX, y = f2.y, w = f2.w, h = f2.h})
|
||||
end
|
||||
|
||||
hs.alert.show("Bumping " .. oldWin:application():name())
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
table.insert(_G.BumpResources, bentoWatcher)
|
||||
|
||||
-- ~~~~~~~~~~ MENU BAR ~~~~~~~~~~
|
||||
local menu = hs.menubar.new()
|
||||
table.insert(_G.BumpResources, menu)
|
||||
|
||||
local function updateMenu()
|
||||
return {
|
||||
{ title = "Bump Status: " .. (_G.BumpState.enabled and "ON" or "OFF"), disabled = true },
|
||||
{ title = "-" },
|
||||
{ title = "Grid: 2x2", fn = function() _G.BumpState.gridSize = "2x2"; hs.reload() end, checked = (_G.BumpState.gridSize == "2x2") },
|
||||
{ title = "Grid: 3x2", fn = function() _G.BumpState.gridSize = "3x2"; hs.reload() end, checked = (_G.BumpState.gridSize == "3x2") },
|
||||
{ title = "-" },
|
||||
{ title = "Reload Bump Only", fn = function() package.loaded["bump"] = nil; require("bump") end },
|
||||
{ title = "Hard Reload All", fn = hs.reload }
|
||||
}
|
||||
end
|
||||
|
||||
menu:setTitle("⇄")
|
||||
menu:setMenu(updateMenu)
|
||||
|
||||
return bump
|
||||
Reference in New Issue
Block a user