default_command.rs

 1use crate::prompt_library::PromptStore;
 2use anyhow::{anyhow, Result};
 3use assistant_slash_command::{
 4    ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
 5    SlashCommandResult,
 6};
 7use gpui::{Task, WeakView};
 8use language::{BufferSnapshot, LspAdapterDelegate};
 9use std::{
10    fmt::Write,
11    sync::{atomic::AtomicBool, Arc},
12};
13use ui::prelude::*;
14use workspace::Workspace;
15
16pub(crate) struct DefaultSlashCommand;
17
18impl SlashCommand for DefaultSlashCommand {
19    fn name(&self) -> String {
20        "default".into()
21    }
22
23    fn description(&self) -> String {
24        "insert default prompt".into()
25    }
26
27    fn menu_text(&self) -> String {
28        "Insert Default Prompt".into()
29    }
30
31    fn requires_argument(&self) -> bool {
32        false
33    }
34
35    fn complete_argument(
36        self: Arc<Self>,
37        _arguments: &[String],
38        _cancellation_flag: Arc<AtomicBool>,
39        _workspace: Option<WeakView<Workspace>>,
40        _cx: &mut WindowContext,
41    ) -> Task<Result<Vec<ArgumentCompletion>>> {
42        Task::ready(Err(anyhow!("this command does not require argument")))
43    }
44
45    fn run(
46        self: Arc<Self>,
47        _arguments: &[String],
48        _context_slash_command_output_sections: &[SlashCommandOutputSection<language::Anchor>],
49        _context_buffer: BufferSnapshot,
50        _workspace: WeakView<Workspace>,
51        _delegate: Option<Arc<dyn LspAdapterDelegate>>,
52        cx: &mut WindowContext,
53    ) -> Task<SlashCommandResult> {
54        let store = PromptStore::global(cx);
55        cx.background_executor().spawn(async move {
56            let store = store.await?;
57            let prompts = store.default_prompt_metadata();
58
59            let mut text = String::new();
60            text.push('\n');
61            for prompt in prompts {
62                if let Some(title) = prompt.title {
63                    writeln!(text, "/prompt {}", title).unwrap();
64                }
65            }
66            text.pop();
67
68            if text.is_empty() {
69                text.push('\n');
70            }
71
72            if !text.ends_with('\n') {
73                text.push('\n');
74            }
75
76            Ok(SlashCommandOutput {
77                sections: vec![SlashCommandOutputSection {
78                    range: 0..text.len(),
79                    icon: IconName::Library,
80                    label: "Default".into(),
81                    metadata: None,
82                }],
83                text,
84                run_commands_in_text: true,
85            }
86            .to_event_stream())
87        })
88    }
89}