Triggering a keydown event on a TextEditor


#1

Hello, so I have been trying for 2 hours to fire a keydown event on the TextEditor, so I’m asking for help on how to do this, and how to do it correctly. This is the test code.

eventA = Fn.keyEvent 'a', e     // Fn.keyEvent -> returns a keydown event
eventEsc = Fn.keyEvent 'escape', e
atom.keymap.handleKeyboardEvent(eventA)
atom.keymap.handleKeyboardEvent(eventEsc)

Now, the weird thing is that the “Escape” event works perfectly, but the “A” event doesnt do shit. The eventA object is the following.

altKey: false, bubbles: true, cancelBubble: false, cancelable: true, charCode: 0, clipboardData: undefined, ctrlKey: false, currentTarget: Window, defaultPrevented: false, detail: 0, eventPhase: 0, 
keyCode: 65, keyIdentifier: "U+41", 
keyLocation: 0, metaKey: false, path: NodeList[0], repeat: false, returnValue: true, shiftKey: false, srcElement: null, target: atom-text-editor.editor.vim-mode.command-mode, timeStamp: 1428184193408, type: "keydown", view: null, which: 65

Any hint would be appreciated.


#2

I can’t say much about your problem if I can’t see all of the code, but my best guess right now is that something goes wrong with using the e variable twice like that. Does it work when you use following code?

eventA = Fn.keyEvent 'a', e // Fn.keyEvent -> returns a keydown event
atom.keymap.handleKeyboardEvent(eventA)
eventEsc = Fn.keyEvent 'escape', e
atom.keymap.handleKeyboardEvent(eventEsc)

If not, could you share the Fn.keyEvent function?


#3

Here goes the (incomplete) event creating function (pretty much a copy of what is found in atom-keymap). I think the variable e is not the problem, because it is only used to extract the target of the event.

keyEvent: (keystroke, ev) ->
    event = document.createEvent 'KeyboardEvent'
    key = keystroke
    keys  = "1234567890-=[];'\\,./"
    chars = '!@#$%^&*()_+{}:"|<>?'
    ctrl = shift = alt = cmd = false
    i = chars.indexOf(keystroke)
    if (/^[a-z]$/.test(keystroke))
        key = keystroke.toUpperCase();
    if (/^[A-Z]$/.test(keystroke))
        shift = true
    if i != -1 && keystroke.length == 1
        key = keys.charAt(i)
        shift = true

    if (key.length == 1)
        keyIdentifier = "U+" + (key.charCodeAt(0).toString(16));
    else
        # switch (key) here
        if !keyIdentifier?
            keyIdentifier = key[0].toUpperCase() + key.slice(1);

    for n, id of KEY
        if id == key
            keyCode = which = Number.parseInt n
    location = KeyboardEvent.DOM_KEY_LOCATION_STANDARD;
    event.initKeyboardEvent(
        'keydown', true, true, null,
        keyIdentifier, location,
        ctrl, alt, shift, cmd )
    Object.defineProperty event, 'which', { get: -> keyCode }
    Object.defineProperty event, 'keyCode', { get: -> keyCode }
    Object.defineProperty event, 'target', { get: -> ev.target }
    Object.defineProperty event, 'currentTarget', { get: -> ev.currentTarget }

    return event

#4

The KeyboardEvent::initKeyboardEvent method is deprecated according to Mozilla. So maybe there’s your problem? In any case I would suggest moving away from that function.

Otherwise, the keyIdentifier looks like a unicode character. Shouldn’t they have 4 digits after the plus sign?


#5

Issue resolved.
FYI, if you come across this thread looking for answers: I used instead the function keydown from https://github.com/atom/vim-mode/blob/master/spec/spec-helper.coffee


#6

Even if the question was answered a long time ago…

I was searching for a easy solution to trigger a keypress, too. And I found it…
So if anyone need to simulate a keypress in atom, you can do it with a JavaScript function like that:

function sendKeyboardTab() {
  var key;
  key = atom.keymaps.constructor.buildKeydownEvent('tab', {target: document.activeElement});
  return atom.keymaps.handleKeyboardEvent(key);
}

If the function is called, a Tab keypress is triggered in the current editor window.