1use std::sync::atomic::AtomicBool;
2use std::sync::Arc;
3
4use anyhow::{Context as _, Result};
5use assets::Assets;
6use assistant_slash_command::{
7 ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
8};
9use gpui::{AppContext, AssetSource, Task, WeakView};
10use language::LspAdapterDelegate;
11use text::LineEnding;
12use ui::prelude::*;
13use workspace::Workspace;
14
15pub(crate) struct WorkflowSlashCommand;
16
17impl SlashCommand for WorkflowSlashCommand {
18 fn name(&self) -> String {
19 "workflow".into()
20 }
21
22 fn description(&self) -> String {
23 "insert a prompt that opts into the edit workflow".into()
24 }
25
26 fn menu_text(&self) -> String {
27 "Insert Workflow Prompt".into()
28 }
29
30 fn requires_argument(&self) -> bool {
31 false
32 }
33
34 fn complete_argument(
35 self: Arc<Self>,
36 _query: String,
37 _cancel: Arc<AtomicBool>,
38 _workspace: Option<WeakView<Workspace>>,
39 _cx: &mut AppContext,
40 ) -> Task<Result<Vec<ArgumentCompletion>>> {
41 Task::ready(Ok(Vec::new()))
42 }
43
44 fn run(
45 self: Arc<Self>,
46 _argument: Option<&str>,
47 _workspace: WeakView<Workspace>,
48 _delegate: Option<Arc<dyn LspAdapterDelegate>>,
49 _cx: &mut WindowContext,
50 ) -> Task<Result<SlashCommandOutput>> {
51 let mut text = match Assets
52 .load("prompts/edit_workflow.md")
53 .and_then(|prompt| prompt.context("prompts/edit_workflow.md not found"))
54 {
55 Ok(prompt) => String::from_utf8_lossy(&prompt).into_owned(),
56 Err(error) => return Task::ready(Err(error)),
57 };
58 LineEnding::normalize(&mut text);
59 let range = 0..text.len();
60
61 Task::ready(Ok(SlashCommandOutput {
62 text,
63 sections: vec![SlashCommandOutputSection {
64 range,
65 icon: IconName::Route,
66 label: "Workflow".into(),
67 }],
68 run_commands_in_text: false,
69 }))
70 }
71}