Skip to content

feat(vscode): add native context menu copy actions for webview chat#3477

Merged
yiliang114 merged 6 commits into
QwenLM:mainfrom
dreamWB:feat/webview-copy-button
Apr 24, 2026
Merged

feat(vscode): add native context menu copy actions for webview chat#3477
yiliang114 merged 6 commits into
QwenLM:mainfrom
dreamWB:feat/webview-copy-button

Conversation

@dreamWB

@dreamWB dreamWB commented Apr 20, 2026

Copy link
Copy Markdown
Collaborator

TLDR

Add three right-click context menu items to the chat message area using VSCode's native webview/context API:

  • Copy Message: copies the right-clicked message's raw markdown content
  • Copy All Messages: copies the full conversation in markdown format
  • Copy Last Reply: copies the last assistant response

This improves usability by allowing users to quickly copy specific messages without manual text selection.

Screenshots / Video Demo

CopyMessage.mp4

Dive Deeper

Implementation details:

  • Commands registered in package.json with webview/context menu entries
  • Clipboard writes go through extension host (vscode.env.clipboard) for reliability in webview sandbox
  • Message identification via data-msg-idx stamped after render
  • Tool-call outputs supported including diff format (git diff style)
  • i18n support via package.nls.json (English) and package.nls.zh-cn.json
  • Menu only shown in message area (not input box or empty state)

Reviewer Test Plan

  1. Open the VSCode extension with the webview chat
  2. Send a message and wait for a response
  3. Right-click on any message in the chat area
  4. Verify the three context menu items appear: "Copy Message", "Copy All Messages", "Copy Last Reply"
  5. Test each option:
    • Copy Message: Should copy only the clicked message's content
    • Copy All Messages: Should copy the entire conversation in markdown format
    • Copy Last Reply: Should copy only the last assistant response
  6. Paste into a text editor to verify the copied content
  7. Test with tool-call outputs (including diff format) to ensure they are properly included

Testing Matrix

🍏 🪟 🐧
npm run
npx
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

Resolves #3052


🤖 Generated with Qwen Code

@yiliang114 yiliang114 self-requested a review April 20, 2026 12:12
Comment thread packages/vscode-ide-companion/src/extension.ts
Comment thread packages/vscode-ide-companion/src/webview/App.tsx Outdated

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall direction looks good and seems to address the main UX gap behind #3052. I left two inline notes: one correctness issue around routing the command back to the webview that actually triggered the context menu when multiple chat surfaces are open, and one markdown-fence edge case in Copy All Messages when tool output already contains triple backticks. I also ran the targeted provider tests locally after building @qwen-code/qwen-code-core and @qwen-code/webui.

Comment thread packages/vscode-ide-companion/src/webview/App.tsx Outdated
Comment thread packages/vscode-ide-companion/src/webview/providers/WebViewProvider.ts Outdated

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature direction looks good and the UX addition makes sense, but there is still one correctness issue that can make Copy Message resolve the wrong item when non-rendered messages are present in allMessages. I left the blocker inline, plus one non-blocking maintainability note.

@tanzhenxin tanzhenxin added the type/feature-request New feature or enhancement request label Apr 21, 2026
@dreamWB dreamWB force-pushed the feat/webview-copy-button branch 2 times, most recently from fd6722b to 0b5da78 Compare April 22, 2026 06:07
yiliang114
yiliang114 previously approved these changes Apr 22, 2026

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread packages/vscode-ide-companion/src/webview/App.tsx Outdated
Comment thread packages/vscode-ide-companion/src/webview/App.tsx
dreamWB added 6 commits April 24, 2026 15:15
Add three right-click context menu items to the chat message area using
VSCode's native webview/context API:
- Copy Message: copies the right-clicked message's raw markdown content
- Copy All Messages: copies the full conversation in markdown format
- Copy Last Reply: copies the last assistant response

Implementation details:
- Commands registered in package.json with webview/context menu entries
- Clipboard writes go through extension host (vscode.env.clipboard) for
  reliability in webview sandbox
- Message identification via data-msg-idx stamped after render
- Tool-call outputs supported including diff format (git diff style)
- i18n support via package.nls.json (English) and package.nls.zh-cn.json
- Menu only shown in message area (not input box or empty state)

Closes QwenLM#3052
…hared message handling

Replace the wrapper-div approach (which broke CSS layout) with a
render-time childIndexMap that maps DOM child positions to allMessages
indices. This avoids both the useLayoutEffect index-drift bug and the
wrapper-div CSS side effects.

- Remove data-msg-idx wrapper divs; messages render directly as
  container children, preserving original [&>*] CSS layout
- Build childIndexMap during MessageList render, skipping null items
  (empty AssistantMessage, hidden tool calls via shouldShowToolCall)
- findMessageIndex walks up from click target to container's direct
  child, then maps through childIndexMap
- Filter hidden tool calls and empty content in copyAllMessages
- Extract handleCommonWebviewMessage to deduplicate routing logic
  across sidebar, editor panel, and restored panel handlers
- Clear lastContextMenuProvider on dispose to prevent memory leaks
…opy failure

- Copy Message on image messages now outputs markdown format ![image](path)
  instead of empty string
- Copy All Messages includes image messages as ![image](path) instead of
  skipping them
- Copy Last Reply skips empty assistant placeholders during streaming
- Resolve intermittent copy failure by pre-resolving message index on
  right-click instead of storing a DOM element reference that can become
  stale after React re-renders
@yiliang114

Copy link
Copy Markdown
Collaborator
image LGTM! Thanks bro

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yiliang114 yiliang114 dismissed wenshao’s stale review April 24, 2026 12:26

has been fixed

@yiliang114 yiliang114 merged commit 5e4ff37 into QwenLM:main Apr 24, 2026
13 checks passed
xaelistic pushed a commit to xaelistic/qwen-code that referenced this pull request Jun 7, 2026
…wenLM#3477)

* feat(vscode): add native context menu copy actions for webview chat

Add three right-click context menu items to the chat message area using
VSCode's native webview/context API:
- Copy Message: copies the right-clicked message's raw markdown content
- Copy All Messages: copies the full conversation in markdown format
- Copy Last Reply: copies the last assistant response

Implementation details:
- Commands registered in package.json with webview/context menu entries
- Clipboard writes go through extension host (vscode.env.clipboard) for
  reliability in webview sandbox
- Message identification via data-msg-idx stamped after render
- Tool-call outputs supported including diff format (git diff style)
- i18n support via package.nls.json (English) and package.nls.zh-cn.json
- Menu only shown in message area (not input box or empty state)

Closes QwenLM#3052

* fix(vscode): wrap tool-call content text in code blocks for copy

* fix(vscode): only wrap tool-call content in code blocks for Copy All, not single Copy Message

* fix(vscode): route copy commands to the right-clicked webview and use dynamic code fences

* fix(vscode): use childIndexMap for copy-message routing and extract shared message handling

Replace the wrapper-div approach (which broke CSS layout) with a
render-time childIndexMap that maps DOM child positions to allMessages
indices. This avoids both the useLayoutEffect index-drift bug and the
wrapper-div CSS side effects.

- Remove data-msg-idx wrapper divs; messages render directly as
  container children, preserving original [&>*] CSS layout
- Build childIndexMap during MessageList render, skipping null items
  (empty AssistantMessage, hidden tool calls via shouldShowToolCall)
- findMessageIndex walks up from click target to container's direct
  child, then maps through childIndexMap
- Filter hidden tool calls and empty content in copyAllMessages
- Extract handleCommonWebviewMessage to deduplicate routing logic
  across sidebar, editor panel, and restored panel handlers
- Clear lastContextMenuProvider on dispose to prevent memory leaks

* fix(vscode): handle image messages in copy and resolve intermittent copy failure

- Copy Message on image messages now outputs markdown format ![image](path)
  instead of empty string
- Copy All Messages includes image messages as ![image](path) instead of
  skipping them
- Copy Last Reply skips empty assistant placeholders during streaming
- Resolve intermittent copy failure by pre-resolving message index on
  right-click instead of storing a DOM element reference that can become
  stale after React re-renders
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/feature-request New feature or enhancement request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

能否增加响应内容复制键

4 participants