Unify copy actions for agent panel and markdown (#63884)

Before, it was not possible at all to copy the text from the agent
panel, only its markdown.
The PR breaks the existing ctrl/cmd-c binding there by using the same
approach markdown preview does: copy as text by default, allow to copy
as markdown via the context menu.

Before:


https://github.com/user-attachments/assets/2014f363-5167-4700-be86-9c0774d7e4fd

After:


https://github.com/user-attachments/assets/1dad253c-7a3b-4ca7-99c8-e8df8b3c3fd6


Release Notes:

- Changed agent panel to copy text with cmd/ctrl-c, as markdown preview
does. `markdown::CopyAsMarkdown` action is available still and can be
bound if needed.
This commit is contained in:
Kirill Bulatov authored and GitHub committed 2026-09-08 11:21:20 +00:00
1 parent 80e2242d3d
commit 2e9b4fe596
5 files changed
+45 -46

No files matched your search

-8
View File
@@ -226,14 +226,6 @@
"ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }],
},
},
{
"context": "AgentPanel > Markdown",
"bindings": {
"copy": "markdown::CopyAsMarkdown",
"ctrl-insert": "markdown::CopyAsMarkdown",
"ctrl-c": "markdown::CopyAsMarkdown",
},
},
{
"context": "AgentFeedbackMessageEditor > Editor",
"bindings": {
-7
View File
@@ -264,13 +264,6 @@
"ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }],
},
},
{
"context": "AgentPanel > Markdown",
"use_key_equivalents": true,
"bindings": {
"cmd-c": "markdown::CopyAsMarkdown",
},
},
{
"context": "AgentFeedbackMessageEditor > Editor",
"use_key_equivalents": true,
-7
View File
@@ -228,13 +228,6 @@
"ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }],
},
},
{
"context": "AgentPanel > Markdown",
"use_key_equivalents": true,
"bindings": {
"ctrl-c": "markdown::CopyAsMarkdown",
},
},
{
"context": "AgentFeedbackMessageEditor > Editor",
"use_key_equivalents": true,
@@ -7566,29 +7566,36 @@ impl ThreadView {
},
);
let has_selection = chunks
.map(|chunks| {
chunks.iter().any(|chunk| {
let md = match chunk {
AssistantMessageChunk::Message { block, .. } => {
block.markdown()
}
AssistantMessageChunk::Thought { block, .. } => {
block.markdown()
}
};
md.map_or(false, |m| m.read(cx).has_selection())
})
})
.unwrap_or(false);
let context_menu_link = chunks.and_then(|chunks| {
chunks.iter().find_map(|chunk| {
let md = match chunk {
let markdown = match chunk {
AssistantMessageChunk::Message { block, .. } => block.markdown(),
AssistantMessageChunk::Thought { block, .. } => block.markdown(),
};
md.and_then(|m| m.read(cx).context_menu_link().cloned())
markdown
.and_then(|markdown| markdown.read(cx).context_menu_link().cloned())
})
});
let selected_text = chunks.and_then(|chunks| {
chunks.iter().find_map(|chunk| {
let markdown = match chunk {
AssistantMessageChunk::Message { block, .. } => block.markdown(),
AssistantMessageChunk::Thought { block, .. } => block.markdown(),
};
markdown.and_then(|markdown| {
markdown.read(cx).context_menu_selected_text().cloned()
})
})
});
let selected_markdown = chunks.and_then(|chunks| {
chunks.iter().find_map(|chunk| {
let markdown = match chunk {
AssistantMessageChunk::Message { block, .. } => block.markdown(),
AssistantMessageChunk::Thought { block, .. } => block.markdown(),
};
markdown.and_then(|markdown| {
markdown.read(cx).context_menu_selected_markdown().cloned()
})
})
});
@@ -7649,11 +7656,24 @@ impl ThreadView {
})
.separator()
})
.action_disabled_when(
!has_selection,
"Copy Selection",
Box::new(markdown::CopyAsMarkdown),
)
.when_some(selected_text, |menu, selected_text| {
menu.entry("Copy", Some(Box::new(markdown::Copy)), move |_, cx| {
cx.write_to_clipboard(ClipboardItem::new_string(
selected_text.to_string(),
));
})
})
.when_some(selected_markdown, |menu, selected_markdown| {
menu.entry(
"Copy as Markdown",
Some(Box::new(markdown::CopyAsMarkdown)),
move |_, cx| {
cx.write_to_clipboard(ClipboardItem::new_string(
selected_markdown.to_string(),
));
},
)
})
.item(copy_this_agent_response)
.separator()
.item(scroll_item)
+2 -1
View File
@@ -79,7 +79,8 @@ The checkpoint button appears even if you interrupt the thread midway through an
Right-click on any agent response in the thread view to access a context menu with the following actions:
- **Copy Selection**: Copies the currently selected text as Markdown (available when text is selected).
- **Copy**: Copies the currently selected text as plain text (available when text is selected).
- **Copy as Markdown**: Copies the currently selected text as Markdown (available when text is selected).
- **Copy This Agent Response**: Copies the full text of the agent response you right-clicked on.
- **Scroll to Top / Scroll to Bottom**: Scrolls to the beginning or end of the thread, depending on your current position.
- **Open Thread as Markdown**: Opens the entire thread as a Markdown file in a new tab.