1use std::sync::atomic::AtomicBool;
2use std::sync::Arc;
3
4use anyhow::Result;
5use assistant_slash_command::{SlashCommand, SlashCommandOutput, SlashCommandOutputSection};
6use chrono::{DateTime, Local};
7use gpui::{AppContext, Task, WeakView};
8use language::LspAdapterDelegate;
9use ui::{prelude::*, ButtonLike, ElevationIndex};
10use workspace::Workspace;
11
12pub(crate) struct NowSlashCommand;
13
14impl SlashCommand for NowSlashCommand {
15 fn name(&self) -> String {
16 "now".into()
17 }
18
19 fn description(&self) -> String {
20 "insert the current date and time".into()
21 }
22
23 fn menu_text(&self) -> String {
24 "Insert current date and time".into()
25 }
26
27 fn requires_argument(&self) -> bool {
28 false
29 }
30
31 fn complete_argument(
32 &self,
33 _query: String,
34 _cancel: Arc<AtomicBool>,
35 _workspace: Option<WeakView<Workspace>>,
36 _cx: &mut AppContext,
37 ) -> Task<Result<Vec<String>>> {
38 Task::ready(Ok(Vec::new()))
39 }
40
41 fn run(
42 self: Arc<Self>,
43 _argument: Option<&str>,
44 _workspace: WeakView<Workspace>,
45 _delegate: Arc<dyn LspAdapterDelegate>,
46 _cx: &mut WindowContext,
47 ) -> Task<Result<SlashCommandOutput>> {
48 let now = Local::now();
49 let text = format!("Today is {now}.", now = now.to_rfc3339());
50 let range = 0..text.len();
51
52 Task::ready(Ok(SlashCommandOutput {
53 text,
54 sections: vec![SlashCommandOutputSection {
55 range,
56 render_placeholder: Arc::new(move |id, unfold, _cx| {
57 NowPlaceholder { id, unfold, now }.into_any_element()
58 }),
59 }],
60 run_commands_in_text: false,
61 }))
62 }
63}
64
65#[derive(IntoElement)]
66struct NowPlaceholder {
67 pub id: ElementId,
68 pub unfold: Arc<dyn Fn(&mut WindowContext)>,
69 pub now: DateTime<Local>,
70}
71
72impl RenderOnce for NowPlaceholder {
73 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
74 let unfold = self.unfold;
75
76 ButtonLike::new(self.id)
77 .style(ButtonStyle::Filled)
78 .layer(ElevationIndex::ElevatedSurface)
79 .child(Icon::new(IconName::CountdownTimer))
80 .child(Label::new(self.now.to_rfc3339()))
81 .on_click(move |_, cx| unfold(cx))
82 }
83}