diff --git a/src/ui/hooks/useAppKeyboardShortcuts.ts b/src/ui/hooks/useAppKeyboardShortcuts.ts index f8099b6a..85b1ca20 100644 --- a/src/ui/hooks/useAppKeyboardShortcuts.ts +++ b/src/ui/hooks/useAppKeyboardShortcuts.ts @@ -4,6 +4,7 @@ import { useRef } from "react"; import type { LayoutMode } from "../../core/types"; import type { MenuId } from "../components/chrome/menu"; import { + isCreateReviewNoteKey, isEscapeKey, isHalfPageDownKey, isHalfPageUpKey, @@ -355,7 +356,7 @@ export function useAppKeyboardShortcuts({ return; } - if (key.name?.toLowerCase() === "c" || key.sequence?.toLowerCase() === "c") { + if (isCreateReviewNoteKey(key)) { runAndCloseMenu(startUserNote); return; } diff --git a/src/ui/lib/keyboard.ts b/src/ui/lib/keyboard.ts index 6439bed6..0a60d124 100644 --- a/src/ui/lib/keyboard.ts +++ b/src/ui/lib/keyboard.ts @@ -27,6 +27,17 @@ export function isSaveDraftNoteKey(key: KeyEvent) { ); } +/** Match the unmodified review-note shortcut without stealing terminal copy chords. */ +export function isCreateReviewNoteKey(key: KeyEvent) { + return ( + (key.name === "c" || key.sequence === "c") && + !key.ctrl && + !key.meta && + !key.option && + !key.shift + ); +} + /** Match any key alias that should scroll forward by a full viewport. */ export function isPageDownKey(key: KeyEvent) { return ( diff --git a/src/ui/lib/ui-lib.test.ts b/src/ui/lib/ui-lib.test.ts index d05f3f09..661c6974 100644 --- a/src/ui/lib/ui-lib.test.ts +++ b/src/ui/lib/ui-lib.test.ts @@ -12,6 +12,7 @@ import { import { buildAgentPopoverContent, resolveAgentPopoverPlacement, wrapText } from "./agentPopover"; import { buildAppMenus } from "./appMenus"; import { + isCreateReviewNoteKey, isEscapeKey, isHalfPageDownKey, isHalfPageUpKey, @@ -280,6 +281,15 @@ describe("ui helpers", () => { expect(isShiftSpacePageUpKey(createKeyEvent({ name: "space", shift: false }))).toBe(false); }); + test("review note shortcut only matches unmodified c", () => { + expect(isCreateReviewNoteKey(createKeyEvent({ name: "c" }))).toBe(true); + expect(isCreateReviewNoteKey(createKeyEvent({ sequence: "c" }))).toBe(true); + expect(isCreateReviewNoteKey(createKeyEvent({ name: "C", shift: true }))).toBe(false); + expect(isCreateReviewNoteKey(createKeyEvent({ name: "c", ctrl: true }))).toBe(false); + expect(isCreateReviewNoteKey(createKeyEvent({ name: "c", meta: true }))).toBe(false); + expect(isCreateReviewNoteKey(createKeyEvent({ name: "c", option: true }))).toBe(false); + }); + test("fitText and padText clamp using the terminal fallback marker", () => { expect(fitText("hello", 0)).toBe(""); expect(fitText("hello", 1)).toBe(".");