now_command.rs

 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}