workflow_command.rs

 1use std::sync::atomic::AtomicBool;
 2use std::sync::Arc;
 3
 4use anyhow::Result;
 5use assistant_slash_command::{
 6    ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
 7    SlashCommandResult,
 8};
 9use gpui::{Task, WeakView};
10use language::{BufferSnapshot, LspAdapterDelegate};
11use ui::prelude::*;
12use workspace::Workspace;
13
14use crate::prompts::PromptBuilder;
15
16pub(crate) struct WorkflowSlashCommand {
17    prompt_builder: Arc<PromptBuilder>,
18}
19
20impl WorkflowSlashCommand {
21    pub const NAME: &'static str = "workflow";
22
23    pub fn new(prompt_builder: Arc<PromptBuilder>) -> Self {
24        Self { prompt_builder }
25    }
26}
27
28impl SlashCommand for WorkflowSlashCommand {
29    fn name(&self) -> String {
30        Self::NAME.into()
31    }
32
33    fn description(&self) -> String {
34        "Insert prompt to opt into the edit workflow".into()
35    }
36
37    fn menu_text(&self) -> String {
38        self.description()
39    }
40
41    fn requires_argument(&self) -> bool {
42        false
43    }
44
45    fn complete_argument(
46        self: Arc<Self>,
47        _arguments: &[String],
48        _cancel: Arc<AtomicBool>,
49        _workspace: Option<WeakView<Workspace>>,
50        _cx: &mut WindowContext,
51    ) -> Task<Result<Vec<ArgumentCompletion>>> {
52        Task::ready(Ok(Vec::new()))
53    }
54
55    fn run(
56        self: Arc<Self>,
57        _arguments: &[String],
58        _context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
59        _context_buffer: BufferSnapshot,
60        _workspace: WeakView<Workspace>,
61        _delegate: Option<Arc<dyn LspAdapterDelegate>>,
62        cx: &mut WindowContext,
63    ) -> Task<SlashCommandResult> {
64        let prompt_builder = self.prompt_builder.clone();
65        cx.spawn(|_cx| async move {
66            let text = prompt_builder.generate_workflow_prompt()?;
67            let range = 0..text.len();
68
69            Ok(SlashCommandOutput {
70                text,
71                sections: vec![SlashCommandOutputSection {
72                    range,
73                    icon: IconName::Route,
74                    label: "Workflow".into(),
75                    metadata: None,
76                }],
77                run_commands_in_text: false,
78            }
79            .to_event_stream())
80        })
81    }
82}