How can I replace the default autocompletion keymap (v6)

I’ve based my configuration on the basic-setup configuration. However, I’ve replaced the line including completionKeymap with my own keymap. For the sake of discussion, I’ve swapped ArrowUp and ArrowDown. The trouble is that my modified keymap does not seem to be applied - up and down still do what they did before.

The manual mentions the defaultKeymap option for the autocompletion extension, but when I set this to false, neither the default keymap nor my own keymap seem to be applied, since ArrowUp just moves the cursor to the beginning of the line and hides the autocomplete dialog.

What am I missing?

I guess I should also add that the only reason I really want to override the keymap is that I want all the keybindings to set preventDefault to true so that pressing enter doesn’t simultaneously submit a form that contains the editor. Maybe completionKeymap should just be updated?

Of course, the question of how to change the keymap still stands, since the reference manual seems to imply that it’s possible.

Yes, that’s how it’s supposed to work. Set that to false and add your own keymap as usual (with suitably high precedence so that it runs before the regular bindings for these keys).

Ahhh, sorry for the noise. I was using my own bindings to codemirror from a different language, and the problem ended up being with my bindings. Anyway, thanks for the reply.

I do have a follow-up question: Is there any way to make keybindings call stopPropagation on the event? In my second comment, I confused preventDefault with stopPropagation. Maybe keybindings should have a stopPropagation boolean option?

No, the library doesn’t concern itself with stopping propagation, but it shouldn’t be too hard to either properly check the event target in your own handlers, or add an intermediate handler on the editor’s wrapping <div> that stops everything you don’t want to escape.

No, the library doesn’t concern itself with stopping propagation

Fair enough.

I’d like to make “Escape” close the autocomplete window if it is open, but if it is not open, the event should get handled by the element containing the editor. To do this, a surrounding div would have to know whether the autocomplete window is open, right? I’m not sure how to do this without some hacky dom query-ing tricks.

I think just checking defaultPrevented on escape key events and calling stopPropagation on them if it’s true should do the trick there.

Ahh, good idea. I think this ought to work, but it seems that if the escape keybinding has preventDefault set to true, then defaultPrevented will also be true, regardless of whether the command attached to the keybinding could be applied or not. Is this a bug or expected behavior?

I think the relevant code is here:

If I’m understanding the code right, if there are multiple keybindings for escape, only one of them needs to have preventDefault for it to apply to all of them. That seems unexpected to me.

How else could it work? The preventDefault behavior applies when the binding doesn’t.

Yeah, you’re totally right. Somehow I was thinking that without preventDefault, the default browser behavior would always happen, regardless of whether the event got handled. Thanks for all the help - I’ve gotten my stuff working as I want it to.

Is the problem with Vimium extension for Chrome, which will intercept the esc key and make CodeMirror lose focus?

This was exactly my problem :sweat_smile: