Files
openidea/wit/events.wit
T
ntbang0901 835a9c883c feat(plugins): let plugins depend on each other and declare extension points (API 1.5) (#2383)
Plugins could not rely on each other: nothing said "this plugin needs that one", and a plugin had no way to let others extend it. Plugin API 1.5 adds both.

- `[[depends]]` in `plugin.toml` (version range, `optional`). A plugin whose required dependency is missing, disabled, the wrong version, cyclic or unable to run is shown as Blocked with the reason and starts once the dependency can run again. Plugins start in dependency order; disabling a plugin others need asks first. Granting or revoking a dependency's permissions also settles its dependents.
- `[[extension-points]]` declares points with typed fields. Dependents contribute to them from `plugin.toml` (checked at install time); the owner reads them through the read-only `extensions` interface (`host::extension_contributions`) and hears changes through the `extensions-changed` event.

The plugin details page shows what a plugin requires, who requires it, and its extension points with their contributors. Covered by the `ext-owner` fixture and `plugin_dependencies.rs`.

Co-authored-by: ntbang0901 <121003585+ntbang0901@users.noreply.github.com>
2026-11-11 02:05:41 +08:00

68 lines
3.2 KiB
Plaintext

package openidea:plugin@1.5.0;
/// Workbench events, delivered in batches to `event-handler.handle`.
interface events {
use types.{error, extension};
record action-performed {
/// Action id (`editor.duplicate-line`).
action: string,
title: string,
/// How the user started it: `keyboard`, `menu`, `toolbar`,
/// `context-menu`, `search` or `other` (more may be added).
source: string,
/// Its keyboard shortcut, when it has one (`Ctrl+D`).
shortcut: option<string>,
}
variant event {
file-opened(string),
file-saved(string),
editor-focused(option<string>),
action-performed(action-performed),
vcs-changed(string),
scheduled,
/// A kind added after 1.0 (subscribed to by its name).
other(extension),
}
/// Delivers `kind` events from now on, for the rest of the session (also
/// across idle reclaim: an event activates the plugin again). Declare
/// `activation = ["on-event:<kind>"]` to get them before first use.
/// API 1.4 also delivers `file-closed` (JSON path string), `settings-changed`
/// (JSON array of the plugin's changed setting keys), and `input-mode-changed`
/// (JSON {path, mode, sub}) through `other`. The last needs `events.input`.
/// API 1.5 also delivers `extensions-changed` (JSON array of the extension
/// points this plugin declares whose contributions changed) through `other`,
/// to the declaring plugin only and without a capability.
/// Kinds: `file-opened`, `file-saved`, `files-changed` (batched disk changes
/// as `other`, with created/modified/removed path lists in JSON), `editor-focused` (the focused editor
/// changed), `vcs-changed` (a repository's state changed: commit,
/// checkout, fetch…), `action-performed` (an IDE action ran) and
/// `scheduled` (the `on-schedule` period elapsed); later IDEs add more,
/// and an IDE that doesn't know one fails with `invalid`.
/// Requires `events` (`events.input` for `action-performed`).
subscribe: func(kind: string) -> result<_, error>;
/// Replaces this kind's subscription with project-relative globs (OR).
/// Empty globs pause delivery; `subscribe` restores unfiltered delivery.
/// Kinds: file-opened, file-saved, files-changed. Requires `events`.
subscribe-paths: func(kind: string, globs: list<string>) -> result<_, error>;
unsubscribe: func(kind: string);
}
/// Long-running work with a progress indicator. While a task is open, the
/// call that began it may run for the background budget (60 s) instead of 5 s,
/// and each `report` or `is-cancelled` renews that budget: work that keeps
/// saying it is alive is not cut off, while work that goes quiet is.
interface tasks {
resource task {
/// `done` of `total` units (`none`: indeterminate), with a short status.
report: func(done: u32, total: option<u32>, message: option<string>);
/// The user cancelled it: stop soon and return.
is-cancelled: func() -> bool;
}
/// Starts a task shown in the status bar; dropping it ends it.
begin: func(title: string, cancellable: bool) -> task;
}