1mod slash_command_registry;
2
3use anyhow::Result;
4use gpui::{AnyElement, AppContext, ElementId, SharedString, Task, WeakView, WindowContext};
5use language::{CodeLabel, LspAdapterDelegate};
6use serde::{Deserialize, Serialize};
7pub use slash_command_registry::*;
8use std::{
9 ops::Range,
10 sync::{atomic::AtomicBool, Arc},
11};
12use workspace::{ui::IconName, Workspace};
13
14pub fn init(cx: &mut AppContext) {
15 SlashCommandRegistry::default_global(cx);
16}
17
18#[derive(Debug)]
19pub struct ArgumentCompletion {
20 /// The label to display for this completion.
21 pub label: CodeLabel,
22 /// The new text that should be inserted into the command when this completion is accepted.
23 pub new_text: String,
24 /// Whether the command should be run when accepting this completion.
25 pub run_command: bool,
26 /// Whether to replace the all arguments, or whether to treat this as an independent argument.
27 pub replace_previous_arguments: bool,
28}
29
30pub trait SlashCommand: 'static + Send + Sync {
31 fn name(&self) -> String;
32 fn label(&self, _cx: &AppContext) -> CodeLabel {
33 CodeLabel::plain(self.name(), None)
34 }
35 fn description(&self) -> String;
36 fn menu_text(&self) -> String;
37 fn complete_argument(
38 self: Arc<Self>,
39 arguments: &[String],
40 cancel: Arc<AtomicBool>,
41 workspace: Option<WeakView<Workspace>>,
42 cx: &mut WindowContext,
43 ) -> Task<Result<Vec<ArgumentCompletion>>>;
44 fn requires_argument(&self) -> bool;
45 fn accepts_arguments(&self) -> bool {
46 self.requires_argument()
47 }
48 fn run(
49 self: Arc<Self>,
50 arguments: &[String],
51 workspace: WeakView<Workspace>,
52 // TODO: We're just using the `LspAdapterDelegate` here because that is
53 // what the extension API is already expecting.
54 //
55 // It may be that `LspAdapterDelegate` needs a more general name, or
56 // perhaps another kind of delegate is needed here.
57 delegate: Option<Arc<dyn LspAdapterDelegate>>,
58 cx: &mut WindowContext,
59 ) -> Task<Result<SlashCommandOutput>>;
60}
61
62pub type RenderFoldPlaceholder = Arc<
63 dyn Send
64 + Sync
65 + Fn(ElementId, Arc<dyn Fn(&mut WindowContext)>, &mut WindowContext) -> AnyElement,
66>;
67
68#[derive(Debug, Default)]
69pub struct SlashCommandOutput {
70 pub text: String,
71 pub sections: Vec<SlashCommandOutputSection<usize>>,
72 pub run_commands_in_text: bool,
73}
74
75#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
76pub struct SlashCommandOutputSection<T> {
77 pub range: Range<T>,
78 pub icon: IconName,
79 pub label: SharedString,
80}