feat(terminal): add Cmd+C/V and Ctrl+Shift+C/V clipboard shortcuts

Intercept keyboard shortcuts in xterm.js so users can copy selected
text with Cmd+C (Mac) or Ctrl+Shift+C (Linux/Win), and paste from
system clipboard with Cmd+V / Ctrl+Shift+V. Without text selected,
Cmd+C still sends SIGINT as expected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
suraj-markup 2026-03-02 00:03:14 +05:30
parent b96eafeb31
commit 783b21dc93
1 changed files with 38 additions and 0 deletions

View File

@ -228,6 +228,44 @@ export function DirectTerminal({
}
});
// Intercept Cmd+C/V (Mac) and Ctrl+Shift+C/V (Linux/Win) for clipboard
terminal.attachCustomKeyEventHandler((e: KeyboardEvent) => {
if (e.type !== "keydown") return true;
const isMac = navigator.platform.toUpperCase().includes("MAC");
if (isMac && e.metaKey && !e.ctrlKey && !e.altKey) {
if (e.code === "KeyC" && terminal.hasSelection()) {
navigator.clipboard?.writeText(terminal.getSelection()).catch(() => {});
return false;
}
if (e.code === "KeyV") {
navigator.clipboard?.readText().then((text) => {
if (text && websocket.readyState === WebSocket.OPEN) {
terminal.paste(text);
}
}).catch(() => {});
return false;
}
}
if (!isMac && e.ctrlKey && e.shiftKey) {
if (e.code === "KeyC" && terminal.hasSelection()) {
navigator.clipboard?.writeText(terminal.getSelection()).catch(() => {});
return false;
}
if (e.code === "KeyV") {
navigator.clipboard?.readText().then((text) => {
if (text && websocket.readyState === WebSocket.OPEN) {
terminal.paste(text);
}
}).catch(() => {});
return false;
}
}
return true;
});
// Handle window resize
const handleResize = () => {
if (fit && websocket.readyState === WebSocket.OPEN) {