diff --git a/crates/assistant/src/assistant.rs b/crates/assistant/src/assistant.rs index 0c9c4a4c11..bb795b1034 100644 --- a/crates/assistant/src/assistant.rs +++ b/crates/assistant/src/assistant.rs @@ -25,8 +25,8 @@ use semantic_index::{CloudEmbeddingProvider, SemanticIndex}; use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsStore}; use slash_command::{ - active_command, default_command, fetch_command, file_command, project_command, prompt_command, - rustdoc_command, search_command, tabs_command, + active_command, default_command, fetch_command, file_command, now_command, project_command, + prompt_command, rustdoc_command, search_command, tabs_command, }; use std::{ fmt::{self, Display}, @@ -307,6 +307,7 @@ fn register_slash_commands(cx: &mut AppContext) { slash_command_registry.register_command(search_command::SearchSlashCommand, true); slash_command_registry.register_command(prompt_command::PromptSlashCommand, true); slash_command_registry.register_command(default_command::DefaultSlashCommand, true); + slash_command_registry.register_command(now_command::NowSlashCommand, true); slash_command_registry.register_command(rustdoc_command::RustdocSlashCommand, false); slash_command_registry.register_command(fetch_command::FetchSlashCommand, false); } diff --git a/crates/assistant/src/slash_command.rs b/crates/assistant/src/slash_command.rs index aba2859e77..bcc1d342c5 100644 --- a/crates/assistant/src/slash_command.rs +++ b/crates/assistant/src/slash_command.rs @@ -20,6 +20,7 @@ pub mod active_command; pub mod default_command; pub mod fetch_command; pub mod file_command; +pub mod now_command; pub mod project_command; pub mod prompt_command; pub mod rustdoc_command; diff --git a/crates/assistant/src/slash_command/now_command.rs b/crates/assistant/src/slash_command/now_command.rs new file mode 100644 index 0000000000..5dc87905b5 --- /dev/null +++ b/crates/assistant/src/slash_command/now_command.rs @@ -0,0 +1,83 @@ +use std::sync::atomic::AtomicBool; +use std::sync::Arc; + +use anyhow::Result; +use assistant_slash_command::{SlashCommand, SlashCommandOutput, SlashCommandOutputSection}; +use chrono::{DateTime, Local}; +use gpui::{AppContext, Task, WeakView}; +use language::LspAdapterDelegate; +use ui::{prelude::*, ButtonLike, ElevationIndex}; +use workspace::Workspace; + +pub(crate) struct NowSlashCommand; + +impl SlashCommand for NowSlashCommand { + fn name(&self) -> String { + "now".into() + } + + fn description(&self) -> String { + "insert the current date and time".into() + } + + fn menu_text(&self) -> String { + "Insert current date and time".into() + } + + fn requires_argument(&self) -> bool { + false + } + + fn complete_argument( + &self, + _query: String, + _cancel: Arc, + _workspace: Option>, + _cx: &mut AppContext, + ) -> Task>> { + Task::ready(Ok(Vec::new())) + } + + fn run( + self: Arc, + _argument: Option<&str>, + _workspace: WeakView, + _delegate: Arc, + _cx: &mut WindowContext, + ) -> Task> { + let now = Local::now(); + let text = format!("Today is {now}.", now = now.to_rfc3339()); + let range = 0..text.len(); + + Task::ready(Ok(SlashCommandOutput { + text, + sections: vec![SlashCommandOutputSection { + range, + render_placeholder: Arc::new(move |id, unfold, _cx| { + NowPlaceholder { id, unfold, now }.into_any_element() + }), + }], + run_commands_in_text: false, + })) + } +} + +#[derive(IntoElement)] +struct NowPlaceholder { + pub id: ElementId, + pub unfold: Arc, + pub now: DateTime, +} + +impl RenderOnce for NowPlaceholder { + fn render(self, _cx: &mut WindowContext) -> impl IntoElement { + let unfold = self.unfold; + + ButtonLike::new(self.id) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::ElevatedSurface) + .child(Icon::new(IconName::CountdownTimer)) + .child(Label::new(self.now.to_rfc3339())) + .on_click(move |_, cx| unfold(cx)) + } +}