Make slash commands defined in extensions return SlashCommandOutput (#13237)

This PR extends the interface for slash commands defined in extensions
to have them return `SlashCommandOutput`.

This allows for slash commands to return multiple output sections for a
single piece of generated text.

Note that we don't allow specifying the icon to display in the
placeholder, as we don't want to commit to that in our API at the
moment.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-06-18 17:28:01 -04:00 committed by GitHub
parent ca18549e02
commit ad4e52842c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 73 additions and 38 deletions

View file

@ -52,11 +52,9 @@ impl SlashCommand for ExtensionSlashCommand {
delegate: Arc<dyn LspAdapterDelegate>,
cx: &mut WindowContext,
) -> Task<Result<SlashCommandOutput>> {
let command_name = SharedString::from(self.command.name.clone());
let argument = argument.map(|arg| arg.to_string());
let text = cx.background_executor().spawn(async move {
let output = self
.extension
let output = cx.background_executor().spawn(async move {
self.extension
.call({
let this = self.clone();
move |extension, store| {
@ -77,19 +75,21 @@ impl SlashCommand for ExtensionSlashCommand {
.boxed()
}
})
.await?;
output.ok_or_else(|| anyhow!("no output from command: {}", self.command.name))
.await
});
cx.foreground_executor().spawn(async move {
let text = text.await?;
let range = 0..text.len();
let output = output.await?;
Ok(SlashCommandOutput {
text,
sections: vec![SlashCommandOutputSection {
range,
icon: IconName::Code,
label: command_name,
}],
text: output.text,
sections: output
.sections
.into_iter()
.map(|section| SlashCommandOutputSection {
range: section.range.into(),
icon: IconName::Code,
label: section.label.into(),
})
.collect(),
run_commands_in_text: false,
})
})

View file

@ -6,7 +6,7 @@ use release_channel::ReleaseChannel;
use since_v0_0_7 as latest;
use super::{wasm_engine, WasmState};
use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};
use language::{LanguageServerName, LspAdapterDelegate};
use semantic_version::SemanticVersion;
use std::{ops::RangeInclusive, sync::Arc};
@ -19,6 +19,7 @@ use wasmtime::{
pub use latest::CodeLabelSpanLiteral;
pub use latest::{
zed::extension::lsp::{Completion, CompletionKind, InsertTextFormat, Symbol, SymbolKind},
zed::extension::slash_command::SlashCommandOutput,
CodeLabel, CodeLabelSpan, Command, Range, SlashCommand,
};
pub use since_v0_0_4::LanguageServerConfig;
@ -262,13 +263,15 @@ impl Extension {
command: &SlashCommand,
argument: Option<&str>,
resource: Resource<Arc<dyn LspAdapterDelegate>>,
) -> Result<Result<Option<String>, String>> {
) -> Result<Result<SlashCommandOutput, String>> {
match self {
Extension::V007(ext) => {
ext.call_run_slash_command(store, command, argument, resource)
.await
}
Extension::V001(_) | Extension::V004(_) | Extension::V006(_) => Ok(Ok(None)),
Extension::V001(_) | Extension::V004(_) | Extension::V006(_) => {
Err(anyhow!("`run_slash_command` not available prior to v0.0.7"))
}
}
}
}

View file

@ -98,6 +98,9 @@ impl HostWorktree for WasmState {
}
}
#[async_trait]
impl common::Host for WasmState {}
#[async_trait]
impl nodejs::Host for WasmState {
async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {