@codingame/monaco-vscode-bulk-edit-service-override 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,364 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { IFileService } from 'vscode/vscode/vs/platform/files/common/files';
3
+ import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
4
+ import { IWorkingCopyFileService } from 'vscode/vscode/vs/workbench/services/workingCopy/common/workingCopyFileService';
5
+ import { IUndoRedoService } from 'vscode/vscode/vs/platform/undoRedo/common/undoRedo';
6
+ import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
7
+ import { ILogService } from 'vscode/vscode/vs/platform/log/common/log';
8
+ import { CancellationToken } from 'vscode/vscode/vs/base/common/cancellation';
9
+ import { tail } from 'vscode/vscode/vs/base/common/arrays';
10
+ import { ITextFileService } from 'vscode/vscode/vs/workbench/services/textfile/common/textfiles';
11
+ import { Schemas } from 'vscode/vscode/vs/base/common/network';
12
+
13
+ var RenameOperation_1;
14
+ class Noop {
15
+ constructor() {
16
+ this.uris = [];
17
+ }
18
+ async perform() { return this; }
19
+ toString() {
20
+ return '(noop)';
21
+ }
22
+ }
23
+ class RenameEdit {
24
+ constructor(newUri, oldUri, options) {
25
+ this.newUri = newUri;
26
+ this.oldUri = oldUri;
27
+ this.options = options;
28
+ this.type = 'rename';
29
+ }
30
+ }
31
+ let RenameOperation = RenameOperation_1 = class RenameOperation {
32
+ constructor(_edits, _undoRedoInfo, _workingCopyFileService, _fileService) {
33
+ this._edits = _edits;
34
+ this._undoRedoInfo = _undoRedoInfo;
35
+ this._workingCopyFileService = _workingCopyFileService;
36
+ this._fileService = _fileService;
37
+ }
38
+ get uris() {
39
+ return this._edits.flatMap(edit => [edit.newUri, edit.oldUri]);
40
+ }
41
+ async perform(token) {
42
+ const moves = [];
43
+ const undoes = [];
44
+ for (const edit of this._edits) {
45
+ const skip = edit.options.overwrite === undefined && edit.options.ignoreIfExists && (await this._fileService.exists(edit.newUri));
46
+ if (!skip) {
47
+ moves.push({
48
+ file: { source: edit.oldUri, target: edit.newUri },
49
+ overwrite: edit.options.overwrite
50
+ });
51
+ undoes.push(( new RenameEdit(edit.oldUri, edit.newUri, edit.options)));
52
+ }
53
+ }
54
+ if (moves.length === 0) {
55
+ return ( new Noop());
56
+ }
57
+ await this._workingCopyFileService.move(moves, token, this._undoRedoInfo);
58
+ return ( new RenameOperation_1(
59
+ undoes,
60
+ { isUndoing: true },
61
+ this._workingCopyFileService,
62
+ this._fileService
63
+ ));
64
+ }
65
+ toString() {
66
+ return `(rename ${( this._edits.map(edit => `${edit.oldUri} to ${edit.newUri}`)).join(', ')})`;
67
+ }
68
+ };
69
+ RenameOperation = RenameOperation_1 = ( __decorate([
70
+ ( __param(2, IWorkingCopyFileService)),
71
+ ( __param(3, IFileService))
72
+ ], RenameOperation));
73
+ class CopyEdit {
74
+ constructor(newUri, oldUri, options) {
75
+ this.newUri = newUri;
76
+ this.oldUri = oldUri;
77
+ this.options = options;
78
+ this.type = 'copy';
79
+ }
80
+ }
81
+ let CopyOperation = class CopyOperation {
82
+ constructor(_edits, _undoRedoInfo, _workingCopyFileService, _fileService, _instaService) {
83
+ this._edits = _edits;
84
+ this._undoRedoInfo = _undoRedoInfo;
85
+ this._workingCopyFileService = _workingCopyFileService;
86
+ this._fileService = _fileService;
87
+ this._instaService = _instaService;
88
+ }
89
+ get uris() {
90
+ return this._edits.flatMap(edit => [edit.newUri, edit.oldUri]);
91
+ }
92
+ async perform(token) {
93
+ const copies = [];
94
+ for (const edit of this._edits) {
95
+ const skip = edit.options.overwrite === undefined && edit.options.ignoreIfExists && (await this._fileService.exists(edit.newUri));
96
+ if (!skip) {
97
+ copies.push({ file: { source: edit.oldUri, target: edit.newUri }, overwrite: edit.options.overwrite });
98
+ }
99
+ }
100
+ if (copies.length === 0) {
101
+ return ( new Noop());
102
+ }
103
+ const stats = await this._workingCopyFileService.copy(copies, token, this._undoRedoInfo);
104
+ const undoes = [];
105
+ for (let i = 0; i < stats.length; i++) {
106
+ const stat = stats[i];
107
+ const edit = this._edits[i];
108
+ undoes.push(( new DeleteEdit(
109
+ stat.resource,
110
+ { recursive: true, folder: this._edits[i].options.folder || stat.isDirectory, ...edit.options },
111
+ false
112
+ )));
113
+ }
114
+ return this._instaService.createInstance(DeleteOperation, undoes, { isUndoing: true });
115
+ }
116
+ toString() {
117
+ return `(copy ${( this._edits.map(edit => `${edit.oldUri} to ${edit.newUri}`)).join(', ')})`;
118
+ }
119
+ };
120
+ CopyOperation = ( __decorate([
121
+ ( __param(2, IWorkingCopyFileService)),
122
+ ( __param(3, IFileService)),
123
+ ( __param(4, IInstantiationService))
124
+ ], CopyOperation));
125
+ class CreateEdit {
126
+ constructor(newUri, options, contents) {
127
+ this.newUri = newUri;
128
+ this.options = options;
129
+ this.contents = contents;
130
+ this.type = 'create';
131
+ }
132
+ }
133
+ let CreateOperation = class CreateOperation {
134
+ constructor(_edits, _undoRedoInfo, _fileService, _workingCopyFileService, _instaService, _textFileService) {
135
+ this._edits = _edits;
136
+ this._undoRedoInfo = _undoRedoInfo;
137
+ this._fileService = _fileService;
138
+ this._workingCopyFileService = _workingCopyFileService;
139
+ this._instaService = _instaService;
140
+ this._textFileService = _textFileService;
141
+ }
142
+ get uris() {
143
+ return ( this._edits.map(edit => edit.newUri));
144
+ }
145
+ async perform(token) {
146
+ const folderCreates = [];
147
+ const fileCreates = [];
148
+ const undoes = [];
149
+ for (const edit of this._edits) {
150
+ if (edit.newUri.scheme === Schemas.untitled) {
151
+ continue;
152
+ }
153
+ if (edit.options.overwrite === undefined && edit.options.ignoreIfExists && (await this._fileService.exists(edit.newUri))) {
154
+ continue;
155
+ }
156
+ if (edit.options.folder) {
157
+ folderCreates.push({ resource: edit.newUri });
158
+ }
159
+ else {
160
+ const encodedReadable = typeof edit.contents !== 'undefined' ? edit.contents : await this._textFileService.getEncodedReadable(edit.newUri);
161
+ fileCreates.push({ resource: edit.newUri, contents: encodedReadable, overwrite: edit.options.overwrite });
162
+ }
163
+ undoes.push(( new DeleteEdit(edit.newUri, edit.options, !edit.options.folder && !edit.contents)));
164
+ }
165
+ if (folderCreates.length === 0 && fileCreates.length === 0) {
166
+ return ( new Noop());
167
+ }
168
+ await this._workingCopyFileService.createFolder(folderCreates, token, this._undoRedoInfo);
169
+ await this._workingCopyFileService.create(fileCreates, token, this._undoRedoInfo);
170
+ return this._instaService.createInstance(DeleteOperation, undoes, { isUndoing: true });
171
+ }
172
+ toString() {
173
+ return `(create ${( this._edits.map(
174
+ edit => edit.options.folder ? `folder ${edit.newUri}` : `file ${edit.newUri} with ${edit.contents?.byteLength || 0} bytes`
175
+ )).join(', ')})`;
176
+ }
177
+ };
178
+ CreateOperation = ( __decorate([
179
+ ( __param(2, IFileService)),
180
+ ( __param(3, IWorkingCopyFileService)),
181
+ ( __param(4, IInstantiationService)),
182
+ ( __param(5, ITextFileService))
183
+ ], CreateOperation));
184
+ class DeleteEdit {
185
+ constructor(oldUri, options, undoesCreate) {
186
+ this.oldUri = oldUri;
187
+ this.options = options;
188
+ this.undoesCreate = undoesCreate;
189
+ this.type = 'delete';
190
+ }
191
+ }
192
+ let DeleteOperation = class DeleteOperation {
193
+ constructor(_edits, _undoRedoInfo, _workingCopyFileService, _fileService, _configurationService, _instaService, _logService) {
194
+ this._edits = _edits;
195
+ this._undoRedoInfo = _undoRedoInfo;
196
+ this._workingCopyFileService = _workingCopyFileService;
197
+ this._fileService = _fileService;
198
+ this._configurationService = _configurationService;
199
+ this._instaService = _instaService;
200
+ this._logService = _logService;
201
+ }
202
+ get uris() {
203
+ return ( this._edits.map(edit => edit.oldUri));
204
+ }
205
+ async perform(token) {
206
+ const deletes = [];
207
+ const undoes = [];
208
+ for (const edit of this._edits) {
209
+ let fileStat;
210
+ try {
211
+ fileStat = await this._fileService.resolve(edit.oldUri, { resolveMetadata: true });
212
+ }
213
+ catch (err) {
214
+ if (!edit.options.ignoreIfNotExists) {
215
+ throw new Error(`${edit.oldUri} does not exist and can not be deleted`);
216
+ }
217
+ continue;
218
+ }
219
+ deletes.push({
220
+ resource: edit.oldUri,
221
+ recursive: edit.options.recursive,
222
+ useTrash: !edit.options.skipTrashBin && this._fileService.hasCapability(edit.oldUri, 4096 ) && this._configurationService.getValue('files.enableTrash')
223
+ });
224
+ let fileContent;
225
+ if (!edit.undoesCreate && !edit.options.folder && !(typeof edit.options.maxSize === 'number' && fileStat.size > edit.options.maxSize)) {
226
+ try {
227
+ fileContent = await this._fileService.readFile(edit.oldUri);
228
+ }
229
+ catch (err) {
230
+ this._logService.error(err);
231
+ }
232
+ }
233
+ if (fileContent !== undefined) {
234
+ undoes.push(( new CreateEdit(edit.oldUri, edit.options, fileContent.value)));
235
+ }
236
+ }
237
+ if (deletes.length === 0) {
238
+ return ( new Noop());
239
+ }
240
+ await this._workingCopyFileService.delete(deletes, token, this._undoRedoInfo);
241
+ if (undoes.length === 0) {
242
+ return ( new Noop());
243
+ }
244
+ return this._instaService.createInstance(CreateOperation, undoes, { isUndoing: true });
245
+ }
246
+ toString() {
247
+ return `(delete ${( this._edits.map(edit => edit.oldUri)).join(', ')})`;
248
+ }
249
+ };
250
+ DeleteOperation = ( __decorate([
251
+ ( __param(2, IWorkingCopyFileService)),
252
+ ( __param(3, IFileService)),
253
+ ( __param(4, IConfigurationService)),
254
+ ( __param(5, IInstantiationService)),
255
+ ( __param(6, ILogService))
256
+ ], DeleteOperation));
257
+ class FileUndoRedoElement {
258
+ constructor(label, code, operations, confirmBeforeUndo) {
259
+ this.label = label;
260
+ this.code = code;
261
+ this.operations = operations;
262
+ this.confirmBeforeUndo = confirmBeforeUndo;
263
+ this.type = 1 ;
264
+ this.resources = operations.flatMap(op => op.uris);
265
+ }
266
+ async undo() {
267
+ await this._reverse();
268
+ }
269
+ async redo() {
270
+ await this._reverse();
271
+ }
272
+ async _reverse() {
273
+ for (let i = 0; i < this.operations.length; i++) {
274
+ const op = this.operations[i];
275
+ const undo = await op.perform(CancellationToken.None);
276
+ this.operations[i] = undo;
277
+ }
278
+ }
279
+ toString() {
280
+ return ( this.operations.map(op => String(op))).join(', ');
281
+ }
282
+ }
283
+ let BulkFileEdits = class BulkFileEdits {
284
+ constructor(_label, _code, _undoRedoGroup, _undoRedoSource, _confirmBeforeUndo, _progress, _token, _edits, _instaService, _undoRedoService) {
285
+ this._label = _label;
286
+ this._code = _code;
287
+ this._undoRedoGroup = _undoRedoGroup;
288
+ this._undoRedoSource = _undoRedoSource;
289
+ this._confirmBeforeUndo = _confirmBeforeUndo;
290
+ this._progress = _progress;
291
+ this._token = _token;
292
+ this._edits = _edits;
293
+ this._instaService = _instaService;
294
+ this._undoRedoService = _undoRedoService;
295
+ }
296
+ async apply() {
297
+ const undoOperations = [];
298
+ const undoRedoInfo = { undoRedoGroupId: this._undoRedoGroup.id };
299
+ const edits = [];
300
+ for (const edit of this._edits) {
301
+ if (edit.newResource && edit.oldResource && !edit.options?.copy) {
302
+ edits.push(( new RenameEdit(edit.newResource, edit.oldResource, edit.options ?? {})));
303
+ }
304
+ else if (edit.newResource && edit.oldResource && edit.options?.copy) {
305
+ edits.push(( new CopyEdit(edit.newResource, edit.oldResource, edit.options ?? {})));
306
+ }
307
+ else if (!edit.newResource && edit.oldResource) {
308
+ edits.push(( new DeleteEdit(edit.oldResource, edit.options ?? {}, false)));
309
+ }
310
+ else if (edit.newResource && !edit.oldResource) {
311
+ edits.push(( new CreateEdit(edit.newResource, edit.options ?? {}, await edit.options.contents)));
312
+ }
313
+ }
314
+ if (edits.length === 0) {
315
+ return [];
316
+ }
317
+ const groups = [];
318
+ groups[0] = [edits[0]];
319
+ for (let i = 1; i < edits.length; i++) {
320
+ const edit = edits[i];
321
+ const lastGroup = tail(groups);
322
+ if (lastGroup[0].type === edit.type) {
323
+ lastGroup.push(edit);
324
+ }
325
+ else {
326
+ groups.push([edit]);
327
+ }
328
+ }
329
+ for (const group of groups) {
330
+ if (this._token.isCancellationRequested) {
331
+ break;
332
+ }
333
+ let op;
334
+ switch (group[0].type) {
335
+ case 'rename':
336
+ op = this._instaService.createInstance(RenameOperation, group, undoRedoInfo);
337
+ break;
338
+ case 'copy':
339
+ op = this._instaService.createInstance(CopyOperation, group, undoRedoInfo);
340
+ break;
341
+ case 'delete':
342
+ op = this._instaService.createInstance(DeleteOperation, group, undoRedoInfo);
343
+ break;
344
+ case 'create':
345
+ op = this._instaService.createInstance(CreateOperation, group, undoRedoInfo);
346
+ break;
347
+ }
348
+ if (op) {
349
+ const undoOp = await op.perform(this._token);
350
+ undoOperations.push(undoOp);
351
+ }
352
+ this._progress.report(undefined);
353
+ }
354
+ const undoRedoElement = ( new FileUndoRedoElement(this._label, this._code, undoOperations, this._confirmBeforeUndo));
355
+ this._undoRedoService.pushElement(undoRedoElement, this._undoRedoGroup, this._undoRedoSource);
356
+ return undoRedoElement.resources;
357
+ }
358
+ };
359
+ BulkFileEdits = ( __decorate([
360
+ ( __param(8, IInstantiationService)),
361
+ ( __param(9, IUndoRedoService))
362
+ ], BulkFileEdits));
363
+
364
+ export { BulkFileEdits };
@@ -0,0 +1,267 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { dispose } from 'vscode/vscode/vs/base/common/lifecycle';
3
+ import { EditOperation } from 'vscode/vscode/vs/editor/common/core/editOperation';
4
+ import { Range } from 'vscode/vscode/vs/editor/common/core/range';
5
+ import { ITextModelService } from 'vscode/vscode/vs/editor/common/services/resolverService';
6
+ import { IEditorWorkerService } from 'vscode/vscode/vs/editor/common/services/editorWorker';
7
+ import { IUndoRedoService } from 'vscode/vscode/vs/platform/undoRedo/common/undoRedo';
8
+ import { SingleModelEditStackElement, MultiModelEditStackElement } from 'vscode/vscode/vs/editor/common/model/editStack';
9
+ import { ResourceMap } from 'vscode/vscode/vs/base/common/map';
10
+ import { IModelService } from 'vscode/vscode/vs/editor/common/services/model';
11
+ import { ResourceTextEdit } from 'vscode/vscode/vs/editor/browser/services/bulkEditService';
12
+ import { SnippetController2 } from 'vscode/vscode/vs/editor/contrib/snippet/browser/snippetController2';
13
+ import { SnippetParser } from 'vscode/vscode/vs/editor/contrib/snippet/browser/snippetParser';
14
+
15
+ class ModelEditTask {
16
+ constructor(_modelReference) {
17
+ this._modelReference = _modelReference;
18
+ this.model = this._modelReference.object.textEditorModel;
19
+ this._edits = [];
20
+ }
21
+ dispose() {
22
+ this._modelReference.dispose();
23
+ }
24
+ isNoOp() {
25
+ if (this._edits.length > 0) {
26
+ return false;
27
+ }
28
+ if (this._newEol !== undefined && this._newEol !== this.model.getEndOfLineSequence()) {
29
+ return false;
30
+ }
31
+ return true;
32
+ }
33
+ addEdit(resourceEdit) {
34
+ this._expectedModelVersionId = resourceEdit.versionId;
35
+ const { textEdit } = resourceEdit;
36
+ if (typeof textEdit.eol === 'number') {
37
+ this._newEol = textEdit.eol;
38
+ }
39
+ if (!textEdit.range && !textEdit.text) {
40
+ return;
41
+ }
42
+ if (Range.isEmpty(textEdit.range) && !textEdit.text) {
43
+ return;
44
+ }
45
+ let range;
46
+ if (!textEdit.range) {
47
+ range = this.model.getFullModelRange();
48
+ }
49
+ else {
50
+ range = Range.lift(textEdit.range);
51
+ }
52
+ this._edits.push({ ...EditOperation.replaceMove(range, textEdit.text), insertAsSnippet: textEdit.insertAsSnippet });
53
+ }
54
+ validate() {
55
+ if (typeof this._expectedModelVersionId === 'undefined' || this.model.getVersionId() === this._expectedModelVersionId) {
56
+ return { canApply: true };
57
+ }
58
+ return { canApply: false, reason: this.model.uri };
59
+ }
60
+ getBeforeCursorState() {
61
+ return null;
62
+ }
63
+ apply() {
64
+ if (this._edits.length > 0) {
65
+ this._edits = (
66
+ this._edits
67
+ .map(this._transformSnippetStringToInsertText, this))
68
+ .sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range));
69
+ this.model.pushEditOperations(null, this._edits, () => null);
70
+ }
71
+ if (this._newEol !== undefined) {
72
+ this.model.pushEOL(this._newEol);
73
+ }
74
+ }
75
+ _transformSnippetStringToInsertText(edit) {
76
+ if (!edit.insertAsSnippet) {
77
+ return edit;
78
+ }
79
+ if (!edit.text) {
80
+ return edit;
81
+ }
82
+ const text = SnippetParser.asInsertText(edit.text);
83
+ return { ...edit, insertAsSnippet: false, text };
84
+ }
85
+ }
86
+ class EditorEditTask extends ModelEditTask {
87
+ constructor(modelReference, editor) {
88
+ super(modelReference);
89
+ this._editor = editor;
90
+ }
91
+ getBeforeCursorState() {
92
+ return this._canUseEditor() ? this._editor.getSelections() : null;
93
+ }
94
+ apply() {
95
+ if (!this._canUseEditor()) {
96
+ super.apply();
97
+ return;
98
+ }
99
+ if (this._edits.length > 0) {
100
+ const snippetCtrl = SnippetController2.get(this._editor);
101
+ if (snippetCtrl && ( this._edits.some(edit => edit.insertAsSnippet))) {
102
+ const snippetEdits = [];
103
+ for (const edit of this._edits) {
104
+ if (edit.range && edit.text !== null) {
105
+ snippetEdits.push({
106
+ range: Range.lift(edit.range),
107
+ template: edit.insertAsSnippet ? edit.text : SnippetParser.escape(edit.text)
108
+ });
109
+ }
110
+ }
111
+ snippetCtrl.apply(snippetEdits, { undoStopBefore: false, undoStopAfter: false });
112
+ }
113
+ else {
114
+ this._edits = (
115
+ this._edits
116
+ .map(this._transformSnippetStringToInsertText, this))
117
+ .sort((a, b) => Range.compareRangesUsingStarts(a.range, b.range));
118
+ this._editor.executeEdits('', this._edits);
119
+ }
120
+ }
121
+ if (this._newEol !== undefined) {
122
+ if (this._editor.hasModel()) {
123
+ this._editor.getModel().pushEOL(this._newEol);
124
+ }
125
+ }
126
+ }
127
+ _canUseEditor() {
128
+ return this._editor?.getModel()?.uri.toString() === ( this.model.uri.toString());
129
+ }
130
+ }
131
+ let BulkTextEdits = class BulkTextEdits {
132
+ constructor(_label, _code, _editor, _undoRedoGroup, _undoRedoSource, _progress, _token, edits, _editorWorker, _modelService, _textModelResolverService, _undoRedoService) {
133
+ this._label = _label;
134
+ this._code = _code;
135
+ this._editor = _editor;
136
+ this._undoRedoGroup = _undoRedoGroup;
137
+ this._undoRedoSource = _undoRedoSource;
138
+ this._progress = _progress;
139
+ this._token = _token;
140
+ this._editorWorker = _editorWorker;
141
+ this._modelService = _modelService;
142
+ this._textModelResolverService = _textModelResolverService;
143
+ this._undoRedoService = _undoRedoService;
144
+ this._edits = ( new ResourceMap());
145
+ for (const edit of edits) {
146
+ let array = this._edits.get(edit.resource);
147
+ if (!array) {
148
+ array = [];
149
+ this._edits.set(edit.resource, array);
150
+ }
151
+ array.push(edit);
152
+ }
153
+ }
154
+ _validateBeforePrepare() {
155
+ for (const array of ( this._edits.values())) {
156
+ for (const edit of array) {
157
+ if (typeof edit.versionId === 'number') {
158
+ const model = this._modelService.getModel(edit.resource);
159
+ if (model && model.getVersionId() !== edit.versionId) {
160
+ throw new Error(`${model.uri.toString()} has changed in the meantime`);
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ async _createEditsTasks() {
167
+ const tasks = [];
168
+ const promises = [];
169
+ for (const [key, edits] of this._edits) {
170
+ const promise = this._textModelResolverService.createModelReference(key).then(async (ref) => {
171
+ let task;
172
+ let makeMinimal = false;
173
+ if (this._editor?.getModel()?.uri.toString() === ( ref.object.textEditorModel.uri.toString())) {
174
+ task = ( new EditorEditTask(ref, this._editor));
175
+ makeMinimal = true;
176
+ }
177
+ else {
178
+ task = ( new ModelEditTask(ref));
179
+ }
180
+ tasks.push(task);
181
+ if (!makeMinimal) {
182
+ edits.forEach(task.addEdit, task);
183
+ return;
184
+ }
185
+ const makeGroupMoreMinimal = async (start, end) => {
186
+ const oldEdits = edits.slice(start, end);
187
+ const newEdits = await this._editorWorker.computeMoreMinimalEdits(ref.object.textEditorModel.uri, ( oldEdits.map(e => e.textEdit)), false);
188
+ if (!newEdits) {
189
+ oldEdits.forEach(task.addEdit, task);
190
+ }
191
+ else {
192
+ newEdits.forEach(edit => task.addEdit(( new ResourceTextEdit(ref.object.textEditorModel.uri, edit, undefined, undefined))));
193
+ }
194
+ };
195
+ let start = 0;
196
+ let i = 0;
197
+ for (; i < edits.length; i++) {
198
+ if (edits[i].textEdit.insertAsSnippet || edits[i].metadata) {
199
+ await makeGroupMoreMinimal(start, i);
200
+ task.addEdit(edits[i]);
201
+ start = i + 1;
202
+ }
203
+ }
204
+ await makeGroupMoreMinimal(start, i);
205
+ });
206
+ promises.push(promise);
207
+ }
208
+ await Promise.all(promises);
209
+ return tasks;
210
+ }
211
+ _validateTasks(tasks) {
212
+ for (const task of tasks) {
213
+ const result = task.validate();
214
+ if (!result.canApply) {
215
+ return result;
216
+ }
217
+ }
218
+ return { canApply: true };
219
+ }
220
+ async apply() {
221
+ this._validateBeforePrepare();
222
+ const tasks = await this._createEditsTasks();
223
+ try {
224
+ if (this._token.isCancellationRequested) {
225
+ return [];
226
+ }
227
+ const resources = [];
228
+ const validation = this._validateTasks(tasks);
229
+ if (!validation.canApply) {
230
+ throw new Error(`${validation.reason.toString()} has changed in the meantime`);
231
+ }
232
+ if (tasks.length === 1) {
233
+ const task = tasks[0];
234
+ if (!task.isNoOp()) {
235
+ const singleModelEditStackElement = ( new SingleModelEditStackElement(this._label, this._code, task.model, task.getBeforeCursorState()));
236
+ this._undoRedoService.pushElement(singleModelEditStackElement, this._undoRedoGroup, this._undoRedoSource);
237
+ task.apply();
238
+ singleModelEditStackElement.close();
239
+ resources.push(task.model.uri);
240
+ }
241
+ this._progress.report(undefined);
242
+ }
243
+ else {
244
+ const multiModelEditStackElement = ( new MultiModelEditStackElement(this._label, this._code, ( tasks.map(t => ( new SingleModelEditStackElement(this._label, this._code, t.model, t.getBeforeCursorState()))))));
245
+ this._undoRedoService.pushElement(multiModelEditStackElement, this._undoRedoGroup, this._undoRedoSource);
246
+ for (const task of tasks) {
247
+ task.apply();
248
+ this._progress.report(undefined);
249
+ resources.push(task.model.uri);
250
+ }
251
+ multiModelEditStackElement.close();
252
+ }
253
+ return resources;
254
+ }
255
+ finally {
256
+ dispose(tasks);
257
+ }
258
+ }
259
+ };
260
+ BulkTextEdits = ( __decorate([
261
+ ( __param(8, IEditorWorkerService)),
262
+ ( __param(9, IModelService)),
263
+ ( __param(10, ITextModelService)),
264
+ ( __param(11, IUndoRedoService))
265
+ ], BulkTextEdits));
266
+
267
+ export { BulkTextEdits };