Example #1
0
	private async onCodeAction(source: Source, workspaceEdit: WorkspaceEdit): Promise<boolean> {
		const success = workspace.applyEdit(workspaceEdit);
		if (!success) {
			return false;
		}

		let firstEdit: TextEdit | undefined = undefined;
		for (const [uri, edits] of workspaceEdit.entries()) {
			if (uri.fsPath === source.uri.fsPath) {
				firstEdit = edits[0];
				break;
			}
		}

		if (!firstEdit) {
			return true;
		}

		const newLines = firstEdit.newText.match(/\n/g);
		const editedRange = new Range(
			firstEdit.range.start.line, 0,
			firstEdit.range.end.line + 1 + (newLines ? newLines.length : 0), 0);
		// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/12249
		// apply formatting to the source range until TS returns formatted results
		const edits = (await commands.executeCommand('vscode.executeFormatRangeProvider', source.uri, editedRange, source.formattingOptions || {})) as TextEdit[];
		if (!edits || !edits.length) {
			return false;
		}
		const formattingEdit = new WorkspaceEdit();
		formattingEdit.set(source.uri, edits);
		return workspace.applyEdit(formattingEdit);
	}
Example #2
0
	private async doRefactoring(file: string, refactor: string, action: string, range: Range): Promise<boolean> {
		const args: Proto.GetEditsForRefactorRequestArgs = {
			file,
			refactor,
			action,
			startLine: range.start.line + 1,
			startOffset: range.start.character + 1,
			endLine: range.end.line + 1,
			endOffset: range.end.character + 1
		};

		const response = await this.client.execute('getEditsForRefactor', args);
		if (!response || !response.body || !response.body.edits.length) {
			return false;
		}

		const edit = this.toWorkspaceEdit(response.body.edits);
		if (!(await workspace.applyEdit(edit))) {
			return false;
		}

		const renameLocation = response.body.renameLocation;
		if (renameLocation) {
			if (window.activeTextEditor && window.activeTextEditor.document.uri.fsPath === file) {
				const pos = new Position(renameLocation.line - 1, renameLocation.offset - 1);
				window.activeTextEditor.selection = new Selection(pos, pos);
				await commands.executeCommand('editor.action.rename');
			}
		}
		return true;
	}
		saveText: async (text: string) => {
			const filename = await utils.createFile('', getFixturePath([
				rule,
				value,
				'test'
			]));
			const doc = await workspace.openTextDocument(filename);
			await window.showTextDocument(doc);
			const edit = new WorkspaceEdit();
			edit.insert(doc.uri, new Position(0, 0), text);
			assert.strictEqual(
				await workspace.applyEdit(edit),
				true,
				'applies edit'
			);
			return await new Promise(resolve => {
				let saveCount = 0;
				workspace.onDidSaveTextDocument(savedDoc => {
					if (++saveCount === (options.saves || 1)) {
						resolve(savedDoc.getText());
					}
				});
				doc.save();
			});
		}
Example #4
0
	private onCodeAction(source: Source, workspaceEdit: WorkspaceEdit) {
		workspace.applyEdit(workspaceEdit).then(success => {
			if (!success) {
				return Promise.reject<boolean>(false);
			}

			let firstEdit: TextEdit | null = null;
			for (const [uri, edits] of workspaceEdit.entries()) {
				if (uri.fsPath === source.uri.fsPath) {
					firstEdit = edits[0];
					break;
				}
			}

			if (!firstEdit) {
				return true;
			}

			const newLines = firstEdit.newText.match(/\n/g);
			const editedRange = new Range(
				new Position(firstEdit.range.start.line, 0),
				new Position(firstEdit.range.end.line + 1 + (newLines ? newLines.length : 0), 0));

			// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/12249
			// apply formatting to the source range until TS returns formatted results
			return commands.executeCommand('vscode.executeFormatRangeProvider', source.uri, editedRange, source.formattingOptions || {}).then((edits: TextEdit[]) => {
				if (!edits || !edits.length) {
					return false;
				}
				const workspaceEdit = new WorkspaceEdit();
				workspaceEdit.set(source.uri, edits);
				return workspace.applyEdit(workspaceEdit);
			});
		});
	}
Example #5
0
export async function applyCodeAction(
	client: ITypescriptServiceClient,
	action: Proto.CodeAction,
	file: string
): Promise<boolean> {
	if (action.changes && action.changes.length) {
		const workspaceEdit = new WorkspaceEdit();
		for (const change of action.changes) {
			for (const textChange of change.textChanges) {
				workspaceEdit.replace(client.asUrl(change.fileName),
					tsTextSpanToVsRange(textChange),
					textChange.newText);
			}
		}

		if (!(await workspace.applyEdit(workspaceEdit))) {
			return false;
		}
	}

	if (action.commands && action.commands.length) {
		for (const command of action.commands) {
			const response = await client.execute('applyCodeActionCommand', { file, command });
			if (!response || !response.body) {
				return false;
			}
		}
	}
	return true;
}
Example #6
0
	private async _revertChanges(textEditor: TextEditor, changes: LineChange[]): Promise<void> {
		const modifiedDocument = textEditor.document;
		const modifiedUri = modifiedDocument.uri;

		if (modifiedUri.scheme !== 'file') {
			return;
		}

		const originalUri = toGitUri(modifiedUri, '~');
		const originalDocument = await workspace.openTextDocument(originalUri);
		const basename = path.basename(modifiedUri.fsPath);
		const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename);
		const yes = localize('revert', "Revert Changes");
		const pick = await window.showWarningMessage(message, { modal: true }, yes);

		if (pick !== yes) {
			return;
		}

		const result = applyLineChanges(originalDocument, modifiedDocument, changes);
		const edit = new WorkspaceEdit();
		edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result);
		workspace.applyEdit(edit);
		await modifiedDocument.save();
	}
	it("renames all exact references but not other items with same name", async () => {
		const doc = currentDoc();
		await setTestContent(`
			class Danny {
				static int myField = 1;
			}
			class Other {
				static int Danny = 2;
			}
			var a = new Danny();
			print(Danny.myField);
		`);
		const renameResult = await (vs.commands.executeCommand("vscode.executeDocumentRenameProvider", doc.uri, positionOf("D^anny"), "NewDanny") as Thenable<vs.WorkspaceEdit>);
		await vs.workspace.applyEdit(renameResult);
		await ensureTestContent(`
			class NewDanny {
				static int myField = 1;
			}
			class Other {
				static int Danny = 2;
			}
			var a = new NewDanny();
			print(NewDanny.myField);
		`);
	});
Example #8
0
	private async doRefactoring(document: TextDocument, file: string, refactor: string, action: string, range: Range): Promise<boolean> {
		await this.formattingOptionsManager.ensureFormatOptionsForDocument(document, undefined);

		const args: Proto.GetEditsForRefactorRequestArgs = {
			...vsRangeToTsFileRange(file, range),
			refactor,
			action
		};

		const response = await this.client.execute('getEditsForRefactor', args);
		if (!response || !response.body || !response.body.edits.length) {
			return false;
		}

		const edit = this.toWorkspaceEdit(response.body.edits);
		if (!(await workspace.applyEdit(edit))) {
			return false;
		}

		const renameLocation = response.body.renameLocation;
		if (renameLocation) {
			if (window.activeTextEditor && window.activeTextEditor.document.uri.fsPath === file) {
				const pos = tsLocationToVsPosition(renameLocation);
				window.activeTextEditor.selection = new Selection(pos, pos);
				await commands.executeCommand('editor.action.rename');
			}
		}
		return true;
	}
Example #9
0
			return commands.executeCommand('vscode.executeFormatRangeProvider', source.uri, editedRange, source.formattingOptions || {}).then((edits: TextEdit[]) => {
				if (!edits || !edits.length) {
					return false;
				}
				const workspaceEdit = new WorkspaceEdit();
				workspaceEdit.set(source.uri, edits);
				return workspace.applyEdit(workspaceEdit);
			});
function applyTextEdit(we) {
    telemetry.traceEvent('command-applytextedit');

    let wse = new vscode.WorkspaceEdit()
    for (let edit of we.documentChanges[0].edits) {
        wse.replace(we.documentChanges[0].textDocument.uri, new vscode.Range(edit.range.start.line, edit.range.start.character, edit.range.end.line, edit.range.end.character), edit.newText)
    }
    vscode.workspace.applyEdit(wse)
}
Example #11
0
 private applyEdit(coords, content): void {
     var vsDocument = window.activeTextEditor.document;
     var edit = this.setEditFactory(vsDocument.uri, coords, content);
     workspace.applyEdit(edit).then(() => {
         //move cursor to end of highlight
         let cursorPos = window.activeTextEditor.selection.active;
         let move = new Selection(cursorPos, cursorPos);
         window.activeTextEditor.selection = move;
     })
 }
Example #12
0
 .then(textedits => {
     if (textedits) {
         let we = new vscode.WorkspaceEdit();
         textedits.forEach(edit => {
             we.replace(textEditor.document.uri, edit.range, edit.newText);
         });
         return vscode.workspace.applyEdit(we);
     }
     return null;
 });
Example #13
0
	private async onCodeAction(action: Proto.CodeAction): Promise<boolean> {
		const workspaceEdit = new WorkspaceEdit();
		for (const change of action.changes) {
			for (const textChange of change.textChanges) {
				workspaceEdit.replace(this.client.asUrl(change.fileName),
					tsTextSpanToVsRange(textChange),
					textChange.newText);
			}
		}

		return workspace.applyEdit(workspaceEdit);
	}
Example #14
0
export async function applyCodeAction(
	client: ITypeScriptServiceClient,
	action: Proto.CodeAction
): Promise<boolean> {
	const workspaceEdit = getEditForCodeAction(client, action);
	if (workspaceEdit) {
		if (!(await workspace.applyEdit(workspaceEdit))) {
			return false;
		}
	}
	return applyCodeActionCommands(client, action);
}
	it("renames alias on the import keyword", async () => {
		const doc = currentDoc();
		await setTestContent(`
			import "dart:async" as async;
		`);

		const renamePrep = await extApi.renameProvider.prepareRename(doc, positionOf("i^mport"), undefined);
		assert.equal(renamePrep.placeholder, "async");
		const renameResult = await extApi.renameProvider.provideRenameEdits(doc, renamePrep.range.start, "async2", undefined);
		await vs.workspace.applyEdit(renameResult);
		await ensureTestContent(`
			import "dart:async" as async2;
		`);
	});
	it("renames the class on the class keyword", async () => {
		const doc = currentDoc();
		await setTestContent(`
			class Danny {}
		`);

		const renamePrep = await extApi.renameProvider.prepareRename(doc, positionOf("D^anny"), undefined);
		assert.equal(renamePrep.placeholder, "Danny");
		const renameResult = await extApi.renameProvider.provideRenameEdits(doc, renamePrep.range.start, "Danny2", undefined);
		await vs.workspace.applyEdit(renameResult);
		await ensureTestContent(`
			class Danny2 {}
		`);
	});
Example #17
0
	private async doRename(
		oldResource: vscode.Uri,
		newResource: vscode.Uri,
	): Promise<void> {
		if (!this.client.apiVersion.gte(API.v290)) {
			return;
		}

		const targetResource = await this.getTargetResource(newResource);
		if (!targetResource) {
			return;
		}

		const targetFile = this.client.toPath(targetResource);
		if (!targetFile) {
			return;
		}

		const newFile = this.client.toPath(newResource);
		if (!newFile) {
			return;
		}

		const oldFile = this.client.toPath(oldResource);
		if (!oldFile) {
			return;
		}

		const document = await vscode.workspace.openTextDocument(targetResource);

		const config = this.getConfiguration(document);
		const setting = config.get<UpdateImportsOnFileMoveSetting>(updateImportsOnFileMoveName);
		if (setting === UpdateImportsOnFileMoveSetting.Never) {
			return;
		}

		// Make sure TS knows about file
		this.client.bufferSyncSupport.closeResource(targetResource);
		this.client.bufferSyncSupport.openTextDocument(document);

		const edits = await this.getEditsForFileRename(targetFile, document, oldFile, newFile);
		if (!edits || !edits.size) {
			return;
		}

		if (await this.confirmActionWithUser(newResource, document)) {
			await vscode.workspace.applyEdit(edits);
		}
	}
	it("edits in '// ignore: ' comment", async () => {
		await openFile(emptyFile);
		await setTestContent(`main() {
  var a = 1;
}`);
		const fixResults = await (vs.commands.executeCommand("vscode.executeCodeActionProvider", currentDoc().uri, rangeOf("|a| = 1")) as Thenable<vs.CodeAction[]>);
		const ignoreLintAction = fixResults.find((r) => r.title.indexOf("Ignore hint 'unused_local_variable' for this line") !== -1);

		await vs.workspace.applyEdit(ignoreLintAction!.edit);

		await ensureTestContent(`main() {
  // ignore: unused_local_variable
  var a = 1;
}`);
	});
Example #19
0
			return new Promise<string>(async resolve => {
				const doc = await createDoc(options.contents);
				workspace.onDidChangeTextDocument(doc.save);
				workspace.onDidSaveTextDocument(savedDoc => {
					assert.strictEqual(savedDoc.isDirty, false, 'dirty saved doc');
					resolve(savedDoc.getText());
				});
				const edit = new WorkspaceEdit();
				edit.insert(doc.uri, new Position(0, 0), text);
				assert.strictEqual(
					await workspace.applyEdit(edit),
					true,
					'editor fails to apply edit'
				);
			});
Example #20
0
		saveText: async (text: string) => {
			const doc = await createDoc();
			const edit = new WorkspaceEdit();
			edit.insert(doc.uri, new Position(0, 0), text);
			assert.strictEqual(
				await workspace.applyEdit(edit),
				true,
				'applies edit'
			);
			return await new Promise(resolve => {
				workspace.onDidSaveTextDocument(savedDoc => {
					resolve(savedDoc.getText());
				});
				doc.save();
			});
		}
Example #21
0
	private onCodeAction(source: Source, workspaceEdit: WorkspaceEdit) {
		workspace.applyEdit(workspaceEdit).then(success => {
			if (!success) {
				return Promise.reject(null);
			}
			// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/12249
			// apply formatting to the source range until TS returns formatted results
			return commands.executeCommand('vscode.executeFormatRangeProvider', source.uri, source.range, {}).then((edits: TextEdit[]) => {
				if (!edits || !edits.length) {
					return false;
				}
				const workspaceEdit = new WorkspaceEdit();
				workspaceEdit.set(source.uri, edits);
				return workspace.applyEdit(workspaceEdit);
			});
		});
	}
Example #22
0
	@command('git.revertSelectedRanges')
	async revertSelectedRanges(): Promise<void> {
		const textEditor = window.activeTextEditor;

		if (!textEditor) {
			return;
		}

		const modifiedDocument = textEditor.document;
		const modifiedUri = modifiedDocument.uri;

		if (modifiedUri.scheme !== 'file') {
			return;
		}

		const originalUri = modifiedUri.with({ scheme: 'git', query: '~' });
		const originalDocument = await workspace.openTextDocument(originalUri);
		const diffs = await computeDiff(originalDocument, modifiedDocument);
		const selections = textEditor.selections;
		const selectedDiffs = diffs.filter(diff => {
			const modifiedRange = diff.modifiedEndLineNumber === 0
				? new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(diff.modifiedStartLineNumber).range.start)
				: new Range(modifiedDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);

			return selections.every(selection => !selection.intersection(modifiedRange));
		});

		if (selectedDiffs.length === diffs.length) {
			return;
		}

		const basename = path.basename(modifiedUri.fsPath);
		const message = localize('confirm revert', "Are you sure you want to revert the selected changes in {0}?", basename);
		const yes = localize('revert', "Revert Changes");
		const pick = await window.showWarningMessage(message, { modal: true }, yes);

		if (pick !== yes) {
			return;
		}

		const result = staging.applyChanges(originalDocument, modifiedDocument, selectedDiffs);
		const edit = new WorkspaceEdit();
		edit.replace(modifiedUri, new Range(new Position(0, 0), modifiedDocument.lineAt(modifiedDocument.lineCount - 1).range.end), result);
		workspace.applyEdit(edit);
	}
Example #23
0
function onDocumentOpen(td: TextDocument) {
	let extension = extname(td.fileName);
	if (extension != ".wurst" && extension != ".jurst") {
		return;
	}
	if (td.lineCount > 1 || td.getText().length > 0) {
		return;
	}

	let packageName = basename(td.fileName, extension);
	let newText = `package ${packageName}\n\n`;

	let edit = new WorkspaceEdit()
	edit.insert(td.uri, new Position(1,1), newText)
	workspace.applyEdit(edit);


}
Example #24
0
	private async doRefactoring(file: string, refactor: string, action: string, range: Range): Promise<boolean> {
		const args: Proto.GetEditsForRefactorRequestArgs = {
			file,
			refactor,
			action,
			startLine: range.start.line + 1,
			startOffset: range.start.character + 1,
			endLine: range.end.line + 1,
			endOffset: range.end.character + 1
		};

		const response = await this.client.execute('getEditsForRefactor', args);
		if (!response || !response.body || !response.body.edits.length) {
			return false;
		}

		const edit = this.toWorkspaceEdit(response.body.edits);
		return workspace.applyEdit(edit);
	}
Example #25
0
	private async doRename(
		oldResource: vscode.Uri,
		newResource: vscode.Uri,
	): Promise<void> {
		// Try to get a js/ts file that is being moved
		// For directory moves, this returns a js/ts file under the directory.
		const jsTsFileThatIsBeingMoved = await this.getJsTsFileBeingMoved(newResource);
		if (!jsTsFileThatIsBeingMoved || !this.client.toPath(jsTsFileThatIsBeingMoved)) {
			return;
		}

		const newFile = this.client.toPath(newResource);
		if (!newFile) {
			return;
		}

		const oldFile = this.client.toPath(oldResource);
		if (!oldFile) {
			return;
		}

		const document = await vscode.workspace.openTextDocument(jsTsFileThatIsBeingMoved);

		const config = this.getConfiguration(document);
		const setting = config.get<UpdateImportsOnFileMoveSetting>(updateImportsOnFileMoveName);
		if (setting === UpdateImportsOnFileMoveSetting.Never) {
			return;
		}

		// Make sure TS knows about file
		this.client.bufferSyncSupport.closeResource(oldResource);
		this.client.bufferSyncSupport.openTextDocument(document);

		const edits = await this.getEditsForFileRename(document, oldFile, newFile);
		if (!edits || !edits.size) {
			return;
		}

		if (await this.confirmActionWithUser(newResource, document)) {
			await vscode.workspace.applyEdit(edits);
		}
	}
Example #26
0
		return this._server.makeRequest<V2.RunCodeActionResponse>(V2.RunCodeAction, req).then(response => {

			if (response && Array.isArray(response.Changes)) {

				let edit = new WorkspaceEdit();

				for (let change of response.Changes) {
					let uri = Uri.file(change.FileName);
					let edits: TextEdit[] = [];
					for (let textChange of change.Changes) {
						edits.push(TextEdit.replace(toRange2(textChange), textChange.NewText));
					}

					edit.set(uri, edits);
				}

				return workspace.applyEdit(edit);
			}

		}, (error) => {
  public addNewLine(document: TextDocument) {
    // get the line count
    let lineCount = document.lineCount;
    console.log('lineCount: ' + lineCount);

    let allText = document.getText();
    let matches = allText.match(/\r?\n$/);
    if (matches) {
      return;
    }

    let workspaceConfiguration = workspace.getConfiguration('editor');
    let lineEnding: string = workspaceConfiguration.get<string>('lineEnding');

    let uri = document.uri;

    let workspaceEdit = new WorkspaceEdit();
    let position = new Position(lineCount, 0);
    workspaceEdit.insert(uri, position, lineEnding);
    workspace.applyEdit(workspaceEdit).then(function() {
      document.save();
    });
  }
Example #28
0
  test('jj -> <Esc> through modehandler', async () => {
    const expectedDocumentContent = 'lorem ipsum';

    // setup
    await setupWithBindings({
      insertModeKeyBindings: defaultInsertModeKeyBindings,
      normalModeKeyBindings: defaultNormalModeKeyBindings,
      visualModeKeyBindings: defaultVisualModeKeyBindings,
    });

    let remapper = new Remappers();

    const edit = new vscode.WorkspaceEdit();
    edit.insert(
      vscode.window.activeTextEditor!.document.uri,
      new vscode.Position(0, 0),
      expectedDocumentContent
    );
    vscode.workspace.applyEdit(edit);

    await modeHandler.handleKeyEvent('i');
    assertEqual(modeHandler.currentMode.name, ModeName.Insert);

    // act
    let actual = false;
    try {
      actual = await remapper.sendKey(['j', 'j'], modeHandler, modeHandler.vimState);
    } catch (e) {
      assert.fail(e);
    }

    // assert
    assert.equal(actual, true);
    assertEqual(modeHandler.currentMode.name, ModeName.Normal);
    assert.equal(vscode.window.activeTextEditor!.document.getText(), expectedDocumentContent);
  });
	private async doRename(
		oldResource: vscode.Uri,
		newResource: vscode.Uri,
	): Promise<void> {
		const targetResource = await this.getTargetResource(newResource);
		if (!targetResource) {
			return;
		}

		const targetFile = this.client.toPath(targetResource);
		if (!targetFile) {
			return;
		}

		const newFile = this.client.toPath(newResource);
		if (!newFile) {
			return;
		}

		const oldFile = this.client.toPath(oldResource);
		if (!oldFile) {
			return;
		}

		const document = await vscode.workspace.openTextDocument(targetResource);

		const config = this.getConfiguration(document);
		const setting = config.get<UpdateImportsOnFileMoveSetting>(updateImportsOnFileMoveName);
		if (setting === UpdateImportsOnFileMoveSetting.Never) {
			return;
		}

		// Make sure TS knows about file
		this.client.bufferSyncSupport.closeResource(oldResource);
		this.client.bufferSyncSupport.openTextDocument(document);

		if (this.client.apiVersion.lt(API.v300) && !fs.lstatSync(newResource.fsPath).isDirectory()) {
			// Workaround for https://github.com/Microsoft/vscode/issues/52967
			// Never attempt to update import paths if the file does not contain something the looks like an export
			try {
				const response = await this.client.execute('navtree', { file: newFile }, nulToken);
				if (response.type !== 'response' || !response.body) {
					return;
				}

				const hasExport = (node: Proto.NavigationTree): boolean => {
					return !!node.kindModifiers.match(/\bexports?\b/g) || !!(node.childItems && node.childItems.some(hasExport));
				};
				if (!hasExport(response.body)) {
					return;
				}
			} catch {
				// noop
			}
		}

		const edits = await this.getEditsForFileRename(targetFile, document, oldFile, newFile);
		if (!edits || !edits.size) {
			return;
		}

		if (await this.confirmActionWithUser(newResource, document)) {
			await vscode.workspace.applyEdit(edits);
		}
	}
        return serverUtils.runCodeAction(this._server, req).then(response => {

            if (response && Array.isArray(response.Changes)) {

                let edit = new vscode.WorkspaceEdit();

                let fileToOpen: Uri = null;
                let renamedFiles: Uri[] = [];

                for (let change of response.Changes) {
                    if (change.ModificationType == FileModificationType.Renamed)
                    {
                        // The file was renamed. Omnisharp has already persisted
                        // the right changes to disk. We don't need to try to
                        // apply text changes (and will skip this file if we see an edit)
                        renamedFiles.push(Uri.file(change.FileName));
                    }
                }

                for (let change of response.Changes) {
                    if (change.ModificationType == FileModificationType.Opened)
                    {
                        // The CodeAction requested that we open a file. 
                        // Record that file name and keep processing CodeActions.
                        // If a CodeAction requests that we open multiple files 
                        // we only open the last one (what would it mean to open multiple files?)
                        fileToOpen = vscode.Uri.file(change.FileName);
                    }

                    if (change.ModificationType == FileModificationType.Modified)
                    {
                        let uri = vscode.Uri.file(change.FileName);
                        if (renamedFiles.some(r => r == uri))
                        {
                            // This file got renamed. Omnisharp has already
                            // persisted the new file with any applicable changes.
                            continue;
                        }

                        let edits: vscode.TextEdit[] = [];
                        for (let textChange of change.Changes) {
                            edits.push(vscode.TextEdit.replace(toRange2(textChange), textChange.NewText));
                        }
    
                        edit.set(uri, edits);
                    }
                }

                let applyEditPromise = vscode.workspace.applyEdit(edit);

                // Unfortunately, the textEditor.Close() API has been deprecated
                // and replaced with a command that can only close the active editor.
                // If files were renamed that weren't the active editor, their tabs will
                // be left open and marked as "deleted" by VS Code
                let next = applyEditPromise;
                if (renamedFiles.some(r => r.fsPath == vscode.window.activeTextEditor.document.uri.fsPath))
                {
                    next = applyEditPromise.then(_ => 
                        {
                            return vscode.commands.executeCommand("workbench.action.closeActiveEditor");
                        });
                }

                return fileToOpen != null
                 ? next.then(_ => 
                        {
                            return vscode.commands.executeCommand("vscode.open", fileToOpen);
                        })
                 : next;
                }
            }, async (error) => {