дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
feat(editor): paste copied files as Markdown links (#599)
Pasting files copied in the project view into a Markdown document now inserts `[](relative/path)`, one link per line, encoded the same way as Markdown images. Other editors and terminals keep inserting the raw path, copied images keep their  route, and remote windows keep raw paths because the clipboard holds client paths. A context-menu Paste that the native command rejects falls back to reading the clipboard. Fixes #573
Цей коміт міститься в:
1 джерело
b3c3150489
коміт
0a71f6be88
4 files changed
+175
-16
No files matched your search
@@ -1,13 +1,23 @@
|
||||
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): Promise<string> {
|
||||
export async function readClipboardText(
|
||||
transfer?: DataTransfer | null,
|
||||
formatFiles: FormatFiles = rawPaths,
|
||||
): Promise<string> {
|
||||
const text = transfer ? transfer.getData("text/plain") : ((await navigator.clipboard?.readText()) ?? "");
|
||||
if (text || (transfer && !hasClipboardFiles(transfer)) || !isTauri()) return text;
|
||||
if ((text && formatFiles === rawPaths) || (transfer && !hasClipboardFiles(transfer)) || !isTauri()) return text;
|
||||
try {
|
||||
return (await call(commands.clipboardFileList())).join("\n");
|
||||
const paths = await call(commands.clipboardFileList());
|
||||
// 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);
|
||||
} catch {
|
||||
return "";
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +26,22 @@ function hasClipboardFiles(transfer: DataTransfer): boolean {
|
||||
}
|
||||
|
||||
/** Claim synchronously so the native handler cannot emit an empty paste while IPC runs. */
|
||||
export function pasteClipboardFiles(event: ClipboardEvent, paste: (text: string) => void): boolean {
|
||||
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") || !hasClipboardFiles(transfer))
|
||||
if (
|
||||
event.defaultPrevented ||
|
||||
!transfer ||
|
||||
(transfer.getData("text/plain") && formatFiles === rawPaths) ||
|
||||
!hasClipboardFiles(transfer)
|
||||
)
|
||||
return false;
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
void readClipboardText(transfer).then((text) => {
|
||||
void readClipboardText(transfer, formatFiles).then((text) => {
|
||||
if (text) paste(text);
|
||||
});
|
||||
return true;
|
||||
|
||||
Reference in new issue
Заблокувати користувача