Slash Command Extensions | Zed Code Editor Documentation
Description: Learn how to use and customize Zed, the fast, collaborative code editor. Official docs on features, configuration, AI tools, and workflows.

# 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}\"")),
            }
        }
    }