HHTWM
Hackable Hammerspoon Tiling WM
HHTWM is a module for Hammerspoon providing automatic layout-based tiling for macOS.
It's configurable, hackable, and composes well with other Hammerspoon libraries.
Setup
- install required dependency -
hs._asm.undocumented.spaces - copy
hhtwm/folder to~/.hammerspoon/ - require the library in your
init.lua:
hhtwm = require('hhtwm') -- it's recommended to make `hhtwm` a global object so it's not garbage collected.
MVP
Smallest init.lua that tiles by default (with no keybindings and no margins):
hhtwm = require('hhtwm') hhtwm.start()
Configuration
All settings are optional.
hhtwm.margin-[number]- gap size between windows (in px)hhtwm.screenMargin-[object]({ top = 30, bottom = 5, left = 5, right = 5 }) - gap size from screen edgeshhtwm.defaultLayout-[string]- name of default layout to be appliedhhtwm.enabledLayouts-[array]- list of enabled layouts, all layouts are enabled by defaulthhtwm.displayLayouts-[object]({ [leftScreenId] = "equal-right" }) - per-screen default layoutshhtwm.filters-[object]- filters to force tiling on/off, example:hhtwm.filters = { { app = 'Finder', tile = false } -- don't tile Finder { app = 'Hammerspoon', title = 'Hammerspoon Console', tile = true } -- force tile Hammerspoon Console }
hhtwm.calcResizeStep-[function]- function to calculate resize step, example:hhtwm.calcResizeStep = function(screen) return 1 / hs.grid.getGrid(screen).w -- make the resize step be the same as hs.grid size for given screen end
API
Module related
hhtwm.start()- starts watching for window changes and tiles when neededhhtwm.stop()- stopshhtwmand stores current state inhs.settings,hhtwm.start()picks those settings up, so state can be persisted over reloadshhtwm.tile()- force tile, usually not neededhhtwm.reset()- resethhtwmstate, usually not needed
Window related
hhtwm.swapInDirection(win, dir)- swaps window in given direction if possible (direction:"west", "south", "north", "east")hhtwm.throwToScreen(win, dir)- throws window to another screen in given directionhhtwm.throwToScreenUsingSpaces(win, dir)- same as above but useshs._asm.undocumented.spacesapihhtwm.throwToSpace(win, spaceIndex)- throws window to space by given indexhhtwm.isFloating(win)- test if window is tiling/floating, returnstrue/falsehhtwm.toggleFloat(win)- toggles floating state of given window
Layout related
hhtwm.setLayout(layout)- sets layout for current spacehhtwm.getLayout()- gets layout for current space (returns layout name)hhtwm.getLayouts()- returns list of available layouts (eitherhhtwm.enabledLayoutsor all layouts fromhhtwm)hhtwm.resizeLayout(resizeOption)- resizes layout by given option, right now some layouts allowthinner/wideroptionshhtwm.equalizeLayout()- resets the layout resize (usually to 50/50)
Example config
You can check out my usage of hhtwm in my dotfiles repo, although it might be over-engineered in places.
