diff --git a/src/components/terminal/terminal-view.test.ts b/src/components/terminal/terminal-view.test.ts new file mode 100644 index 000000000..3982b293a --- /dev/null +++ b/src/components/terminal/terminal-view.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from "vitest" +import { isTerminalCopyShortcut } from "@/lib/terminal/shortcuts" + +type ShortcutEvent = Parameters[0] + +function event(overrides: Partial = {}): ShortcutEvent { + return { + code: "KeyC", + altKey: false, + metaKey: false, + ctrlKey: true, + shiftKey: true, + ...overrides, + } +} + +describe("isTerminalCopyShortcut", () => { + it("reserves only Ctrl+Shift+C outside macOS", () => { + expect(isTerminalCopyShortcut(event(), false)).toBe(true) + expect(isTerminalCopyShortcut(event(), true)).toBe(false) + expect(isTerminalCopyShortcut(event({ shiftKey: false }), false)).toBe( + false + ) + expect(isTerminalCopyShortcut(event({ altKey: true }), false)).toBe(false) + expect(isTerminalCopyShortcut(event({ metaKey: true }), false)).toBe(false) + expect(isTerminalCopyShortcut(event({ code: "KeyV" }), false)).toBe(false) + }) +}) diff --git a/src/components/terminal/terminal-view.tsx b/src/components/terminal/terminal-view.tsx index f7946286f..d82956d1c 100644 --- a/src/components/terminal/terminal-view.tsx +++ b/src/components/terminal/terminal-view.tsx @@ -10,6 +10,8 @@ import { } from "@/lib/api" import { createWriteQueue } from "@/lib/terminal/write-queue" import { getTerminalTheme } from "@/lib/terminal/theme" +import { isTerminalCopyShortcut } from "@/lib/terminal/shortcuts" +import { copyTextToClipboard } from "@/lib/utils" import { useZoomLevel, useTerminalFont } from "@/hooks/use-appearance" import { detectPlatform } from "@/hooks/use-platform" import type { TerminalEvent } from "@/lib/types" @@ -173,6 +175,13 @@ export function TerminalView({ return false } + if (isTerminalCopyShortcut(e, isMac)) { + const selection = term.getSelection() + if (selection) void copyTextToClipboard(selection) + e.preventDefault() + return false + } + if (altKey && !ctrlKey && !metaKey && !shiftKey) { if (code === "ArrowLeft") return writeSeq("\x1bb") if (code === "ArrowRight") return writeSeq("\x1bf") diff --git a/src/lib/terminal/shortcuts.ts b/src/lib/terminal/shortcuts.ts new file mode 100644 index 000000000..b2c48a24a --- /dev/null +++ b/src/lib/terminal/shortcuts.ts @@ -0,0 +1,18 @@ +type TerminalShortcutEvent = Pick< + KeyboardEvent, + "code" | "altKey" | "metaKey" | "ctrlKey" | "shiftKey" +> + +export function isTerminalCopyShortcut( + event: TerminalShortcutEvent, + isMac: boolean +): boolean { + return ( + !isMac && + event.code === "KeyC" && + event.ctrlKey && + event.shiftKey && + !event.altKey && + !event.metaKey + ) +}