diff --git a/package.json b/package.json index fd1705bf5f..cfd2c9d0fa 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,11 @@ "command": "PowerShell.ShowSessionMenu", "title": "Show Session Menu", "category": "PowerShell" + }, + { + "command": "PowerShell.SelectPSSARules", + "title": "Select PSScriptAnalyzer Rules", + "category": "PowerShell" } ], "snippets": [ diff --git a/src/checkboxQuickPick.ts b/src/checkboxQuickPick.ts new file mode 100644 index 0000000000..c3d579d6ba --- /dev/null +++ b/src/checkboxQuickPick.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import vscode = require("vscode"); +import QuickPickItem = vscode.QuickPickItem; + +export class CheckboxQuickPickItem { + name: string; + isSelected: boolean; +} + +export class CheckboxQuickPick { + private static readonly confirm: string = "$(check)"; + private static readonly checkboxOn: string = "[ x ]"; + private static readonly checkboxOff: string = "[ ]"; + private static readonly confirmPlaceHolder: string = "Select 'Confirm' to confirm change; Press 'esc' key to cancel changes"; + + public static show( + checkboxQuickPickItems: CheckboxQuickPickItem[], + callback: (items: CheckboxQuickPickItem[]) => void): void { + CheckboxQuickPick.showInner(checkboxQuickPickItems.slice(), callback); + } + + private static showInner( + items: CheckboxQuickPickItem[], + callback: (items: CheckboxQuickPickItem[]) => void): void { + vscode.window.showQuickPick( + CheckboxQuickPick.getQuickPickItems(items), + { + ignoreFocusOut: true, + matchOnDescription: true, + placeHolder: CheckboxQuickPick.confirmPlaceHolder + }).then((selection) => { + if (!selection) { + return; + } + + if (selection.label === CheckboxQuickPick.confirm) { + callback(items); + return; + } + + let index: number = CheckboxQuickPick.getRuleIndex(items, selection.description); + CheckboxQuickPick.toggleSelection(items[index]); + CheckboxQuickPick.showInner(items, callback); + }); + } + + private static getRuleIndex(items: CheckboxQuickPickItem[], itemLabel: string): number { + return items.findIndex(item => item.name === itemLabel); + } + + private static getQuickPickItems(items: CheckboxQuickPickItem[]): QuickPickItem[] { + let quickPickItems: QuickPickItem[] = []; + quickPickItems.push({ label: CheckboxQuickPick.confirm, description: "Confirm" }); + items.forEach(item => + quickPickItems.push({ + label: CheckboxQuickPick.convertToCheckBox(item.isSelected), description: item.name + })); + return quickPickItems; + } + + private static toggleSelection(item: CheckboxQuickPickItem): void { + item.isSelected = !item.isSelected; + } + + private static convertToCheckBox(state: boolean): string { + if (state) { + return CheckboxQuickPick.checkboxOn; + } + else { + return CheckboxQuickPick.checkboxOff; + } + } +} \ No newline at end of file diff --git a/src/features/SelectPSSARules.ts b/src/features/SelectPSSARules.ts new file mode 100644 index 0000000000..c3908e5556 --- /dev/null +++ b/src/features/SelectPSSARules.ts @@ -0,0 +1,68 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import vscode = require("vscode"); +import { IFeature } from "../feature"; +import { LanguageClient, RequestType } from "vscode-languageclient"; +import { CheckboxQuickPickItem, CheckboxQuickPick } from "../checkboxQuickPick"; + +export namespace GetPSSARulesRequest { + export const type: RequestType = { get method(): string { return "powerShell/getPSSARules"; } }; +} + +export namespace SetPSSARulesRequest { + export const type: RequestType = { get method(): string { return "powerShell/setPSSARules"; } }; +} + +class RuleInfo { + name: string; + isEnabled: boolean; +} + +class SetPSSARulesRequestParams { + filepath: string; + ruleInfos: RuleInfo[]; +} + +export class SelectPSSARulesFeature implements IFeature { + + private command: vscode.Disposable; + private languageClient: LanguageClient; + + constructor() { + this.command = vscode.commands.registerCommand("PowerShell.SelectPSSARules", () => { + if (this.languageClient === undefined) { + return; + } + + this.languageClient.sendRequest(GetPSSARulesRequest.type, null).then((returnedRules) => { + if (returnedRules == null) { + vscode.window.showWarningMessage( + "PowerShell extension uses PSScriptAnalyzer settings file - Cannot update rules."); + return; + } + let options: CheckboxQuickPickItem[] = returnedRules.map(function (rule: RuleInfo): CheckboxQuickPickItem { + return { name: rule.name, isSelected: rule.isEnabled }; + }); + CheckboxQuickPick.show(options, (updatedOptions) => { + let filepath: string = vscode.window.activeTextEditor.document.uri.fsPath; + let ruleInfos: RuleInfo[] = updatedOptions.map( + function (option: CheckboxQuickPickItem): RuleInfo { + return { name: option.name, isEnabled: option.isSelected }; + }); + let requestParams: SetPSSARulesRequestParams = {filepath, ruleInfos}; + this.languageClient.sendRequest(SetPSSARulesRequest.type, requestParams); + }); + }); + }); + } + + public setLanguageClient(languageclient: LanguageClient): void { + this.languageClient = languageclient; + } + + public dispose(): void { + this.command.dispose(); + } +} diff --git a/src/main.ts b/src/main.ts index 5540ee3fcf..9766fa4cdd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,6 +15,7 @@ import { ExpandAliasFeature } from './features/ExpandAlias'; import { ShowHelpFeature } from './features/ShowOnlineHelp'; import { FindModuleFeature } from './features/PowerShellFindModule'; import { ExtensionCommandsFeature } from './features/ExtensionCommands'; +import { SelectPSSARulesFeature } from './features/SelectPSSARules'; import { CodeActionsFeature } from './features/CodeActions'; // NOTE: We will need to find a better way to deal with the required @@ -76,6 +77,7 @@ export function activate(context: vscode.ExtensionContext): void { new ShowHelpFeature(), new FindModuleFeature(), new ExtensionCommandsFeature(), + new SelectPSSARulesFeature(), new CodeActionsFeature() ];