assistant_slash_command.rs

 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}