Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------------------------------------------------
- -- Unsupported Spaces extension. Uses private APIs but works okay.
- -- (http://github.com/asmagill/hammerspoon_asm.undocumented)
- spaces = require("hs._asm.undocumented.spaces")
- -- Get output of a bash command
- function os.capture(cmd)
- local f = assert(io.popen(cmd, 'r'))
- local s = assert(f:read('*a'))
- f:close()
- s = string.gsub(s, '^%s+', '')
- s = string.gsub(s, '%s+$', '')
- s = string.gsub(s, '[\n\r]+', ' ')
- return s
- end
- -- Update the fan and temp. Needs iStats CLI tool from homebrew.
- local function updateStats()
- fanSpeed = os.capture("iStats fan speed | cut -c14- | sed 's/\\..*//'")
- temp = os.capture("iStats cpu temp | cut -c11- | sed 's/\\..*//'")
- end
- -- Makes (and updates) the topbar menu filled with the current Space, the
- -- temperature and the fan speed. The Space only updates if the space is changed
- -- with the Hammerspoon shortcut (option + arrows does not work).
- local function makeStatsMenu(calledFromWhere)
- if statsMenu == nil then
- statsMenu = hs.menubar.new()
- end
- if calledFromWhere == "spaceChange" then
- currentSpace = tostring(spaces.currentSpace())
- else
- updateStats()
- end
- statsMenu:setTitle("Space " .. currentSpace .. " | Fan: " .. fanSpeed .. " | Temp: " .. temp)
- end
- -- Gets a list of windows and iterates until the window title is non-empty.
- -- This avoids focusing the hidden windows apparently placed on top of all
- -- Google Chrome windows. It also checks if the empty title belongs to Chrome,
- -- because some apps don't give any of their windows a title, and should still
- -- be focused.
- local function spaceChange()
- makeStatsMenu("spaceChange")
- visibleWindows = hs.window.orderedWindows()
- for i, window in ipairs(visibleWindows) do
- if window:application():title() == "Google Chrome" then
- if window:title() ~= "" then
- window:focus()
- break
- end
- else
- window:focus()
- break
- end
- end
- end
- --------------------------------------------------------------------------------
- -- Options
- -- How often to update Fan and Temp
- updateStatsInterval = 20
- statsMenuTimer = hs.timer.new(updateStatsInterval, makeStatsMenu)
- statsMenuTimer:start()
- -- instant window resizing
- hs.window.animationDuration = 0
- local mash = {"cmd", "alt", "ctrl"}
- local mashshift = {"cmd", "alt", "ctrl", "shift"}
- --------------------------------------------------------------------------------
- -- Applications launch
- local function newChromeWindow()
- os.execute("/Applications/'Google Chrome.app'/Contents/MacOS/'Google Chrome' --new-window")
- visibleWindows = hs.window.orderedWindows()
- visibleWindows[2]:focus()
- end
- hs.hotkey.bind(mash, "c", function()
- newChromeWindow()
- end)
- local function moveWindowToSpace()
- -- zoomXY = hs.window.focusedWindow():zoomButtonRect()
- -- zoomXY.x = zoomXY.x + 15
- -- zoomXY.y = zoomXY.y + 5
- -- hs.eventtap.event.newMouseEvent(hs.eventtap.event.types.leftmousedown, zoomXY):post()
- local mods = {["ctrl"] = true}
- changeSpaceOSX = hs.eventtap.event.newKeyEvent(mods, "2", true)
- -- spaces.moveToSpace("2")
- -- hs.eventtap.event.newMouseEvent(hs.eventtap.event.types.leftmouseup, zoomXY):post()
- end
- hs.hotkey.bind(mash, "v", function()
- hs.timer.doAfter(3, moveWindowToSpace):start()
- end)
- function reload_config(files)
- hs.reload()
- end
- hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reload_config):start()
- hs.alert.show("Config loaded")
- --------------------------------------------------------------------------------
- -- snap windows to edges
- -- (and make them half-width or half-height)
- hs.hotkey.bind(mash, "y", function()
- local win = hs.window.focusedWindow()
- local f = win:fullFrame()
- local screen = win:screen()
- local max = screen:fullFrame()
- f.x = max.x
- f.y = max.y
- f.w = max.w / 2
- f.h = max.h
- win:setFrame(f)
- end)
- hs.hotkey.bind(mash, "u", function()
- local win = hs.window.focusedWindow()
- local f = win:frame()
- local screen = win:screen()
- local max = screen:frame()
- f.x = max.x
- f.y = max.y + (max.h / 2)
- f.w = max.w
- f.h = max.h / 2
- win:setFrame(f)
- end)
- hs.hotkey.bind(mash, "i", function()
- local win = hs.window.focusedWindow()
- local f = win:frame()
- local screen = win:screen()
- local max = screen:frame()
- f.x = max.x
- f.y = max.y
- f.w = max.w
- f.h = max.h / 2
- win:setFrame(f)
- end)
- hs.hotkey.bind(mash, "o", function()
- local win = hs.window.focusedWindow()
- local f = win:frame()
- local screen = win:screen()
- local max = screen:frame()
- f.x = max.x + (max.w / 2)
- f.y = max.y
- f.w = max.w / 2
- f.h = max.h
- win:setFrame(f)
- end)
- --------------------------------------------------------------------------------
- -- Manual window moving and resizing
- -- Credit to GitHub user: ztomer
- hs.grid.MARGINX = 0
- hs.grid.MARGINY = 0
- hs.grid.GRIDHEIGHT = 18
- hs.grid.GRIDWIDTH = 18
- --Alter gridsize
- hs.hotkey.bind(mashshift, '=', function() hs.grid.adjustHeight( 1) end)
- hs.hotkey.bind(mashshift, '-', function() hs.grid.adjustHeight(-1) end)
- hs.hotkey.bind(mash, '=', function() hs.grid.adjustWidth( 1) end)
- hs.hotkey.bind(mash, '-', function() hs.grid.adjustWidth(-1) end)
- --Snap windows
- hs.hotkey.bind(mash, ';', function() hs.grid.snap(hs.window.focusedWindow()) end)
- hs.hotkey.bind(mash, "'", function() hs.fnutils.map(hs.window.visibleWindows(), hs.grid.snap) end)
- --Move windows
- hs.hotkey.bind(mash, 'j', hs.grid.pushWindowDown)
- hs.hotkey.bind(mash, 'k', hs.grid.pushWindowUp)
- hs.hotkey.bind(mash, 'h', hs.grid.pushWindowLeft)
- hs.hotkey.bind(mash, 'l', hs.grid.pushWindowRight)
- --resize windows
- hs.hotkey.bind(mashshift, 'k', hs.grid.resizeWindowShorter)
- hs.hotkey.bind(mashshift, 'j', hs.grid.resizeWindowTaller)
- hs.hotkey.bind(mashshift, 'l', hs.grid.resizeWindowWider)
- hs.hotkey.bind(mashshift, 'h', hs.grid.resizeWindowThinner)
- -- toggle window zoom (acts like Alt+Shift+GreenPlusButton)
- hs.hotkey.bind(mash, "m", function()
- local win = hs.window.focusedWindow()
- local frame = win:frame()
- local id = win:id()
- -- init table to save window state
- savedwin = savedwin or {}
- savedwin[id] = savedwin[id] or {}
- if (savedwin[id].maximized == nil or savedwin[id].maximized == false) then
- savedwin[id].frame = frame
- savedwin[id].maximized = true
- win:maximize()
- else
- savedwin[id].maximized = false
- win:setFrame(savedwin[id].frame)
- savedwin[id] = nil
- end
- end)
- --------------------------------------------------------------------------------
- -- switch Spaces
- hs.hotkey.bind(mash, '1', function()
- spaces.moveToSpace("1")
- spaceChange()
- end)
- hs.hotkey.bind(mash, '2', function()
- spaces.moveToSpace("2")
- spaceChange()
- end)
- hs.hotkey.bind(mash, '3', function()
- spaces.moveToSpace("3")
- spaceChange()
- end)
- hs.hotkey.bind(mash, '4', function()
- spaces.moveToSpace("4")
- spaceChange()
- end)
- hs.hotkey.bind(mash, '5', function()
- spaces.moveToSpace("5")
- spaceChange()
- end)
- hs.hotkey.bind(mash, '6', function()
- spaces.moveToSpace("6")
- spaceChange()
- end)
- --------------------------------------------------------------------------------
- -- Initialize
- currentSpace = tostring(spaces.currentSpace())
- updateStats()
- makeStatsMenu()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement