1# Slash Commands
2
3Extensions may provide slash commands for use in the Assistant.
4
5## Example extension
6
7To see a working example of an extension that provides slash commands, check out the [`slash-commands-example` extension](https://github.com/zed-industries/zed/tree/main/extensions/slash-commands-example).
8
9This extension can be [installed as a dev extension](./developing-extensions.md#developing-an-extension-locally) if you want to try it out for yourself.
10
11## Defining slash commands
12
13A given extension may provide one or more slash commands. Each slash command must be registered in the `extension.toml`.
14
15For example, here is an extension that provides two slash commands: `/echo` and `/pick-one`:
16
17```toml
18[slash_commands.echo]
19description = "echoes the provided input"
20requires_argument = true
21
22[slash_commands.pick-one]
23description = "pick one of three options"
24requires_argument = true
25```
26
27Each slash command may define the following properties:
28
29- `description`: A description of the slash command that will be shown when completing available commands.
30- `requires_argument`: Indicates whether a slash command requires at least one argument to run.
31
32## Implementing slash command behavior
33
34To implement behavior for your slash commands, implement `run_slash_command` for your extension.
35
36This method accepts the slash command that will be run, the list of arguments passed to it, and an optional `Worktree`.
37
38This 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.
39
40Your extension should `match` on the command name (without the leading `/`) and then execute behavior accordingly:
41
42```rs
43impl zed::Extension for MyExtension {
44 fn run_slash_command(
45 &self,
46 command: SlashCommand,
47 args: Vec<String>,
48 _worktree: Option<&Worktree>,
49 ) -> Result<SlashCommandOutput, String> {
50 match command.name.as_str() {
51 "echo" => {
52 if args.is_empty() {
53 return Err("nothing to echo".to_string());
54 }
55
56 let text = args.join(" ");
57
58 Ok(SlashCommandOutput {
59 sections: vec![SlashCommandOutputSection {
60 range: (0..text.len()).into(),
61 label: "Echo".to_string(),
62 }],
63 text,
64 })
65 }
66 "pick-one" => {
67 let Some(selection) = args.first() else {
68 return Err("no option selected".to_string());
69 };
70
71 match selection.as_str() {
72 "option-1" | "option-2" | "option-3" => {}
73 invalid_option => {
74 return Err(format!("{invalid_option} is not a valid option"));
75 }
76 }
77
78 let text = format!("You chose {selection}.");
79
80 Ok(SlashCommandOutput {
81 sections: vec![SlashCommandOutputSection {
82 range: (0..text.len()).into(),
83 label: format!("Pick One: {selection}"),
84 }],
85 text,
86 })
87 }
88 command => Err(format!("unknown slash command: \"{command}\"")),
89 }
90 }
91}
92```
93
94## Auto-completing slash command arguments
95
96For slash commands that have arguments, you may also choose to implement `complete_slash_command_argument` to provide completions for your slash commands.
97
98This 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.
99
100A `SlashCommandArgumentCompletion` consists of the following properties:
101
102- `label`: The label that will be shown in the completion menu.
103- `new_text`: The text that will be inserted when the completion is accepted.
104- `run_command`: Whether the slash command will be run when the completion is accepted.
105
106Once again, your extension should `match` on the command name (without the leading `/`) and return the desired argument completions:
107
108```rs
109impl zed::Extension for MyExtension {
110 fn complete_slash_command_argument(
111 &self,
112 command: SlashCommand,
113 _args: Vec<String>,
114 ) -> Result<Vec<SlashCommandArgumentCompletion>, String> {
115 match command.name.as_str() {
116 "echo" => Ok(vec![]),
117 "pick-one" => Ok(vec![
118 SlashCommandArgumentCompletion {
119 label: "Option One".to_string(),
120 new_text: "option-1".to_string(),
121 run_command: true,
122 },
123 SlashCommandArgumentCompletion {
124 label: "Option Two".to_string(),
125 new_text: "option-2".to_string(),
126 run_command: true,
127 },
128 SlashCommandArgumentCompletion {
129 label: "Option Three".to_string(),
130 new_text: "option-3".to_string(),
131 run_command: true,
132 },
133 ]),
134 command => Err(format!("unknown slash command: \"{command}\"")),
135 }
136 }
137}
138```