[SOLVED] Is there an imperative API for setting keymaps?


#1

Is there an imperative API for setting keymaps? I find it difficult to group related key mappings together due to the limitation that there can’t be duplicate keys in CSON, so I have to spread related mapping across the file to different selectors.

For example, something like

atom.keymap.add('.selector', {
  'cmd-y': 'do:something'
})

#2

Yes. See https://atom.io/docs/api/latest/KeymapManager.


#3

Is there a way around the first argument to KeyManager.add()? For example, do I have to create a new name string each time?

Is there a way around the first argument to KeymapManager.add()? For example, do I have to make a name each time I use .add(), as in the 'bindings1' name string in the following example?

    atom.keymaps.add('bindings1', {
        'atom-text-editor': {
            'cmd-alt-o': 'symbols-list:toggle'
        }
    })

#4

There’s no way around it because the function of the name is to provide a unique identifier so that the batch of keybindings can be addressed as one bundle (if your package gets disabled, for example, and the keybindings need to be cleared).


#5

Why not use the Disposable internally? It’s already being returned.

How about this following trick based on the leaf-node selector?

// keymap.cson
'*:not(:has(*))':
  'cmd-k': 'my:command'
atom.commands.add '*:not(:has(*))', 'my:command', () -> {
  # do what I need here?
}

#6

@DamnedScholar Ah, dang,

Uncaught SyntaxError: *:div(:has(*)) is not a valid selector(…)

The concept would work though! If I understand correctly, only one element can be focused at a time? If so, that logic will always be fired because in theory there’s always some focused leaf node, right? Is there ever a time when not a single leaf node is focused?


#7

Any given leaf node is going to be a child of a node that has its own keymaps attached to it. You still have to override them individually.


#8

So, to answer the question

Is there ever a time when not a single leaf node is focused?

the answer is yes? Still new to Atom here. Is it a full tree-branch that is always in focus, starting from a leaf and all the way to the root? Or, what determines focus?


#9

As I understand the situation, your question is irrelevant. Any leaf node selector will still inherit all keybindings associated with, for example, atom-workspace. You can’t make a new binding for cmd-k and not have to deal with the existing ones without nullifying the existing ones. I think your best bet would be to write a script that programmatically gets matching keybindings and overrides them.


#10

@DamnedScholar I was under the impression that the element with focus (suppose it has the most specific selector while being a leaf node) means that a key mapping would take effect on that element (for example, the keybinding resolver shows the associated command for that element as green at the top while other commands are greyed out). If this is the case, then I was thinking that perhaps I could stop propagation of the event at that leaf node, therefore the key mapping would never take effect on less-specific elements (which effectively means the key map is canceled). If I’m not mistaken, to make a command keep bubbling, we must call e.abortKeyBinding() inside the command that was triggered by a key stroke, so if I don’t call e.abortKeyBinding() in my case then I was thinking that I could just leave that leaf-node’s command empty so that effectively the key stroke becomes a no-op on the leaf node having the most specific selector. But, I haven’t been able to try that because Atom says the leaf-node selector is an invalid selector.


#11

I did try it, using multiple class names (atom-pane atom-text-editor is valid), because of that line in the keymaps portion of the docs. It still bubbled, but that doesn’t necessarily mean that the keymap section is wrong, just that the behavior for multiple-key bindings like cmd-k up is different and was neglected.


#12

Gotcha. So I should apply the command to all of those ("cmd-k up", "cmd-k down", "cmd-k left", "cmd-k a", "cmd-k b", etc), then run my new logic in that shared command! But that still won’t prevent the delay will it? Is there an option for that?


#13

I’ll just try getting the list of /^cmd-k /g mappings from atom.keymaps and use unset!, hoping that turns off the delay if no more multi-key maps are present. A setting for delay length could possibly help some too.


#14

This is what I was thinking, yes.