| /* eslint-disable @typescript-eslint/no-explicit-any */ |
| /*--------------------------------------------------------- |
| * Copyright (C) Microsoft Corporation. All rights reserved. |
| * Licensed under the MIT License. See LICENSE in the project root for license information. |
| *--------------------------------------------------------*/ |
| |
| 'use strict'; |
| |
| import cp = require('child_process'); |
| import vscode = require('vscode'); |
| import { getGoConfig } from './config'; |
| import { Edit, FilePatch, getEditsFromUnifiedDiffStr, isDiffToolAvailable } from './diffUtils'; |
| import { toolExecutionEnvironment } from './goEnv'; |
| import { promptForMissingTool } from './goInstallTools'; |
| import { outputChannel } from './goStatus'; |
| import { byteOffsetAt, canonicalizeGOPATHPrefix, getBinPath } from './util'; |
| import { killProcessTree } from './utils/processUtils'; |
| |
| export class GoRenameProvider implements vscode.RenameProvider { |
| public provideRenameEdits( |
| document: vscode.TextDocument, |
| position: vscode.Position, |
| newName: string, |
| token: vscode.CancellationToken |
| ): Thenable<vscode.WorkspaceEdit> { |
| return vscode.workspace.saveAll(false).then(() => { |
| return this.doRename(document, position, newName, token); |
| }); |
| } |
| |
| private doRename( |
| document: vscode.TextDocument, |
| position: vscode.Position, |
| newName: string, |
| token: vscode.CancellationToken |
| ): Thenable<vscode.WorkspaceEdit> { |
| return new Promise<vscode.WorkspaceEdit>((resolve, reject) => { |
| const filename = canonicalizeGOPATHPrefix(document.fileName); |
| const range = document.getWordRangeAtPosition(position); |
| const pos = range ? range.start : position; |
| const offset = byteOffsetAt(document, pos); |
| const env = toolExecutionEnvironment(); |
| const gorename = getBinPath('gorename'); |
| const buildTags = getGoConfig(document.uri)['buildTags']; |
| const gorenameArgs = ['-offset', filename + ':#' + offset, '-to', newName]; |
| if (buildTags) { |
| gorenameArgs.push('-tags', buildTags); |
| } |
| const canRenameToolUseDiff = isDiffToolAvailable(); |
| if (canRenameToolUseDiff) { |
| gorenameArgs.push('-d'); |
| } |
| |
| // eslint-disable-next-line prefer-const |
| let p: cp.ChildProcess; |
| if (token) { |
| token.onCancellationRequested(() => killProcessTree(p)); |
| } |
| |
| p = cp.execFile(gorename, gorenameArgs, { env }, (err, stdout, stderr) => { |
| try { |
| if (err && (<any>err).code === 'ENOENT') { |
| promptForMissingTool('gorename'); |
| return reject('Could not find gorename tool.'); |
| } |
| if (err) { |
| const errMsg = stderr ? 'Rename failed: ' + stderr.replace(/\n/g, ' ') : 'Rename failed'; |
| console.log(errMsg); |
| outputChannel.appendLine(errMsg); |
| outputChannel.show(); |
| return reject(); |
| } |
| |
| const result = new vscode.WorkspaceEdit(); |
| |
| if (canRenameToolUseDiff) { |
| const filePatches = getEditsFromUnifiedDiffStr(stdout); |
| filePatches.forEach((filePatch: FilePatch) => { |
| const fileUri = vscode.Uri.file(filePatch.fileName); |
| filePatch.edits.forEach((edit: Edit) => { |
| edit.applyUsingWorkspaceEdit(result, fileUri); |
| }); |
| }); |
| } |
| |
| return resolve(result); |
| } catch (e) { |
| reject(e); |
| } |
| }); |
| }); |
| } |
| } |