Last active
December 20, 2021 14:20
-
-
Save luosky/61b2d14e6ce5148489a93e38dbb4a3ef to your computer and use it in GitHub Desktop.
Hammerspoon config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local alert = require("hs.alert") -- http://www.hammerspoon.org/docs/hs.alert.html | |
local pasteboard = require("hs.pasteboard") -- http://www.hammerspoon.org/docs/hs.pasteboard.html | |
local settings = require("hs.settings") -- http://www.hammerspoon.org/docs/hs.settings.html | |
-- http://www.hammerspoon.org/docs/hs.chooser.html | |
------------------------ | |
-- default config | |
------------------------ | |
-- screen name can use hs.screen.allScreens()[1]:name() to see | |
local laptop = "Color LCD" | |
local mainDesktop = "DELL U2412M" | |
local vDesktop = "DELL U2312HM" | |
local hyper = {'cmd','alt','shift','ctrl'} | |
hs.grid.setGrid('4x4','1920x1200') | |
hs.window.animationDuration = 0 | |
-- hs.alert(hs.screen.allScreens()[3]) | |
--------------------------- | |
-- reload config | |
--------------------------- | |
-- ofun = function() | |
-- hs.reload() | |
-- hs.alert.show("Config loaded") | |
-- k.triggered = true | |
-- end | |
-- k:bind({}, '/', nil, ofun) | |
function reloadConfig(files) | |
doReload = false | |
for _,file in pairs(files) do | |
if file:sub(-4) == ".lua" then | |
doReload = true | |
end | |
end | |
if doReload then | |
hs.reload() | |
end | |
end | |
local myWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/.hammerspoon/", reloadConfig):start() | |
hs.alert.show("HammperSpoon Config loaded") | |
-- hs.notify.new({ | |
-- title='Hammerspoon', | |
-- informativeText='Config loaded' | |
-- }):send() | |
---------------- | |
-- Screen Layout | |
---------------- | |
function autoLayout() | |
local screens = hs.screen.allScreens() | |
local count = countArray(screens) | |
-- hs.alert(count) | |
if count == 1 then | |
oneScreenLayout() | |
elseif count == 2 then | |
twoScreenLayout() | |
elseif count == 3 then | |
threeScreenLayout() | |
end | |
end | |
function countArray(array) | |
count = 0 | |
for k,v in pairs(array) do | |
count = count + 1 | |
end | |
return count | |
end | |
local max = hs.layout.maximized | |
local left75 = hs.layout.left75 | |
local left60 = {0,0,0.6,1} | |
local right40 = {0.6,0,0.4,1} | |
local right25 = hs.layout.right25 | |
local top50 = {0,0,1,0.5} | |
local bottom50 = {0,0.5,1,0.5} | |
function oneScreenLayout() | |
-- local app = hs.application.get("Reeder") | |
-- app:selectMenuItem({"View", "Switch to Classic Layout"}) | |
local windowLayout = { | |
-- max | |
{"Cocos Creator", nil, laptop, hs.layout.maximized, nil, nil}, | |
{"iTunes", "iTunes", laptop, hs.layout.maximized, nil, nil}, | |
{"iTunes", "MiniPlayer", laptop, nil, nil, hs.geometry.rect(0, -48, 400, 48)}, | |
-- left 75 | |
{"Google Chrome", nil, laptop, hs.layout.left75, nil, nil}, | |
{"WorkFlowy", nil, laptop, right25, nil, nil}, | |
{"Safari", nil, laptop, hs.layout.left75, nil, nil}, | |
{"Sublime Text", nil, laptop, hs.layout.left75, nil, nil}, | |
-- left 50 | |
{"Reeder", nil, laptop, hs.layout.left50, nil, nil}, | |
-- right 40 | |
{"WeChat", nil, laptop, right40, nil, nil}, | |
{"QQ", nil, laptop, right40, nil, nil}, | |
} | |
hs.layout.apply(windowLayout) | |
hs.alert.show("One Scrren Layout") | |
end | |
function twoScreenLayout() | |
local app = hs.application.get("Reeder") | |
if app ~= nil then | |
app:selectMenuItem({"View", "Switch to Minimized Layout"}) | |
end | |
local windowLayout = { | |
-- {"Cocos Creator", "Cocos Creator", mainDesktop, hs.layout.maximized, nil, nil}, -- 不起作用? | |
{"Xcode", nil, mainDesktop, hs.layout.maximized, nil, nil}, | |
{"Google Chrome", nil, mainDesktop, hs.layout.left75, nil, nil}, | |
{"Safari", nil, laptop, hs.layout.left75, nil, nil}, | |
{"iTunes", "iTunes", laptop, hs.layout.maximized, nil, nil}, | |
{"iTunes", "MiniPlayer", laptop, nil, nil, hs.geometry.rect(0, -48, 400, 48)}, | |
{"Reeder", nil, laptop, hs.layout.left50, nil, nil}, | |
{"WeChat", nil, laptop, hs.layout.right50, nil, nil}, | |
} | |
function winTitleComparater(winTitle, layoutWinTitle) | |
-- if layoutWinTitle == "Cocos Creator" then | |
-- hs.alert(winTitle) | |
-- hs.alert(layoutWinTitle) | |
-- -- return true | |
-- end | |
return winTitle == layoutWinTitle | |
end | |
hs.layout.apply(windowLayout,winTitleComparater) | |
hs.alert.show("Two Scrren Layout") | |
end | |
function threeScreenLayout() | |
local app = hs.application.get("Reeder") | |
if app ~= nil then | |
app:selectMenuItem({"View", "Switch to Minimized Layout"}) | |
end | |
local windowLayout = { | |
-- Main Desktop | |
-- {"Cocos Creator", nil, mainDesktop, hs.layout.maximized, nil, nil}, -- 不起作用? | |
{"Xcode", nil, mainDesktop, hs.layout.maximized, nil, nil}, | |
{"Code", nil, mainDesktop, hs.layout.maximized, nil, nil}, | |
{"Google Chrome", nil, mainDesktop, left75, nil, nil}, | |
{"WorkFlowy", nil, mainDesktop, right25, nil, nil}, | |
{"Sublime Text", nil, mainDesktop, hs.layout.left75, nil, nil}, | |
-- Laptop | |
-- max | |
{"Spark", nil, laptop, hs.layout.maximized, nil, nil}, | |
{"iTunes", "iTunes", laptop, hs.layout.maximized, nil, nil}, | |
{"iTunes", "MiniPlayer", laptop, nil, nil, hs.geometry.rect(0, -48, 400, 48)}, | |
-- left | |
{"Day One", nil, laptop, right50, nil, nil}, | |
--right | |
{"Reeder", nil, laptop, hs.layout.right50, nil, nil}, | |
-- V Desktop | |
-- top | |
{"Safari", nil, vDesktop, top50, nil, nil}, | |
{"QQ", nil, vDesktop, top50, nil, nil}, | |
--bottom | |
{"WeChat", nil, vDesktop, bottom50, nil, nil}, | |
{"Simulator", nil, vDesktop, {0.25,0.5,0.25,0.5}, nil, nil}, | |
} | |
function winTitleComparater(winTitle, layoutWinTitle) | |
-- if layoutWinTitle == "Cocos Creator" then | |
-- hs.alert(winTitle) | |
-- hs.alert(layoutWinTitle) | |
-- -- return true | |
-- end | |
return winTitle == layoutWinTitle | |
end | |
hs.layout.apply(windowLayout,winTitleComparater) | |
hs.alert.show("Three Scrren Layout") | |
end | |
--------------------------- | |
-- Layout config | |
--------------------------- | |
-- hs.logger:d(hs.screen.allScreens()) | |
-- hs.alert.show(hs.screen.allScreens()[1]) | |
autoLayout() | |
--------------------------- | |
-- Launcher config | |
--------------------------- | |
function focusApp(appName) | |
local isDebug = false | |
-- local result = hs.application.launchOrFocus(appName) | |
-- hs.alert(result) | |
local app = hs.application.find(appName) | |
if isDebug then | |
alert(app) | |
end | |
-- app.activate() | |
if app == nil then | |
if isDebug then | |
alert("nil app") | |
end | |
hs.application.launchOrFocus(string.gsub(appName,"%s+", "")) -- 不能有空格。。。 | |
return | |
end | |
local mainWin = app:mainWindow() | |
if mainWin == nil then | |
-- alert(appName) | |
mainWin = hs.window.find(appName) | |
-- alert(mainWin) | |
end | |
-- local wins = app:allWindows() | |
-- local wins = hs.appfinder.appFromName(appName):allWindows() | |
-- hs.alert(wins) | |
-- app:activate() | |
mainWin:focus() | |
-- hs.fnutils.each(wins, function(win) | |
-- hs.alert("each") | |
-- hs.alert(win) | |
-- hs.alert(win:size()) | |
-- -- win:focus() | |
-- -- hs.logger:i(win:title()) | |
-- end) | |
-- for i, win in ipairs(wins) do | |
-- hs.alert(win:title()) | |
-- -- hs.logger.d(win:title()) | |
-- end | |
end | |
-- expose_app = hs.expose.new('Safari','Google Chrome') -- only windows in the current Mission Control Space | |
-- hs.hotkey.bind('ctrl-cmd-shift','e','App Expose',function()expose_app:toggleShow()end) | |
function setupCaffeine() | |
local caffeine = hs.menubar.new() | |
function setCaffeineDisplay(state) | |
if state then | |
caffeine:setTitle("AWAKE") | |
else | |
caffeine:setTitle("SLEEPY") | |
end | |
end | |
function caffeineClicked() | |
local state = hs.caffeinate.toggle("displayIdle") | |
setCaffeineDisplay(state) | |
end | |
if caffeine then | |
caffeine:setClickCallback(caffeineClicked) | |
setCaffeineDisplay(hs.caffeinate.get("displayIdle")) | |
end | |
end | |
setupCaffeine() | |
--[[ | |
----------------------------- | |
-- Hyper Settings | |
----------------------------- | |
-- A global variable for the Hyper Mode | |
k = hs.hotkey.modal.new({}, "F17") | |
-- function k:entered() | |
-- hs.alert("Enter Hyper Mode") | |
-- end | |
-- function k:exited() | |
-- hs.alert("Exit Hyper Mode") | |
-- end | |
-- Enter Hyper Mode when F18 (Hyper/Capslock) is pressed | |
pressedF18 = function() | |
k.triggered = false | |
k:enter() | |
-- if hs.eventtap.checkKeyboardModifiers().cmd then | |
-- -- k.exit() | |
-- -- k.triggered = true | |
-- else | |
-- end | |
end | |
-- Leave Hyper Mode when F18 (Hyper/Capslock) is pressed, | |
-- send ESCAPE if no other keys are pressed. | |
releasedF18 = function() | |
if not k.triggered then | |
-- if hs.eventtap.checkKeyboardModifiers()["cmd"] then | |
-- hs.eventtap.keyStroke({'cmd'} , 'Tab') | |
-- else | |
hs.eventtap.keyStroke({} , 'Tab') | |
-- end | |
end | |
k:exit() | |
end | |
-- Bind the Hyper key | |
f18 = hs.hotkey.bind({}, 'F18', pressedF18, releasedF18) | |
-- Trigger existing hyper key shortcuts | |
hyperBindings = {'a','b','c','d','e','f','g','i','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','SPACE','h','j','k','l'} | |
for i,key in ipairs(hyperBindings) do | |
k:bind({}, key, nil, function() hs.eventtap.keyStroke(hyper, key) | |
k.triggered = true | |
end) | |
end | |
-- Alt + Tab | |
-- t = hs.hotkey.modal.new({'cmd'},"f18") | |
-- t.bind({},'F18',nil, function() t.eventtap.keyStroke({'cmd'},'Tab') end) | |
hs.hotkey.bind({'cmd'}, 'F18', function() hs.eventtap.keyStroke({'cmd'},"Tab");k:exit(); end) | |
-- hs.hotkey.bind({'cmd'}, 'ESCAPE', function() hs.eventtap.keyStroke({'cmd'},"Tab");k:exit(); end) | |
-- tb = hs.hotkey.modal.new({'cmd'}, "ESCAPE") | |
-- function tb:entered() hs.alert'Entered mode'; hs.eventtap.keyStroke({'cmd'},"Tab"); end | |
-- function tb:exited() hs.alert'Exited mode' end | |
-- tb:bind('', 'ESCAPE', function() tb:exit() end) | |
-- tb:bind('', 'J', 'Pressed J',function() print'let the record show that J was pressed' end) | |
-- tb:bind('', 'h', function() hs.eventtap.keyStroke({},"left") end) | |
-- tb:bind('', 'l', function() hs.eventtap.keyStroke({},"right") end) | |
-- tb:bind('cmd', 'ESCAPE', function() hs.eventtap.keyStroke({'cmd'},"Tab") end) | |
-- k:bind({}, 'w', nil, function() hs.eventtap.keyStroke({"cmd","alt","shift","ctrl"}, 'w') end) | |
-- k:bind({}, 'cmd', nil, function() hs.eventtap.keyStroke('cmd', 'tab') end) | |
-- OR build your own | |
-- launch = function(appname) | |
-- hs.application.launchOrFocus(appname) | |
-- k.triggered = true | |
-- end | |
-- Single keybinding for app launch | |
-- singleapps = { | |
-- {'q', 'Newton'}, | |
-- -- {'w', 'Google Chrome'}, | |
-- {'e', 'Sublime Text'}, | |
-- -- {'r', 'Google Chrome'} | |
-- } | |
-- for i, app in ipairs(singleapps) do | |
-- k:bind({}, app[1], function() launch(app[2]); k:exit(); end) | |
-- end | |
-- Sequential keybindings, e.g. Hyper-a,f for Finder | |
-- a = hs.hotkey.modal.new({}, "F16") | |
-- apps = { | |
-- {'d', 'Twitter'}, | |
-- {'f', 'Finder'}, | |
-- {'s', 'Skype'}, | |
-- } | |
-- for i, app in ipairs(apps) do | |
-- a:bind({}, app[1], function() launch(app[2]); a:exit(); end) | |
-- end | |
-- HYPER+L: Open news.google.com in the default browser | |
-- lfun = function() | |
-- news = "app = Application.currentApplication(); app.includeStandardAdditions = true; app.doShellScript('open http://news.google.com')" | |
-- hs.osascript.javascript(news) | |
-- k.triggered = true | |
-- end | |
-- k:bind('', 'l', nil, lfun) | |
------------------- | |
-- Launcher Mode -- | |
------------------- | |
-- | |
-- This feature assumes you have instructed Karabiner-Elements to map right_command to f19: | |
-- { | |
-- "profiles": [ | |
-- { | |
-- "name": "Default profile", | |
-- "selected": true, | |
-- "simple_modifications": { | |
-- "right_command": "f19" | |
-- } | |
-- } | |
-- ] | |
-- } | |
-- | |
-- local launcherModeKeyCode = hs.keycodes.map["f19"] | |
-- local launcherModeBindings = { | |
-- x = "Xcode", | |
-- r = "Simulator", | |
-- s = "Slack", | |
-- e = "Sublime Text", | |
-- z = "Zeplin", | |
-- m = "Mail", | |
-- c = "Chrome", | |
-- t = "Terminal", | |
-- a = "Activity Monitor", | |
-- i = "iTunes", | |
-- w = "Google Chrome", | |
-- } | |
-- local arrowKeysTable = { | |
-- h = "left", | |
-- j = "down", | |
-- k = "up", | |
-- l = "right" | |
-- } | |
-- local inLauncherMode = false | |
-- f19down = hs.eventtap.new({ hs.eventtap.event.types.keyDown }, function(event) | |
-- local keyCode = event:getKeyCode() | |
-- local characters = event:getCharacters() | |
-- local isRepeat = event:getProperty(hs.eventtap.event.properties.keyboardEventAutorepeat) | |
-- if keyCode == launcherModeKeyCode and isRepeat == 0 then | |
-- inLauncherMode = true | |
-- end | |
-- if inLauncherMode then | |
-- return true | |
-- end | |
-- end) | |
-- f19down:start() | |
-- rcmd_tap = hs.eventtap.new({ hs.eventtap.event.types.keyUp }, function(event) | |
-- local keyCode = event:getKeyCode() | |
-- local characters = event:getCharacters() | |
-- if keyCode == launcherModeKeyCode then | |
-- inLauncherMode = false | |
-- end | |
-- local appToLaunch = nil | |
-- local arrowKeyToSend = nil | |
-- if inLauncherMode then | |
-- arrowKeyToSend = arrowKeysTable[characters] | |
-- appToLaunch = launcherModeBindings[characters] | |
-- if arrowKeyToSend ~= nil then | |
-- -- hs.alert(arrowKeyToSend) | |
-- modifiers = {} | |
-- -- if hs.eventtap.checkKeyboardModifiers().cmd then w | |
-- -- table.insert(modifiers,'cmd') | |
-- -- end | |
-- -- hs.alert(modifiers) | |
-- hs.eventtap.keyStroke({}, "left") | |
-- -- return trueww | |
-- elseif appToLaunch ~= nil then | |
-- hs.application.launchOrFocus(appToLaunch) | |
-- hs.alert(appToLaunch) | |
-- end | |
-- end | |
-- -- return appToLaunch ~= nil | |
-- return true | |
-- end) | |
-- rcmd_tap:start() | |
-- flagsChange = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, function(event) | |
-- local keyCode = event:getKeyCode() | |
-- local characters = event:getCharacters() | |
-- local isRepeat = event:getProperty(hs.eventtap.event.properties.keyboardEventAutorepeat) | |
-- hs.alert(keyCode) | |
-- end) | |
-- flagsChange:start() | |
]] | |
--------------------------- | |
-- 将所有 Finder 窗口一起显示 | |
--------------------------- | |
function applicationWatcher(appName, eventType, appObject) | |
if (eventType == hs.application.watcher.activated) then | |
if (appName == "Finder") then | |
appObject:selectMenuItem({"Window", "Bring All to Front"}) | |
end | |
end | |
end | |
local appWatcher = hs.application.watcher.new(applicationWatcher) | |
appWatcher:start() | |
--[[ | |
--------------------------- | |
-- 连上 usb 后自动打开 timemachine | |
--------------------------- | |
local usbWatcher = nil | |
function usbDeviceCallback(data) | |
if (data["productName"] == "") then | |
if (data["eventType"] == "added") then | |
-- hs.application.launchOrFocus("Time Machine") | |
hs.osascript.applescript("/usr/bin/tmutil startbackup --auto --block") | |
end | |
end | |
end | |
usbWatcher = hs.usb.watcher.new(usbDeviceCallback) | |
usbWatcher:start() | |
--]] | |
--------------------------- | |
-- Mute volume when leaving home Wifi network | |
-- Revert to 25 when arriving home | |
--------------------------- | |
local wifiWatcher = nil | |
local homeSSID1 = "renjian" | |
local homeSSID2 = "lain" | |
local lastSSID = hs.wifi.currentNetwork() | |
function ssidChangedCallback() | |
newSSID = hs.wifi.currentNetwork() | |
local changedToHome = (newSSID == homeSSID1 or newSSID == homeSSID2) and lastSSID ~= homeSSID1 and lastSSID ~= homeSSID2 | |
local changedFromHome = (newSSID ~= homeSSID1 and newSSID ~= homeSSID2) and (lastSSID == homeSSID1 and lastSSID == homeSSID2) | |
if changedToHome then | |
-- We just joined our home WiFi network | |
hs.audiodevice.defaultOutputDevice():setVolume(25) | |
elseif changedFromHome then | |
-- We just departed our home WiFi network | |
hs.audiodevice.defaultOutputDevice():setVolume(0) | |
end | |
lastSSID = newSSID | |
end | |
wifiWatcher = hs.wifi.watcher.new(ssidChangedCallback) | |
wifiWatcher:start() | |
--------------------------- | |
-- Mouse Highlight | |
--------------------------- | |
local mouseCircle = nil | |
local mouseCircleTimer = nil | |
function mouseHighlight() | |
-- Delete an existing highlight if it exists | |
if mouseCircle then | |
mouseCircle:delete() | |
if mouseCircleTimer then | |
mouseCircleTimer:stop() | |
end | |
end | |
-- Get the current co-ordinates of the mouse pointer | |
mousepoint = hs.mouse.getAbsolutePosition() | |
-- Prepare a big red circle around the mouse pointer | |
mouseCircle = hs.drawing.circle(hs.geometry.rect(mousepoint.x-40, mousepoint.y-40, 80, 80)) | |
mouseCircle:setStrokeColor({["red"]=1,["blue"]=0,["green"]=0,["alpha"]=1}) | |
mouseCircle:setFill(false) | |
mouseCircle:setStrokeWidth(5) | |
mouseCircle:show() | |
-- Set a timer to delete the circle after 3 seconds | |
mouseCircleTimer = hs.timer.doAfter(3, function() mouseCircle:delete() end) | |
end | |
--[[ | |
--------------------------------- | |
-- tmux 式的窗口布局 | |
--------------------------------- | |
hs.mjomatic.go({ | |
"CCCCCiiiii # <-- The windowgram, it defines the shapes and positions of windows", | |
"CCCCCiiiii", | |
"SSSSSiiiii", | |
"SSSSSYYYYY", | |
"SSSSSYYYYY", | |
"", | |
"C Google Chrome # <-- window C has application():title() 'Google Chrome'", | |
"i iTerm2", | |
"Y Safari", | |
"S Sublime Text"} | |
) | |
--]] | |
----------------------------- | |
-- Hourly Reminder | |
----------------------------- | |
function showDoingThings () | |
local wwid = "com.luosky.wwid" | |
local defaultDoingThings = { | |
{text = "Work"}, | |
{text = "Playing"}, | |
} | |
local doingThings = settings.get(wwid) or defaultDoingThings | |
-- local doingThings = defaultDoingThings | |
local lastDoingThing = doingThings[1] | |
function saveToDoingThings(item) | |
if item == nil then return end | |
-- Loop to enforce limit on qty of elements in history. Removes the oldest items | |
while (#doingThings >= 10) do | |
table.remove(doingThings,1) | |
end | |
table.insert(doingThings, item) | |
settings.set(wwid,doingThings) -- updates the saved history | |
end | |
function choiceSelected(choice) | |
if choice == nil then | |
return | |
end | |
if choice.text == lastDoingThing.text then | |
focusApp("Day One Classic") | |
return | |
end | |
saveToDoingThings(choice) | |
lastDoingThing = choice | |
local now = os.date("%I:%M %p") | |
pasteboard.setContents("[" .. now .. "] " .. lastDoingThing.text) | |
-- hs.application.launchOrFocus("Day One Classic") | |
focusApp("Day One Classic") | |
end | |
local chooser = hs.chooser.new(choiceSelected) | |
chooser:choices(reverse(doingThings)) | |
chooser:queryChangedCallback(function () | |
local query = chooser:query() | |
if query == nil then return end | |
local choices = { {text = query} } | |
for i = #doingThings, 1, -1 do | |
table.insert(choices, doingThings[i]) | |
end | |
chooser:choices(choices) | |
end) | |
chooser:show() | |
end | |
timer = hs.timer.delayed.new(3600, function() | |
showDoingThings() | |
alert("最近一小时做了啥?") | |
timer:setDelay(3600) | |
timer.start() | |
end) | |
timer.start() | |
function reverse(tbl) | |
local result = {} | |
for i = #tbl, 1, -1 do | |
table.insert(result, tbl[i]) | |
end | |
return result | |
end | |
----------------------------- | |
-- 快捷键绑定 | |
----------------------------- | |
hs.hotkey.bind(hyper,"1",autoLayout) | |
hs.hotkey.bind(hyper, "4", function() | |
local win = hs.window.focusedWindow() | |
local fullscreenSize = hs.screen.mainScreen():frame().size | |
local unitRect = hs.screen.mainScreen():toUnitRect(win:frame()) | |
if unitRect.w >= 1.0 then | |
win:moveToUnit({x=0.125,y=0.125,w=0.75,h=0.75}) | |
else | |
win:maximize() | |
-- win:moveToUnit(hs.layout.maximized) | |
end | |
end) | |
hs.hotkey.bind(hyper, "5", function() | |
local win = hs.window.focusedWindow() | |
-- win:moveToUnit(hs.layout.maximized) | |
hs.grid.show() | |
end) | |
-- hs.hotkey.bind(hyper,"ESCAPE",function() focusApp("Workflowy") end) | |
hs.hotkey.bind(hyper,"2",function() focusApp("Workflowy") end) | |
hs.hotkey.bind(hyper,"y",function() focusApp("Cocos Creator") end) | |
hs.hotkey.bind(hyper,"s",function() focusApp("Simulator") end) | |
hs.hotkey.bind(hyper, "=", mouseHighlight) | |
hs.hotkey.bind(hyper, "`", function() showDoingThings() alert("现在打算做啥?") end) | |
--[[ | |
----------------------------- | |
-- SpaceFN | |
----------------------------- | |
arrowModal = hs.hotkey.modal.new({}, nil) | |
enterSpaceFN = function() | |
arrowModal:enter() | |
arrowModal.triggered = false | |
end | |
spaceFNKeyBinding = hs.hotkey.bind({}, 'SPACE', enterSpaceFN, function() | |
if not arrowModal.triggered then | |
spaceFNKeyBinding:disable() | |
hs.eventtap.keyStroke({}, 'SPACE') | |
-- hs.eventtap.keyStrokes(' ') | |
end | |
arrowModal:exit() | |
spaceFNKeyBinding:enable() | |
end) | |
-- Cursor movement modifiers for line, word, selecting, etc. | |
arrowKeysModifiers = { | |
{''}, | |
{'cmd'}, | |
{'ctrl'}, | |
{'alt'}, | |
{'shift'}, | |
{'cmd','shift'}, | |
{'cmd','alt'}, | |
{'cmd','ctrl'}, | |
{'ctrl','shift'}, | |
{'alt','shift'}, | |
} | |
arrowKeysMap = { | |
{'h','left'}, | |
{'j','down'}, | |
{'k','up'}, | |
{'l','right'}, | |
{'a','left'}, | |
{'s','left'}, | |
{'d','down'}, | |
{'e','up'}, | |
{'f','right'}, | |
} | |
for i, map in ipairs(arrowKeysMap) do | |
for j,modifier in ipairs(arrowKeysModifiers) do | |
func = function() | |
hs.eventtap.keyStroke(modifier,map[2]) | |
arrowModal.triggered = true | |
end | |
arrowModal:bind(modifier,map[1],func) | |
-- arrowModal:bind({}, map[1], function() hs.eventtap.keyStroke({}, map[2]) end) | |
-- arrowModal:bind({'shift'}, map[1], function() hs.eventtap.keyStroke({'shift'}, map[2]) end) | |
-- arrowModal:bind({'cmd'}, map[1], function() hs.eventtap.keyStroke({'cmd'}, map[2]) end) | |
-- arrowModal:bind({'alt'}, map[1], function() hs.eventtap.keyStroke({'alt'}, map[2]) end) | |
-- arrowModal:bind({'cmd','shift'}, map[1], function() hs.eventtap.keyStroke({'cmd','shift'}, map[2]) end) | |
-- arrowModal:bind({'alt','shift'}, map[1], function() hs.eventtap.keyStroke({'alt','shift'}, map[2]) end) | |
end | |
end | |
]]-- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment