1mod slash_command_registry;
2
3use anyhow::Result;
4use gpui::{AnyElement, AppContext, ElementId, Task, WeakView, WindowContext};
5use language::{CodeLabel, LspAdapterDelegate};
6pub use slash_command_registry::*;
7use std::{
8 ops::Range,
9 sync::{atomic::AtomicBool, Arc},
10};
11use workspace::Workspace;
12
13pub fn init(cx: &mut AppContext) {
14 SlashCommandRegistry::default_global(cx);
15}
16
17pub trait SlashCommand: 'static + Send + Sync {
18 fn name(&self) -> String;
19 fn label(&self, _cx: &AppContext) -> CodeLabel {
20 CodeLabel::plain(self.name(), None)
21 }
22 fn description(&self) -> String;
23 fn tooltip_text(&self) -> String;
24 fn complete_argument(
25 &self,
26 query: String,
27 cancel: Arc<AtomicBool>,
28 cx: &mut AppContext,
29 ) -> Task<Result<Vec<String>>>;
30 fn requires_argument(&self) -> bool;
31 fn run(
32 self: Arc<Self>,
33 argument: Option<&str>,
34 workspace: WeakView<Workspace>,
35 // TODO: We're just using the `LspAdapterDelegate` here because that is
36 // what the extension API is already expecting.
37 //
38 // It may be that `LspAdapterDelegate` needs a more general name, or
39 // perhaps another kind of delegate is needed here.
40 delegate: Arc<dyn LspAdapterDelegate>,
41 cx: &mut WindowContext,
42 ) -> Task<Result<SlashCommandOutput>>;
43}
44
45pub type RenderFoldPlaceholder = Arc<
46 dyn Send
47 + Sync
48 + Fn(ElementId, Arc<dyn Fn(&mut WindowContext)>, &mut WindowContext) -> AnyElement,
49>;
50
51pub struct SlashCommandOutput {
52 pub text: String,
53 pub sections: Vec<SlashCommandOutputSection<usize>>,
54}
55
56#[derive(Clone)]
57pub struct SlashCommandOutputSection<T> {
58 pub range: Range<T>,
59 pub render_placeholder: RenderFoldPlaceholder,
60}