Allow defining slash commands in extensions (#12255)

This PR adds initial support for defining slash commands for the
Assistant from extensions.

Slash commands are defined in an extension's `extension.toml`:

```toml
[slash_commands.gleam-project]
description = "Returns information about the current Gleam project."
requires_argument = false
```

and then executed via the `run_slash_command` method on the `Extension`
trait:

```rs
impl Extension for GleamExtension {
    // ...

    fn run_slash_command(
        &self,
        command: SlashCommand,
        _argument: Option<String>,
        worktree: &zed::Worktree,
    ) -> Result<Option<String>, String> {
        match command.name.as_str() {
            "gleam-project" => Ok(Some("Yayyy".to_string())),
            command => Err(format!("unknown slash command: \"{command}\"")),
        }
    }
}
```

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-05-24 15:44:32 -04:00 committed by GitHub
parent 055a13a9b6
commit 82f5f36422
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 310 additions and 14 deletions

View file

@ -13,4 +13,4 @@ path = "src/gleam.rs"
crate-type = ["cdylib"]
[dependencies]
zed_extension_api = "0.0.6"
zed_extension_api = { path = "../../crates/extension_api" }

View file

@ -13,3 +13,7 @@ language = "Gleam"
[grammars.gleam]
repository = "https://github.com/gleam-lang/tree-sitter-gleam"
commit = "8432ffe32ccd360534837256747beb5b1c82fca1"
[slash_commands.gleam-project]
description = "Returns information about the current Gleam project."
requires_argument = false

View file

@ -1,6 +1,6 @@
use std::fs;
use zed::lsp::CompletionKind;
use zed::{CodeLabel, CodeLabelSpan, LanguageServerId};
use zed::{CodeLabel, CodeLabelSpan, LanguageServerId, SlashCommand};
use zed_extension_api::{self as zed, Result};
struct GleamExtension {
@ -142,6 +142,28 @@ impl zed::Extension for GleamExtension {
code,
})
}
fn run_slash_command(
&self,
command: SlashCommand,
_argument: Option<String>,
worktree: &zed::Worktree,
) -> Result<Option<String>, String> {
match command.name.as_str() {
"gleam-project" => {
let mut message = String::new();
message.push_str("You are in a Gleam project.\n");
if let Some(gleam_toml) = worktree.read_text_file("gleam.toml").ok() {
message.push_str("The `gleam.toml` is as follows:\n");
message.push_str(&gleam_toml);
}
Ok(Some(message))
}
command => Err(format!("unknown slash command: \"{command}\"")),
}
}
}
zed::register_extension!(GleamExtension);