Add a "Claude Actions" editor context menu (Explain / Add to Chat) - #27
Add a "Claude Actions" editor context menu (Explain / Add to Chat)#27DaveTseng2019 wants to merge 2 commits into
Conversation
Right-click in the code editor for two commands that reuse the existing at_mentioned/attachment plumbing: Explain stages the selection as a text attachment with an instruction header, Add to Chat @-mentions the file with the selection's line range. Both insert-not-submit, matching every other at_mentioned use in this codebase. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an editor right-click “Claude Actions” submenu to stage the current selection for Claude Code (either as an explanatory prompt attachment or as an @ mention of the file/range), reusing the existing SelectionService + AttachmentService plumbing in the VSIX.
Changes:
- Adds VSCT contributions for an editor context submenu (“Claude Actions”) with Explain and Add to Chat commands.
- Exposes the live selection snapshot (
SelectionService.Current) and implementsSelectionService.MentionCurrentAsync()to sendat_mentionedwith an optional line range. - Widens
AttachmentService.ToWorkspaceRelativevisibility to support workspace-relative mentions from the new commands.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ClaudeCodeVS/VSCommandTable.vsct | Adds the editor context submenu and command placements/IDs. |
| src/ClaudeCodeVS/Editor/SelectionService.cs | Exposes Current and adds a helper to @-mention the current selection/file. |
| src/ClaudeCodeVS/ClaudeCodeVsPackage.cs | Registers the new commands and wires handlers for Explain/Add to Chat. |
| src/ClaudeCodeVS/Attachments/AttachmentService.cs | Makes ToWorkspaceRelative internal so other components can reuse it. |
| CLAUDE.md | Documents the VSCT placement gotcha and Exp hive caching behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| var mentionPath = Attachments.AttachmentService.ToWorkspaceRelative(info.FilePath) ?? info.FilePath; | ||
| var @params = new JObject { ["filePath"] = mentionPath }; | ||
| if (!info.IsEmpty) | ||
| { | ||
| @params["lineStart"] = info.StartLine; | ||
| @params["lineEnd"] = info.EndLine; | ||
| } | ||
|
|
||
| try | ||
| { | ||
| await server.BroadcastNotificationAsync("at_mentioned", @params, CancellationToken.None); | ||
| var range = info.IsEmpty ? "" : $" (lines {info.StartLine + 1}-{info.EndLine + 1})"; | ||
| Log.Info($"Add to Chat: mentioned '{System.IO.Path.GetFileName(info.FilePath)}'{range}."); |
| var header = sel.FilePath is null | ||
| ? "Explain this code:" | ||
| : $"Explain this code from {System.IO.Path.GetFileName(sel.FilePath)} (lines {sel.StartLine + 1}-{sel.EndLine + 1}):"; |
SelectionInfo.EndLine is LSP-shaped (exclusive), so a whole-line selection parks the end at column 0 of the next line - the header and the at_mentioned range then claimed one line too many. Added EndLineInclusive and used it for both human-facing ranges and at_mentioned's lineEnd; the selection_changed / getCurrentSelection JSON keeps the exclusive LSP coordinates it's contractually required to send. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Good catch — fixed in 0d89bd4.
Verified end-to-end against CLI 2.1.225: selecting whole lines 7-9 now inserts |
Re-submission of the context-menu half of the now-closed #24, split out so each PR is one reviewable topic.
What
A "Claude Actions" submenu on the editor right-click menu, with two entries:
Explain this code from Foo.cs (lines 12-30):), using the same insert-not-submit staging a pasted prompt already uses.@-mentions the current file and line range in place.Both read
SelectionService.Current, which the existing MEFTextViewListeneralready keeps live, so there is no new editor plumbing.Notes
AttachmentService.ToWorkspaceRelative(visibility widened tointernal) so it sends a workspace-relative path, matching what the tray already sends, rather than an absolute one.<Menu>is parented to a<Group>underIDM_VS_CTXT_CODEWIN, not to the menu ID directly - parenting straight to the menu ID compiles and registers fine but the submenu silently never renders.Commands.Raise).🤖 Generated with Claude Code