organizeImports.ts 3.6 KB
Newer Older
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
7
import * as nls from 'vscode-nls';
8
import * as Proto from '../protocol';
9
import { ITypeScriptServiceClient } from '../typescriptService';
10
import API from '../utils/api';
11
import { Command, CommandManager } from '../utils/commandManager';
12
import { VersionDependentRegistration } from '../utils/dependentRegistration';
13
import * as typeconverts from '../utils/typeConverters';
14
import FileConfigurationManager from './fileConfigurationManager';
M
Matt Bierner 已提交
15
import TelemetryReporter from '../utils/telemetry';
16
import { nulToken } from '../utils/cancellation';
17

M
Matt Bierner 已提交
18 19
const localize = nls.loadMessageBundle();

20

21 22
class OrganizeImportsCommand implements Command {
	public static readonly Id = '_typescript.organizeImports';
23

24
	public readonly id = OrganizeImportsCommand.Id;
25 26

	constructor(
M
Matt Bierner 已提交
27 28
		private readonly client: ITypeScriptServiceClient,
		private readonly telemetryReporter: TelemetryReporter,
29 30
	) { }

31
	public async execute(file: string): Promise<boolean> {
M
Matt Bierner 已提交
32 33 34 35 36 37 38 39 40
		/* __GDPR__
			"organizeImports.execute" : {
				"${include}": [
					"${TypeScriptCommonProperties}"
				]
			}
		*/
		this.telemetryReporter.logTelemetry('organizeImports.execute', {});

41 42 43 44 45 46 47 48
		const args: Proto.OrganizeImportsRequestArgs = {
			scope: {
				type: 'file',
				args: {
					file
				}
			}
		};
49
		const { body } = await this.client.execute('organizeImports', args, nulToken);
50
		const edits = typeconverts.WorkspaceEdit.fromFileCodeEdits(this.client, body);
M
Matt Bierner 已提交
51
		return vscode.workspace.applyEdit(edits);
52 53 54
	}
}

M
Matt Bierner 已提交
55 56
export class OrganizeImportsCodeActionProvider implements vscode.CodeActionProvider {
	public constructor(
57
		private readonly client: ITypeScriptServiceClient,
58 59
		commandManager: CommandManager,
		private readonly fileConfigManager: FileConfigurationManager,
M
Matt Bierner 已提交
60 61
		telemetryReporter: TelemetryReporter,

62
	) {
M
Matt Bierner 已提交
63
		commandManager.register(new OrganizeImportsCommand(client, telemetryReporter));
64
	}
M
Matt Bierner 已提交
65

66
	public readonly metadata: vscode.CodeActionProviderMetadata = {
67
		providedCodeActionKinds: [vscode.CodeActionKind.SourceOrganizeImports]
68 69
	};

M
Matt Bierner 已提交
70
	public provideCodeActions(
71
		document: vscode.TextDocument,
M
Matt Bierner 已提交
72
		_range: vscode.Range,
73
		context: vscode.CodeActionContext,
74
		token: vscode.CancellationToken
M
Matt Bierner 已提交
75
	): vscode.CodeAction[] {
M
Matt Bierner 已提交
76
		const file = this.client.toPath(document.uri);
77 78 79 80
		if (!file) {
			return [];
		}

81 82 83 84
		if (!context.only || !context.only.contains(vscode.CodeActionKind.SourceOrganizeImports)) {
			return [];
		}

85 86
		this.fileConfigManager.ensureConfigurationForDocument(document, token);

87 88 89
		const action = new vscode.CodeAction(
			localize('oraganizeImportsAction.title', "Organize Imports"),
			vscode.CodeActionKind.SourceOrganizeImports);
90
		action.command = { title: '', command: OrganizeImportsCommand.Id, arguments: [file] };
M
Matt Bierner 已提交
91 92
		return [action];
	}
93 94 95 96 97 98
}

export function register(
	selector: vscode.DocumentSelector,
	client: ITypeScriptServiceClient,
	commandManager: CommandManager,
M
Matt Bierner 已提交
99 100
	fileConfigurationManager: FileConfigurationManager,
	telemetryReporter: TelemetryReporter,
101
) {
102
	return new VersionDependentRegistration(client, API.v280, () => {
M
Matt Bierner 已提交
103
		const organizeImportsProvider = new OrganizeImportsCodeActionProvider(client, commandManager, fileConfigurationManager, telemetryReporter);
104 105 106
		return vscode.languages.registerCodeActionsProvider(selector,
			organizeImportsProvider,
			organizeImportsProvider.metadata);
107 108
	});
}