Merge branch 'master' of git.awful.club:jowj/chd
This commit is contained in:
commit
8cbcb369c0
128
.config/hammerspoon/init.lua
Normal file
128
.config/hammerspoon/init.lua
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
hammerSpoonEmoji = "🔨🥄"
|
||||||
|
|
||||||
|
hs.printf("======== config file reloaded ========")
|
||||||
|
hs.alert.show(hammerSpoonEmoji .. " Config Loaded")
|
||||||
|
|
||||||
|
animationDuration = 0
|
||||||
|
|
||||||
|
-- window sizing
|
||||||
|
hs.hotkey.bind({"cmd", "ctrl"}, "Left", 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 / 2
|
||||||
|
f.h = max.h
|
||||||
|
win:setFrame(f)
|
||||||
|
end)
|
||||||
|
|
||||||
|
hs.hotkey.bind({"cmd","ctrl"}, "Right", 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)
|
||||||
|
|
||||||
|
hs.hotkey.bind({"cmd", "ctrl"}, "f", function()
|
||||||
|
-- size focused window to size of desktop
|
||||||
|
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
|
||||||
|
win:setFrame(f)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
hs.hotkey.bind({"cmd", "ctrl"}, "up", function()
|
||||||
|
-- size focused window to top half of display
|
||||||
|
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({"cmd", "ctrl"}, "down", function()
|
||||||
|
-- size focused window to bottom half of display
|
||||||
|
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)
|
||||||
|
|
||||||
|
-- quick reload
|
||||||
|
hs.hotkey.bind({"cmd", "ctrl"}, "R", function()
|
||||||
|
hs.reload()
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- stolen from @mrled
|
||||||
|
appCuts = {
|
||||||
|
e = 'Emacs',
|
||||||
|
d = 'Dash',
|
||||||
|
h = 'Hammerspoon',
|
||||||
|
f = 'Firefox',
|
||||||
|
l = 'Slack',
|
||||||
|
o = 'Microsoft Outlook',
|
||||||
|
p = '1Password 7',
|
||||||
|
r = 'Riot',
|
||||||
|
s = 'Safari',
|
||||||
|
t = 'iTerm',
|
||||||
|
c = 'Google Chrome'
|
||||||
|
}
|
||||||
|
|
||||||
|
modalHotKey = dofile(os.getenv("HOME") .. "/.config/hammerspoon/modalHotKey.lua")
|
||||||
|
appActionTable = {}
|
||||||
|
for key, app in pairs(appCuts) do
|
||||||
|
appActionTable[key] = function() hs.application.launchOrFocus(app) end
|
||||||
|
end
|
||||||
|
appModal = modalHotKey.new(
|
||||||
|
hs.hotkey.modal.new({"cmd", "ctrl"}, "Space"),
|
||||||
|
appActionTable,
|
||||||
|
appCuts,
|
||||||
|
hammerSpoonEmoji .. "Awful App Switcher"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- stolen from stackoverflow, for moving between monitors.
|
||||||
|
-- Get the focused window, its window frame dimensions, its screen frame dimensions,
|
||||||
|
-- and the next screen's frame dimensions.
|
||||||
|
-- https://stackoverflow.com/questions/54151343/how-to-move-an-application-between-monitors-in-hammerspoon
|
||||||
|
hs.hotkey.bind({"cmd", "ctrl"}, "o", function()
|
||||||
|
local focusedWindow = hs.window.focusedWindow()
|
||||||
|
local focusedScreenFrame = focusedWindow:screen():frame()
|
||||||
|
local nextScreenFrame = focusedWindow:screen():next():frame()
|
||||||
|
local windowFrame = focusedWindow:frame()
|
||||||
|
|
||||||
|
-- Calculate the coordinates of the window frame in the next screen and retain aspect ratio
|
||||||
|
windowFrame.x = ((((windowFrame.x - focusedScreenFrame.x) / focusedScreenFrame.w) * nextScreenFrame.w) + nextScreenFrame.x)
|
||||||
|
windowFrame.y = ((((windowFrame.y - focusedScreenFrame.y) / focusedScreenFrame.h) * nextScreenFrame.h) + nextScreenFrame.y)
|
||||||
|
windowFrame.h = ((windowFrame.h / focusedScreenFrame.h) * nextScreenFrame.h)
|
||||||
|
windowFrame.w = ((windowFrame.w / focusedScreenFrame.w) * nextScreenFrame.w)
|
||||||
|
|
||||||
|
-- Set the focused window's new frame dimensions
|
||||||
|
focusedWindow:setFrame(windowFrame)
|
||||||
|
end)
|
148
.config/hammerspoon/modalHotKey.lua
Normal file
148
.config/hammerspoon/modalHotKey.lua
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
--[[ modalHotKey.lua
|
||||||
|
Adapted from https://github.com/asmagill/hammerspoon-config/blob/master/_scratch/modalSuppression.lua
|
||||||
|
see https://github.com/Hammerspoon/hammerspoon/issues/1505
|
||||||
|
save file somewhere then type `modalHotKey = dofile("modalHotKey.lua")` to load it
|
||||||
|
Here's an example based on my usage:
|
||||||
|
appCuts = {
|
||||||
|
e = 'Emacs',
|
||||||
|
f = 'Finder',
|
||||||
|
j = 'Cisco Jabber',
|
||||||
|
k = 'Keychain Access',
|
||||||
|
o = 'Microsoft Outlook',
|
||||||
|
s = 'Safari',
|
||||||
|
t = 'Terminal',
|
||||||
|
}
|
||||||
|
appActionTable = {}
|
||||||
|
for key, app in pairs(appCuts) do
|
||||||
|
appActionTable[key] = function() hs.application.launchOrFocus(app) end
|
||||||
|
end
|
||||||
|
modalHotKey = dofile("modalHotKey.lua")
|
||||||
|
appModal = modalHotKey.new(
|
||||||
|
hs.hotkey.modal.new({"cmd", "ctrl"}, "t"),
|
||||||
|
appActionTable,
|
||||||
|
appCuts,
|
||||||
|
"Special Application Switcher"
|
||||||
|
)
|
||||||
|
*only* the recognized key sequences will be allowed through -- this means you can't even quit hammerspoon with Cmd-Q
|
||||||
|
without tapping escape first.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
-- suppressKeysOtherThanOurs(): Create custom eventtap to suppress unwanted keys and pass through the ones we do want
|
||||||
|
-- modal: An object created from module.new() below (not just a modal hotkey from hs.hotkey.modal.new(); requires our extension methods)
|
||||||
|
local suppressKeysOtherThanOurs = function(modal)
|
||||||
|
local passThroughKeys = {}
|
||||||
|
|
||||||
|
-- this is annoying because the event's raw flag bitmasks differ from the bitmasks used by hotkey, so
|
||||||
|
-- we have to convert here for the lookup
|
||||||
|
|
||||||
|
for i,v in ipairs(modal.keys) do
|
||||||
|
-- parse for flags, get keycode for each
|
||||||
|
local kc, mods = tostring(v._hk):match("keycode: (%d+), mods: (0x[^ ]+)")
|
||||||
|
local hkFlags = tonumber(mods)
|
||||||
|
local hkOriginal = hkFlags
|
||||||
|
local flags = 0
|
||||||
|
if (hkFlags & 256) == 256 then hkFlags, flags = hkFlags - 256, flags | hs.eventtap.event.rawFlagMasks.command end
|
||||||
|
if (hkFlags & 512) == 512 then hkFlags, flags = hkFlags - 512, flags | hs.eventtap.event.rawFlagMasks.shift end
|
||||||
|
if (hkFlags & 2048) == 2048 then hkFlags, flags = hkFlags - 2048, flags | hs.eventtap.event.rawFlagMasks.alternate end
|
||||||
|
if (hkFlags & 4096) == 4096 then hkFlags, flags = hkFlags - 4096, flags | hs.eventtap.event.rawFlagMasks.control end
|
||||||
|
if hkFlags ~= 0 then print("unexpected flag pattern detected for " .. tostring(v._hk)) end
|
||||||
|
passThroughKeys[tonumber(kc)] = flags
|
||||||
|
end
|
||||||
|
|
||||||
|
return hs.eventtap.new({
|
||||||
|
hs.eventtap.event.types.keyDown,
|
||||||
|
hs.eventtap.event.types.keyUp,
|
||||||
|
}, function(event)
|
||||||
|
-- check only the flags we care about and filter the rest
|
||||||
|
local flags = event:getRawEventData().CGEventData.flags & (
|
||||||
|
hs.eventtap.event.rawFlagMasks.command |
|
||||||
|
hs.eventtap.event.rawFlagMasks.control |
|
||||||
|
hs.eventtap.event.rawFlagMasks.alternate |
|
||||||
|
hs.eventtap.event.rawFlagMasks.shift
|
||||||
|
)
|
||||||
|
if passThroughKeys[event:getKeyCode()] == flags then
|
||||||
|
hs.printf("passing: %3d 0x%08x", event:getKeyCode(), flags)
|
||||||
|
return false -- pass it through so hotkey can catch it
|
||||||
|
else
|
||||||
|
hs.printf("suppressing: %3d 0x%08x", event:getKeyCode(), flags)
|
||||||
|
modal:exitWithMessage("Invalid modal key " .. event:getKeyCode() .. " exiting mode")
|
||||||
|
return true -- delete it if we got this far -- it's a key that we want suppressed
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
|
||||||
|
-- new(): Create a new modal hotkey
|
||||||
|
-- triggerKey: A table created by invoking hs.hotkey.modal.new(), like hs.hotkey.modal.new({"cmd", "ctrl"}, "t")
|
||||||
|
-- actionTable: A table of {subKey = action} pairs
|
||||||
|
-- actionDescTable: A table of {subKey = description} pairs
|
||||||
|
-- modalMessagePrefix: A message prefix to display when communicating to the user about this hot key
|
||||||
|
module.new = function(triggerKey, actionTable, actionDescTable, modalMessagePrefix)
|
||||||
|
local modality = {}
|
||||||
|
modality.activeAlert = nil
|
||||||
|
modality.alertMessage = modalMessagePrefix .. "\n========\n"
|
||||||
|
|
||||||
|
-- Create a table of index->subKey mappings
|
||||||
|
-- This lets us alphabetize our hotkeys for display
|
||||||
|
alphaKeys = {}
|
||||||
|
for subKey, _ in pairs(actionDescTable) do
|
||||||
|
table.insert(alphaKeys, subKey)
|
||||||
|
end
|
||||||
|
table.sort(alphaKeys)
|
||||||
|
|
||||||
|
-- Show a menu of allowed subKey presses
|
||||||
|
doubleTab = " "
|
||||||
|
for idx, subKey in pairs(alphaKeys) do
|
||||||
|
desc = actionDescTable[subKey]
|
||||||
|
modality.alertMessage = modality.alertMessage .. "\n" .. subKey .. ":" .. doubleTab .. desc
|
||||||
|
end
|
||||||
|
|
||||||
|
triggerKey.exitWithMessage = function(self, message)
|
||||||
|
hs.alert(modalMessagePrefix .. "\n========\n" .. message)
|
||||||
|
self:exit()
|
||||||
|
end
|
||||||
|
|
||||||
|
triggerKey.entered = function(self)
|
||||||
|
self._eventtap = suppressKeysOtherThanOurs(self):start()
|
||||||
|
modality.activeAlert = hs.alert.show(modality.alertMessage, {}, hs.screen.mainScreen(), "forever")
|
||||||
|
end
|
||||||
|
|
||||||
|
triggerKey.exited = function(self)
|
||||||
|
self._eventtap:stop()
|
||||||
|
self._eventtap = nil
|
||||||
|
hs.alert.closeSpecific(modality.activeAlert)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- define an explicit way out
|
||||||
|
triggerKey:bind({}, "escape", function() triggerKey:exit() end)
|
||||||
|
|
||||||
|
for subKey, action in pairs(actionTable) do
|
||||||
|
triggerKey:bind({}, subKey, function()
|
||||||
|
action()
|
||||||
|
triggerKey:exit()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
modality.triggerKey = triggerKey
|
||||||
|
|
||||||
|
modality.start = function(self)
|
||||||
|
if self.triggerKey._eventtap then
|
||||||
|
self.triggerKey:enter()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
modality.stop = function(self)
|
||||||
|
if self.triggerKey._eventtap then
|
||||||
|
self.triggerKey:exit()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
modality.started = function(self)
|
||||||
|
return not not self.triggerKey._eventtap
|
||||||
|
end
|
||||||
|
|
||||||
|
return modality
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return module
|
7
.zshrc
7
.zshrc
@ -34,12 +34,7 @@ man() {
|
|||||||
man "$@"
|
man "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# history control variables
|
setopt appendhistory
|
||||||
export HISTCONTROL=ignoreboth
|
|
||||||
export HISTSIZE="INFINITE"
|
|
||||||
export HISTFILESIZE=5000
|
|
||||||
export HISTCONTROL="ignorespace"
|
|
||||||
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "
|
|
||||||
|
|
||||||
# make less more friendly for non-text input files, see lesspipe(1)
|
# make less more friendly for non-text input files, see lesspipe(1)
|
||||||
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
|
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
|
||||||
|
Loading…
Reference in New Issue
Block a user