Command visibility in command palette

Hi,

What I’m trying to achieve is have a bunch of wizard commands, the user can search with >Wizard: and see all the available wizards. The wizards are also shown in a New > context submenu of our navigator view. So to achieve that the isEnabled method of each wizard command handler is always returning true but the isVisible return true only for a certain selection. The problem is that it affects the visibility in the command palette search as well, any way to get around that for certain commands?

[original thread by Hanksha]

You can make commands always visible and control visibility of menu items by when closure.

[Hanksha]

You mean MenuAction.when? If so what should be the value, the type is string

there is ContextKeyService which allow to register new keys and change their values

when it is an expression over such keys

which gets evaluated when you try to operate with menus to decide what should be visible

[Hanksha]

wouldn’t it be simpler to have a isVisible method on MenuAction?

It will be an additional API and we already have means for it, plus we need when closure support for VS Code compatibility.

[Hanksha]

So in Vs code the when is used both for menu items and keybindings? In the link you gave me it’s only for the latter

For us too, keybinding: https://github.com/eclipse-theia/theia/blob/d5a60bb069bdb126dcdf0166bc69cca1014eb291/packages/core/src/common/keybinding.ts#L28-L31

[Hanksha]

Yeah but it’s not keybindings activation that interest me it’s menu item and results of the command palette search that interests me

[Hanksha]

If contributing another method to the MenuAction is not possible, is it possible to extend it? Maybe rebind a different context menu renderer?

Why don’t when work for you? How would you implement isVisible for a command?

[Hanksha]

It’s not that it would not work, it’s more that it’s not convenient. If I understand well when being a string expression there is no compile time check or type safety. Also it’s limited since you can’t inject services if needed in your expression, would have to register a context key for each custom stuff.

[Hanksha]

commands.registerCommand(MyWizardCommand, {
            execute: () => /* open wizard */,
            isEnabled: () => true ,
            isVisible: () => true
        });
menus.registerMenuAction(menuPath, {
            commandId: MyWizardCommand.id,
            // add this method in addition of the "when"
            isVisible: () => myInjectService.someState === expectedState
        });

[Hanksha]

It’s a bit like Eclipse RCP visibleWhen if you’re familiar with this https://help.eclipse.org/2019-12/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Fguide%2Fworkbench_cmd_menus.htm

You can file a proposal issue, but we cannot do it without agreement from everybody. Generally, personally, I dislike to have many ways of doing the same thing. I think MyInjectService can have a context key which value is updated in statically type safe manner and when when just references this value. If you afraid to mistype it you can introduce a constant.

[Hanksha]

It’s not very coherent though, command handlers use functions for enablement and visibility but menu actions use a string expression. But it’s alright, I’ll just find a way to achieve that internally. Another option would be for me to provide custom results in the command palette with a custom prefix like Wizard instead of >Wizard, anyway to do that?

You will need to implement a new prefix quick contribution look like other quick contributions are implemented. Type ? to see all available in the quick palette.