From be20f44edbc3e0ce95e6a54371aa8bd735a85a4b Mon Sep 17 00:00:00 2001 From: Scott Hyndman Date: Fri, 13 Feb 2026 05:54:10 -0500 Subject: [PATCH] feat(tui): Added Alt+Shift+C keyboard shortcut to copy prompt to clipboard --- .../src/modes/components/custom-editor.ts | 8 ++++++++ .../src/modes/controllers/input-controller.ts | 20 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/src/modes/components/custom-editor.ts b/packages/coding-agent/src/modes/components/custom-editor.ts index 171d87231..4cd3d4540 100644 --- a/packages/coding-agent/src/modes/components/custom-editor.ts +++ b/packages/coding-agent/src/modes/components/custom-editor.ts @@ -19,6 +19,8 @@ export class CustomEditor extends Editor { onQuestionMark?: () => void; onCapsLock?: () => void; onAltP?: () => void; + /** Called when Alt+Shift+C is pressed to copy prompt to clipboard. */ + onCopyPrompt?: () => void; /** Called when Ctrl+V is pressed. Returns true if handled (image found), false to fall through to text paste. */ onCtrlV?: () => Promise; /** Called when Alt+Up is pressed (dequeue keybinding). */ @@ -150,6 +152,12 @@ export class CustomEditor extends Editor { return; } + // Intercept Alt+Shift+C to copy prompt to clipboard + if (matchesKey(data, "alt+shift+c") && this.onCopyPrompt) { + this.onCopyPrompt(); + return; + } + // Intercept ? when editor is empty to show hotkeys if (data === "?" && this.getText().length === 0 && this.onQuestionMark) { this.onQuestionMark(); diff --git a/packages/coding-agent/src/modes/controllers/input-controller.ts b/packages/coding-agent/src/modes/controllers/input-controller.ts index 0d0acbb3b..7d71c65fa 100644 --- a/packages/coding-agent/src/modes/controllers/input-controller.ts +++ b/packages/coding-agent/src/modes/controllers/input-controller.ts @@ -1,6 +1,6 @@ import * as fs from "node:fs/promises"; import type { AgentMessage } from "@oh-my-pi/pi-agent-core"; -import { readImageFromClipboard } from "@oh-my-pi/pi-natives"; +import { copyToClipboard, readImageFromClipboard } from "@oh-my-pi/pi-natives"; import { $env } from "@oh-my-pi/pi-utils"; import type { SettingPath, SettingValue } from "../../config/settings"; import { settings } from "../../config/settings"; @@ -74,6 +74,7 @@ export class InputController { this.ctx.editor.onCtrlG = () => void this.openExternalEditor(); this.ctx.editor.onQuestionMark = () => this.ctx.handleHotkeysCommand(); this.ctx.editor.onCtrlV = () => this.handleImagePaste(); + this.ctx.editor.onCopyPrompt = () => this.handleCopyPrompt(); // Wire up extension shortcuts this.registerExtensionShortcuts(); @@ -664,6 +665,23 @@ export class InputController { } } + /** Copy current prompt text to system clipboard. */ + handleCopyPrompt(): void { + const text = this.ctx.editor.getText(); + if (!text) { + this.ctx.showStatus("Nothing to copy"); + return; + } + copyToClipboard(text) + .then(() => { + const preview = text.length > 30 ? `${text.slice(0, 30)}...` : text; + this.ctx.showStatus(`Copied: ${preview}`); + }) + .catch(() => { + this.ctx.showWarning("Failed to copy to clipboard"); + }); + } + cycleThinkingLevel(): void { const newLevel = this.ctx.session.cycleThinkingLevel(); if (newLevel === undefined) {