Skip to content

Instantly share code, notes, and snippets.

@joshvasquez
Last active October 17, 2022 00:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshvasquez/48d4e5b11435a9eb5e1599bf97507139 to your computer and use it in GitHub Desktop.
Save joshvasquez/48d4e5b11435a9eb5e1599bf97507139 to your computer and use it in GitHub Desktop.
Simple Hammerspoon Configuration
-- for simpler binding of keys, define the modifiers ahead of time.
local hyper = {"cmd","alt","ctrl","shift"}
local meh = {"alt","ctrl","shift"}
-- grid size determines how the windows can be split into a grid
-- laid out evenly onto the desktop
-- grid margins defines spacing on x and y between windows and the menu
-- bar/monitor edges 0x0 if you want no space between windows.
-- for the case where you only ever need to move a window between three
-- equally sized windows, '3x1' is sufficient grid size.
gridSize = '3x1'
gridMargins = '10x10'
-- set the dimensions. If you need to cover two different
-- grid sizes you'll have to set them locally inside the
-- window management functions
hs.grid.setGrid(gridSize)
hs.grid.setMargins(gridMargins)
-- setting it to false, although this is false by default. It will
-- prevent window wiggling before setting into place which is
-- annoying
hs.window.setFrameCorrectness =false
-- function to move the active window to designated coordinates
-- based on the defined grid
function setWindow(w,h,x,y)
if hs.window.focusedWindow() then
local win = hs.window.frontmostWindow()
local id = win:id()
local screen = win:screen()
cell = hs.grid.get(win, screen)
cell.w = w
cell.h = h
cell.x = x
cell.y = y
hs.grid.set(win, cell, screen)
end
end
--
hs.hotkey.bind(meh, "j", function()
-- assuming you only use one gridSize, setting them specifically for
-- each function is unnecessary. If you do want to use more, you can
-- define it like this
hs.grid.setGrid('3x1')
-- setWindow function takes four arguments, w, h, x, and y. w represents
-- width of the window according to the defined grid. In 3x1 '1' will take
-- up 1/3 of the width of the screen. h represents height and since the grid
-- is 1 high, 1 will take up 100% of the vertical space. x is the horizontal
-- axis and y the vertical axis. All movement is assuming you start from top
-- left. 0,0 would indicate it does not move at all from top left, so it will
-- take up the left most section of the screen. the next two will take up the
-- second and third section of the screen. In cases with larger grids, you'd
-- change the numbers to match the translation you want relative to the new
-- grid size
setWindow(1,1,0,0)
hs.grid.setGrid(gridSize)
end)
hs.hotkey.bind(meh, "k", function()
hs.grid.setGrid('3x1')
setWindow(1,1,1,0)
hs.grid.setGrid(gridSize)
end)
hs.hotkey.bind(meh, "l", function()
hs.grid.setGrid('3x1')
setWindow(1,1,2,0)
hs.grid.setGrid(gridSize)
end)
-- directional movement of focus between windows
-- I use hyper hjkl to move between windows relative to their
-- position on screen. Note that this is buggy and there are
-- cases where it won't find any eligble windows or a window
-- will stop being eligible. I wouldn't use this to replace
-- other cmd - tab alternatives you may have
hs.hotkey.bind(hyper, "h", function()
-- this will focus the next eligble window to the west of the active window.
hs.window.focusedWindow().focusWindowWest()
-- this will show an alert of the new window you focus.
-- This is entirely optional and you can delete this if
-- you don't like it
hs.alert(hs.window.focusedWindow():title())
end)
hs.hotkey.bind(hyper, "j", function()
hs.window.focusedWindow().focusWindowSouth()
hs.alert(hs.window.focusedWindow():title())
end)
hs.hotkey.bind(hyper, "k", function()
hs.window.focusedWindow().focusWindowNorth()
hs.alert(hs.window.focusedWindow():title())
end)
hs.hotkey.bind(hyper, "l", function()
hs.window.focusedWindow().focusWindowEast()
hs.alert(hs.window.focusedWindow():title())
end)
-- window swap alternative to command tab
-- this creates a list of open applications that you
-- can fuzzy search type to swap between applications
-- This emulates functionality of something like rofi
-- on linux or contexts (https://contexts.co/) on MacOS
hs.hotkey.bind(hyper, 'space', function()
local switcher = hs.chooser.new(function(choice)
if not choice then return end
hs.application.launchOrFocusByBundleID(choice.id)
end)
local windows = hs.fnutils.map(hs.window.filter.new():getWindows(), function(win)
if win ~= hs.window.focusedWindow() then
return {
text = win:title(),
subText = win:application():title(),
image = hs.image.imageFromAppBundle(win:application():bundleID()),
id = win:application():bundleID()
}
end
end)
switcher
:query(nil)
:placeholderText('Switch to...')
:width(22)
:searchSubText(true)
:choices(windows)
:show()
end)
@joshvasquez
Copy link
Author

I'd suggest looking at the hammerspoon docs if you need more information on what is going on in any fo the api functions used here.

https://www.hammerspoon.org/docs/index.html

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