feat(ux): unify "Ask Claude to Edit" + inline prompt at selection; fix keybindings
Operator feedback on the Ask-Claude ergonomics (relates to #42/#43/#60):
- One user-facing command `cowriting.edit` ("Ask Claude to Edit") routes to the
selection or whole-document flow at runtime via the pure `routeEdit` helper
(selection → editSelection; none / tab right-click → editDocument). The two
underlying commands stay registered for the seams + E2E but are hidden from the
palette, and the split menu pairs collapse to one entry.
- Keybindings with `mac` variants (the missing variant is why ⌃⌥R "didn't work"
on macOS — Option combos are unreliable there): `cmd+alt+e`/`ctrl+alt+e` for
Ask-Claude-to-Edit, `cmd+alt+r`/`ctrl+alt+r` for the review panel.
- The instruction prompt now renders INLINE at the selection/cursor via a
dedicated Comments-API controller (`InlineAskController`, `cowriting.askClaude`)
instead of the top-center QuickInput — VS Code's Inline-Chat-style placement.
Both Ask-Claude entry points (editSelection + the preview's askClaude) share it.
Tests: routeEdit unit tests; E2E menu/palette assertions updated for the unified
command; E2E drives the inline prompt by stubbing `api.inlineAsk.prompt`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { isAuthorable, isUnderRoot, selectionRejection } from "../src/workspacePath";
|
||||
import { isAuthorable, isUnderRoot, routeEdit, selectionRejection } from "../src/workspacePath";
|
||||
|
||||
describe("isUnderRoot", () => {
|
||||
const root = "/a/vscode-cowriting-plugin/sandbox";
|
||||
@@ -58,3 +58,27 @@ describe("selectionRejection — F8 widened (accepts out-of-folder + untitled)",
|
||||
expect(msg).not.toMatch(/select some text/i);
|
||||
});
|
||||
});
|
||||
|
||||
describe("routeEdit (single Ask-Claude-to-Edit gesture)", () => {
|
||||
const focused = { hasUri: false, uriMatchesActiveEditor: false, hasActiveEditor: true, selectionEmpty: false };
|
||||
|
||||
it("non-empty selection in the focused editor → selection", () => {
|
||||
expect(routeEdit(focused)).toBe("selection");
|
||||
});
|
||||
it("empty selection in the focused editor → document", () => {
|
||||
expect(routeEdit({ ...focused, selectionEmpty: true })).toBe("document");
|
||||
});
|
||||
it("no active editor → document", () => {
|
||||
expect(routeEdit({ ...focused, hasActiveEditor: false, selectionEmpty: true })).toBe("document");
|
||||
});
|
||||
it("tab right-click on a doc that ISN'T the focused editor → document (no selection to act on)", () => {
|
||||
expect(routeEdit({ hasUri: true, uriMatchesActiveEditor: false, hasActiveEditor: true, selectionEmpty: false })).toBe(
|
||||
"document",
|
||||
);
|
||||
});
|
||||
it("tab right-click on the focused editor with a selection → selection", () => {
|
||||
expect(routeEdit({ hasUri: true, uriMatchesActiveEditor: true, hasActiveEditor: true, selectionEmpty: false })).toBe(
|
||||
"selection",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user