mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-21 10:49:07 +00:00
Allow external copying files into the workspace on markdown drop / paste (#182572)
Allow copying files in the workspace on markdown drop / paste Fixes #157043 Also: - Renames the markdown paste settings and makes them no longer experimental - Makes the copyFiles setting no longer experimental - Adds a `markdown.copyFiles.overwriteBehavior` which lets you control if/how existing files are overwritten
This commit is contained in:
@@ -4,18 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { coalesce } from '../../util/arrays';
|
||||
import { Schemes } from '../../util/schemes';
|
||||
import { NewFilePathGenerator } from './copyFiles';
|
||||
import { createUriListSnippet, tryGetUriListSnippet } from './dropIntoEditor';
|
||||
|
||||
const supportedImageMimes = new Set([
|
||||
'image/bmp',
|
||||
'image/gif',
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/webp',
|
||||
]);
|
||||
import { createEditForMediaFiles, mediaMimes, tryGetUriListSnippet } from './shared';
|
||||
|
||||
class PasteEditProvider implements vscode.DocumentPasteEditProvider {
|
||||
|
||||
@@ -27,12 +17,12 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider {
|
||||
dataTransfer: vscode.DataTransfer,
|
||||
token: vscode.CancellationToken,
|
||||
): Promise<vscode.DocumentPasteEdit | undefined> {
|
||||
const enabled = vscode.workspace.getConfiguration('markdown', document).get('experimental.editor.pasteLinks.enabled', true);
|
||||
const enabled = vscode.workspace.getConfiguration('markdown', document).get('editor.filePaste.enabled', true);
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const createEdit = await this._makeCreateImagePasteEdit(document, dataTransfer, token);
|
||||
const createEdit = await this._getMediaFilesEdit(document, dataTransfer, token);
|
||||
if (createEdit) {
|
||||
return createEdit;
|
||||
}
|
||||
@@ -47,56 +37,23 @@ class PasteEditProvider implements vscode.DocumentPasteEditProvider {
|
||||
return uriEdit;
|
||||
}
|
||||
|
||||
private async _makeCreateImagePasteEdit(document: vscode.TextDocument, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.DocumentPasteEdit | undefined> {
|
||||
private async _getMediaFilesEdit(document: vscode.TextDocument, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.DocumentPasteEdit | undefined> {
|
||||
if (document.uri.scheme === Schemes.untitled) {
|
||||
return;
|
||||
}
|
||||
|
||||
interface FileEntry {
|
||||
readonly uri: vscode.Uri;
|
||||
readonly newFileContents?: vscode.DataTransferFile;
|
||||
}
|
||||
|
||||
const pathGenerator = new NewFilePathGenerator();
|
||||
const fileEntries = coalesce(await Promise.all(Array.from(dataTransfer, async ([mime, item]): Promise<FileEntry | undefined> => {
|
||||
if (!supportedImageMimes.has(mime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = item?.asFile();
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.uri) {
|
||||
// If the file is already in a workspace, we don't want to create a copy of it
|
||||
const workspaceFolder = vscode.workspace.getWorkspaceFolder(file.uri);
|
||||
if (workspaceFolder) {
|
||||
return { uri: file.uri };
|
||||
}
|
||||
}
|
||||
|
||||
const uri = await pathGenerator.getNewFilePath(document, file, token);
|
||||
return uri ? { uri, newFileContents: file } : undefined;
|
||||
})));
|
||||
if (!fileEntries.length) {
|
||||
const copyFilesIntoWorkspace = vscode.workspace.getConfiguration('markdown', document).get<'mediaFiles' | 'never'>('editor.filePaste.copyIntoWorkspace', 'mediaFiles');
|
||||
if (copyFilesIntoWorkspace === 'never') {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaceEdit = new vscode.WorkspaceEdit();
|
||||
for (const entry of fileEntries) {
|
||||
if (entry.newFileContents) {
|
||||
workspaceEdit.createFile(entry.uri, { contents: entry.newFileContents });
|
||||
}
|
||||
}
|
||||
|
||||
const snippet = createUriListSnippet(document, fileEntries.map(entry => entry.uri));
|
||||
if (!snippet) {
|
||||
const edit = await createEditForMediaFiles(document, dataTransfer, token);
|
||||
if (!edit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pasteEdit = new vscode.DocumentPasteEdit(snippet.snippet, this._id, snippet.label);
|
||||
pasteEdit.additionalEdit = workspaceEdit;
|
||||
const pasteEdit = new vscode.DocumentPasteEdit(edit.snippet, this._id, edit.label);
|
||||
pasteEdit.additionalEdit = edit.additionalEdits;
|
||||
pasteEdit.priority = this._getPriority(dataTransfer);
|
||||
return pasteEdit;
|
||||
}
|
||||
@@ -114,7 +71,7 @@ export function registerPasteSupport(selector: vscode.DocumentSelector,) {
|
||||
return vscode.languages.registerDocumentPasteEditProvider(selector, new PasteEditProvider(), {
|
||||
pasteMimeTypes: [
|
||||
'text/uri-list',
|
||||
...supportedImageMimes,
|
||||
...mediaMimes,
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user