73 lines
2.5 KiB
Markdown
73 lines
2.5 KiB
Markdown
# Menus
|
|
|
|
Menus are declared in the manifest and implemented by registering command
|
|
handlers during activation.
|
|
|
|
```json
|
|
{
|
|
"contributes": {
|
|
"menus": [
|
|
{
|
|
"id": "hello-plugin.menu",
|
|
"label": "Hello Plugin",
|
|
"topLevel": true,
|
|
"order": 100
|
|
}
|
|
],
|
|
"menuItems": [
|
|
{
|
|
"id": "hello-plugin.open.item",
|
|
"targetMenuId": "hello-plugin.menu",
|
|
"label": "Open Dashboard",
|
|
"command": "hello-plugin.open",
|
|
"order": 10,
|
|
"when": "projectOpen"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
Then register the command id:
|
|
|
|
```ts
|
|
export function activate(ctx: ActivateContext): void {
|
|
const disposable = ctx.commands?.registerCommand("hello-plugin.open", async () => {
|
|
const win = await ctx.services?.windows.open({ layoutType: "hello-plugin.dashboard" });
|
|
return win
|
|
? { status: "opened", alreadyOpen: win.alreadyOpen }
|
|
: { status: "skipped", reason: "ui-service-unavailable", message: "UI service unavailable." };
|
|
});
|
|
if (disposable) ctx.subscriptions.push(disposable);
|
|
}
|
|
```
|
|
|
|
## Rules
|
|
|
|
- There is no separate `contributes.commands` collection. A command can only be
|
|
registered if at least one manifest `menuItems[].command` or
|
|
`slashCommands[].command` entry declares that exact id.
|
|
- A missing command handler is surfaced by the host as a retryable reload error;
|
|
menu clicks must never fail silently.
|
|
- A registered handler's rejected promise is not swallowed: the host logs the
|
|
plugin id, command id, status, reason and message, then presents a generic
|
|
retryable error without raw payloads. In
|
|
particular, return/await `services.windows.open(...)` so native-window
|
|
failures follow this path.
|
|
- An open/focus handler returns `status: "opened"` whether `alreadyOpen` is
|
|
`false` (new window) or `true` (existing window focused). Neither success
|
|
produces an alert.
|
|
- Keep diagnostic views reachable when optional executables such as Git, ADB or
|
|
Gradle are missing. Let the view explain that degraded state instead of
|
|
skipping the menu action before opening it.
|
|
- A handler owns precondition checks and feedback. See
|
|
[Commands And Feedback](commands-and-feedback.md).
|
|
- Menu item `when` expressions are evaluated by the host; unsupported or false
|
|
conditions hide/disable the item according to host policy.
|
|
|
|
## Targets
|
|
|
|
`targetMenuId` can refer to a plugin top-level menu id or a host menu id exposed
|
|
by IdeA. Prefer a plugin top-level menu for plugin-specific workflows and host
|
|
menus only when the action naturally belongs beside native actions.
|