hs.hotkey.alertDuration = 0
hs.hints.showTitleThresh = 0
hs.window.animationDuration = 0
-- hyper
local hyper = {"cmd", "ctrl"}
-- Use the standardized config location, if present
-- custom_config = hs.fs.pathToAbsolute(os.getenv("HOME") .. '/.config/hammerspoon/private/config.lua')
-- if custom_config then
-- print("Loading custom config")
-- dofile( os.getenv("HOME") .. "/.config/hammerspoon/private/config.lua")
-- privatepath = hs.fs.pathToAbsolute(hs.configdir .. '/private/config.lua')
-- if privatepath then
-- hs.alert("You have config in both .config/hammerspoon and .hammerspoon/private.\nThe .config/hammerspoon one will be used.")
-- end
-- else
-- -- otherwise fallback to 'classic' location.
-- if not privatepath then
-- privatepath = hs.fs.pathToAbsolute(hs.configdir .. '/private')
-- -- Create `~/.hammerspoon/private` directory if not exists.
-- hs.fs.mkdir(hs.configdir .. '/private')
-- end
-- privateconf = hs.fs.pathToAbsolute(hs.configdir .. '/private/config.lua')
-- if privateconf then
-- -- Load awesomeconfig file if exists
-- require('private/config')
-- end
-- end
hsreload_keys = hsreload_keys or {{"cmd", "shift", "ctrl"}, "R"}
if string.len(hsreload_keys[2]) > 0 then
hs.hotkey.bind(hsreload_keys[1], hsreload_keys[2], "Reload Configuration", function() hs.reload() end)
end
-- ModalMgr Spoon must be loaded explicitly, because this repository heavily relies upon it.
hs.loadSpoon("ModalMgr")
-- Define default Spoons which will be loaded later
if not hspoon_list then
hspoon_list = {
-- "AClock",
-- "BingDaily",
-- "CircleClock",
--"ClipShow",
-- "CountDown",
--"HCalendar",
--"HSaria2",
--"HSearch",
--"SpeedMenu",
"WinWin",
-- "FnMate",
}
end
-- Load those Spoons
for _, v in pairs(hspoon_list) do
hs.loadSpoon(v)
end
-- Then we create/register all kinds of modal keybindings environments.
-- Register windowHints (Register a keybinding which is NOT modal environment with modal supervisor)
-- hswhints_keys = hswhints_keys or {"alt", "tab"}
-- if string.len(hswhints_keys[2]) > 0 then
-- spoon.ModalMgr.supervisor:bind(hswhints_keys[1], hswhints_keys[2], 'Show Window Hints', function()
-- spoon.ModalMgr:deactivateAll()
-- hs.hints.windowHints()
-- end)
-- end
-- appM modal environment
-- spoon.ModalMgr:new("appM")
-- local cmodal = spoon.ModalMgr.modal_list["appM"]
-- cmodal:bind('', 'escape', 'Deactivate appM', function() spoon.ModalMgr:deactivate({"appM"}) end)
-- cmodal:bind('', 'Q', 'Deactivate appM', function() spoon.ModalMgr:deactivate({"appM"}) end)
-- cmodal:bind('', 'tab', 'Toggle Cheatsheet', function() spoon.ModalMgr:toggleCheatsheet() end)
-- if not hsapp_list then
-- hsapp_list = {
-- {key = 'f', name = 'Finder'},
-- {key = 's', name = 'Safari'},
-- {key = 't', name = 'Terminal'},
-- {key = 'v', id = 'com.apple.ActivityMonitor'},
-- {key = 'y', id = 'com.apple.systempreferences'},
-- }
-- end
-- for _, v in ipairs(hsapp_list) do
-- if v.id then
-- local located_name = hs.application.nameForBundleID(v.id)
-- if located_name then
-- cmodal:bind('', v.key, located_name, function()
-- hs.application.launchOrFocusByBundleID(v.id)
-- spoon.ModalMgr:deactivate({"appM"})
-- end)
-- end
-- elseif v.name then
-- cmodal:bind('', v.key, v.name, function()
-- hs.application.launchOrFocus(v.name)
-- spoon.ModalMgr:deactivate({"appM"})
-- end)
-- end
-- end
-- resizeM modal environment
if spoon.WinWin then
spoon.ModalMgr:new("resizeM")
local cmodal = spoon.ModalMgr.modal_list["resizeM"]
cmodal:bind('', 'escape', 'Deactivate resizeM', function() spoon.ModalMgr:deactivate({"resizeM"}) end)
cmodal:bind('', 'Q', 'Deactivate resizeM', function() spoon.ModalMgr:deactivate({"resizeM"}) end)
cmodal:bind('', 'tab', 'Toggle Cheatsheet', function() spoon.ModalMgr:toggleCheatsheet() end)
cmodal:bind('', 'A', 'Move Leftward', function() spoon.WinWin:stepMove("left") end, nil, function() spoon.WinWin:stepMove("left") end)
cmodal:bind('', 'D', 'Move Rightward', function() spoon.WinWin:stepMove("right") end, nil, function() spoon.WinWin:stepMove("right") end)
cmodal:bind('', 'W', 'Move Upward', function() spoon.WinWin:stepMove("up") end, nil, function() spoon.WinWin:stepMove("up") end)
cmodal:bind('', 'S', 'Move Downward', function() spoon.WinWin:stepMove("down") end, nil, function() spoon.WinWin:stepMove("down") end)
cmodal:bind('', 'H', 'Lefthalf of Screen', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfleft") end)
cmodal:bind('', 'L', 'Righthalf of Screen', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfright") end)
cmodal:bind('', 'K', 'Uphalf of Screen', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfup") end)
cmodal:bind('', 'J', 'Downhalf of Screen', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfdown") end)
cmodal:bind('', 'Y', 'NorthWest Corner', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerNW") end)
cmodal:bind('', 'O', 'NorthEast Corner', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerNE") end)
cmodal:bind('', 'U', 'SouthWest Corner', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerSW") end)
cmodal:bind('', 'I', 'SouthEast Corner', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerSE") end)
cmodal:bind('', 'F', 'Fullscreen', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("fullscreen") end)
cmodal:bind('', 'C', 'Center Window', function() spoon.WinWin:stash() spoon.WinWin:moveAndResize("center") end)
cmodal:bind('', '=', 'Stretch Outward', function() spoon.WinWin:moveAndResize("expand") end, nil, function() spoon.WinWin:moveAndResize("expand") end)
cmodal:bind('', '-', 'Shrink Inward', function() spoon.WinWin:moveAndResize("shrink") end, nil, function() spoon.WinWin:moveAndResize("shrink") end)
cmodal:bind('shift', 'H', 'Move Leftward', function() spoon.WinWin:stepResize("left") end, nil, function() spoon.WinWin:stepResize("left") end)
cmodal:bind('shift', 'L', 'Move Rightward', function() spoon.WinWin:stepResize("right") end, nil, function() spoon.WinWin:stepResize("right") end)
cmodal:bind('shift', 'K', 'Move Upward', function() spoon.WinWin:stepResize("up") end, nil, function() spoon.WinWin:stepResize("up") end)
cmodal:bind('shift', 'J', 'Move Downward', function() spoon.WinWin:stepResize("down") end, nil, function() spoon.WinWin:stepResize("down") end)
cmodal:bind('', 'left', 'Move to Left Monitor', function() spoon.WinWin:stash() spoon.WinWin:moveToScreen("left") end)
cmodal:bind('', 'right', 'Move to Right Monitor', function() spoon.WinWin:stash() spoon.WinWin:moveToScreen("right") end)
cmodal:bind('', 'up', 'Move to Above Monitor', function() spoon.WinWin:stash() spoon.WinWin:moveToScreen("up") end)
cmodal:bind('', 'down', 'Move to Below Monitor', function() spoon.WinWin:stash() spoon.WinWin:moveToScreen("down") end)
cmodal:bind('', 'space', 'Move to Next Monitor', function() spoon.WinWin:stash() spoon.WinWin:moveToScreen("next") end)
cmodal:bind('', '[', 'Undo Window Manipulation', function() spoon.WinWin:undo() end)
cmodal:bind('', ']', 'Redo Window Manipulation', function() spoon.WinWin:redo() end)
cmodal:bind('', '`', 'Center Cursor', function() spoon.WinWin:centerCursor() end)
-- Register resizeM with modal supervisor
hsresizeM_keys = hsresizeM_keys or {"alt", "R"}
if string.len(hsresizeM_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hsresizeM_keys[1], hsresizeM_keys[2], "Enter resizeM Environment", function()
-- Deactivate some modal environments or not before activating a new one
spoon.ModalMgr:deactivateAll()
-- Show an status indicator so we know we're in some modal environment now
spoon.ModalMgr:activate({"resizeM"}, "#B22222")
end)
end
end
-- F
hFwhints_keys = {{"cmd", "shift"}, "F"}
if string.len(hFwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hFwhints_keys[1], hFwhints_keys[2], 'Show Window F', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("fullscreen")
end)
end
-- space
hSwhints_keys = {{"cmd", "shift"}, "space"}
if string.len(hSwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hSwhints_keys[1], hSwhints_keys[2], 'Show Window space', function()
spoon.WinWin:stash() spoon.WinWin:moveToScreen("next")
end)
end
-- H
hHwhints_keys = {{"cmd", "shift"}, "H"}
if string.len(hHwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hHwhints_keys[1], hHwhints_keys[2], 'Show Window H', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfleft")
end)
end
-- l
hLwhints_keys = {{"cmd", "shift"}, "L"}
if string.len(hLwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hLwhints_keys[1], hLwhints_keys[2], 'Show Window L', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfright")
end)
end
-- j
hJwhints_keys = {{"cmd", "shift"}, "J"}
if string.len(hJwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hJwhints_keys[1], hJwhints_keys[2], 'Show Window J', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfup")
end)
end
-- k
hKwhints_keys = {{"cmd", "shift"}, "K"}
if string.len(hKwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hKwhints_keys[1], hKwhints_keys[2], 'Show Window K', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("halfdown")
end)
end
-- y
hYwhints_keys = {{"cmd", "shift"}, "Y"}
if string.len(hYwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hYwhints_keys[1], hYwhints_keys[2], 'Show Window Y', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerNW")
end)
end
-- u
hUwhints_keys = {{"cmd", "shift"}, "U"}
if string.len(hUwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hUwhints_keys[1], hUwhints_keys[2], 'Show Window U', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerSW")
end)
end
-- i
HIwhints_keys = {{"cmd", "shift"}, "I"}
if string.len(HIwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(HIwhints_keys[1], HIwhints_keys[2], 'Show Window I', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerSE")
end)
end
-- o
hOwhints_keys = {{"cmd", "shift"}, "O"}
if string.len(hOwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hOwhints_keys[1], hOwhints_keys[2], 'Show Window O', function()
spoon.WinWin:stash() spoon.WinWin:moveAndResize("cornerNE")
end)
end
-- w
hWwhints_keys = {{"cmd", "shift"}, "up"}
if string.len(hWwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hWwhints_keys[1], hWwhints_keys[2], 'Show Window O', function()
spoon.WinWin:stepResize("up")
end)
end
-- a
hAwhints_keys = {{"cmd", "shift"}, "left"}
if string.len(hAwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hAwhints_keys[1], hAwhints_keys[2], 'Show Window O', function()
spoon.WinWin:stepResize("left")
end)
end
-- s
hSwhints_keys = {{"cmd", "shift"}, "down"}
if string.len(hSwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hSwhints_keys[1], hSwhints_keys[2], 'Show Window O', function()
spoon.WinWin:stepResize("down")
end)
end
-- d
hDwhints_keys = {{"cmd", "shift"}, "right"}
if string.len(hDwhints_keys[2]) > 0 then
spoon.ModalMgr.supervisor:bind(hDwhints_keys[1], hDwhints_keys[2], 'Show Window O', function()
spoon.WinWin:stepResize("right")
end)
end
-- cheatsheetM modal environment (Because KSheet Spoon is NOT loaded, cheatsheetM will NOT be activated)
-- Finally we initialize ModalMgr supervisor
spoon.ModalMgr.supervisor:enter()
local key2App = {
--a = '',
b = "Google Chrome", -- b for browser
-- c = "Messages", --vscode
-- d = "GoldenDict", -- d for dict
-- e = "Code", -- e for editor
f = "Finder",
g = "GitHub Desktop",
i = "IntelliJ IDEA",
-- j = "Spotify",
-- k = "",
-- l = 'Dictionary',
-- m = "Spotify", -- m for music
n = 'NxShell',
-- o used --max babe
-- p = "PDFGuru",
-- q = "QSpace",
-- r = 'Reminders',
-- s = 'System Preferences',
-- t = "iTerm2", -- t for term
-- u
v = 'Visual Studio Code-2',
-- w = 'TaskPaper',
-- x = 'Sublime Text',
-- y = 'Dictionary',
-- z = 'iTerm2'
t = 'iTerm2',
d = 'DBeaver'
}
for key, app in pairs(key2App) do
hs.hotkey.bind(
hyper,
key,
function()
--application.launchOrFocus(app)
toggle_application(app)
--hs.grid.set(hs.window.focusedWindow(), gomiddle)
end
)
end
-- Toggle application focus
function toggle_application(_app)
-- finds a running applications
local app = hs.application.find(_app)
if not app then
-- application not running, launch app
hs.application.launchOrFocus(_app)
return
end
-- application running, toggle hide/unhide
local mainwin = app:mainWindow()
if mainwin then
if true == app:isFrontmost() then
mainwin:application():hide()
else
mainwin:application():activate(true)
mainwin:application():unhide()
mainwin:focus()
end
else
-- no windows, maybe hide
if true == app:hide() then
-- focus app
application.launchOrFocus(_app)
else
-- nothing to do
end
end
end
local inputEnglish = false
-- 监听 esc 键按下事件
local function handleEscEvent(event)
-- 检查按键是否为 esc 键
if event:getKeyCode() == 53 then
-- 切换输入法
if not inputEnglish then
-- 如果当前不是英文输入法,则切换到英文输入法
hs.keycodes.currentSourceID("com.apple.keylayout.ABC")
inputEnglish = true
else
-- 如果当前是英文输入法,则切换到之前的输入法
hs.eventtap.keyStroke({}, 102, 0)
inputEnglish = false
end
end
end
-- 创建一个新的事件监听器
local escWatcher = hs.eventtap.new({hs.eventtap.event.types.keyDown}, handleEscEvent)
-- 启动事件监听器
escWatcher:start()