Skip to content

Commit

Permalink
Merge pull request PowerShell#505 from PowerShell/kapilmb/format-on-type
Browse files Browse the repository at this point in the history
Enable formatOnType feature
  • Loading branch information
Kapil Borle authored Feb 15, 2017
2 parents 332f3d0 + 4929ab6 commit 68798e5
Showing 1 changed file with 81 additions and 7 deletions.
88 changes: 81 additions & 7 deletions src/features/DocumentFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
CancellationToken,
DocumentFormattingEditProvider,
DocumentRangeFormattingEditProvider,
OnTypeFormattingEditProvider,
Position,
Range,
TextEditor,
TextLine
Expand All @@ -26,6 +28,21 @@ export namespace ScriptFileMarkersRequest {
export const type: RequestType<any, any, void> = { get method(): string { return "powerShell/getScriptFileMarkers"; } };
}

export namespace ScriptRegionRequest {
export const type: RequestType<any, any, void> = { get method(): string { return "powerShell/getScriptRegion"; } };
}

interface ScriptRegionRequestParams {
fileUri: string;
character: string;
line: number;
column: number;
}

interface ScriptRegionRequestResult {
scriptRegion: ScriptRegion;
}

// TODO move some of the common interface to a separate file?
interface ScriptFileMarkersRequestParams {
fileUri: string;
Expand Down Expand Up @@ -65,6 +82,18 @@ interface MarkerCorrection {
edits: ScriptRegion[];
}

function toRange(scriptRegion: ScriptRegion): vscode.Range {
return new vscode.Range(
scriptRegion.startLineNumber - 1,
scriptRegion.startColumnNumber - 1,
scriptRegion.endLineNumber - 1,
scriptRegion.endColumnNumber - 1);
}

function toOneBasedPosition(position: Position): Position {
return position.translate({ lineDelta: 1, characterDelta: 1 });
}

function editComparer(leftOperand: ScriptRegion, rightOperand: ScriptRegion): number {
if (leftOperand.startLineNumber < rightOperand.startLineNumber) {
return -1;
Expand Down Expand Up @@ -131,7 +160,10 @@ class DocumentLocker {
}
}

class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider {
class PSDocumentFormattingEditProvider implements
DocumentFormattingEditProvider,
DocumentRangeFormattingEditProvider,
OnTypeFormattingEditProvider {
private static documentLocker = new DocumentLocker();
private static statusBarTracker = new Object();
private languageClient: LanguageClient;
Expand Down Expand Up @@ -188,6 +220,25 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
return textEdits;
}

provideOnTypeFormattingEdits(
document: TextDocument,
position: Position,
ch: string,
options: FormattingOptions,
token: CancellationToken): TextEdit[] | Thenable<TextEdit[]> {
return this.getScriptRegion(document, position, ch).then(scriptRegion => {
if (scriptRegion === null) {
return this.emptyPromise;
}

return this.provideDocumentRangeFormattingEdits(
document,
toRange(scriptRegion),
options,
token);
});
}

setLanguageClient(languageClient: LanguageClient): void {
this.languageClient = languageClient;

Expand All @@ -198,6 +249,24 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
PSDocumentFormattingEditProvider.disposeAllStatusBars();
}

private getScriptRegion(document: TextDocument, position: Position, ch: string): Thenable<ScriptRegion> {
let oneBasedPosition = toOneBasedPosition(position);
return this.languageClient.sendRequest(
ScriptRegionRequest.type,
{
fileUri: document.uri.toString(),
character: ch,
line: oneBasedPosition.line,
column: oneBasedPosition.character
}).then((result: ScriptRegionRequestResult) => {
if (result === null) {
return null;
}

return result.scriptRegion;
});
}

private snapRangeToEdges(range: Range, document: TextDocument): Range {
return range.with({
start: range.start.with({ character: 0 }),
Expand Down Expand Up @@ -302,11 +371,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
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];
let editRange: Range = new vscode.Range(
edit.startLineNumber - 1,
edit.startColumnNumber - 1,
edit.endLineNumber - 1,
edit.endColumnNumber - 1);
let editRange: Range = toRange(edit);

if (range === null || range.contains(editRange.start)) {

Expand Down Expand Up @@ -392,8 +457,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
}

export class DocumentFormatterFeature implements IFeature {
private firstTriggerCharacter: string = "}";
private moreTriggerCharacters: string[] = ["\n"];
private formattingEditProvider: vscode.Disposable;
private rangeFormattingEditProvider: vscode.Disposable;
private onTypeFormattingEditProvider: vscode.Disposable;
private languageClient: LanguageClient;
private documentFormattingEditProvider: PSDocumentFormattingEditProvider;

Expand All @@ -405,6 +473,11 @@ export class DocumentFormatterFeature implements IFeature {
this.rangeFormattingEditProvider = vscode.languages.registerDocumentRangeFormattingEditProvider(
"powershell",
this.documentFormattingEditProvider);
this.onTypeFormattingEditProvider = vscode.languages.registerOnTypeFormattingEditProvider(
"powershell",
this.documentFormattingEditProvider,
this.firstTriggerCharacter,
...this.moreTriggerCharacters);
}

public setLanguageClient(languageclient: LanguageClient): void {
Expand All @@ -415,5 +488,6 @@ export class DocumentFormatterFeature implements IFeature {
public dispose(): any {
this.formattingEditProvider.dispose();
this.rangeFormattingEditProvider.dispose();
this.onTypeFormattingEditProvider.dispose();
}
}
}

0 comments on commit 68798e5

Please sign in to comment.