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}