diff --git a/crates/extension/src/extension_indexed_docs_provider.rs b/crates/extension/src/extension_indexed_docs_provider.rs index ba3d213e69..957af63afd 100644 --- a/crates/extension/src/extension_indexed_docs_provider.rs +++ b/crates/extension/src/extension_indexed_docs_provider.rs @@ -31,7 +31,25 @@ impl IndexedDocsProvider for ExtensionIndexedDocsProvider { } async fn suggest_packages(&self) -> Result> { - Ok(Vec::new()) + self.extension + .call({ + let id = self.id.clone(); + |extension, store| { + async move { + let packages = extension + .call_suggest_docs_packages(store, id.as_ref()) + .await? + .map_err(|err| anyhow!("{err:?}"))?; + + Ok(packages + .into_iter() + .map(|package| PackageName::from(package.as_str())) + .collect()) + } + .boxed() + } + }) + .await } async fn index(&self, package: PackageName, database: Arc) -> Result<()> { diff --git a/crates/extension/src/wasm_host/wit.rs b/crates/extension/src/wasm_host/wit.rs index 11cf692a7c..721b6ea0ba 100644 --- a/crates/extension/src/wasm_host/wit.rs +++ b/crates/extension/src/wasm_host/wit.rs @@ -291,6 +291,19 @@ impl Extension { } } + pub async fn call_suggest_docs_packages( + &self, + store: &mut Store, + provider: &str, + ) -> Result, String>> { + match self { + Extension::V010(ext) => ext.call_suggest_docs_packages(store, provider).await, + Extension::V001(_) | Extension::V004(_) | Extension::V006(_) => Err(anyhow!( + "`suggest_docs_packages` not available prior to v0.1.0" + )), + } + } + pub async fn call_index_docs( &self, store: &mut Store, diff --git a/crates/extension_api/src/extension_api.rs b/crates/extension_api/src/extension_api.rs index 7b872e4414..ce0476cf00 100644 --- a/crates/extension_api/src/extension_api.rs +++ b/crates/extension_api/src/extension_api.rs @@ -129,6 +129,16 @@ pub trait Extension: Send + Sync { Err("`run_slash_command` not implemented".to_string()) } + /// Returns a list of package names as suggestions to be included in the + /// search results of the `/docs` slash command. + /// + /// This can be used to provide completions for known packages (e.g., from the + /// local project or a registry) before a package has been indexed. + fn suggest_docs_packages(&self, _provider: String) -> Result, String> { + Ok(Vec::new()) + } + + /// Indexes the docs for the specified package. fn index_docs( &self, _provider: String, @@ -260,6 +270,10 @@ impl wit::Guest for Component { extension().run_slash_command(command, argument, worktree) } + fn suggest_docs_packages(provider: String) -> Result, String> { + extension().suggest_docs_packages(provider) + } + fn index_docs( provider: String, package: String, diff --git a/crates/extension_api/wit/since_v0.1.0/extension.wit b/crates/extension_api/wit/since_v0.1.0/extension.wit index 8b210d8bbc..e42c2b7eb1 100644 --- a/crates/extension_api/wit/since_v0.1.0/extension.wit +++ b/crates/extension_api/wit/since_v0.1.0/extension.wit @@ -135,6 +135,13 @@ world extension { /// Returns the output from running the provided slash command. export run-slash-command: func(command: slash-command, argument: option, worktree: option>) -> result; + /// Returns a list of packages as suggestions to be included in the `/docs` + /// search results. + /// + /// This can be used to provide completions for known packages (e.g., from the + /// local project or a registry) before a package has been indexed. + export suggest-docs-packages: func(provider-name: string) -> result, string>; + /// Indexes the docs for the specified package. export index-docs: func(provider-name: string, package-name: string, database: borrow) -> result<_, string>; } diff --git a/extensions/gleam/src/gleam.rs b/extensions/gleam/src/gleam.rs index 9acd808d17..b48ba13c5f 100644 --- a/extensions/gleam/src/gleam.rs +++ b/extensions/gleam/src/gleam.rs @@ -246,6 +246,17 @@ impl zed::Extension for GleamExtension { } } + fn suggest_docs_packages(&self, provider: String) -> Result, String> { + match provider.as_str() { + "gleam-hexdocs" => Ok(vec![ + "gleam_stdlib".to_string(), + "birdie".to_string(), + "startest".to_string(), + ]), + _ => Ok(Vec::new()), + } + } + fn index_docs( &self, provider: String,