assistant_slash_command.rs

 1mod slash_command_registry;
 2
 3use std::sync::atomic::AtomicBool;
 4use std::sync::Arc;
 5
 6use anyhow::Result;
 7use futures::channel::oneshot;
 8use gpui::{AppContext, Task};
 9
10pub use slash_command_registry::*;
11
12pub fn init(cx: &mut AppContext) {
13    SlashCommandRegistry::default_global(cx);
14}
15
16pub trait SlashCommand: 'static + Send + Sync {
17    fn name(&self) -> String;
18    fn description(&self) -> String;
19    fn complete_argument(
20        &self,
21        query: String,
22        cancel: Arc<AtomicBool>,
23        cx: &mut AppContext,
24    ) -> Task<Result<Vec<String>>>;
25    fn requires_argument(&self) -> bool;
26    fn run(&self, argument: Option<&str>, cx: &mut AppContext) -> SlashCommandInvocation;
27}
28
29pub struct SlashCommandInvocation {
30    pub output: Task<Result<String>>,
31    pub invalidated: oneshot::Receiver<()>,
32    pub cleanup: SlashCommandCleanup,
33}
34
35#[derive(Default)]
36pub struct SlashCommandCleanup(Option<Box<dyn FnOnce()>>);
37
38impl SlashCommandCleanup {
39    pub fn new(cleanup: impl FnOnce() + 'static) -> Self {
40        Self(Some(Box::new(cleanup)))
41    }
42}
43
44impl Drop for SlashCommandCleanup {
45    fn drop(&mut self) {
46        if let Some(cleanup) = self.0.take() {
47            cleanup();
48        }
49    }
50}