Should keybindings from plugins vs keybindings from extensions have different behaviours?

Hi, in order to achieve compatibility with VSCode I think we may need to differ the behaviours between how plugins and extensions behave when registering keybindings and I just wanted to get some thoughts.

From what I understand, in Theia right now, if you contribute a keybinding that is colliding with another keybinding then the keybinding will not register. This works fine for extensions because they know what keybindings are registered ahead of time. However, for VSCode plugins, it is impossible for them to know what keybindings are available or not in Theia and this causes a lot of keybindings from the VSCode plugins to not get registered.

Due to these, I propose that keybindings coming from plugins have an override capability that makes keybindings from plugins become the default and allows them to register regardless of if they conflict. This will align the behaviour of plugins with VSCode (without this keybindings coming from plugins doesn’t really make sense). Additionally, keybindings coming from extensions will retain their default behaviour.

I’m willing to do all the programming for this issue I just wanted to know what everyone thought before I jumped into it.

[original thread by Josh Pinkney]

Maybe you will just have to change how Theia’s keybinding registry work, there might be a better way of handling collisions indeed. IIRC VS Code allows binding the same keys to different commands, but I don’t know how they pick between them.

we should align it, in VS Code they use when closure to dedup keybindings

I don’t think it is possible to dedup when closure during registration. We should verify it. If it is so then our existing check does not make sense if when closure is provided and we should register both keybindings, one of them will win depending on the context (result of whenclosure evaluation) .

depending on the context
if the when clauses both evaluate to true, we can only refuse the override or define a policy who wins. Can we determine a priority (for example, “extensions win over plugins”) or is it just “last one wins”?

[Josh Pinkney]

I’ve done a quick look at different behaviours, and in a few days I will do a deeper dive into the behaviour
but I’ve tried with 3 different commands:

Fold Level 3 - When is set to editorTextFocus
Show All commands (coming from Eclipse Keybindings) - When is not defined
workbench.action.focusThirdEditorGroup - When is not defined

As expected, Fold Level 3 takes precidence when editorTextFocus is true. However, Show All commands (which the keybinding comes from a plugin) takes precedence over workbench.action.focusThirdEditorGroup all the time.

Just to test more I changed “File: New Untitled File”, (when is not defined) to be the same keybinding and my keybinding activates “File: New Untitled File” and Show All Commands
no longer works.

I thought it could be a source issue (user vs default) but I changed Show All Commands to be a different
keybinding and then changed it back and now Show All Commands was the active command that occurred when you hit the keybinding, leading me to think its last mapped.

I then removed the Show All Commands keybinding again and it went to the last mapped
command.

@jpinkney are you testing against Theia or VS Code? please check how it behaves in VS Code, we should just align behaviour

[Josh Pinkney]

@anton-kosyakov That test was in VSCode

so they don’t seem to have any collisions checking and last map keybindings wins

i think we can just remove collision checking

usually keybinidings don’t collide because of different when clause, and if they do, a user can dedup them via preferences

right now in Theia if there are several keybindings matching the first one wins, not sure whether it is the last mapped, but probably it is not very important to mimic now

Not sure the current user configuration in Theia allows to remove a keybinding already bound?

@paul-marechal Do you mean default keybinding?

actually VS Code has special syntax for it and we don’t support it:

,
    {
        "key": "alt+cmd+up",
        "command": "-editor.action.insertCursorAbove",
        "when": "editorTextFocus"
    }

- before a command seems to mean that this keybinding is removed

@paul-marechal Could you open an issue to support it?

[Josh Pinkney]

I’ve created an issue for support of that removal rule: https://github.com/theia-ide/theia/issues/5303