I can't speak to the Vim application specifically, but generally it is *not* the key-down that an application acts upon, but the key-up... one reason for this is to support the pop-ups that occur in some applications when you hold down certain keys, like "a", for example, and then get a list of various diacritical marks that can be applied to the "a"... until the key-up, the system can't be 100% certain that you are done with tapping that key.
A more "proper" way to generate keystrokes from a bound hotkey would be something like:
h = hs.hotkey.bind({trigger-modifiers}, "trigger-key", function()
hs.eventtap.event.newKeyEvent({desired-modifiers}, "desired-key", true):post()
end, function()
hs.eventtap.event.newKeyEvent({desired-modifiers}, "desired-key", false):post()
end, function()
hs.eventtap.event.newKeyEvent({desired-modifiers}, "desired-key", true):setProperty(hs.eventtap.event.properties.keyboardEventAutorepeat, 1):post()
end)
This works by generating an appropriate message to your actual status of the trigger key -- a down, when you hit the trigger key, an up when you release it, and a repeat if you hold it down long enough.
Haven't used this beyond an initial test, though, so I can't say if there might be some unexpected interactions because of timing or context switching between the frontmost application and the Hammerspoon application, but... it seems to work in my initial testing.