feat(plugins): tidy the unreleased 1.3 API before it freezes (#2079)

- workspace.symbols becomes the project method project.symbols(query, limit), like find-files; the Rust SDK's Project::symbols is unchanged, components built against the previous main need a rebuild.
- The open-log-tab web message names its arguments args, as pty-spawn and the services process-log do; baseArgs is refused with log-error rather than ignored.
- Document the hover, semantic-tokens and diagnostics provider exports and their worlds.
This commit is contained in:
l0ng-ai authored and GitHub committed 2026-11-08 09:43:29 +08:00
1 parent 32a778d28d
commit ec171c3188
86 files changed
+177 -111

No files matched your search

+33 -33
View File
@@ -519,39 +519,6 @@ impl workspace::Host for StoreData {
self.host.project_of(Path::new(&path)).map(|root| self.push(ProjectRes { root })).transpose()
}
fn symbols(
&mut self,
project: Resource<ProjectRes>,
query: String,
limit: u32,
) -> Fallible<Vec<workspace::SymbolInfo>> {
if let Err(e) = self.require(Capability::ProjectRead) {
return Ok(Err(e));
}
if query.len() > 256 {
return Ok(Err(wit::Error::Invalid("symbol query exceeds 256 UTF-8 bytes".into())));
}
let root = &self.table.get(&project)?.root;
Ok(self
.host
.symbols(root, &query, limit.min(1000) as usize, &self.cancel.token(), self.deadline)
.map(|symbols| {
symbols
.into_iter()
.map(|s| workspace::SymbolInfo {
name: s.name,
kind: s.kind,
container: s.container,
location: wit::Location {
path: to_ipc(&s.location.path),
range: range_to_wit(&s.location.range),
},
})
.collect()
})
.map_err(to_wit))
}
fn projects(&mut self) -> Fallible<Vec<Resource<ProjectRes>>> {
if let Err(e) = self.require(Capability::ProjectRead) {
return Ok(Err(e));
@@ -632,6 +599,39 @@ impl workspace::HostProject for StoreData {
Ok(self.host.find_files(&root, &glob, limit.min(MAX_FIND) as usize).map_err(to_wit))
}
fn symbols(
&mut self,
this: Resource<ProjectRes>,
query: String,
limit: u32,
) -> Fallible<Vec<workspace::SymbolInfo>> {
if let Err(e) = self.require(Capability::ProjectRead) {
return Ok(Err(e));
}
if query.len() > 256 {
return Ok(Err(wit::Error::Invalid("symbol query exceeds 256 UTF-8 bytes".into())));
}
let root = &self.table.get(&this)?.root;
Ok(self
.host
.symbols(root, &query, limit.min(1000) as usize, &self.cancel.token(), self.deadline)
.map(|symbols| {
symbols
.into_iter()
.map(|s| workspace::SymbolInfo {
name: s.name,
kind: s.kind,
container: s.container,
location: wit::Location {
path: to_ipc(&s.location.path),
range: range_to_wit(&s.location.range),
},
})
.collect()
})
.map_err(to_wit))
}
fn write_file(&mut self, this: Resource<ProjectRes>, path: String, text: String) -> Fallible<()> {
if let Err(e) = self.require(Capability::ProjectWrite) {
return Ok(Err(e));
Binary file not shown.
@@ -1 +1 @@
da346bd256a61b971c09632465b187c580809cb7f16faa2588d22c6369cba600
6efbb6db8442a4dec21e65bb8c4c65e08b0da32082ee26e870c0419ebaf4e7fb
Binary file not shown.
@@ -1 +1 @@
002f86e29e9bf4f5f4adeeedd2889d492dbf41b60900c03c25cd84d6f3d226fb
21520d2522afaa7212e5c9b765110a334b2a1fe69302f602f05a61dcee08cd0b
Binary file not shown.
@@ -1 +1 @@
a2815b273e270d473a80c3d416a41d9d7a44bbc7c87b8aae6668c734e89bac5c
9d79e3f45abf0aaba03d30aa482decd3142d879b5964d12298b0aa6cbac581fd
Binary file not shown.
@@ -1 +1 @@
88bead9074bf6f2dfa2ceb0756b010b7f3b322e3bd977858f2fac97c840fd56e
05442db7ac00e3bcc4670d87d846c46a05c02d101e1651c587245fd5aeb1152f
Binary file not shown.
@@ -1 +1 @@
75145b486069cfb44429127ecb11ad863b9c6a88eff3205248c6ce5cf157d516
47c2a8deea407ed7bf6a56af8c118295f4ceed394faaff9b535e97cb4ea31115
Binary file not shown.
@@ -1 +1 @@
85d822e6ff64e6a5528d0b09d5ad3817ef77ea0f8a4832337c8958a002179755
884a42bd59ac64d08e9a0d3a72d4f1d1f25e850ef0b828be01142b61eda8db64
Binary file not shown.
@@ -1 +1 @@
badc9dc4fa12739850a5935b3d13e9a223fa7e348af785c5e164a32c5dda2989
48d2ab9cc824ed06ae34126d6651a9b7127599626cc00f7aa76d9b3161a2963f
Binary file not shown.
@@ -1 +1 @@
52565fa3ed2d76a4f61f7e870bb74124ca901a4efbc12025039c69aaf9a97844
5233d7518b685e641fdd48ac2a53e6ca7381c182d36d7920607714703ba37a47
Binary file not shown.
@@ -1 +1 @@
dcff32b4f59f5f9ad868fd6cb94a8e8e38e4ff4258b70ed3cb0cfd394ae632a3
3a77168e971d60ca4248b9bb2c27516614f74409324125821e74e3a236a67fb9
Binary file not shown.
@@ -1 +1 @@
91988c62e885b8792028710a460fc47300de19b96bf9ed23748709e5cdcc5cc1
4261434b2dd234426253f07f7e7e3daf8676fcf5680a578ac1b99f503fea2859
Binary file not shown.
@@ -1 +1 @@
ebc79bf4f9847003dca269a2870f1ca8d4362102a644ca220dc630c3040fbdf7
cc07e85ef5324b4d1d706665b0025b6682a581d1b91196f45a64284e238c7297
Binary file not shown.
@@ -1 +1 @@
fb262393a3c0149719b460bc39d8df656a7e8a52f51257c2e1188e0e620bb3eb
d0c974dee4010d0e3186bd426e3c53d09c2c56861b04e40f2187515bbb81f8d9
Binary file not shown.
@@ -1 +1 @@
78959a803256b5555deadb8952e7410cc661c83dd1046fcf71e2143c2e33d524
91ed6b9ee1cf77a0c3bee941aafceb252e7acd241f1d85ecb0366de98ee541d5
Binary file not shown.
@@ -1 +1 @@
d16118dd417be01dd23cc2e8693c3d5f5f12b679b72e3c5c5991370fa0b3bccb
3eb9c513691e5ad323d4ba6520ccec6305049a39f13e8d74dccb728ab2f0ffca
Binary file not shown.
@@ -1 +1 @@
c73610ba50bc540f6719865a4864ec647f1e4b5983fc254e886e7c99d3b552f8
6d59a4f37827a64d40cfe34dbcd9fea2b1de40ab39596c364b2cb7f5502de063
Binary file not shown.
@@ -1 +1 @@
46d77e5912893a8a70150944b26c9f41f23ffcccaa6666a245a0203fd836f77b
5da249c8c78cfcdf8f580099974d2ca654e98debb319f253c42ba18e5082fd0e
Binary file not shown.
@@ -1 +1 @@
42848c3b8b0aeaee3e861c8b76b85d13d28374572fc6e17e059b2d2015fbac17
961f07c9e1044e3e8c861a85ce4b2020cbbe9ce02b3764d1ec44a83d6c95eba1
Binary file not shown.
@@ -1 +1 @@
135f065b9832ba8c86ca0fb5ea4b30ae6a4b38c00f178215ce288fee737acbb6
31c61ed0204bd3b2f9152d20f9f275effc305ba7dd095d708c00f34fce023492
Binary file not shown.
@@ -1 +1 @@
c6f9b2167494532cc201279f2ac4a9c642ac09571197d7101e773c87b0ab19d5
162cde1d53b72a4c88a98cc51a31a2536d0506aeef60e15295b44c682be50fb7
Binary file not shown.
@@ -1 +1 @@
b7e055bda20c99de9385a6c90ee1e2ae57fb9288b84b8c71e3eb9cb536869fc6
aa7327f38c6277cfd7751b921bd43ac63ab8cb615ea428ccdfe9c4750606c6ad
Binary file not shown.
@@ -1 +1 @@
c61cbdcbb2af15cffdd75f8bc5bd411d849b80cb0cd19227a7632b2770e21f58
afece2c28e5077507159da59a93a73ede869678d168b3eaa7345962183417744
Binary file not shown.
@@ -1 +1 @@
c79eefe6730dc50e4c013b80cc1493c89974d9bbcbc7f4278e6136f20dbbffc3
29dd12ef6b9399c3d58b80ca145f6e903b70a9b220be7ca69a2672ee2c3e5582
+1 -1
View File
@@ -20,7 +20,7 @@ while true; do
done`;
const send = (program) => openidea.postMessage(JSON.stringify({
op: 'open-log-tab', key: 'probe', title: 'Probe logs', program,
baseArgs: ['--noprofile', '--norc', '-c', script, 'log-probe'],
args: ['--noprofile', '--norc', '-c', script, 'log-probe'],
toggles: [{ id: 'verbose', label: 'Verbose', args: ['--verbose'] }]
}));
document.querySelector('#open').onclick = () => send('bash');
Binary file not shown.
@@ -1 +1 @@
0dfe2f704cf0ad9b2ab06cfb92a190a19bcf18fe3d5da473a6f05b16002a76ff
ebc3a1213b97addb5abcbbfcf4baaff3f7644d1b60b62e2f215d3a35f36f221b
+3 -3
View File
@@ -1119,7 +1119,7 @@ openidea.postMessage(JSON.stringify({
key: "server-output",
title: "Server logs",
program: "my-server",
baseArgs: ["logs"],
args: ["logs"],
toggles: [{ id: "verbose", label: "Verbose", args: ["--verbose"] }],
}));
```
@@ -1130,9 +1130,9 @@ session caps and lifecycle rules are the same as for web frame PTYs. The tab
uses the backend PTY API, never a shell fallback. It supplies no environment
overrides; the environment is inherited. A shell requires its own explicit grant.
`program` is required. `baseArgs` and `toggles` default to empty arrays; `title`
`program` is required. `args` and `toggles` default to empty arrays; `title`
defaults to the program. Each toggle has a unique `id`, a plugin-localized
`label`, and `args` appended after `baseArgs` in declaration order. Changing a
`label`, and `args` appended after the top-level `args` in declaration order. Changing a
toggle terminates the previous process and replaces the stream. `key` defaults
to the title and is scoped to the calling plugin and view; reopening the same
key focuses its existing tab. Titles are at most 256 characters, keys 128,
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
344df18074d7171c42ae2c245e6ea2beeb7119ed6bf74b76503d241513ddcdba
b390c7f6acf5d32cbf451faf7a6393f2d4f130d5131ef0857a2b0904c434f598
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
b5f99458a32d54373661e8f61569b1e675e19594275036153b8c52fea74d8f69
1eea85130f5feacdcd6aade3548ac8e6ca4c1b316441346a89a7be6c13caaba7
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
b6f765692f944b63cb9ec0749a49c9d3be077b0eab709f148ffb0fb058ff1829
d2e1a074d81a4f29935524b6ba11a94d6a9bc301833ea721ed9e7cab461e198e
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
27a37336df957085a73504c5957033f1b178bcc47c190ffcd234ebad2d900817
150ed795daab29e3a152e50ebdf5e4ec3ca569d792962b77fce5fac428e7e076
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
99f00d65801c278a6d8a4e4466d0bf71738233c849dfcaf44902d60a557b8757
580e19fd349b6be1f2d4c32e572015337ef8f1e73b1b1f24199fc6d4ea73189f
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
0ace6d1b7f9f3cac0d23f92660d97d6eb6c79174203471970f3e4ca9f7d9b531
64d1e9a8bf48355f380feba052ea0ffb5f4ae7957b04d0a62a04e1d49d6ed690
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
9241c310c638a6a2e5e90e32c0651c76184498d193ad344f762f33a301bcaaab
ef76535391c4186a6373ef61197d96cc3ad7c42f47505ec75328ba5385e4df6e
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
e484774db29b214fb7247c6a403a7c9dbfaa030b0315c353826bf44982f82d61
246a3ace4e3ccdd9ed4f2499cde275c9ea2402fbb902893cc2d8d3403175bd47
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
ec03327641cc9f32d9205718847939981b3ec5e74e4aa2b800ba1598bccdb70f
75b3b93fe5ca2c5a58052c931f4d9cd824c379227d7f4cd8477fa89d045cda06
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
baf14df1362b15a0022456d3ea927b9fe07533dabf1fb717888ea98179152464
59f62db0a1c20a1d4fa6b380cd3272ec70ea4789835873d0abe3839ec08c94c3
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
5c96088e3f31ee74669bb4481fee6c95f51a9d875ad9bed9123f3e0de1a6ead5
548c6ed16fcd5d3a053bf6d8417d52ebd0fd74138d0665e9205eb8bf32ec497a
+1 -1
View File
@@ -311,7 +311,7 @@ mod imp {
}
pub fn project_symbols(p: &ProjectRes, query: &str, limit: u32) -> Result<Vec<SymbolInfo>, Error> {
wit::workspace::symbols(p, query, limit)
p.symbols(query, limit)
.map(|symbols| {
symbols
.into_iter()
+8 -1
View File
@@ -1,15 +1,22 @@
package openidea:[email protected];
/// Optional diagnostics for the current, possibly unsaved document (API 1.3).
/// Optional export (world `plugin-diagnostics`): problems in the current,
/// possibly unsaved document, for the languages declared with the
/// `diagnostics` provider kind. Asked shortly after a document opens or
/// changes, under the editor-provider budget; it can't ask the user.
interface diagnostics-provider {
use diagnostics.{diagnostic};
/// The document to check (the editor's text, unsaved edits included).
record document {
/// Absolute path.
path: string,
language: string,
version: u64,
text: string,
}
/// The document's problems, at most 5,000; they replace what this
/// provider reported before, and an empty list removes them.
diagnostics: func(doc: document) -> list<diagnostic>;
}
+10
View File
@@ -1,19 +1,29 @@
package openidea:[email protected];
/// Optional export (world `plugin-hover`): Markdown added to the hover of
/// documents of the languages declared with the `hover` provider kind,
/// including languages the plugin doesn't contribute. It shows below the
/// language server's hover, under the edit-path budget.
interface hover-provider {
use types.{position, range};
/// The document hovered (the editor's text while it is open).
record document {
/// Absolute path.
path: string,
language: string,
version: u64,
text: string,
}
/// What the plugin adds to the hover.
record hover-content {
/// At most 64 KiB.
markdown: string,
/// The text the hover describes; used when the server names none.
range: option<range>,
}
/// The hover at `at`, or `none` to add nothing.
hover: func(doc: document, at: position) -> option<hover-content>;
}
+5
View File
@@ -59,11 +59,13 @@ world plugin-indexing {
export document-indexer;
}
/// A plugin with semantic tokens (`semantic-tokens` under `[[contributes.providers]]`).
world plugin-semantic-tokens {
include plugin;
export semantic-tokens-provider;
}
/// A plugin adding to hovers (`hover` under `[[contributes.providers]]`).
world plugin-hover {
include plugin;
export hover-provider;
@@ -115,10 +117,12 @@ world indexing {
export document-indexer;
}
/// Only the `semantic-tokens-provider` export, generated next to `plugin` like `syntax`.
world semantic-tokens {
export semantic-tokens-provider;
}
/// Only the `hover-provider` export, generated next to `plugin` like `syntax`.
world hover {
export hover-provider;
}
@@ -149,6 +153,7 @@ world plugin-endpoints {
export endpoints-provider;
}
/// Only the `endpoints-provider` export, generated next to `plugin` like `syntax`.
world endpoints {
export endpoints-provider;
}
+11
View File
@@ -1,20 +1,31 @@
package openidea:[email protected];
/// Optional export (world `plugin-semantic-tokens`): semantic colouring of
/// documents of the languages declared with the `semantic-tokens` provider
/// kind, including languages the plugin doesn't contribute. The tokens join
/// the language server's and win where they overlap one.
interface semantic-tokens-provider {
use types.{range};
/// The document to colour (the editor's text while it is open).
record document {
/// Absolute path.
path: string,
language: string,
version: u64,
text: string,
}
/// A token: part of one line.
record semantic-token {
range: range,
/// An LSP token type in kebab-case (`method`, `property`, `type`, …).
kind: string,
/// LSP token modifiers in kebab-case (`static`, `deprecated`, …).
modifiers: list<string>,
}
/// The document's tokens, at most 65,536; asked again after each edit,
/// under the edit-path budget.
semantic-tokens: func(doc: document) -> list<semantic-token>;
}
+10 -11
View File
@@ -39,17 +39,6 @@ interface workspace {
location: location,
}
/// Fuzzy symbol search (CamelHump and container-qualified queries) over the
/// current index only; never starts or waits for a language server. Results
/// may be incomplete while indexing and ranges reflect the indexed text,
/// not necessarily unsaved edits. Empty queries return no symbols. Queries
/// over 256 UTF-8 bytes are invalid; limit is capped at 1000 (zero is empty).
/// Only paths readable under this project's root are returned; external
/// content roots are excluded. Cancellation returns cancelled; exceeding the
/// current call's deadline fails. A closed project is not-found.
/// Requires `project.read`. New in 1.3.
symbols: func(project: borrow<project>, query: string, limit: u32) -> result<list<symbol-info>, error>;
/// A project open in the IDE.
resource project {
/// Absolute path of the project root. Requires `project.read`.
@@ -80,6 +69,16 @@ interface workspace {
/// at most `limit`, as absolute paths. Ignored and excluded files are
/// skipped. Requires `project.read`.
find-files: func(glob: string, limit: u32) -> result<list<string>, error>;
/// Fuzzy symbol search (CamelHump and container-qualified queries) over the
/// current index only; never starts or waits for a language server. Results
/// may be incomplete while indexing and ranges reflect the indexed text,
/// not necessarily unsaved edits. Empty queries return no symbols. Queries
/// over 256 UTF-8 bytes are invalid; limit is capped at 1000 (zero is
/// empty). Only paths readable under the root are returned; external
/// content roots are excluded. Cancellation returns cancelled; exceeding
/// the current call's deadline fails. A closed project is not-found.
/// Requires `project.read`.
symbols: func(query: string, limit: u32) -> result<list<symbol-info>, error>;
}
/// Projects open in any window. Requires `project.read`.
@@ -19,7 +19,7 @@ const plugin = { id: "probe", enabled: true, capabilities: [{ id: "process:bash"
const spec = {
program: "bash",
title: "Probe logs",
baseArgs: ["--noprofile", "--norc"],
args: ["--noprofile", "--norc"],
toggles: [{ id: "verbose", label: "Verbose", args: ["-v"] }],
};
let stopActions: () => void;
@@ -76,9 +76,10 @@ describe("plugin streaming log tabs", () => {
{ program: "sh" },
{ program: "/bin/bash" },
{ program: " bash" },
{ baseArgs: [123] },
{ baseArgs: ["\0"] },
{ baseArgs: ["x".repeat(4097)] },
{ args: [123] },
{ args: ["\0"] },
{ args: ["x".repeat(4097)] },
{ baseArgs: ["--verbose"] },
{ cwd: "/" },
{ env: { PATH: "/tmp" } },
{ title: "x".repeat(257) },
@@ -102,7 +103,7 @@ describe("plugin streaming log tabs", () => {
const f = setup();
expect(webPtyBackend).toHaveBeenCalledWith("probe", "logs");
expect(f.backend.spawn).toHaveBeenCalledWith(
expect.objectContaining({ program: "bash", env: {}, args: spec.baseArgs }),
expect.objectContaining({ program: "bash", env: {}, args: spec.args }),
expect.any(Function),
);
expect(f.view().state.facet(EditorState.readOnly)).toBe(true);
@@ -128,7 +129,7 @@ describe("plugin streaming log tabs", () => {
fireEvent.click(screen.getByRole("switch", { name: "Verbose" }));
await waitFor(() => expect(f.backend.kill).toHaveBeenCalledWith(42));
expect(f.backend.spawn).toHaveBeenLastCalledWith(
expect.objectContaining({ args: [...spec.baseArgs, "-v"] }),
expect.objectContaining({ args: [...spec.args, "-v"] }),
expect.any(Function),
);
vi.mocked(f.backend.kill).mockClear();
@@ -277,7 +277,7 @@ describe("WebView", () => {
title: "App Logs",
key: "shared",
program: "tail",
baseArgs: ["-f", "app.log"],
args: ["-f", "app.log"],
toggles: [{ id: "verbose", label: "Verbose", args: ["-v"] }],
};
@@ -308,7 +308,7 @@ describe("WebView", () => {
pluginId: "acme.draw",
title: "App Logs",
program: "tail",
baseArgs: ["-f", "app.log"],
args: ["-f", "app.log"],
toggles: [{ id: "verbose", label: "Verbose", args: ["-v"] }],
},
});
+1 -1
View File
@@ -395,7 +395,7 @@ function PluginLogEditorBody({ input, data }: { input: EditorInput; data: Plugin
op: "pty-spawn",
sessionId: "log",
program: data.program,
args: [...data.baseArgs, ...data.toggles.filter((t) => on.has(t.id)).flatMap((t) => t.args)],
args: [...data.args, ...data.toggles.filter((t) => on.has(t.id)).flatMap((t) => t.args)],
cols: 240,
rows: 40,
}),
+7 -6
View File
@@ -13,7 +13,7 @@ export interface PluginLogEditorData {
key?: string;
title: string;
program: string;
baseArgs: string[];
args: string[];
toggles: PluginLogToggleSpec[];
}
@@ -25,27 +25,28 @@ const args = (v: unknown): v is string[] =>
/** Reject malformed requests instead of silently running a different command. */
export function logTabData(pluginId: string, view: string, value: object, length: number): PluginLogEditorData {
const m = value as Record<string, unknown>;
const { program, baseArgs = [], toggles = [], key, title = program } = m;
const { program, args: command = [], toggles = [], key, title = program } = m;
if (
length > 2 << 20 ||
!text(program, 256) ||
program.trim() !== program ||
!text(title, 256) ||
(key !== undefined && !text(key, 128)) ||
!args(baseArgs) ||
!args(command) ||
!Array.isArray(toggles) ||
toggles.length > 32 ||
toggles.some((t) => !t || !text(t.id, 64) || !text(t.label, 128) || !args(t.args)) ||
new Set(toggles.map((t) => t.id)).size !== toggles.length ||
baseArgs.length + toggles.reduce((n, t) => n + t.args.length, 0) > 256 ||
command.length + toggles.reduce((n, t) => n + t.args.length, 0) > 256 ||
"cwd" in m ||
"env" in m
"env" in m ||
"baseArgs" in m
)
throw new Error(tx("Invalid log stream configuration"));
const plugin = usePlugins.getState().plugins.find((p) => p.id === pluginId);
if (!plugin?.enabled || !plugin.capabilities.some((c) => c.id === `process:${program}` && c.granted))
throw new Error(tx`Cannot start PTY: process:${program} capability not granted.`);
return { pluginId, view, key: key as string | undefined, title, program, baseArgs, toggles };
return { pluginId, view, key: key as string | undefined, title, program, args: command, toggles };
}
/** Bound both line count and text size, including output with no newlines. */
+8 -1
View File
@@ -1,15 +1,22 @@
package openidea:[email protected];
/// Optional diagnostics for the current, possibly unsaved document (API 1.3).
/// Optional export (world `plugin-diagnostics`): problems in the current,
/// possibly unsaved document, for the languages declared with the
/// `diagnostics` provider kind. Asked shortly after a document opens or
/// changes, under the editor-provider budget; it can't ask the user.
interface diagnostics-provider {
use diagnostics.{diagnostic};
/// The document to check (the editor's text, unsaved edits included).
record document {
/// Absolute path.
path: string,
language: string,
version: u64,
text: string,
}
/// The document's problems, at most 5,000; they replace what this
/// provider reported before, and an empty list removes them.
diagnostics: func(doc: document) -> list<diagnostic>;
}
+10
View File
@@ -1,19 +1,29 @@
package openidea:[email protected];
/// Optional export (world `plugin-hover`): Markdown added to the hover of
/// documents of the languages declared with the `hover` provider kind,
/// including languages the plugin doesn't contribute. It shows below the
/// language server's hover, under the edit-path budget.
interface hover-provider {
use types.{position, range};
/// The document hovered (the editor's text while it is open).
record document {
/// Absolute path.
path: string,
language: string,
version: u64,
text: string,
}
/// What the plugin adds to the hover.
record hover-content {
/// At most 64 KiB.
markdown: string,
/// The text the hover describes; used when the server names none.
range: option<range>,
}
/// The hover at `at`, or `none` to add nothing.
hover: func(doc: document, at: position) -> option<hover-content>;
}
+5
View File
@@ -59,11 +59,13 @@ world plugin-indexing {
export document-indexer;
}
/// A plugin with semantic tokens (`semantic-tokens` under `[[contributes.providers]]`).
world plugin-semantic-tokens {
include plugin;
export semantic-tokens-provider;
}
/// A plugin adding to hovers (`hover` under `[[contributes.providers]]`).
world plugin-hover {
include plugin;
export hover-provider;
@@ -115,10 +117,12 @@ world indexing {
export document-indexer;
}
/// Only the `semantic-tokens-provider` export, generated next to `plugin` like `syntax`.
world semantic-tokens {
export semantic-tokens-provider;
}
/// Only the `hover-provider` export, generated next to `plugin` like `syntax`.
world hover {
export hover-provider;
}
@@ -149,6 +153,7 @@ world plugin-endpoints {
export endpoints-provider;
}
/// Only the `endpoints-provider` export, generated next to `plugin` like `syntax`.
world endpoints {
export endpoints-provider;
}
+11
View File
@@ -1,20 +1,31 @@
package openidea:[email protected];
/// Optional export (world `plugin-semantic-tokens`): semantic colouring of
/// documents of the languages declared with the `semantic-tokens` provider
/// kind, including languages the plugin doesn't contribute. The tokens join
/// the language server's and win where they overlap one.
interface semantic-tokens-provider {
use types.{range};
/// The document to colour (the editor's text while it is open).
record document {
/// Absolute path.
path: string,
language: string,
version: u64,
text: string,
}
/// A token: part of one line.
record semantic-token {
range: range,
/// An LSP token type in kebab-case (`method`, `property`, `type`, …).
kind: string,
/// LSP token modifiers in kebab-case (`static`, `deprecated`, …).
modifiers: list<string>,
}
/// The document's tokens, at most 65,536; asked again after each edit,
/// under the edit-path budget.
semantic-tokens: func(doc: document) -> list<semantic-token>;
}
+10 -11
View File
@@ -39,17 +39,6 @@ interface workspace {
location: location,
}
/// Fuzzy symbol search (CamelHump and container-qualified queries) over the
/// current index only; never starts or waits for a language server. Results
/// may be incomplete while indexing and ranges reflect the indexed text,
/// not necessarily unsaved edits. Empty queries return no symbols. Queries
/// over 256 UTF-8 bytes are invalid; limit is capped at 1000 (zero is empty).
/// Only paths readable under this project's root are returned; external
/// content roots are excluded. Cancellation returns cancelled; exceeding the
/// current call's deadline fails. A closed project is not-found.
/// Requires `project.read`. New in 1.3.
symbols: func(project: borrow<project>, query: string, limit: u32) -> result<list<symbol-info>, error>;
/// A project open in the IDE.
resource project {
/// Absolute path of the project root. Requires `project.read`.
@@ -80,6 +69,16 @@ interface workspace {
/// at most `limit`, as absolute paths. Ignored and excluded files are
/// skipped. Requires `project.read`.
find-files: func(glob: string, limit: u32) -> result<list<string>, error>;
/// Fuzzy symbol search (CamelHump and container-qualified queries) over the
/// current index only; never starts or waits for a language server. Results
/// may be incomplete while indexing and ranges reflect the indexed text,
/// not necessarily unsaved edits. Empty queries return no symbols. Queries
/// over 256 UTF-8 bytes are invalid; limit is capped at 1000 (zero is
/// empty). Only paths readable under the root are returned; external
/// content roots are excluded. Cancellation returns cancelled; exceeding
/// the current call's deadline fails. A closed project is not-found.
/// Requires `project.read`.
symbols: func(query: string, limit: u32) -> result<list<symbol-info>, error>;
}
/// Projects open in any window. Requires `project.read`.