@Kaehfin this is exactly what I was looking for today. I installed Hammerspoon and did the Hello World so I know it’s working. I tried saving this in the .hammerspoom/Spoons path but couldn’t get it to load.
I had some issues with that script, it’s got some things that are limiting how fast it can press.
So, with the help of ChatGPT, I improved it and now you can pick which keybinds you want to use, which buttons it’s going to press, how many of the keybinds you want, and finally, how long the delay are in between.
There’s also a master keybind that’s set to cmd + 1, that lets you use the keyboard normally when it’s set to off, and when it’s on, it’ll start the key spamming when you push your keybinds.
Now here’s for the juicy part, here’s the code:
local toggle = {}
local keyRepeatTimer = {}
local keyPressInterval = 0.1 -- Set the delay here (0.1 seconds = 100 ms)
-- Arrays for keybinds and keys to press
local keybinds = {"1", "2"} -- You can add more keybinds here
local keysToPress = {"å", "ä"} -- Corresponding keys to press
-- Function to stop all key repetition timers
local function stopAllKeyRepeats()
for i, _ in ipairs(toggle) do
if keyRepeatTimer[i] and keyRepeatTimer[i]:running() then
keyRepeatTimer[i]:stop()
end
toggle[i] = false
end
end
k = hs.hotkey.modal.new('cmd', '1')
function k:entered() hs.alert'Entered mode' end
-- Stop all keypresses when exiting the modal
function k:exited()
hs.alert'Exited mode'
stopAllKeyRepeats()
end
k:bind('cmd', '1', function()
k:exit()
end)
-- Function to create a key event (keydown and keyup)
local function pressKey(key)
local keyDown = hs.eventtap.event.newKeyEvent({}, key, true)
local keyUp = hs.eventtap.event.newKeyEvent({}, key, false)
keyDown:post()
keyUp:post()
end
-- Function to start key repetition for a given toggle and key
local function startKeyRepeat(i)
-- Stop any existing timer for this keybind
if keyRepeatTimer[i] and keyRepeatTimer[i]:running() then
keyRepeatTimer[i]:stop()
end
-- Create a single timer for key repetition
keyRepeatTimer[i] = hs.timer.doEvery(keyPressInterval, function()
if toggle[i] then
pressKey(keysToPress[i])
else
keyRepeatTimer[i]:stop() -- Stop the timer if toggled off
end
end)
end
-- Dynamically create keybinds and their corresponding actions
for i, keybind in ipairs(keybinds) do
toggle[i] = false -- Initialize toggle for each keybind
k:bind('', keybind, function()
if toggle[i] then
stopAllKeyRepeats() -- Stop all if any key is active
else
stopAllKeyRepeats() -- Stop any currently running key presses
toggle[i] = true -- Start the repetition for this keybind
startKeyRepeat(i)
end
end)
end