From b3236a4c57a28e97e526694be0335922d174ff0d Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 29 Dec 2016 12:30:57 -0800 Subject: [PATCH 01/18] Add an initial version of code formatting feature --- src/features/DocumentFormatter.ts | 141 ++++++++++++++++++++++++++++++ src/main.ts | 4 +- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 src/features/DocumentFormatter.ts diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts new file mode 100644 index 0000000000..cd6f41ba72 --- /dev/null +++ b/src/features/DocumentFormatter.ts @@ -0,0 +1,141 @@ +import vscode = require('vscode'); +import { languages, TextDocument, TextEdit, FormattingOptions, CancellationToken } from 'vscode' +import { LanguageClient, RequestType, NotificationType } from 'vscode-languageclient'; +import Window = vscode.window; +import { IFeature } from '../feature'; + +export namespace ScriptFileMarkersRequest { + export const type: RequestType = { get method(): string { return "powerShell/getScriptFileMarkers"; } }; +} + +// TODO move some of the common interface to a separate file? +interface ScriptFileMarkersRequestParams { + filePath: string; + rules: string[]; +} + +interface ScriptFileMarkersRequestResultParams { + markers: ScriptFileMarker[]; +} + +interface ScriptFileMarker { + message: string; + level: ScriptFileMarkerLevel; + scriptRegion: ScriptRegion; + correction: MarkerCorrection; +} + +enum ScriptFileMarkerLevel { + Information = 0, + Warning, + Error +} + +interface ScriptRegion { + file: string; + text: string; + startLineNumber: number; + startColumnNumber: number; + startOffset: number; + endLineNumber: number; + endColumnNumber: number; + endOffset: number; +} + +interface MarkerCorrection { + name: string; + edits: ScriptRegion[] +} + +class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider { + private languageClient: LanguageClient; + private readonly ruleOrder: string[] = [ + "PSPlaceCloseBrace", + "PSPlaceOpenBrace"]; + + provideDocumentFormattingEdits( + document: TextDocument, + options: FormattingOptions, + token: CancellationToken): TextEdit[] | Thenable { + + // we need to order the edits such that edit i should not invalidate + // the edits in edit j s.t i < j (seems like a hard problem) + // or + // peform edits ourself and return an empty textedit array + return this.applyEditsInOrder(document, options, 0); + } + + applyEditsInOrder( + document: TextDocument, + options: FormattingOptions, + index: number): Thenable | TextEdit[] { + if (this.languageClient !== null && index < this.ruleOrder.length) { + return this.languageClient.sendRequest( + ScriptFileMarkersRequest.type, + { + filePath: document.fileName, + rules: [this.ruleOrder[index]] + }) + .then((result: ScriptFileMarkersRequestResultParams) => { + + // TODO modify undo stops to make sure all the edits + // can be undone and redone in a single step + this.applyEdits(result.markers, 0); + this.applyEditsInOrder(document, options, ++index); + + // we do not return a valid array because our text edits + // need to be executed in a particular order and it is + // easier if we perform the edits ourselves + return TextEdit[0]; + }); + } else { + return TextEdit[0]; + } + } + + applyEdits(markers: ScriptFileMarker[], index: number): void { + if (index >= markers.length) { + return; + } + + let edit: ScriptRegion = markers[index++].correction.edits[0]; + Window.activeTextEditor.edit((editBuilder) => { + editBuilder.replace( + new vscode.Range( + edit.startLineNumber - 1, + edit.startColumnNumber - 1, + edit.endLineNumber - 1, + edit.endColumnNumber - 1), + edit.text); + }).then((isEditApplied) => { + this.applyEdits(markers, index); + }); // TODO handle rejection + + } + + setLanguageClient(languageClient: LanguageClient): void { + this.languageClient = languageClient; + } +} + +export class DocumentFormatterFeature implements IFeature { + private disposable: vscode.Disposable; + private languageClient: LanguageClient; + private documentFormattingEditProvider: PSDocumentFormattingEditProvider; + + constructor() { + this.documentFormattingEditProvider = new PSDocumentFormattingEditProvider(); + this.disposable = vscode.languages.registerDocumentFormattingEditProvider( + "powershell", + this.documentFormattingEditProvider); + } + + public setLanguageClient(languageclient: LanguageClient): void { + this.languageClient = languageclient; + this.documentFormattingEditProvider.setLanguageClient(languageclient); + } + + public dispose(): any { + this.disposable.dispose(); + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index a08ffa2fd3..da40056598 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,6 +18,7 @@ import { FindModuleFeature } from './features/PowerShellFindModule'; import { ExtensionCommandsFeature } from './features/ExtensionCommands'; import { SelectPSSARulesFeature } from './features/SelectPSSARules'; import { CodeActionsFeature } from './features/CodeActions'; +import { DocumentFormatterFeature } from './features/DocumentFormatter'; // NOTE: We will need to find a better way to deal with the required // PS Editor Services version... @@ -95,7 +96,8 @@ export function activate(context: vscode.ExtensionContext): void { new ExtensionCommandsFeature(), new SelectPSSARulesFeature(), new CodeActionsFeature(), - new NewFileOrProjectFeature() + new NewFileOrProjectFeature(), + new DocumentFormatterFeature(), ]; sessionManager = From b62e1c5aeff97d845cdaebb3552738554f85c89d Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Sun, 1 Jan 2017 12:53:33 -0800 Subject: [PATCH 02/18] Fix in order edit application --- src/features/DocumentFormatter.ts | 36 +++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index cd6f41ba72..2545179326 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -51,7 +51,8 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP private languageClient: LanguageClient; private readonly ruleOrder: string[] = [ "PSPlaceCloseBrace", - "PSPlaceOpenBrace"]; + "PSPlaceOpenBrace", + "PSUseConsistentIndentation"]; provideDocumentFormattingEdits( document: TextDocument, @@ -62,10 +63,10 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP // the edits in edit j s.t i < j (seems like a hard problem) // or // peform edits ourself and return an empty textedit array - return this.applyEditsInOrder(document, options, 0); + return this.executeRulesInOrder(document, options, 0); } - applyEditsInOrder( + executeRulesInOrder( document: TextDocument, options: FormattingOptions, index: number): Thenable | TextEdit[] { @@ -80,26 +81,40 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP // TODO modify undo stops to make sure all the edits // can be undone and redone in a single step - this.applyEdits(result.markers, 0); - this.applyEditsInOrder(document, options, ++index); + + // sort in decending order of the edits + result.markers.sort(function(a: ScriptFileMarker, b: ScriptFileMarker): number { + let leftOperand: number = a.correction.edits[0].startLineNumber, + rightOperand: number = b.correction.edits[0].startLineNumber; + if (leftOperand < rightOperand) { + return 1; + } else if (leftOperand > rightOperand) { + return -1; + } else { + return 0; + } + }); + return this.applyEdits(result.markers, 0); // we do not return a valid array because our text edits // need to be executed in a particular order and it is // easier if we perform the edits ourselves - return TextEdit[0]; + }) + .then(() => { + return this.executeRulesInOrder(document, options, index + 1); }); } else { return TextEdit[0]; } } - applyEdits(markers: ScriptFileMarker[], index: number): void { + applyEdits(markers: ScriptFileMarker[], index: number): Thenable { if (index >= markers.length) { return; } - let edit: ScriptRegion = markers[index++].correction.edits[0]; - Window.activeTextEditor.edit((editBuilder) => { + let edit: ScriptRegion = markers[index].correction.edits[0]; + return Window.activeTextEditor.edit((editBuilder) => { editBuilder.replace( new vscode.Range( edit.startLineNumber - 1, @@ -108,9 +123,8 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP edit.endColumnNumber - 1), edit.text); }).then((isEditApplied) => { - this.applyEdits(markers, index); + return this.applyEdits(markers, index + 1); }); // TODO handle rejection - } setLanguageClient(languageClient: LanguageClient): void { From f3f42e3f78fccbb7f9a0bb5de00532b282ef2807 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 5 Jan 2017 16:01:39 -0800 Subject: [PATCH 03/18] Pass code formatting options to AnalysisService --- package.json | 5 +++++ src/features/DocumentFormatter.ts | 19 ++++++++++++++++++- src/settings.ts | 30 ++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index a0f58698e7..42581c71ef 100644 --- a/package.json +++ b/package.json @@ -270,6 +270,11 @@ "type": "boolean", "default": false, "description": "Launches the language service with the /waitForDebugger flag to force it to wait for a .NET debugger to attach before proceeding." + }, + "powershell.codeformatting.openBraceOnSameLine":{ + "type":"boolean", + "default": true, + "description": "Places open brace on the same line as its associated statement." } } } diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 2545179326..ccb74938a2 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -3,6 +3,8 @@ import { languages, TextDocument, TextEdit, FormattingOptions, CancellationToken import { LanguageClient, RequestType, NotificationType } from 'vscode-languageclient'; import Window = vscode.window; import { IFeature } from '../feature'; +import * as Settings from '../settings'; +import * as Utils from '../utils'; export namespace ScriptFileMarkersRequest { export const type: RequestType = { get method(): string { return "powerShell/getScriptFileMarkers"; } }; @@ -12,6 +14,7 @@ export namespace ScriptFileMarkersRequest { interface ScriptFileMarkersRequestParams { filePath: string; rules: string[]; + settings: string; } interface ScriptFileMarkersRequestResultParams { @@ -71,11 +74,13 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP options: FormattingOptions, index: number): Thenable | TextEdit[] { if (this.languageClient !== null && index < this.ruleOrder.length) { + let rule = this.ruleOrder[index]; return this.languageClient.sendRequest( ScriptFileMarkersRequest.type, { filePath: document.fileName, - rules: [this.ruleOrder[index]] + rules: [rule], + settings: this.getSettings(rule) }) .then((result: ScriptFileMarkersRequestResultParams) => { @@ -130,6 +135,18 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP setLanguageClient(languageClient: LanguageClient): void { this.languageClient = languageClient; } + + getSettings(rule: string): string { + let settings: Settings.ISettings = Settings.load(Utils.PowerShellLanguageId); + return `@{ + IncludeRules = @('${rule}') + Rules = @{ + PSPlaceOpenBrace = @{ + OnSameLine = \$${settings.codeformatting.openBraceOnSameLine} + } + } +}`; + } } export class DocumentFormatterFeature implements IFeature { diff --git a/src/settings.ts b/src/settings.ts index 611e605322..61ce4d4417 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -6,6 +6,10 @@ import vscode = require('vscode'); +export interface ICodeFormattingSettings { + openBraceOnSameLine: boolean; +} + export interface IScriptAnalysisSettings { enable?: boolean settingsPath: string @@ -19,31 +23,37 @@ export interface IDeveloperSettings { } export interface ISettings { - useX86Host?: boolean, - enableProfileLoading?: boolean, - scriptAnalysis?: IScriptAnalysisSettings, - developer?: IDeveloperSettings, + useX86Host?: boolean; + enableProfileLoading?: boolean; + scriptAnalysis?: IScriptAnalysisSettings; + developer?: IDeveloperSettings; + codeformatting?: ICodeFormattingSettings; } export function load(myPluginId: string): ISettings { - let configuration = vscode.workspace.getConfiguration(myPluginId); + let configuration: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(myPluginId); - let defaultScriptAnalysisSettings = { + let defaultScriptAnalysisSettings: IScriptAnalysisSettings = { enable: true, settingsPath: "" }; - let defaultDeveloperSettings = { + let defaultDeveloperSettings: IDeveloperSettings = { powerShellExePath: undefined, bundledModulesPath: "../modules/", editorServicesLogLevel: "Normal", editorServicesWaitForDebugger: false - } + }; + + let defaultCodeFormattingSettings: ICodeFormattingSettings = { + openBraceOnSameLine: true + }; return { useX86Host: configuration.get("useX86Host", false), enableProfileLoading: configuration.get("enableProfileLoading", false), scriptAnalysis: configuration.get("scriptAnalysis", defaultScriptAnalysisSettings), - developer: configuration.get("developer", defaultDeveloperSettings) - } + developer: configuration.get("developer", defaultDeveloperSettings), + codeformatting: configuration.get("codeformatting", defaultCodeFormattingSettings) + }; } From bd8c9d778d58d975136917600995cafd7de87082 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 5 Jan 2017 16:22:25 -0800 Subject: [PATCH 04/18] Update ScriptFileMarkersRequestParams interface --- src/features/DocumentFormatter.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index ccb74938a2..d8bda12b7d 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -13,7 +13,6 @@ export namespace ScriptFileMarkersRequest { // TODO move some of the common interface to a separate file? interface ScriptFileMarkersRequestParams { filePath: string; - rules: string[]; settings: string; } @@ -79,7 +78,6 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP ScriptFileMarkersRequest.type, { filePath: document.fileName, - rules: [rule], settings: this.getSettings(rule) }) .then((result: ScriptFileMarkersRequestResultParams) => { From c1ca84b45ee0d1ef96544db758ef7869e7598bef Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Fri, 6 Jan 2017 14:25:52 -0800 Subject: [PATCH 05/18] Add ability to set indentation size --- package.json | 5 +++++ src/features/DocumentFormatter.ts | 25 +++++++++++++++++++++---- src/settings.ts | 4 +++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 42581c71ef..8f9aaf3f09 100644 --- a/package.json +++ b/package.json @@ -275,6 +275,11 @@ "type":"boolean", "default": true, "description": "Places open brace on the same line as its associated statement." + }, + "powershell.codeformatting.indentationSize":{ + "type":"number", + "default": 4, + "description": "The indentation size in number of Space characters." } } } diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index d8bda12b7d..ec695b1d71 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -86,7 +86,7 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP // can be undone and redone in a single step // sort in decending order of the edits - result.markers.sort(function(a: ScriptFileMarker, b: ScriptFileMarker): number { + result.markers.sort(function (a: ScriptFileMarker, b: ScriptFileMarker): number { let leftOperand: number = a.correction.edits[0].startLineNumber, rightOperand: number = b.correction.edits[0].startLineNumber; if (leftOperand < rightOperand) { @@ -136,12 +136,29 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP getSettings(rule: string): string { let settings: Settings.ISettings = Settings.load(Utils.PowerShellLanguageId); + let ruleProperty: string; + switch (rule) { + case "PSPlaceOpenBrace": + ruleProperty = `${rule} = @{ + OnSameLine = \$${settings.codeformatting.openBraceOnSameLine} + }`; + break; + + case "PSUseConsistentIndentation": + ruleProperty = `${rule} = @{ + IndentationSize = ${settings.codeformatting.indentationSize} + }`; + break; + + default: + ruleProperty = ""; + break; + } + return `@{ IncludeRules = @('${rule}') Rules = @{ - PSPlaceOpenBrace = @{ - OnSameLine = \$${settings.codeformatting.openBraceOnSameLine} - } + ${ruleProperty} } }`; } diff --git a/src/settings.ts b/src/settings.ts index 61ce4d4417..4dcb6ab4a1 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -8,6 +8,7 @@ import vscode = require('vscode'); export interface ICodeFormattingSettings { openBraceOnSameLine: boolean; + indentationSize: number; } export interface IScriptAnalysisSettings { @@ -46,7 +47,8 @@ export function load(myPluginId: string): ISettings { }; let defaultCodeFormattingSettings: ICodeFormattingSettings = { - openBraceOnSameLine: true + openBraceOnSameLine: true, + indentationSize: 4 }; return { From 9f82b56e29038c5d0366c76dc5164ae6054bcc04 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Mon, 9 Jan 2017 13:18:42 -0800 Subject: [PATCH 06/18] Add enable property to formatting rules --- src/features/DocumentFormatter.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index ec695b1d71..58c514d59b 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -139,19 +139,25 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP let ruleProperty: string; switch (rule) { case "PSPlaceOpenBrace": + // TODO Add newlineafter option to settings ruleProperty = `${rule} = @{ + Enable = \$true OnSameLine = \$${settings.codeformatting.openBraceOnSameLine} + NewLineAfter = \$true }`; break; case "PSUseConsistentIndentation": ruleProperty = `${rule} = @{ + Enable = \$true IndentationSize = ${settings.codeformatting.indentationSize} }`; break; default: - ruleProperty = ""; + ruleProperty = `${rule} = @{ + Enable = \$true + }`; break; } From 9c61aa4630407689891aa6361945d19596a78843 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Mon, 9 Jan 2017 17:46:16 -0800 Subject: [PATCH 07/18] Add option to add new line after open brace --- package.json | 5 +++++ src/features/DocumentFormatter.ts | 3 +-- src/settings.ts | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8f9aaf3f09..5cf2b54f8e 100644 --- a/package.json +++ b/package.json @@ -276,6 +276,11 @@ "default": true, "description": "Places open brace on the same line as its associated statement." }, + "powershell.codeformatting.newLineAfterOpenBrace":{ + "type":"boolean", + "default": true, + "description": "A new line must follow an open brace." + }, "powershell.codeformatting.indentationSize":{ "type":"number", "default": 4, diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 58c514d59b..02c859b242 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -139,11 +139,10 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP let ruleProperty: string; switch (rule) { case "PSPlaceOpenBrace": - // TODO Add newlineafter option to settings ruleProperty = `${rule} = @{ Enable = \$true OnSameLine = \$${settings.codeformatting.openBraceOnSameLine} - NewLineAfter = \$true + NewLineAfter = \$${settings.codeformatting.newLineAfterOpenBrace} }`; break; diff --git a/src/settings.ts b/src/settings.ts index 4dcb6ab4a1..8e6cf99ecf 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -8,6 +8,7 @@ import vscode = require('vscode'); export interface ICodeFormattingSettings { openBraceOnSameLine: boolean; + newLineAfterOpenBrace: boolean; indentationSize: number; } @@ -48,6 +49,7 @@ export function load(myPluginId: string): ISettings { let defaultCodeFormattingSettings: ICodeFormattingSettings = { openBraceOnSameLine: true, + newLineAfterOpenBrace: true, indentationSize: 4 }; From 755cc65e8b1029024493ef25e93b654e68fa26f7 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Mon, 9 Jan 2017 17:48:43 -0800 Subject: [PATCH 08/18] Add one stop undo/redo option to code formatting --- src/features/DocumentFormatter.ts | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 02c859b242..b98bacd663 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -51,11 +51,22 @@ interface MarkerCorrection { class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider { private languageClient: LanguageClient; + + // The order in which the rules will be executed starting from the first element. private readonly ruleOrder: string[] = [ "PSPlaceCloseBrace", "PSPlaceOpenBrace", "PSUseConsistentIndentation"]; + // Allows edits to be undone and redone is a single step. + // Should we expose this through settings? + private aggregateUndoStop: boolean; + + constructor(aggregateUndoStop: boolean) + { + this.aggregateUndoStop = aggregateUndoStop; + } + provideDocumentFormattingEdits( document: TextDocument, options: FormattingOptions, @@ -111,12 +122,14 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP } } - applyEdits(markers: ScriptFileMarker[], index: number): Thenable { - if (index >= markers.length) { + applyEdit(markers: ScriptFileMarker[], markerIndex: number, ruleIndex: number): Thenable { + if (markerIndex >= markers.length) { return; } - let edit: ScriptRegion = markers[index].correction.edits[0]; + let undoStopAfter = !this.aggregateUndoStop || (ruleIndex === this.ruleOrder.length - 1 && markerIndex === markers.length - 1); + let undoStopBefore = !this.aggregateUndoStop || (ruleIndex === 0 && markerIndex === 0); + let edit: ScriptRegion = markers[markerIndex].correction.edits[0]; return Window.activeTextEditor.edit((editBuilder) => { editBuilder.replace( new vscode.Range( @@ -125,8 +138,12 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP edit.endLineNumber - 1, edit.endColumnNumber - 1), edit.text); + }, + { + undoStopAfter: undoStopAfter, + undoStopBefore: undoStopBefore }).then((isEditApplied) => { - return this.applyEdits(markers, index + 1); + return this.applyEdit(markers, markerIndex + 1, ruleIndex); }); // TODO handle rejection } @@ -175,7 +192,7 @@ export class DocumentFormatterFeature implements IFeature { private documentFormattingEditProvider: PSDocumentFormattingEditProvider; constructor() { - this.documentFormattingEditProvider = new PSDocumentFormattingEditProvider(); + this.documentFormattingEditProvider = new PSDocumentFormattingEditProvider(true); this.disposable = vscode.languages.registerDocumentFormattingEditProvider( "powershell", this.documentFormattingEditProvider); From d4809fcb7d9b7b4b37afd5ab6fe698c5e943a216 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Mon, 9 Jan 2017 17:53:37 -0800 Subject: [PATCH 09/18] Handle multiple violations on one line --- src/features/DocumentFormatter.ts | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index b98bacd663..b47f10d554 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -85,6 +85,8 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP index: number): Thenable | TextEdit[] { if (this.languageClient !== null && index < this.ruleOrder.length) { let rule = this.ruleOrder[index]; + let uniqueMarkers: ScriptFileMarker[] = []; + let markers: ScriptFileMarker[]; return this.languageClient.sendRequest( ScriptFileMarkersRequest.type, { @@ -92,12 +94,10 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP settings: this.getSettings(rule) }) .then((result: ScriptFileMarkersRequestResultParams) => { - - // TODO modify undo stops to make sure all the edits - // can be undone and redone in a single step + markers = result.markers; // sort in decending order of the edits - result.markers.sort(function (a: ScriptFileMarker, b: ScriptFileMarker): number { + markers.sort(function (a: ScriptFileMarker, b: ScriptFileMarker): number { let leftOperand: number = a.correction.edits[0].startLineNumber, rightOperand: number = b.correction.edits[0].startLineNumber; if (leftOperand < rightOperand) { @@ -108,13 +108,31 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP return 0; } }); - return this.applyEdits(result.markers, 0); + + // We cannot handle multiple edits on the same line hence we + // filter the markers so that there is only one edit per line + if (markers.length > 0) { + uniqueMarkers.push(markers[0]); + for (let marker of markers.slice(1)) { + if (marker.correction.edits[0].startLineNumber + !== uniqueMarkers[uniqueMarkers.length - 1].correction.edits[0].startLineNumber) { + uniqueMarkers.push(marker); + } + } + } // we do not return a valid array because our text edits // need to be executed in a particular order and it is // easier if we perform the edits ourselves + return this.applyEdit(uniqueMarkers, 0, index); }) .then(() => { + + // execute the same rule again if we left out violations + // on the same line + if (uniqueMarkers.length !== markers.length) { + return this.executeRulesInOrder(document, options, index); + } return this.executeRulesInOrder(document, options, index + 1); }); } else { From 88551de2857bd387d10fa415dd194650158c8732 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Tue, 10 Jan 2017 11:52:49 -0800 Subject: [PATCH 10/18] Use edits directly instead of through markers --- src/features/DocumentFormatter.ts | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index b47f10d554..9724ac22dc 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -85,8 +85,8 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP index: number): Thenable | TextEdit[] { if (this.languageClient !== null && index < this.ruleOrder.length) { let rule = this.ruleOrder[index]; - let uniqueMarkers: ScriptFileMarker[] = []; - let markers: ScriptFileMarker[]; + let uniqueEdits: ScriptRegion[] = []; + let edits: ScriptRegion[]; return this.languageClient.sendRequest( ScriptFileMarkersRequest.type, { @@ -94,12 +94,12 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP settings: this.getSettings(rule) }) .then((result: ScriptFileMarkersRequestResultParams) => { - markers = result.markers; + edits = result.markers.map(m => { return m.correction.edits[0]; }); // sort in decending order of the edits - markers.sort(function (a: ScriptFileMarker, b: ScriptFileMarker): number { - let leftOperand: number = a.correction.edits[0].startLineNumber, - rightOperand: number = b.correction.edits[0].startLineNumber; + edits.sort(function (a: ScriptRegion, b: ScriptRegion): number { + let leftOperand: number = a.startLineNumber, + rightOperand: number = b.startLineNumber; if (leftOperand < rightOperand) { return 1; } else if (leftOperand > rightOperand) { @@ -111,12 +111,12 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP // We cannot handle multiple edits on the same line hence we // filter the markers so that there is only one edit per line - if (markers.length > 0) { - uniqueMarkers.push(markers[0]); - for (let marker of markers.slice(1)) { - if (marker.correction.edits[0].startLineNumber - !== uniqueMarkers[uniqueMarkers.length - 1].correction.edits[0].startLineNumber) { - uniqueMarkers.push(marker); + if (edits.length > 0) { + uniqueEdits.push(edits[0]); + for (let edit of edits.slice(1)) { + if (edit.startLineNumber + !== uniqueEdits[uniqueEdits.length - 1].startLineNumber) { + uniqueEdits.push(edit); } } } @@ -124,13 +124,13 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP // we do not return a valid array because our text edits // need to be executed in a particular order and it is // easier if we perform the edits ourselves - return this.applyEdit(uniqueMarkers, 0, index); + return this.applyEdit(uniqueEdits, 0, index); }) .then(() => { // execute the same rule again if we left out violations // on the same line - if (uniqueMarkers.length !== markers.length) { + if (uniqueEdits.length !== edits.length) { return this.executeRulesInOrder(document, options, index); } return this.executeRulesInOrder(document, options, index + 1); @@ -140,14 +140,14 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP } } - applyEdit(markers: ScriptFileMarker[], markerIndex: number, ruleIndex: number): Thenable { - if (markerIndex >= markers.length) { + applyEdit(edits: ScriptRegion[], markerIndex: number, ruleIndex: number): Thenable { + if (markerIndex >= edits.length) { return; } - let undoStopAfter = !this.aggregateUndoStop || (ruleIndex === this.ruleOrder.length - 1 && markerIndex === markers.length - 1); + let undoStopAfter = !this.aggregateUndoStop || (ruleIndex === this.ruleOrder.length - 1 && markerIndex === edits.length - 1); let undoStopBefore = !this.aggregateUndoStop || (ruleIndex === 0 && markerIndex === 0); - let edit: ScriptRegion = markers[markerIndex].correction.edits[0]; + let edit: ScriptRegion = edits[markerIndex]; return Window.activeTextEditor.edit((editBuilder) => { editBuilder.replace( new vscode.Range( @@ -161,7 +161,7 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP undoStopAfter: undoStopAfter, undoStopBefore: undoStopBefore }).then((isEditApplied) => { - return this.applyEdit(markers, markerIndex + 1, ruleIndex); + return this.applyEdit(edits, markerIndex + 1, ruleIndex); }); // TODO handle rejection } From 7291539a5b170443697f2f8a61a89891c5007e10 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Tue, 10 Jan 2017 12:05:33 -0800 Subject: [PATCH 11/18] Include startcolumnnumber in edit comparison --- src/features/DocumentFormatter.ts | 53 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 9724ac22dc..f886ca426f 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -49,6 +49,24 @@ interface MarkerCorrection { edits: ScriptRegion[] } +function editComparer(leftOperand: ScriptRegion, rightOperand: ScriptRegion): number { + if (leftOperand.startLineNumber < rightOperand.startLineNumber) { + return -1; + } else if (leftOperand.startLineNumber > rightOperand.startLineNumber) { + return 1; + } else { + if (leftOperand.startColumnNumber < rightOperand.startColumnNumber) { + return -1; + } + else if (leftOperand.startColumnNumber > rightOperand.startColumnNumber) { + return 1; + } + else { + return 0; + } + } +} + class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider { private languageClient: LanguageClient; @@ -62,8 +80,7 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP // Should we expose this through settings? private aggregateUndoStop: boolean; - constructor(aggregateUndoStop: boolean) - { + constructor(aggregateUndoStop: boolean) { this.aggregateUndoStop = aggregateUndoStop; } @@ -94,28 +111,20 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP settings: this.getSettings(rule) }) .then((result: ScriptFileMarkersRequestResultParams) => { - edits = result.markers.map(m => { return m.correction.edits[0]; }); + edits = result.markers.map(marker => { return marker.correction.edits[0]; }); // sort in decending order of the edits - edits.sort(function (a: ScriptRegion, b: ScriptRegion): number { - let leftOperand: number = a.startLineNumber, - rightOperand: number = b.startLineNumber; - if (leftOperand < rightOperand) { - return 1; - } else if (leftOperand > rightOperand) { - return -1; - } else { - return 0; - } + edits.sort((left: ScriptRegion, right: ScriptRegion) => { + return -1 * editComparer(left, right); }); - // We cannot handle multiple edits on the same line hence we + // We cannot handle multiple edits at the same point hence we // filter the markers so that there is only one edit per line + // This ideally should not happen but it is good to have some additional safeguard if (edits.length > 0) { uniqueEdits.push(edits[0]); for (let edit of edits.slice(1)) { - if (edit.startLineNumber - !== uniqueEdits[uniqueEdits.length - 1].startLineNumber) { + if (editComparer(uniqueEdits[uniqueEdits.length - 1], edit) !== 0) { uniqueEdits.push(edit); } } @@ -157,12 +166,12 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP edit.endColumnNumber - 1), edit.text); }, - { - undoStopAfter: undoStopAfter, - undoStopBefore: undoStopBefore - }).then((isEditApplied) => { - return this.applyEdit(edits, markerIndex + 1, ruleIndex); - }); // TODO handle rejection + { + undoStopAfter: undoStopAfter, + undoStopBefore: undoStopBefore + }).then((isEditApplied) => { + return this.applyEdit(edits, markerIndex + 1, ruleIndex); + }); // TODO handle rejection } setLanguageClient(languageClient: LanguageClient): void { From e1e0dd7040a8bfbbe6c21054a9d90879e26d202a Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Tue, 10 Jan 2017 17:07:14 -0800 Subject: [PATCH 12/18] Provide code formatting of selection --- src/features/DocumentFormatter.ts | 101 +++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 30 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index f886ca426f..7398c8c400 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -1,5 +1,14 @@ import vscode = require('vscode'); -import { languages, TextDocument, TextEdit, FormattingOptions, CancellationToken } from 'vscode' +import { + languages, + TextDocument, + TextEdit, + FormattingOptions, + CancellationToken, + DocumentFormattingEditProvider, + DocumentRangeFormattingEditProvider, + Range, +} from 'vscode'; import { LanguageClient, RequestType, NotificationType } from 'vscode-languageclient'; import Window = vscode.window; import { IFeature } from '../feature'; @@ -67,7 +76,7 @@ function editComparer(leftOperand: ScriptRegion, rightOperand: ScriptRegion): nu } } -class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditProvider { +class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider { private languageClient: LanguageClient; // The order in which the rules will be executed starting from the first element. @@ -88,16 +97,20 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP document: TextDocument, options: FormattingOptions, token: CancellationToken): TextEdit[] | Thenable { + return this.provideDocumentRangeFormattingEdits(document, null, options, token); + } - // we need to order the edits such that edit i should not invalidate - // the edits in edit j s.t i < j (seems like a hard problem) - // or - // peform edits ourself and return an empty textedit array - return this.executeRulesInOrder(document, options, 0); + provideDocumentRangeFormattingEdits( + document: TextDocument, + range: Range, + options: FormattingOptions, + token: CancellationToken): TextEdit[] | Thenable { + return this.executeRulesInOrder(document, range, options, 0); } executeRulesInOrder( document: TextDocument, + range: Range, options: FormattingOptions, index: number): Thenable | TextEdit[] { if (this.languageClient !== null && index < this.ruleOrder.length) { @@ -130,26 +143,34 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP } } + // we need to update the range as the edits might + // have changed the original layout + if (range !== null) { + let tempRange: Range = this.getSelectionRange(document); + if (tempRange !== null) { + range = tempRange; + } + } + // we do not return a valid array because our text edits // need to be executed in a particular order and it is // easier if we perform the edits ourselves - return this.applyEdit(uniqueEdits, 0, index); + return this.applyEdit(uniqueEdits, range, 0, index); }) .then(() => { - // execute the same rule again if we left out violations // on the same line if (uniqueEdits.length !== edits.length) { - return this.executeRulesInOrder(document, options, index); + return this.executeRulesInOrder(document, range, options, index); } - return this.executeRulesInOrder(document, options, index + 1); + return this.executeRulesInOrder(document, range, options, index + 1); }); } else { return TextEdit[0]; } } - applyEdit(edits: ScriptRegion[], markerIndex: number, ruleIndex: number): Thenable { + applyEdit(edits: ScriptRegion[], range: Range, markerIndex: number, ruleIndex: number): Thenable { if (markerIndex >= edits.length) { return; } @@ -157,21 +178,36 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP let undoStopAfter = !this.aggregateUndoStop || (ruleIndex === this.ruleOrder.length - 1 && markerIndex === edits.length - 1); let undoStopBefore = !this.aggregateUndoStop || (ruleIndex === 0 && markerIndex === 0); let edit: ScriptRegion = edits[markerIndex]; - return Window.activeTextEditor.edit((editBuilder) => { - editBuilder.replace( - new vscode.Range( - edit.startLineNumber - 1, - edit.startColumnNumber - 1, - edit.endLineNumber - 1, - edit.endColumnNumber - 1), - edit.text); - }, - { - undoStopAfter: undoStopAfter, - undoStopBefore: undoStopBefore - }).then((isEditApplied) => { - return this.applyEdit(edits, markerIndex + 1, ruleIndex); - }); // TODO handle rejection + let editRange: Range = new vscode.Range( + edit.startLineNumber - 1, + edit.startColumnNumber - 1, + edit.endLineNumber - 1, + edit.endColumnNumber - 1); + if (range === null || range.contains(editRange)) { + return Window.activeTextEditor.edit((editBuilder) => { + editBuilder.replace( + editRange, + edit.text); + }, + { + undoStopAfter: undoStopAfter, + undoStopBefore: undoStopBefore + }).then((isEditApplied) => { + return this.applyEdit(edits, range, markerIndex + 1, ruleIndex); + }); // TODO handle rejection + } + else { + return this.applyEdit(edits, range, markerIndex + 1, ruleIndex); + } + } + + getSelectionRange(document: TextDocument): Range { + let editor = vscode.window.visibleTextEditors.find(editor => editor.document === document); + if (editor !== undefined) { + return editor.selection as Range; + } + + return null; } setLanguageClient(languageClient: LanguageClient): void { @@ -214,13 +250,17 @@ class PSDocumentFormattingEditProvider implements vscode.DocumentFormattingEditP } export class DocumentFormatterFeature implements IFeature { - private disposable: vscode.Disposable; + private formattingEditProvider: vscode.Disposable; + private rangeFormattingEditProvider: vscode.Disposable; private languageClient: LanguageClient; private documentFormattingEditProvider: PSDocumentFormattingEditProvider; constructor() { this.documentFormattingEditProvider = new PSDocumentFormattingEditProvider(true); - this.disposable = vscode.languages.registerDocumentFormattingEditProvider( + this.formattingEditProvider = vscode.languages.registerDocumentFormattingEditProvider( + "powershell", + this.documentFormattingEditProvider); + this.rangeFormattingEditProvider = vscode.languages.registerDocumentRangeFormattingEditProvider( "powershell", this.documentFormattingEditProvider); } @@ -231,6 +271,7 @@ export class DocumentFormatterFeature implements IFeature { } public dispose(): any { - this.disposable.dispose(); + this.formattingEditProvider.dispose(); + this.rangeFormattingEditProvider.dispose(); } } \ No newline at end of file From 631c508f47ec2aef5b7f0e0d45df6c9b05f0e5c3 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 12 Jan 2017 19:46:55 -0800 Subject: [PATCH 13/18] Use editor.tabSize as indentationSize --- src/features/DocumentFormatter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 7398c8c400..fd7a153df2 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -229,7 +229,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider case "PSUseConsistentIndentation": ruleProperty = `${rule} = @{ Enable = \$true - IndentationSize = ${settings.codeformatting.indentationSize} + IndentationSize = ${vscode.workspace.getConfiguration("editor").get("tabSize")} }`; break; From 669cbca982604357ca69617d8568a8aff43b3564 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 12 Jan 2017 19:49:09 -0800 Subject: [PATCH 14/18] Remove codeformatting.indentationSize setting --- package.json | 5 ----- src/settings.ts | 8 +++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 5cf2b54f8e..5299fed2cd 100644 --- a/package.json +++ b/package.json @@ -280,11 +280,6 @@ "type":"boolean", "default": true, "description": "A new line must follow an open brace." - }, - "powershell.codeformatting.indentationSize":{ - "type":"number", - "default": 4, - "description": "The indentation size in number of Space characters." } } } diff --git a/src/settings.ts b/src/settings.ts index 8e6cf99ecf..d3a3992c2d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -9,12 +9,11 @@ import vscode = require('vscode'); export interface ICodeFormattingSettings { openBraceOnSameLine: boolean; newLineAfterOpenBrace: boolean; - indentationSize: number; } export interface IScriptAnalysisSettings { - enable?: boolean - settingsPath: string + enable?: boolean; + settingsPath: string; } export interface IDeveloperSettings { @@ -49,8 +48,7 @@ export function load(myPluginId: string): ISettings { let defaultCodeFormattingSettings: ICodeFormattingSettings = { openBraceOnSameLine: true, - newLineAfterOpenBrace: true, - indentationSize: 4 + newLineAfterOpenBrace: true }; return { From 44fc30c9950bb2e14f3b237da385aed601489909 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 12 Jan 2017 21:57:50 -0800 Subject: [PATCH 15/18] Add copyright header to DocumentFormatter.ts --- src/features/DocumentFormatter.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index fd7a153df2..1935b7d56d 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + import vscode = require('vscode'); import { languages, From 44d7122adaa99364f864df651a71c85d835dd7ac Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 12 Jan 2017 22:03:23 -0800 Subject: [PATCH 16/18] Change codeformatting to codeFormatting --- package.json | 4 ++-- src/features/DocumentFormatter.ts | 4 ++-- src/settings.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 5299fed2cd..41683464a9 100644 --- a/package.json +++ b/package.json @@ -271,12 +271,12 @@ "default": false, "description": "Launches the language service with the /waitForDebugger flag to force it to wait for a .NET debugger to attach before proceeding." }, - "powershell.codeformatting.openBraceOnSameLine":{ + "powershell.codeFormatting.openBraceOnSameLine":{ "type":"boolean", "default": true, "description": "Places open brace on the same line as its associated statement." }, - "powershell.codeformatting.newLineAfterOpenBrace":{ + "powershell.codeFormatting.newLineAfterOpenBrace":{ "type":"boolean", "default": true, "description": "A new line must follow an open brace." diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 1935b7d56d..9fb7ac1413 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -225,8 +225,8 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider case "PSPlaceOpenBrace": ruleProperty = `${rule} = @{ Enable = \$true - OnSameLine = \$${settings.codeformatting.openBraceOnSameLine} - NewLineAfter = \$${settings.codeformatting.newLineAfterOpenBrace} + OnSameLine = \$${settings.codeFormatting.openBraceOnSameLine} + NewLineAfter = \$${settings.codeFormatting.newLineAfterOpenBrace} }`; break; diff --git a/src/settings.ts b/src/settings.ts index d3a3992c2d..b29237ef40 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -28,7 +28,7 @@ export interface ISettings { enableProfileLoading?: boolean; scriptAnalysis?: IScriptAnalysisSettings; developer?: IDeveloperSettings; - codeformatting?: ICodeFormattingSettings; + codeFormatting?: ICodeFormattingSettings; } export function load(myPluginId: string): ISettings { @@ -56,6 +56,6 @@ export function load(myPluginId: string): ISettings { enableProfileLoading: configuration.get("enableProfileLoading", false), scriptAnalysis: configuration.get("scriptAnalysis", defaultScriptAnalysisSettings), developer: configuration.get("developer", defaultDeveloperSettings), - codeformatting: configuration.get("codeformatting", defaultCodeFormattingSettings) + codeFormatting: configuration.get("codeFormatting", defaultCodeFormattingSettings) }; } From ad50303810c32fbc603daa9d4b3ad21d7278a225 Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Thu, 12 Jan 2017 22:08:11 -0800 Subject: [PATCH 17/18] Make formatting edit as one atomic edit --- src/features/DocumentFormatter.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 9fb7ac1413..971373cab1 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -90,10 +90,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider "PSUseConsistentIndentation"]; // Allows edits to be undone and redone is a single step. - // Should we expose this through settings? + // It is usefuld to have undo stops after every edit while debugging + // hence we keep this as an option but set it true by default. private aggregateUndoStop: boolean; - constructor(aggregateUndoStop: boolean) { + constructor(aggregateUndoStop = true) { this.aggregateUndoStop = aggregateUndoStop; } @@ -260,7 +261,7 @@ export class DocumentFormatterFeature implements IFeature { private documentFormattingEditProvider: PSDocumentFormattingEditProvider; constructor() { - this.documentFormattingEditProvider = new PSDocumentFormattingEditProvider(true); + this.documentFormattingEditProvider = new PSDocumentFormattingEditProvider(); this.formattingEditProvider = vscode.languages.registerDocumentFormattingEditProvider( "powershell", this.documentFormattingEditProvider); From 7fb403322c6b16788571d8502bbcd6f15271604e Mon Sep 17 00:00:00 2001 From: Kapil Borle Date: Fri, 13 Jan 2017 19:23:12 -0800 Subject: [PATCH 18/18] Pass settings object for codeformatting --- src/features/DocumentFormatter.ts | 34 +++++++++++-------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/features/DocumentFormatter.ts b/src/features/DocumentFormatter.ts index 971373cab1..dc6c0dda49 100644 --- a/src/features/DocumentFormatter.ts +++ b/src/features/DocumentFormatter.ts @@ -26,7 +26,7 @@ export namespace ScriptFileMarkersRequest { // TODO move some of the common interface to a separate file? interface ScriptFileMarkersRequestParams { filePath: string; - settings: string; + settings: any; } interface ScriptFileMarkersRequestResultParams { @@ -219,38 +219,28 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider this.languageClient = languageClient; } - getSettings(rule: string): string { - let settings: Settings.ISettings = Settings.load(Utils.PowerShellLanguageId); - let ruleProperty: string; + getSettings(rule: string): any { + let psSettings: Settings.ISettings = Settings.load(Utils.PowerShellLanguageId); + let ruleSettings = new Object(); + ruleSettings["Enable"] = true; + switch (rule) { case "PSPlaceOpenBrace": - ruleProperty = `${rule} = @{ - Enable = \$true - OnSameLine = \$${settings.codeFormatting.openBraceOnSameLine} - NewLineAfter = \$${settings.codeFormatting.newLineAfterOpenBrace} - }`; + ruleSettings["OnSameLine"] = psSettings.codeFormatting.openBraceOnSameLine; + ruleSettings["NewLineAfter"] = psSettings.codeFormatting.newLineAfterOpenBrace; break; case "PSUseConsistentIndentation": - ruleProperty = `${rule} = @{ - Enable = \$true - IndentationSize = ${vscode.workspace.getConfiguration("editor").get("tabSize")} - }`; + ruleSettings["IndentationSize"] = vscode.workspace.getConfiguration("editor").get("tabSize"); break; default: - ruleProperty = `${rule} = @{ - Enable = \$true - }`; break; } - return `@{ - IncludeRules = @('${rule}') - Rules = @{ - ${ruleProperty} - } -}`; + let settings: Object = new Object(); + settings[rule] = ruleSettings; + return settings; } }