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 f88a12cd1e1..7a8b10adc23 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -1005,6 +1005,31 @@ suite('vscode API - workspace', () => { assert.strictEqual(e.files[1].oldUri.toString(), file2.toString()); }); + test('Should send a single FileWillRenameEvent instead of separate events when moving multiple files at once#111867', async function () { + this.skip(); + + const event = new Promise(resolve => { + let sub = vscode.workspace.onWillCreateFiles(e => { + sub.dispose(); + resolve(e); + }); + }); + + const file1 = vscode.Uri.parse(`fake-fs:/${rndName()}`); + const file2 = vscode.Uri.parse(`fake-fs:/${rndName()}`); + + const we = new vscode.WorkspaceEdit(); + we.createFile(file1, { overwrite: true }); + we.createFile(file2, { overwrite: true }); + await vscode.workspace.applyEdit(we); + + const e = await event; + + assert.strictEqual(e.files.length, 2); + assert.strictEqual(e.files[0].toString(), file1.toString()); + assert.strictEqual(e.files[1].toString(), file2.toString()); + }); + test('Should send a single FileWillRenameEvent instead of separate events when moving multiple files at once#111867', async function () { const file1 = await createRandomFile(); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts index 54a778e1714..4c4b94f82c1 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts @@ -8,7 +8,7 @@ import { WorkspaceFileEditOptions } from 'vs/editor/common/modes'; import { IFileService, FileSystemProviderCapabilities, IFileContent } from 'vs/platform/files/common/files'; import { IProgress } from 'vs/platform/progress/common/progress'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkingCopyFileService, IFileOperationUndoRedoInfo, IMoveOperation, ICopyOperation, IDeleteOperation } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; +import { IWorkingCopyFileService, IFileOperationUndoRedoInfo, IMoveOperation, ICopyOperation, IDeleteOperation, ICreateOperation, ICreateFileOperation } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { IWorkspaceUndoRedoElement, UndoRedoElementType, IUndoRedoService, UndoRedoGroup, UndoRedoSource } from 'vs/platform/undoRedo/common/undoRedo'; import { URI } from 'vs/base/common/uri'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -166,6 +166,8 @@ class CreateOperation implements IFileOperation { async perform(token: CancellationToken): Promise { + const folderCreates: ICreateOperation[] = []; + const fileCreates: ICreateFileOperation[] = []; const undoes: DeleteEdit[] = []; for (const edit of this._edits) { @@ -173,14 +175,20 @@ class CreateOperation implements IFileOperation { continue; // not overwriting, but ignoring, and the target file exists } if (edit.options.folder) { - await this._workingCopyFileService.createFolder([{ resource: edit.newUri }], this._undoRedoInfo, token); + folderCreates.push({ resource: edit.newUri }); } else { - await this._workingCopyFileService.create([{ resource: edit.newUri, contents: edit.contents, overwrite: edit.options.overwrite }], this._undoRedoInfo, token); + fileCreates.push({ resource: edit.newUri, contents: edit.contents, overwrite: edit.options.overwrite }); } - undoes.push(new DeleteEdit(edit.newUri, edit.options, !edit.options.folder && !edit.contents)); } + if (fileCreates.length === 0 && folderCreates.length === 0) { + return new Noop(); + } + + await this._workingCopyFileService.createFolder(folderCreates, this._undoRedoInfo, token); + await this._workingCopyFileService.create(fileCreates, this._undoRedoInfo, token); + return this._instaService.createInstance(DeleteOperation, undoes, { isUndoing: true }); }