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 menu_text(&self) -> String;
24 fn complete_argument(
25 &self,
26 query: String,
27 cancel: Arc<AtomicBool>,
28 workspace: Option<WeakView<Workspace>>,
29 cx: &mut AppContext,
30 ) -> Task<Result<Vec<String>>>;
31 fn requires_argument(&self) -> bool;
32 fn run(
33 self: Arc<Self>,
34 argument: Option<&str>,
35 workspace: WeakView<Workspace>,
36 // TODO: We're just using the `LspAdapterDelegate` here because that is
37 // what the extension API is already expecting.
38 //
39 // It may be that `LspAdapterDelegate` needs a more general name, or
40 // perhaps another kind of delegate is needed here.
41 delegate: Arc<dyn LspAdapterDelegate>,
42 cx: &mut WindowContext,
43 ) -> Task<Result<SlashCommandOutput>>;
44}
45
46pub type RenderFoldPlaceholder = Arc<
47 dyn Send
48 + Sync
49 + Fn(ElementId, Arc<dyn Fn(&mut WindowContext)>, &mut WindowContext) -> AnyElement,
50>;
51
52pub struct SlashCommandOutput {
53 pub text: String,
54 pub sections: Vec<SlashCommandOutputSection<usize>>,
55 pub run_commands_in_text: bool,
56}
57
58#[derive(Clone)]
59pub struct SlashCommandOutputSection<T> {
60 pub range: Range<T>,
61 pub render_placeholder: RenderFoldPlaceholder,
62}