generated from nhcarrigan/template
fix: preserve Ctrl+C copy behaviour when text is selected
Resolves #195. Before sending an interrupt signal, check whether the user has text selected. If so, let the browser handle Ctrl+C as a native copy rather than interrupting Claude.
This commit is contained in:
@@ -240,9 +240,10 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+C - Interrupt (only when processing)
|
||||
// Ctrl+C - Interrupt (only when processing AND no text is selected)
|
||||
if (event.ctrlKey && event.key === "c") {
|
||||
if (get(isClaudeProcessing)) {
|
||||
const hasSelection = Boolean(window.getSelection()?.toString());
|
||||
if (get(isClaudeProcessing) && !hasSelection) {
|
||||
event.preventDefault();
|
||||
handleInterrupt();
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* +page.svelte keyboard shortcut tests
|
||||
*
|
||||
* Tests the pure decision logic for the Ctrl+C keyboard shortcut handler.
|
||||
* The handler should only intercept Ctrl+C (to send an interrupt signal) when:
|
||||
* - Claude is currently processing a request, AND
|
||||
* - No text is currently selected (so normal copy behaviour is preserved)
|
||||
*
|
||||
* Manual testing checklist:
|
||||
* - [ ] Ctrl+C with text selected copies the text (browser default)
|
||||
* - [ ] Ctrl+C with no text selected and Claude processing sends an interrupt
|
||||
* - [ ] Ctrl+C with no text selected and Claude idle does nothing special
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from "vitest";
|
||||
|
||||
// Mirror the Ctrl+C interrupt decision logic from +page.svelte
|
||||
function shouldInterruptOnCtrlC(isProcessing: boolean, hasSelection: boolean): boolean {
|
||||
return isProcessing && !hasSelection;
|
||||
}
|
||||
|
||||
describe("Ctrl+C interrupt logic", () => {
|
||||
it("interrupts when Claude is processing and no text is selected", () => {
|
||||
expect(shouldInterruptOnCtrlC(true, false)).toBe(true);
|
||||
});
|
||||
|
||||
it("does not interrupt when text is selected, even if Claude is processing", () => {
|
||||
expect(shouldInterruptOnCtrlC(true, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not interrupt when Claude is idle and no text is selected", () => {
|
||||
expect(shouldInterruptOnCtrlC(false, false)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not interrupt when Claude is idle and text is selected", () => {
|
||||
expect(shouldInterruptOnCtrlC(false, true)).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user