From 61e4b6413a20df7c787a0ef16951a4d52c001ac6 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 5 Jul 2024 14:08:42 -0400 Subject: [PATCH] zed_extension_api: Return structured slash command completions (#13879) This PR updates the extension API to use structured slash command completions instead of plain strings. This allows slash commands defined in extensions to take advantage of the improvements made in #13876. Release Notes: - N/A --- .../extension/src/extension_slash_command.rs | 6 ++--- crates/extension/src/wasm_host/wit.rs | 4 ++-- crates/extension_api/src/extension_api.rs | 8 ++++--- .../wit/since_v0.0.7/extension.wit | 4 ++-- .../wit/since_v0.0.7/slash-command.wit | 10 +++++++++ extensions/gleam/src/gleam.rs | 22 ++++++++++++++----- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/crates/extension/src/extension_slash_command.rs b/crates/extension/src/extension_slash_command.rs index 3c8a965984..086ddafbb0 100644 --- a/crates/extension/src/extension_slash_command.rs +++ b/crates/extension/src/extension_slash_command.rs @@ -63,9 +63,9 @@ impl SlashCommand for ExtensionSlashCommand { completions .into_iter() .map(|completion| ArgumentCompletion { - label: completion.clone(), - new_text: completion, - run_command: true, + label: completion.label, + new_text: completion.new_text, + run_command: completion.run_command, }) .collect(), ) diff --git a/crates/extension/src/wasm_host/wit.rs b/crates/extension/src/wasm_host/wit.rs index 374a337063..25e928c972 100644 --- a/crates/extension/src/wasm_host/wit.rs +++ b/crates/extension/src/wasm_host/wit.rs @@ -20,7 +20,7 @@ use wasmtime::{ pub use latest::CodeLabelSpanLiteral; pub use latest::{ zed::extension::lsp::{Completion, CompletionKind, InsertTextFormat, Symbol, SymbolKind}, - zed::extension::slash_command::SlashCommandOutput, + zed::extension::slash_command::{SlashCommandArgumentCompletion, SlashCommandOutput}, CodeLabel, CodeLabelSpan, Command, Range, SlashCommand, }; pub use since_v0_0_4::LanguageServerConfig; @@ -263,7 +263,7 @@ impl Extension { store: &mut Store, command: &SlashCommand, query: &str, - ) -> Result, String>> { + ) -> Result, String>> { match self { Extension::V007(ext) => { ext.call_complete_slash_command_argument(store, command, query) diff --git a/crates/extension_api/src/extension_api.rs b/crates/extension_api/src/extension_api.rs index 88c27bc052..e0adf1b84b 100644 --- a/crates/extension_api/src/extension_api.rs +++ b/crates/extension_api/src/extension_api.rs @@ -25,7 +25,9 @@ pub use wit::{ npm_package_latest_version, }, zed::extension::platform::{current_platform, Architecture, Os}, - zed::extension::slash_command::{SlashCommand, SlashCommandOutput, SlashCommandOutputSection}, + zed::extension::slash_command::{ + SlashCommand, SlashCommandArgumentCompletion, SlashCommandOutput, SlashCommandOutputSection, + }, CodeLabel, CodeLabelSpan, CodeLabelSpanLiteral, Command, DownloadedFileType, EnvVars, KeyValueStore, LanguageServerInstallationStatus, Range, Worktree, }; @@ -114,7 +116,7 @@ pub trait Extension: Send + Sync { &self, _command: SlashCommand, _query: String, - ) -> Result, String> { + ) -> Result, String> { Ok(Vec::new()) } @@ -247,7 +249,7 @@ impl wit::Guest for Component { fn complete_slash_command_argument( command: SlashCommand, query: String, - ) -> Result, String> { + ) -> Result, String> { extension().complete_slash_command_argument(command, query) } diff --git a/crates/extension_api/wit/since_v0.0.7/extension.wit b/crates/extension_api/wit/since_v0.0.7/extension.wit index f1d26dabc8..90f7c9978a 100644 --- a/crates/extension_api/wit/since_v0.0.7/extension.wit +++ b/crates/extension_api/wit/since_v0.0.7/extension.wit @@ -8,7 +8,7 @@ world extension { use common.{range}; use lsp.{completion, symbol}; - use slash-command.{slash-command, slash-command-output}; + use slash-command.{slash-command, slash-command-argument-completion, slash-command-output}; /// Initializes the extension. export init-extension: func(); @@ -130,7 +130,7 @@ world extension { export labels-for-symbols: func(language-server-id: string, symbols: list) -> result>, string>; /// Returns the completions that should be shown when completing the provided slash command with the given query. - export complete-slash-command-argument: func(command: slash-command, query: string) -> result, string>; + export complete-slash-command-argument: func(command: slash-command, query: string) -> result, string>; /// Returns the output from running the provided slash command. export run-slash-command: func(command: slash-command, argument: option, worktree: borrow) -> result; diff --git a/crates/extension_api/wit/since_v0.0.7/slash-command.wit b/crates/extension_api/wit/since_v0.0.7/slash-command.wit index 17d4a61552..f52561c2ef 100644 --- a/crates/extension_api/wit/since_v0.0.7/slash-command.wit +++ b/crates/extension_api/wit/since_v0.0.7/slash-command.wit @@ -28,4 +28,14 @@ interface slash-command { /// The label to display in the placeholder for this section. label: string, } + + /// A completion for a slash command argument. + record slash-command-argument-completion { + /// The label to display for this completion. + label: string, + /// The new text that should be inserted into the command when this completion is accepted. + new-text: string, + /// Whether the command should be run when accepting this completion. + run-command: bool, + } } diff --git a/extensions/gleam/src/gleam.rs b/extensions/gleam/src/gleam.rs index 27478a2915..1ed1c536fa 100644 --- a/extensions/gleam/src/gleam.rs +++ b/extensions/gleam/src/gleam.rs @@ -4,7 +4,7 @@ use std::fs; use zed::lsp::CompletionKind; use zed::{ CodeLabel, CodeLabelSpan, HttpRequest, KeyValueStore, LanguageServerId, SlashCommand, - SlashCommandOutput, SlashCommandOutputSection, + SlashCommandArgumentCompletion, SlashCommandOutput, SlashCommandOutputSection, }; use zed_extension_api::{self as zed, Result}; @@ -154,12 +154,24 @@ impl zed::Extension for GleamExtension { &self, command: SlashCommand, _query: String, - ) -> Result, String> { + ) -> Result, String> { match command.name.as_str() { "gleam-project" => Ok(vec![ - "apple".to_string(), - "banana".to_string(), - "cherry".to_string(), + SlashCommandArgumentCompletion { + label: "apple".to_string(), + new_text: "Apple".to_string(), + run_command: false, + }, + SlashCommandArgumentCompletion { + label: "banana".to_string(), + new_text: "Banana".to_string(), + run_command: false, + }, + SlashCommandArgumentCompletion { + label: "cherry".to_string(), + new_text: "Cherry".to_string(), + run_command: true, + }, ]), _ => Ok(Vec::new()), }