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