default_command.rs

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