From 2bd7bca9106fd89570b3aa7d739a9d0db76d9400 Mon Sep 17 00:00:00 2001 From: Karthik Nadig Date: Thu, 23 Mar 2023 11:48:58 -0700 Subject: [PATCH] Use new formatter install prompt on missing formatter --- src/client/formatters/baseFormatter.ts | 18 +++++++++++------- .../prompts/installFormatterPrompt.ts | 18 +++++++++++------- src/client/providers/prompts/types.ts | 5 ++++- src/client/providers/serviceRegistry.ts | 3 +++ 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/client/formatters/baseFormatter.ts b/src/client/formatters/baseFormatter.ts index b91a6ac85def..bffa03a8b1e1 100644 --- a/src/client/formatters/baseFormatter.ts +++ b/src/client/formatters/baseFormatter.ts @@ -11,6 +11,7 @@ import { IServiceContainer } from '../ioc/types'; import { traceError, traceLog } from '../logging'; import { getTempFileWithDocumentContents, getTextEditsFromPatch } from './../common/editor'; import { IFormatterHelper } from './types'; +import { IInstallFormatterPrompt } from '../providers/prompts/types'; export abstract class BaseFormatter { protected readonly workspace: IWorkspaceService; @@ -103,13 +104,16 @@ export abstract class BaseFormatter { let customError = `Formatting with ${this.Id} failed.`; if (isNotInstalledError(error)) { - const installer = this.serviceContainer.get(IInstaller); - const isInstalled = await installer.isInstalled(this.product, resource); - if (!isInstalled) { - customError += `\nYou could either install the '${this.Id}' formatter, turn it off or use another formatter.`; - installer - .promptToInstall(this.product, resource) - .catch((ex) => traceError('Python Extension: promptToInstall', ex)); + const prompt = this.serviceContainer.get(IInstallFormatterPrompt); + if (!(await prompt.showInstallFormatterPrompt(resource))) { + const installer = this.serviceContainer.get(IInstaller); + const isInstalled = await installer.isInstalled(this.product, resource); + if (!isInstalled) { + customError += `\nYou could either install the '${this.Id}' formatter, turn it off or use another formatter.`; + installer + .promptToInstall(this.product, resource) + .catch((ex) => traceError('Python Extension: promptToInstall', ex)); + } } } diff --git a/src/client/providers/prompts/installFormatterPrompt.ts b/src/client/providers/prompts/installFormatterPrompt.ts index db23e130d1fd..5e9ff7f818ef 100644 --- a/src/client/providers/prompts/installFormatterPrompt.ts +++ b/src/client/providers/prompts/installFormatterPrompt.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { Uri } from 'vscode'; +import { inject, injectable } from 'inversify'; import { IDisposableRegistry } from '../../common/types'; import { Common, ToolsExtensions } from '../../common/utils/localize'; import { isExtensionEnabled } from '../../common/vscodeApis/extensionsApi'; @@ -18,31 +19,32 @@ import { AUTOPEP8_EXTENSION, BLACK_EXTENSION, IInstallFormatterPrompt } from './ const SHOW_FORMATTER_INSTALL_PROMPT_DONOTSHOW_KEY = 'showFormatterExtensionInstallPrompt'; +@injectable() export class InstallFormatterPrompt implements IInstallFormatterPrompt { private shownThisSession = false; - constructor(private readonly serviceContainer: IServiceContainer) {} + constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) {} - public async showInstallFormatterPrompt(resource?: Uri): Promise { + public async showInstallFormatterPrompt(resource?: Uri): Promise { if (!inFormatterExtensionExperiment(this.serviceContainer)) { - return; + return false; } const promptState = doNotShowPromptState(SHOW_FORMATTER_INSTALL_PROMPT_DONOTSHOW_KEY, this.serviceContainer); if (this.shownThisSession || promptState.value) { - return; + return false; } const config = getConfiguration('python', resource); const formatter = config.get('formatting.provider', 'none'); if (!['autopep8', 'black'].includes(formatter)) { - return; + return false; } const editorConfig = getConfiguration('editor', { uri: resource, languageId: 'python' }); const defaultFormatter = editorConfig.get('defaultFormatter', ''); if ([BLACK_EXTENSION, AUTOPEP8_EXTENSION].includes(defaultFormatter)) { - return; + return false; } const black = isExtensionEnabled(BLACK_EXTENSION); @@ -111,12 +113,14 @@ export class InstallFormatterPrompt implements IInstallFormatterPrompt { } else if (selection === Common.doNotShowAgain) { await promptState.updateValue(true); } + + return this.shownThisSession; } } export function registerInstallFormatterPrompt(serviceContainer: IServiceContainer): void { const disposables = serviceContainer.get(IDisposableRegistry); - const installFormatterPrompt = new InstallFormatterPrompt(serviceContainer); + const installFormatterPrompt = serviceContainer.get(IInstallFormatterPrompt); disposables.push( onDidSaveTextDocument(async (e) => { const editorConfig = getConfiguration('editor', { uri: e.uri, languageId: 'python' }); diff --git a/src/client/providers/prompts/types.ts b/src/client/providers/prompts/types.ts index 47fead687cf5..4edaadb46b46 100644 --- a/src/client/providers/prompts/types.ts +++ b/src/client/providers/prompts/types.ts @@ -1,9 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import { Uri } from 'vscode'; + export const BLACK_EXTENSION = 'ms-python.black-formatter'; export const AUTOPEP8_EXTENSION = 'ms-python.autopep8'; +export const IInstallFormatterPrompt = Symbol('IInstallFormatterPrompt'); export interface IInstallFormatterPrompt { - showInstallFormatterPrompt(): Promise; + showInstallFormatterPrompt(resource?: Uri): Promise; } diff --git a/src/client/providers/serviceRegistry.ts b/src/client/providers/serviceRegistry.ts index a96ec14ff5e9..70fc6dc34135 100644 --- a/src/client/providers/serviceRegistry.ts +++ b/src/client/providers/serviceRegistry.ts @@ -6,10 +6,13 @@ import { IExtensionSingleActivationService } from '../activation/types'; import { IServiceManager } from '../ioc/types'; import { CodeActionProviderService } from './codeActionProvider/main'; +import { InstallFormatterPrompt } from './prompts/installFormatterPrompt'; +import { IInstallFormatterPrompt } from './prompts/types'; export function registerTypes(serviceManager: IServiceManager): void { serviceManager.addSingleton( IExtensionSingleActivationService, CodeActionProviderService, ); + serviceManager.addSingleton(IInstallFormatterPrompt, InstallFormatterPrompt); }