Skip to content

Add a "Claude Actions" editor context menu (Explain / Add to Chat) - #27

Open
DaveTseng2019 wants to merge 2 commits into
firish:mainfrom
DaveTseng2019:feat/editor-context-menu
Open

Add a "Claude Actions" editor context menu (Explain / Add to Chat)#27
DaveTseng2019 wants to merge 2 commits into
firish:mainfrom
DaveTseng2019:feat/editor-context-menu

Conversation

@DaveTseng2019

Copy link
Copy Markdown

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 - stages the current selection as a text attachment with an instruction header (Explain this code from Foo.cs (lines 12-30):), using the same insert-not-submit staging a pasted prompt already uses.
  • Add to Chat - @-mentions the current file and line range in place.

Both read SelectionService.Current, which the existing MEF TextViewListener already keeps live, so there is no new editor plumbing.

Notes

  • The mention path goes through the shared AttachmentService.ToWorkspaceRelative (visibility widened to internal) so it sends a workspace-relative path, matching what the tray already sends, rather than an absolute one.
  • VSCT: the <Menu> is parented to a <Group> under IDM_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.
  • Verified in the Experimental hive by actually right-clicking in the editor (screenshot-checked, since the failure mode above is invisible to Commands.Raise).

🤖 Generated with Claude Code

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>
Copilot AI lite review requested due to automatic review settings August 8, 2026 03:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 implements SelectionService.MentionCurrentAsync() to send at_mentioned with an optional line range.
  • Widens AttachmentService.ToWorkspaceRelative visibility 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.

Comment on lines +73 to +85
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}.");
Comment thread src/ClaudeCodeVS/ClaudeCodeVsPackage.cs Outdated
Comment on lines +85 to +87
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>
@DaveTseng2019

Copy link
Copy Markdown
Author

Good catch — fixed in 0d89bd4.

SelectionInfo.EndLine is LSP-shaped (exclusive), so a whole-line selection parks the end at column 0 of the next line and both the Explain header and the at_mentioned range claimed one line too many. Added SelectionInfo.EndLineInclusive and used it at all three sites (Explain header, Add to Chat's lineEnd, the feed log). The selection_changed / getCurrentSelection JSON keeps the exclusive LSP coordinates it's contractually required to send.

Verified end-to-end against CLI 2.1.225: selecting whole lines 7-9 now inserts @Sample.cs#L7-9 (CLI confirms "3 lines selected"); it was #L7-10 before. The Explain attachment header reads (lines 7-9) too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants