Файли
Arnaud Ritti 39f6162c12 feat(plugins): services views in the Services tool window (#1760)
A plugin view declared with `location = "services"` (plugin API 1.3, `engines.openidea ^1.3`) shows its tree in the Services tool window, next to Docker and the run configurations. The nodes, the toolbar (acting on one selected node) and their events come from `view-provider`; `viewItem.context` menus give the nodes a right-click menu. The pane beside the tree comes from a new optional export, `service-provider.detail(view, key)` (worlds `plugin-services` / `services`), which returns typed tabs: a message, read-only text or a process log. The IDE switches tabs without calling the plugin.

For a log, the UI names only the node and tab (`plugin_service_log`); the host asks the plugin for the pane again and runs its program with the plugin's `process:` grant in the project root, with the arguments of the toggles that are on, streaming its output into the log pane Docker uses until it exits (the exit code is shown), the pane closes or the Services window is hidden. A cancelled request starts nothing, lines are cut at 16 KiB, and revoking the grant or cancelling kills the program and what it started. The log pane moves to `src/ui/LogPane` and drops output that arrives after its source was stopped. The Rust SDK gains `openidea_plugin::services` (`Services`, `Tab`, `Pane`, `ProcessLog`). All components are rebuilt for the WIT change.

Closes #1736

Co-authored-by: arnaud-ritti <[email protected]>
2026-11-07 09:39:18 +08:00

51 рядки
1.6 KiB
Plaintext

package openidea:[email protected];
/// What the pane beside the Services tree shows for a plugin's node.
interface service-types {
/// A switch above a log; when on, `args` are appended and the program
/// starts again.
record log-toggle {
id: string,
label: string,
args: list<string>,
}
/// A program the IDE runs, its output followed in a log (ANSI stripped,
/// the last 5000 lines) until it exits or the pane closes. Needs the
/// plugin's `process:<program>` grant; runs in the project root.
record process-log {
program: string,
args: list<string>,
toggles: list<log-toggle>,
}
/// The body of a tab.
variant pane {
/// A centred message: an empty state or why there is nothing to show.
message(string),
/// Read-only text the user can select and copy, at most 1 MiB.
text(string),
log(process-log),
}
/// A tab of a node's pane; the IDE switches tabs without calling the plugin.
record tab {
id: string,
label: string,
body: pane,
}
}
/// The detail pane of the nodes of a plugin's `location = "services"` views.
/// The nodes themselves, the toolbar and their events come from
/// `view-provider` (`render` / `handle` of the view).
interface service-provider {
use types.{error};
use invocation.{invocation};
use service-types.{tab};
/// The tabs of node `key` of view `view` (at most 8), rendered when the
/// node is selected and again after `views.refresh(view)`.
detail: func(view: string, key: string, ctx: borrow<invocation>) -> result<list<tab>, error>;
}