From 4ab96434d0ff79db8fb7b4aa129cec7b049c511f Mon Sep 17 00:00:00 2001 From: goerlibe <23436477+goerlibe@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:40:56 +0100 Subject: [PATCH] feat: options to turn codelenses on/off via setting/command/button --- package.json | 20 ++++++++- src/DiscoPoP/DiscoPoPCodeLensProvider.ts | 57 +++++++++++++++++++++++- src/DiscoPoPExtension.ts | 49 ++++++++++++++++---- src/Utils/Commands.ts | 8 ++-- 4 files changed, 119 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index f63eef8..e1e0aa2 100644 --- a/package.json +++ b/package.json @@ -171,18 +171,22 @@ "command": "discopop.loadHotspotResults", "icon": "$(history)" }, + { + "title": "Toggle CodeLens Setting", + "command": "discopop.toggleCodeLens", + "category": "DiscoPoP", + "icon": "$(eye)" + }, { "title": "Enable Recommendations CodeLens", "command": "discopop.enableCodeLens", "category": "DiscoPoP", - "enablement": "false", "icon": "$(eye)" }, { "title": "Disable Recommendations CodeLens", "command": "discopop.disableCodeLens", "category": "DiscoPoP", - "enablement": "false", "icon": "$(eye-closed)" }, { @@ -286,6 +290,18 @@ "group": "navigation" } ], + "editor/title": [ + { + "command": "discopop.enableCodeLens", + "group": "navigation", + "when": "discopop.codeLensEnabled == disabled" + }, + { + "command": "discopop.disableCodeLens", + "group": "navigation", + "when": "discopop.codeLensEnabled === enabled" + } + ], "view/item/context": [ { "command": "discopop.applySingleSuggestion", diff --git a/src/DiscoPoP/DiscoPoPCodeLensProvider.ts b/src/DiscoPoP/DiscoPoPCodeLensProvider.ts index 40d3b7d..7f0b23b 100644 --- a/src/DiscoPoP/DiscoPoPCodeLensProvider.ts +++ b/src/DiscoPoP/DiscoPoPCodeLensProvider.ts @@ -33,7 +33,9 @@ export class DiscoPoPCodeLens extends vscode.CodeLens { export class DiscoPoPCodeLensProvider implements vscode.CodeLensProvider { - public hidden: boolean = false // TODO hide suggestions if disabled in settings, or if disabled in this editor + private codeLensProviderDisposable: vscode.Disposable = undefined + + public hidden: boolean = false private suggestionsByFileId: Map // hide codelenses while we wait for the lineMapping and appliedStatus to be updated @@ -71,6 +73,11 @@ export class DiscoPoPCodeLensProvider // update lenses when settings change (codeLenses visibility might have changed) vscode.workspace.onDidChangeConfiguration((_) => { + if (Config.codeLensEnabled()) { + this._register() + } else { + this.dispose() + } this._onDidChangeCodeLenses.fire() }) @@ -83,6 +90,30 @@ export class DiscoPoPCodeLensProvider this.appliedStatus.onDidChange(() => { this.stopWaitingForAppliedStatus() }) + + // immediately register + this._register() + } + + private _register() { + this.codeLensProviderDisposable?.dispose() + this.codeLensProviderDisposable = + vscode.languages.registerCodeLensProvider( + // TODO only apply this provider for files listed in the fileMapping (or even better: only for files that have suggestions) + { scheme: 'file', language: 'cpp' }, + this + ) + this.show() + } + + public dispose() { + vscode.commands.executeCommand( + 'setContext', + 'discopop.codeLensEnabled', + 'undefined' + ) + this.codeLensProviderDisposable?.dispose() + this.codeLensProviderDisposable = undefined } /** @@ -94,6 +125,10 @@ export class DiscoPoPCodeLensProvider this.waitForAppliedStatus = waitForAppliedStatus this._onDidChangeCodeLenses.fire() + if (this.hidden) { + return + } + // indicate to the user that we are recomputing the codelenses vscode.window.withProgress( { @@ -139,6 +174,26 @@ export class DiscoPoPCodeLensProvider } } + public hide() { + vscode.commands.executeCommand( + 'setContext', + 'discopop.codeLensEnabled', + 'disabled' + ) + this.hidden = true + this._onDidChangeCodeLenses.fire() + } + + public show() { + vscode.commands.executeCommand( + 'setContext', + 'discopop.codeLensEnabled', + 'enabled' + ) + this.hidden = false + this._onDidChangeCodeLenses.fire() + } + public provideCodeLenses( document: vscode.TextDocument, _token: vscode.CancellationToken diff --git a/src/DiscoPoPExtension.ts b/src/DiscoPoPExtension.ts index cccd9d5..8bd78bc 100644 --- a/src/DiscoPoPExtension.ts +++ b/src/DiscoPoPExtension.ts @@ -51,8 +51,6 @@ export class DiscoPoPExtension { private hotspotTreeDisposable: vscode.Disposable | undefined = undefined private suggestionTreeDisposable: vscode.Disposable | undefined = undefined - private codeLensProviderDisposable: vscode.Disposable | undefined = - undefined public constructor(private context: vscode.ExtensionContext) { this.projectManager = new ProjectManager(context) @@ -73,6 +71,7 @@ export class DiscoPoPExtension { // enable code lenses for all suggestions // TODO we should not create a new code lens provider every time, + this.codeLensProvider?.dispose() this.codeLensProvider = new DiscoPoPCodeLensProvider( this.dpResults.fileMapping, this.dpResults.lineMapping, @@ -80,12 +79,6 @@ export class DiscoPoPExtension { fullConfig.getDiscoPoPBuildDirectory() + '/.discopop', Array.from(this.dpResults.suggestionsByType.values()).flat() ) - await this.codeLensProviderDisposable?.dispose() - this.codeLensProviderDisposable = - vscode.languages.registerCodeLensProvider( - { scheme: 'file', language: 'cpp' }, // TODO only apply this provider for files listed in the fileMapping - this.codeLensProvider - ) } public async showHotspotDetectionResults( @@ -111,6 +104,12 @@ export class DiscoPoPExtension { } public activate() { + vscode.commands.executeCommand( + 'setContext', + 'discopop.codeLensEnabled', + 'undefined' + ) + this.context.subscriptions.push( vscode.commands.registerCommand( Commands.runDiscoPoPAndHotspotDetection, @@ -394,6 +393,7 @@ export class DiscoPoPExtension { ) ) + // used by tree view this.context.subscriptions.push( vscode.commands.registerCommand( Commands.applySingleSuggestion, @@ -408,6 +408,7 @@ export class DiscoPoPExtension { ) ) + // used by tree view this.context.subscriptions.push( vscode.commands.registerCommand( Commands.rollbackSingleSuggestion, @@ -426,6 +427,38 @@ export class DiscoPoPExtension { ) ) + this.context.subscriptions.push( + vscode.commands.registerCommand( + Commands.toggleCodeLens, + async () => { + const currentValue = vscode.workspace + .getConfiguration('discopop') + .get('recommendationsCodeLens', true) + vscode.workspace + .getConfiguration('discopop') + .update('recommendationsCodeLens', !currentValue, true) + } + ) + ) + + this.context.subscriptions.push( + vscode.commands.registerCommand( + Commands.enableCodeLens, + async () => { + this.codeLensProvider?.show() + } + ) + ) + + this.context.subscriptions.push( + vscode.commands.registerCommand( + Commands.disableCodeLens, + async () => { + this.codeLensProvider?.hide() + } + ) + ) + // to allow undoing all suggestions, we need to get a hold on the .discopop directory // once we refactor to have more state in the extension, this is simple: // this.context.subscriptions.push( diff --git a/src/Utils/Commands.ts b/src/Utils/Commands.ts index 548672d..3f44a28 100644 --- a/src/Utils/Commands.ts +++ b/src/Utils/Commands.ts @@ -35,8 +35,8 @@ export class Commands { public static rollbackAllSuggestions: string = 'discopop.rollbackAllSuggestions' - // enable/disable/change settings - // TODO - // public static enableCodeLens: string = 'discopop.enableCodeLens' - //public static disableCodeLens: string = 'discopop.disableCodeLens' + // codeLens + public static toggleCodeLens: string = 'discopop.toggleCodeLens' // global setting + public static enableCodeLens: string = 'discopop.enableCodeLens' // temporarily enable codeLens + public static disableCodeLens: string = 'discopop.disableCodeLens' // temporarily disable codeLens }