
This PR removes the `tooltip_text` field from `SlashCommandManifestEntry`s. The `tooltip_text` is currently only used to set the `menu_text` on a slash command, which is only used for featured slash commands. Since slash commands from extensions are not currently able to be featured, we don't need extension authors to provide this field in the manifest. This is a backwards-compatible change. Release Notes: - N/A
5.3 KiB
Slash Commands
Extensions may provide slash commands for use in the Assistant.
Example extension
To see a working example of an extension that provides slash commands, check out the slash-commands-example
extension.
This extension can be installed as a dev extension if you want to try it out for yourself.
Defining slash commands
A given extension may provide one or more slash commands. Each slash command must be registered in the extension.toml
.
For example, here is an extension that provides two slash commands: /echo
and /pick-one
:
[slash_commands.echo]
description = "echoes the provided input"
requires_argument = true
[slash_commands.pick-one]
description = "pick one of three options"
requires_argument = true
Each slash command may define the following properties:
description
: A description of the slash command that will be shown when completing available commands.requires_argument
: Indicates whether a slash command requires at least one argument to run.
Implementing slash command behavior
To implement behavior for your slash commands, implement run_slash_command
for your extension.
This method accepts the slash command that will be run, the list of arguments passed to it, and an optional Worktree
.
This method returns SlashCommandOutput
, which contains the textual output of the command in the text
field. The output may also define SlashCommandOutputSection
s that contain ranges into the output. These sections are then rendered as creases in the Assistant's context editor.
Your extension should match
on the command name (without the leading /
) and then execute behavior accordingly:
impl zed::Extension for MyExtension {
fn run_slash_command(
&self,
command: SlashCommand,
args: Vec<String>,
_worktree: Option<&Worktree>,
) -> Result<SlashCommandOutput, String> {
match command.name.as_str() {
"echo" => {
if args.is_empty() {
return Err("nothing to echo".to_string());
}
let text = args.join(" ");
Ok(SlashCommandOutput {
sections: vec![SlashCommandOutputSection {
range: (0..text.len()).into(),
label: "Echo".to_string(),
}],
text,
})
}
"pick-one" => {
let Some(selection) = args.first() else {
return Err("no option selected".to_string());
};
match selection.as_str() {
"option-1" | "option-2" | "option-3" => {}
invalid_option => {
return Err(format!("{invalid_option} is not a valid option"));
}
}
let text = format!("You chose {selection}.");
Ok(SlashCommandOutput {
sections: vec![SlashCommandOutputSection {
range: (0..text.len()).into(),
label: format!("Pick One: {selection}"),
}],
text,
})
}
command => Err(format!("unknown slash command: \"{command}\"")),
}
}
}
Auto-completing slash command arguments
For slash commands that have arguments, you may also choose to implement complete_slash_command_argument
to provide completions for your slash commands.
This method accepts the slash command that will be run and the list of arguments passed to it. It returns a list of SlashCommandArgumentCompletion
s that will be shown in the completion menu.
A SlashCommandArgumentCompletion
consists of the following properties:
label
: The label that will be shown in the completion menu.new_text
: The text that will be inserted when the completion is accepted.run_command
: Whether the slash command will be run when the completion is accepted.
Once again, your extension should match
on the command name (without the leading /
) and return the desired argument completions:
impl zed::Extension for MyExtension {
fn complete_slash_command_argument(
&self,
command: SlashCommand,
_args: Vec<String>,
) -> Result<Vec<SlashCommandArgumentCompletion>, String> {
match command.name.as_str() {
"echo" => Ok(vec![]),
"pick-one" => Ok(vec![
SlashCommandArgumentCompletion {
label: "Option One".to_string(),
new_text: "option-1".to_string(),
run_command: true,
},
SlashCommandArgumentCompletion {
label: "Option Two".to_string(),
new_text: "option-2".to_string(),
run_command: true,
},
SlashCommandArgumentCompletion {
label: "Option Three".to_string(),
new_text: "option-3".to_string(),
run_command: true,
},
]),
command => Err(format!("unknown slash command: \"{command}\"")),
}
}
}