From b0140c2ca4af8b923aeb792fd81a98ccc0f50a1e Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 6 Sep 2022 16:19:08 +0200 Subject: [PATCH 1/2] support `contents` option with `WorkspaceEdit#createFile` --- .../src/singlefolder-tests/workspace.test.ts | 17 +++++++++++++++++ src/vs/editor/common/languages.ts | 1 + src/vs/monaco.d.ts | 1 + .../api/common/extHostTypeConverters.ts | 4 ++-- src/vs/workbench/api/common/extHostTypes.ts | 3 ++- .../contrib/bulkEdit/browser/bulkFileEdits.ts | 4 ++-- 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index a6b277c57a1..126d37524c9 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -1169,4 +1169,21 @@ suite('vscode API - workspace', () => { assert.strictEqual(document.getText(), 'foobarhello\nworld'); assert.deepStrictEqual(edt.selections, [new vscode.Selection(0, 0, 0, 3)]); }); + + + test('Support creating binary files in a WorkspaceEdit', async function (): Promise { + + const fileUri = vscode.Uri.parse(`${testFs.scheme}:/${rndName()}`); + const data = Buffer.from('Hello Binary Files'); + + const ws = new vscode.WorkspaceEdit(); + ws.createFile(fileUri, { contents: data, ignoreIfExists: false, overwrite: false }); + + const success = await vscode.workspace.applyEdit(ws); + assert.ok(success); + + const actual = await vscode.workspace.fs.readFile(fileUri); + + assert.deepStrictEqual(actual, data); + }); }); diff --git a/src/vs/editor/common/languages.ts b/src/vs/editor/common/languages.ts index b6e81bfb8f7..cd402de4dc4 100644 --- a/src/vs/editor/common/languages.ts +++ b/src/vs/editor/common/languages.ts @@ -1411,6 +1411,7 @@ export interface WorkspaceFileEditOptions { folder?: boolean; skipTrashBin?: boolean; maxSize?: number; + contentsBase64?: string; } export interface IWorkspaceFileEdit { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 7bd8af19e51..2259a4f522d 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -7093,6 +7093,7 @@ declare namespace monaco.languages { folder?: boolean; skipTrashBin?: boolean; maxSize?: number; + contentsBase64?: string; } export interface IWorkspaceFileEdit { diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index e9856c990bc..b4b0ae070d3 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { asArray, coalesce, isNonEmptyArray } from 'vs/base/common/arrays'; -import { VSBuffer } from 'vs/base/common/buffer'; +import { encodeBase64, VSBuffer } from 'vs/base/common/buffer'; import * as htmlContent from 'vs/base/common/htmlContent'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ResourceSet } from 'vs/base/common/map'; @@ -592,7 +592,7 @@ export namespace WorkspaceEdit { result.edits.push({ oldResource: entry.from, newResource: entry.to, - options: entry.options, + options: { ...entry.options, contentsBase64: entry.options?.contents && encodeBase64(VSBuffer.wrap(entry.options.contents)) }, metadata: entry.metadata }); diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 238a0be8e0b..6faff22d474 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -660,6 +660,7 @@ export interface IFileOperationOptions { ignoreIfExists?: boolean; ignoreIfNotExists?: boolean; recursive?: boolean; + contents?: Uint8Array; } export const enum FileEditType { @@ -729,7 +730,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { this._edits.push({ _type: FileEditType.File, from, to, options, metadata }); } - createFile(uri: vscode.Uri, options?: { overwrite?: boolean; ignoreIfExists?: boolean }, metadata?: vscode.WorkspaceEditEntryMetadata): void { + createFile(uri: vscode.Uri, options?: { overwrite?: boolean; ignoreIfExists?: boolean; contents?: Uint8Array }, metadata?: vscode.WorkspaceEditEntryMetadata): void { this._edits.push({ _type: FileEditType.File, from: undefined, to: uri, options, metadata }); } diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts index 2cd2d328bd3..cea77beb41a 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts @@ -13,7 +13,7 @@ import { IWorkspaceUndoRedoElement, UndoRedoElementType, IUndoRedoService, UndoR import { URI } from 'vs/base/common/uri'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { VSBuffer } from 'vs/base/common/buffer'; +import { decodeBase64, VSBuffer } from 'vs/base/common/buffer'; import { ResourceFileEdit } from 'vs/editor/browser/services/bulkEditService'; import { CancellationToken } from 'vs/base/common/cancellation'; import { tail } from 'vs/base/common/arrays'; @@ -345,7 +345,7 @@ export class BulkFileEdits { } else if (!edit.newResource && edit.oldResource) { edits.push(new DeleteEdit(edit.oldResource, edit.options ?? {}, false)); } else if (edit.newResource && !edit.oldResource) { - edits.push(new CreateEdit(edit.newResource, edit.options ?? {}, undefined)); + edits.push(new CreateEdit(edit.newResource, edit.options ?? {}, edit.options.contentsBase64 ? decodeBase64(edit.options.contentsBase64) : undefined)); } } From 4da1e34afee7411ff2214930389f1e03fd4c3f44 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 7 Sep 2022 13:21:05 +0200 Subject: [PATCH 2/2] add `content` property to vscode-dts-defined properties --- .../src/singlefolder-tests/workspace.test.ts | 2 +- src/vscode-dts/vscode.d.ts | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index 126d37524c9..57762b4d1b1 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -1177,7 +1177,7 @@ suite('vscode API - workspace', () => { const data = Buffer.from('Hello Binary Files'); const ws = new vscode.WorkspaceEdit(); - ws.createFile(fileUri, { contents: data, ignoreIfExists: false, overwrite: false }); + ws.createFile(fileUri, { contents: data, ignoreIfExists: false, overwrite: false }); const success = await vscode.workspace.applyEdit(ws); assert.ok(success); diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 2c90006429d..20ac638f80e 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -3589,14 +3589,15 @@ declare module 'vscode' { /** * Create a regular file. * - * @param uri Uri of the new file.. + * @param uri Uri of the new file. * @param options Defines if an existing file should be overwritten or be - * ignored. When overwrite and ignoreIfExists are both set overwrite wins. + * ignored. When `overwrite` and `ignoreIfExists` are both set `overwrite` wins. * When both are unset and when the file already exists then the edit cannot - * be applied successfully. + * be applied successfully. The `content`-property allows to set the initial contents + * the file is being created with. * @param metadata Optional metadata for the entry. */ - createFile(uri: Uri, options?: { overwrite?: boolean; ignoreIfExists?: boolean }, metadata?: WorkspaceEditEntryMetadata): void; + createFile(uri: Uri, options?: { overwrite?: boolean; ignoreIfExists?: boolean; contents?: Uint8Array }, metadata?: WorkspaceEditEntryMetadata): void; /** * Delete a file or folder.