дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
CI / Rust (ubuntu-22.04) (push) Failing after 1h0m17s
CI / Remote server (linux musl) (push) Failing after 25m8s
CI / Cargo deny (push) Successful in 1m39s
CI / Frontend (push) Successful in 25m40s
CI / E2E (push) Failing after 15m24s
CI / Rust (macos-latest) (push) Canceled after 0s
CI / Rust (windows-latest) (push) Canceled after 0s
Pasting an image, audio or video from the clipboard into a local terminal saves the bytes to the per-user terminal cache (20 MB limit, files older than 24 h cleaned up on the next paste, private permissions) and inserts the shell-quoted path without running anything. Copied files paste their original paths, plain text pastes unchanged, and SSH sessions keep the existing remote image-paste route. Paths are quoted per shell (zsh/bash, fish, PowerShell, cmd.exe); fish quoting now escapes backslashes and single quotes. Fixes #838 Co-authored-by: kkMihai <[email protected]>
52 рядки
1.7 KiB
TypeScript
52 рядки
1.7 KiB
TypeScript
import { call, commands, isTauri } from "./ipc";
|
|
import { ipcPath } from "./paths";
|
|
|
|
type FormatFiles = (paths: string[]) => string;
|
|
const rawPaths: FormatFiles = (paths) => paths.join("\n");
|
|
|
|
/** WebKit exposes native file URLs as Files, hiding the pasteboard's text flavor. */
|
|
export async function readClipboardText(
|
|
transfer?: DataTransfer | null,
|
|
formatFiles: FormatFiles = rawPaths,
|
|
): Promise<string> {
|
|
const text = transfer
|
|
? transfer.getData("text/plain")
|
|
: ((await navigator.clipboard?.readText().catch(() => "")) ?? "");
|
|
if ((text && formatFiles === rawPaths) || (transfer && !hasClipboardFiles(transfer)) || !isTauri()) return text;
|
|
let paths: string[];
|
|
try {
|
|
paths = await call(commands.clipboardFileList());
|
|
} catch {
|
|
return text;
|
|
}
|
|
// Windows also supplies the file list as text; unrelated text still wins.
|
|
if (text && text.replace(/\r\n/g, "\n").split("\n").map(ipcPath).join("\n") !== paths.join("\n")) return text;
|
|
return formatFiles(paths);
|
|
}
|
|
|
|
function hasClipboardFiles(transfer: DataTransfer): boolean {
|
|
return !!transfer.files.length || Array.from(transfer.types).includes("Files");
|
|
}
|
|
|
|
/** Claim synchronously so the native handler cannot emit an empty paste while IPC runs. */
|
|
export function pasteClipboardFiles(
|
|
event: ClipboardEvent,
|
|
paste: (text: string) => void,
|
|
formatFiles: FormatFiles = rawPaths,
|
|
): boolean {
|
|
const transfer = event.clipboardData;
|
|
if (
|
|
event.defaultPrevented ||
|
|
!transfer ||
|
|
(transfer.getData("text/plain") && formatFiles === rawPaths) ||
|
|
!hasClipboardFiles(transfer)
|
|
)
|
|
return false;
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
void readClipboardText(transfer, formatFiles).then((text) => {
|
|
if (text) paste(text);
|
|
});
|
|
return true;
|
|
}
|