From 350fd6db4c0fa49c01a45c8bd09d58904d3176a8 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 7 Apr 2025 17:42:11 -0400 Subject: [PATCH] agent: Copy text as Markdown (#28272) Release Notes: - agent: Copying text in the Agent Panel will now copy it as Markdown. Co-authored-by: Antonio Scandurra --- assets/keymaps/default-linux.json | 7 +++++++ assets/keymaps/default-macos.json | 7 +++++++ crates/markdown/src/markdown.rs | 20 ++++++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 112a3ce263d3a99cac7862da8e9ef1d04554b261..c500a5a620158c612f472cb3b99eb005b983579d 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -631,6 +631,13 @@ "ctrl-alt-e": "agent::RemoveAllContext" } }, + { + "context": "AgentPanel > Markdown", + "bindings": { + "copy": "markdown::CopyAsMarkdown", + "ctrl-c": "markdown::CopyAsMarkdown" + } + }, { "context": "AgentPanel && prompt_editor", "use_key_equivalents": true, diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index fb911e714b0122f3065ad05ed689d70de1af0213..9de4538656d406adb3cc080235641afa107e844d 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -291,6 +291,13 @@ "cmd-alt-e": "agent::RemoveAllContext" } }, + { + "context": "AgentPanel > Markdown", + "use_key_equivalents": true, + "bindings": { + "cmd-c": "markdown::CopyAsMarkdown" + } + }, { "context": "AgentPanel && prompt_editor", "use_key_equivalents": true, diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index 081ccea9fb343b20a3e23cc6d7ac34a9d8e9c8e0..5aa70c0cba2ba3d442a79cb28f26541749ee2229 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -90,7 +90,7 @@ struct Options { copy_code_block_buttons: bool, } -actions!(markdown, [Copy]); +actions!(markdown, [Copy, CopyAsMarkdown]); impl Markdown { pub fn new( @@ -178,6 +178,14 @@ impl Markdown { cx.write_to_clipboard(ClipboardItem::new_string(text)); } + fn copy_as_markdown(&self, _: &mut Window, cx: &mut Context) { + if self.selection.end <= self.selection.start { + return; + } + let text = self.source[self.selection.start..self.selection.end].to_string(); + cx.write_to_clipboard(ClipboardItem::new_string(text)); + } + fn parse(&mut self, cx: &mut Context) { if self.source.is_empty() { return; @@ -1040,8 +1048,8 @@ impl Element for MarkdownElement { let mut context = KeyContext::default(); context.add("Markdown"); window.set_key_context(context); - let entity = self.markdown.clone(); window.on_action(std::any::TypeId::of::(), { + let entity = self.markdown.clone(); let text = rendered_markdown.text.clone(); move |_, phase, window, cx| { let text = text.clone(); @@ -1050,6 +1058,14 @@ impl Element for MarkdownElement { } } }); + window.on_action(std::any::TypeId::of::(), { + let entity = self.markdown.clone(); + move |_, phase, window, cx| { + if phase == DispatchPhase::Bubble { + entity.update(cx, move |this, cx| this.copy_as_markdown(window, cx)) + } + } + }); self.paint_mouse_listeners(hitbox, &rendered_markdown.text, window, cx); rendered_markdown.element.paint(window, cx);