diff --git a/crates/assistant/src/prompt_library.rs b/crates/assistant/src/prompt_library.rs index 117df8bd8b..67634fb3c4 100644 --- a/crates/assistant/src/prompt_library.rs +++ b/crates/assistant/src/prompt_library.rs @@ -42,7 +42,12 @@ use workspace::Workspace; actions!( prompt_library, - [NewPrompt, DeletePrompt, ToggleDefaultPrompt] + [ + NewPrompt, + DeletePrompt, + DuplicatePrompt, + ToggleDefaultPrompt + ] ); /// Init starts loading the PromptStore in the background and assigns @@ -411,6 +416,12 @@ impl PromptLibrary { } } + pub fn duplicate_active_prompt(&mut self, cx: &mut ViewContext) { + if let Some(active_prompt_id) = self.active_prompt_id { + self.duplicate_prompt(active_prompt_id, cx); + } + } + pub fn toggle_default_for_active_prompt(&mut self, cx: &mut ViewContext) { if let Some(active_prompt_id) = self.active_prompt_id { self.toggle_default_for_prompt(active_prompt_id, cx); @@ -564,6 +575,25 @@ impl PromptLibrary { } } + pub fn duplicate_prompt(&mut self, prompt_id: PromptId, cx: &mut ViewContext) { + if let Some(prompt) = self.prompt_editors.get(&prompt_id) { + let new_id = PromptId::new(); + let title = prompt.title_editor.read(cx).text(cx); + let body = prompt.body_editor.read(cx).text(cx); + let save = self + .store + .save(new_id, Some(title.into()), false, body.into()); + self.picker.update(cx, |picker, cx| picker.refresh(cx)); + cx.spawn(|this, mut cx| async move { + save.await?; + this.update(&mut cx, |prompt_library, cx| { + prompt_library.load_prompt(new_id, true, cx) + }) + }) + .detach_and_log_err(cx); + } + } + fn focus_active_prompt(&mut self, _: &Tab, cx: &mut ViewContext) { if let Some(active_prompt) = self.active_prompt_id { self.prompt_editors[&active_prompt] @@ -897,24 +927,28 @@ impl PromptLibrary { cx.dispatch_action(Box::new(DeletePrompt)); }), ) - // .child( - // IconButton::new( - // "duplicate-prompt", - // IconName::BookCopy, - // ) - // .size(ButtonSize::Large) - // .style(ButtonStyle::Transparent) - // .shape(IconButtonShape::Square) - // .size(ButtonSize::Large) - // .tooltip(move |cx| { - // Tooltip::for_action( - // "Duplicate Prompt", - // &gpui::NoAction, - // cx, - // ) - // }) - // .disabled(true), - // ) + .child( + IconButton::new( + "duplicate-prompt", + IconName::BookCopy, + ) + .size(ButtonSize::Large) + .style(ButtonStyle::Transparent) + .shape(IconButtonShape::Square) + .size(ButtonSize::Large) + .tooltip(move |cx| { + Tooltip::for_action( + "Duplicate Prompt", + &DuplicatePrompt, + cx, + ) + }) + .on_click(|_, cx| { + cx.dispatch_action(Box::new( + DuplicatePrompt, + )); + }), + ) .child( IconButton::new( "toggle-default-prompt", @@ -973,6 +1007,7 @@ impl Render for PromptLibrary { .key_context("PromptLibrary") .on_action(cx.listener(|this, &NewPrompt, cx| this.new_prompt(cx))) .on_action(cx.listener(|this, &DeletePrompt, cx| this.delete_active_prompt(cx))) + .on_action(cx.listener(|this, &DuplicatePrompt, cx| this.duplicate_active_prompt(cx))) .on_action(cx.listener(|this, &ToggleDefaultPrompt, cx| { this.toggle_default_for_active_prompt(cx) })) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index c3cf05a8f0..18289a9851 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2131,7 +2131,7 @@ impl Editor { self.refresh_inline_completion(false, cx); } - pub fn placeholder_text(&self, _cx: &mut WindowContext) -> Option<&str> { + pub fn placeholder_text(&self, _cx: &WindowContext) -> Option<&str> { self.placeholder_text.as_deref() }