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: Arc<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 icon: IconName::CountdownTimer,
57 label: now.to_rfc3339().into(),
58 }],
59 run_commands_in_text: false,
60 }))
61 }
62}
63
64#[derive(IntoElement)]
65struct NowPlaceholder {
66 pub id: ElementId,
67 pub unfold: Arc<dyn Fn(&mut WindowContext)>,
68 pub now: DateTime<Local>,
69}
70
71impl RenderOnce for NowPlaceholder {
72 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
73 let unfold = self.unfold;
74
75 ButtonLike::new(self.id)
76 .style(ButtonStyle::Filled)
77 .layer(ElevationIndex::ElevatedSurface)
78 .child(Icon::new(IconName::CountdownTimer))
79 .child(Label::new(self.now.to_rfc3339()))
80 .on_click(move |_, cx| unfold(cx))
81 }
82}