mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 10:08:49 +01:00
Move TS/JS to use organize imports codeAction instead of command (#47850)
* Move TS/JS to use organize imports code action Fixes #47845 Fixes #46647 - Defines a new standard `SourceOrganizeImports` `CodeActionKind` to be used to implement organize imports in a consistent way. - Add a new `Organize imports` command and keybinding that executes these actions. - Move over the existing js/ts organize imports command to use the new code action kind * Use supportedCodeActions context key * Document code action kind values * Fix regular expression Make sure we only match whole scopes and not `unicorn.source.organizeImports`
This commit is contained in:
@@ -19,7 +19,6 @@ import ManagedFileContextManager from './utils/managedFileContext';
|
||||
import { lazy, Lazy } from './utils/lazy';
|
||||
import * as fileSchemes from './utils/fileSchemes';
|
||||
import LogDirectoryProvider from './utils/logDirectoryProvider';
|
||||
import { OrganizeImportsCommand, OrganizeImportsContextManager } from './features/organizeImports';
|
||||
|
||||
export function activate(
|
||||
context: vscode.ExtensionContext
|
||||
@@ -74,11 +73,6 @@ function createLazyClientHost(
|
||||
|
||||
context.subscriptions.push(clientHost);
|
||||
|
||||
const organizeImportsContext = new OrganizeImportsContextManager();
|
||||
clientHost.serviceClient.onTsServerStarted(api => {
|
||||
organizeImportsContext.onDidChangeApiVersion(api);
|
||||
}, null, context.subscriptions);
|
||||
|
||||
clientHost.serviceClient.onReady(() => {
|
||||
context.subscriptions.push(
|
||||
ProjectStatus.create(
|
||||
@@ -103,7 +97,6 @@ function registerCommands(
|
||||
commandManager.register(new commands.RestartTsServerCommand(lazyClientHost));
|
||||
commandManager.register(new commands.TypeScriptGoToProjectConfigCommand(lazyClientHost));
|
||||
commandManager.register(new commands.JavaScriptGoToProjectConfigCommand(lazyClientHost));
|
||||
commandManager.register(new OrganizeImportsCommand(lazyClientHost));
|
||||
}
|
||||
|
||||
function isSupportedDocument(
|
||||
|
||||
@@ -4,37 +4,27 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as Proto from '../protocol';
|
||||
import { Command } from '../utils/commandManager';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import { Command, CommandManager } from '../utils/commandManager';
|
||||
import { isSupportedLanguageMode } from '../utils/languageModeIds';
|
||||
import * as typeconverts from '../utils/typeConverters';
|
||||
|
||||
import { isSupportedLanguageMode } from '../utils/languageModeIds';
|
||||
import API from '../utils/api';
|
||||
import { Lazy } from '../utils/lazy';
|
||||
import TypeScriptServiceClientHost from '../typeScriptServiceClientHost';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
|
||||
export class OrganizeImportsCommand implements Command {
|
||||
public static readonly Ids = ['javascript.organizeImports', 'typescript.organizeImports'];
|
||||
class OrganizeImportsCommand implements Command {
|
||||
public static readonly Id = '_typescript.organizeImports';
|
||||
|
||||
public readonly id = OrganizeImportsCommand.Ids;
|
||||
public readonly id = OrganizeImportsCommand.Id;
|
||||
|
||||
constructor(
|
||||
private readonly lazyClientHost: Lazy<TypeScriptServiceClientHost>
|
||||
private readonly client: ITypeScriptServiceClient
|
||||
) { }
|
||||
|
||||
public async execute(): Promise<boolean> {
|
||||
// Don't force activation
|
||||
if (!this.lazyClientHost.hasValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const client = this.lazyClientHost.value.serviceClient;
|
||||
if (!client.apiVersion.has280Features()) {
|
||||
if (!this.client.apiVersion.has280Features()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -43,7 +33,7 @@ export class OrganizeImportsCommand implements Command {
|
||||
return false;
|
||||
}
|
||||
|
||||
const file = client.normalizePath(editor.document.uri);
|
||||
const file = this.client.normalizePath(editor.document.uri);
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
@@ -56,67 +46,42 @@ export class OrganizeImportsCommand implements Command {
|
||||
}
|
||||
}
|
||||
};
|
||||
const response = await client.execute('organizeImports', args);
|
||||
const response = await this.client.execute('organizeImports', args);
|
||||
if (!response || !response.success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const edits = typeconverts.WorkspaceEdit.fromFromFileCodeEdits(client, response.body);
|
||||
const edits = typeconverts.WorkspaceEdit.fromFromFileCodeEdits(this.client, response.body);
|
||||
return await vscode.workspace.applyEdit(edits);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When clause context set when the ts version supports organize imports.
|
||||
*/
|
||||
const contextName = 'typescript.canOrganizeImports';
|
||||
|
||||
export class OrganizeImportsContextManager {
|
||||
|
||||
private currentValue: boolean = false;
|
||||
|
||||
public onDidChangeApiVersion(apiVersion: API): any {
|
||||
this.updateContext(apiVersion.has280Features());
|
||||
}
|
||||
|
||||
private updateContext(newValue: boolean) {
|
||||
if (newValue === this.currentValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
vscode.commands.executeCommand('setContext', contextName, newValue);
|
||||
this.currentValue = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class OrganizeImportsCodeActionProvider implements vscode.CodeActionProvider {
|
||||
private static readonly organizeImportsKind = vscode.CodeActionKind.Source.append('organizeImports');
|
||||
|
||||
public constructor(
|
||||
private readonly client: ITypeScriptServiceClient
|
||||
) { }
|
||||
private readonly client: ITypeScriptServiceClient,
|
||||
commandManager: CommandManager
|
||||
) {
|
||||
commandManager.register(new OrganizeImportsCommand(client));
|
||||
}
|
||||
|
||||
public readonly metadata: vscode.CodeActionProviderMetadata = {
|
||||
providedCodeActionKinds: [OrganizeImportsCodeActionProvider.organizeImportsKind]
|
||||
providedCodeActionKinds: [vscode.CodeActionKind.SourceOrganizeImports]
|
||||
};
|
||||
|
||||
public provideCodeActions(
|
||||
document: vscode.TextDocument,
|
||||
_document: vscode.TextDocument,
|
||||
_range: vscode.Range,
|
||||
_context: vscode.CodeActionContext,
|
||||
_token: vscode.CancellationToken
|
||||
): vscode.CodeAction[] {
|
||||
if (!isSupportedLanguageMode(document)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!this.client.apiVersion.has280Features()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const action = new vscode.CodeAction(localize('oraganizeImportsAction.title', "Organize Imports"), OrganizeImportsCodeActionProvider.organizeImportsKind);
|
||||
action.command = { title: '', command: OrganizeImportsCommand.Ids[0] };
|
||||
const action = new vscode.CodeAction(
|
||||
localize('oraganizeImportsAction.title', "Organize Imports"),
|
||||
vscode.CodeActionKind.SourceOrganizeImports);
|
||||
action.command = { title: '', command: OrganizeImportsCommand.Id };
|
||||
return [action];
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ export default class LanguageProvider {
|
||||
constructor(
|
||||
private readonly client: TypeScriptServiceClient,
|
||||
private readonly description: LanguageDescription,
|
||||
commandManager: CommandManager,
|
||||
private readonly commandManager: CommandManager,
|
||||
typingsStatus: TypingsStatus
|
||||
) {
|
||||
this.formattingOptionsManager = new FormattingConfigurationManager(client);
|
||||
@@ -123,9 +123,6 @@ export default class LanguageProvider {
|
||||
const refactorProvider = new (await import('./features/refactorProvider')).default(client, this.formattingOptionsManager, commandManager);
|
||||
this.disposables.push(languages.registerCodeActionsProvider(selector, refactorProvider, refactorProvider.metadata));
|
||||
|
||||
const organizeImportsProvider = new (await import('./features/organizeImports')).OrganizeImportsCodeActionProvider(client);
|
||||
this.disposables.push(languages.registerCodeActionsProvider(selector, organizeImportsProvider, organizeImportsProvider.metadata));
|
||||
|
||||
await this.initFoldingProvider();
|
||||
this.disposables.push(workspace.onDidChangeConfiguration(c => {
|
||||
if (c.affectsConfiguration(foldingSetting)) {
|
||||
@@ -247,6 +244,11 @@ export default class LanguageProvider {
|
||||
if (this.client.apiVersion.has213Features()) {
|
||||
this.versionDependentDisposables.push(languages.registerTypeDefinitionProvider(selector, new (await import('./features/typeDefinitionProvider')).default(this.client)));
|
||||
}
|
||||
|
||||
if (this.client.apiVersion.has280Features()) {
|
||||
const organizeImportsProvider = new (await import('./features/organizeImports')).OrganizeImportsCodeActionProvider(this.client, this.commandManager);
|
||||
this.versionDependentDisposables.push(languages.registerCodeActionsProvider(selector, organizeImportsProvider, organizeImportsProvider.metadata));
|
||||
}
|
||||
}
|
||||
|
||||
public triggerAllDiagnostics(): void {
|
||||
|
||||
Reference in New Issue
Block a user