Skip to content

Instantly share code, notes, and snippets.

@tvhung83
Created October 14, 2019 08:29
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 tvhung83/b4a9c5f17f5ad4eea660c2a33f4530bc to your computer and use it in GitHub Desktop.
Save tvhung83/b4a9c5f17f5ad4eea660c2a33f4530bc to your computer and use it in GitHub Desktop.
-- Mike Solomon @msol 2019
local log = hs.logger.new('main', 'info')
DEVELOPING_THIS = false -- set to true to ease debugging
HYPER = {'ctrl', 'shift', 'alt', 'cmd'}
-- App bindings
function setUpAppBindings()
-- hyperFocusAll('w', 'React Native Debugger', 'Simulator', 'qemu-system-x86_64')
hyperFocusOrOpen('e', 'Notes')
hyperFocusOrOpen('i', 'IntelliJ IDEA', 'IntelliJ IDEA-EAP', 'Xcode', 'Android Studio', 'Atom', 'Code')
hyperFocusOrOpen('a', 'Finder')
hyperFocusOrOpen('c', 'Calendar')
hyperFocusOrOpen('m', 'Mail')
hyperFocusOrOpen('r', 'Slack')
hyperFocusOrOpen('t', 'Safari')
hyperFocusOrOpen(';', 'iTerm2')
hyperFocusOrOpen('s', 'Skype')
hyperFocusOrOpen('g', 'Google Chrome', 'Firefox')
hyperFocusOrOpen('space', 'Sublime Text')
end
-- Window management
function setUpWindowManagement()
hs.window.animationDuration = 0 -- disable animations
hs.grid.setMargins({0, 0})
hs.grid.setGrid('2x2')
function mkSetFocus(to)
return function() hs.grid.set(hs.window.focusedWindow(), to) end
end
local fullScreen = hs.geometry("0,0 2x2")
local leftHalf = hs.geometry("0,0 1x2")
local rightHalf = hs.geometry("1,0 1x2")
local topHalf = hs.geometry("0,0 2x1")
local bottomHalf = hs.geometry("0,1 2x1")
local upperLeft = hs.geometry("0,0 1x1")
local lowerLeft = hs.geometry("0,1 1x1")
local upperRight = hs.geometry("1,0 1x1")
local lowerRight = hs.geometry("1,1 1x1")
-- hs.hotkey.bind(HYPER, 'f', mkSetFocus(fullScreen))
-- hs.hotkey.bind(HYPER, 'h', mkSetFocus(leftHalf))
-- hs.hotkey.bind(HYPER, "l", mkSetFocus(rightHalf))
-- hs.hotkey.bind(HYPER, 'j', mkSetFocus(upHalf))
-- hs.hotkey.bind(HYPER, "k", mkSetFocus(bottomHalf))
-- hs.hotkey.bind(HYPER, "y", mkSetFocus(upperLeft))
-- hs.hotkey.bind(HYPER, "b", mkSetFocus(lowerLeft))
-- hs.hotkey.bind(HYPER, "u", mkSetFocus(upperRight))
-- hs.hotkey.bind(HYPER, "n", mkSetFocus(lowerRight))
hs.hotkey.bind(HYPER, "return", mkSetFocus(fullScreen))
hs.hotkey.bind(HYPER, "up", mkSetFocus(topHalf))
hs.hotkey.bind(HYPER, "down", mkSetFocus(bottomHalf))
hs.hotkey.bind(HYPER, "left", mkSetFocus(leftHalf))
hs.hotkey.bind(HYPER, "right", mkSetFocus(rightHalf))
-- hs.hotkey.bind(HYPER, "v", hs.window.filter.focusNorth)
-- hs.hotkey.bind(HYPER, "c", hs.window.filter.focusSouth)
-- hs.hotkey.bind(HYPER, "j", hs.window.filter.focusWest)
-- hs.hotkey.bind(HYPER, "p", hs.window.filter.focusEast)
hs.hotkey.bind(HYPER, "q", hs.hints.windowHints)
-- HYPER "d" -- Bound in Karabiner to Cmd+Tab (application switcher)
-- HYPER "k" -- Bound in Karabiner to Cmd+` (next window of application)
-- throw to other screen
hs.hotkey.bind(HYPER, 'o', function()
local window = hs.window.focusedWindow()
window:moveToScreen(window:screen():next())
end)
end
-- focus on the last-focused window of the application given by name, or else launch it
function hyperFocusOrOpen(key, app)
local focus = mkFocusByPreferredApplicationTitle(true, app)
function focusOrOpen()
return (focus() or hs.application.launchOrFocus(app))
end
hs.hotkey.bind(HYPER, key, focusOrOpen)
end
-- focus on the last-focused window of the first application given by name
function hyperFocus(key, ...)
hs.hotkey.bind(HYPER, key, mkFocusByPreferredApplicationTitle(true, ...))
end
-- focus on the last-focused window of every application given by name
function hyperFocusAll(key, ...)
hs.hotkey.bind(HYPER, key, mkFocusByPreferredApplicationTitle(false, ...))
end
-- creates callback function to select application windows by application name
function mkFocusByPreferredApplicationTitle(stopOnFirst, ...)
local arguments = {...} -- create table to close over variadic args
return function()
local nowFocused = hs.window.focusedWindow()
local appFound = false
for _, app in ipairs(arguments) do
if stopOnFirst and appFound then break end
log:d('Searching for app ', app)
local application = hs.application.get(app)
if application ~= nil then
log:d('Found app', application)
local window = application:mainWindow()
if window ~= nil then
log:d('Found main window', window)
if window == nowFocused then
log:d('Already focused, moving on', application)
else
window:focus()
appFound = true
end
end
end
end
return appFound
end
end
function maybeEnableDebug()
if DEVELOPING_THIS then
log.setLogLevel('debug')
log.d('Loading in development mode')
-- automatically reload changes when we're developing
hs.pathwatcher.new(os.getenv('HOME') .. '/.hammerspoon/', hs.reload):start()
hs.alert('Hammerspoon config reloaded')
log:d('Hammerspoon config reloaded')
end
end
function setUpClipboardTool()
ClipboardTool = hs.loadSpoon('ClipboardTool')
ClipboardTool.show_in_menubar = false
ClipboardTool:start()
ClipboardTool:bindHotkeys({
toggle_clipboard = {HYPER, "p"}
})
end
function setUpCaffeine()
Caffeine = hs.loadSpoon('Caffeine')
Caffeine:bindHotkeys({
toggle = {HYPER, 'z'}
})
end
-- Main
maybeEnableDebug()
setUpAppBindings()
setUpWindowManagement()
-- setUpClipboardTool()
setUpCaffeine()
hs.loadSpoon("ReloadConfiguration")
spoon.ReloadConfiguration:start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment