Skip to content

Commit 68798e5

Browse files
author
Kapil Borle
authored
Merge pull request PowerShell#505 from PowerShell/kapilmb/format-on-type
Enable formatOnType feature
2 parents 332f3d0 + 4929ab6 commit 68798e5

File tree

1 file changed

+81
-7
lines changed

1 file changed

+81
-7
lines changed

src/features/DocumentFormatter.ts

+81-7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
CancellationToken,
1212
DocumentFormattingEditProvider,
1313
DocumentRangeFormattingEditProvider,
14+
OnTypeFormattingEditProvider,
15+
Position,
1416
Range,
1517
TextEditor,
1618
TextLine
@@ -26,6 +28,21 @@ export namespace ScriptFileMarkersRequest {
2628
export const type: RequestType<any, any, void> = { get method(): string { return "powerShell/getScriptFileMarkers"; } };
2729
}
2830

31+
export namespace ScriptRegionRequest {
32+
export const type: RequestType<any, any, void> = { get method(): string { return "powerShell/getScriptRegion"; } };
33+
}
34+
35+
interface ScriptRegionRequestParams {
36+
fileUri: string;
37+
character: string;
38+
line: number;
39+
column: number;
40+
}
41+
42+
interface ScriptRegionRequestResult {
43+
scriptRegion: ScriptRegion;
44+
}
45+
2946
// TODO move some of the common interface to a separate file?
3047
interface ScriptFileMarkersRequestParams {
3148
fileUri: string;
@@ -65,6 +82,18 @@ interface MarkerCorrection {
6582
edits: ScriptRegion[];
6683
}
6784

85+
function toRange(scriptRegion: ScriptRegion): vscode.Range {
86+
return new vscode.Range(
87+
scriptRegion.startLineNumber - 1,
88+
scriptRegion.startColumnNumber - 1,
89+
scriptRegion.endLineNumber - 1,
90+
scriptRegion.endColumnNumber - 1);
91+
}
92+
93+
function toOneBasedPosition(position: Position): Position {
94+
return position.translate({ lineDelta: 1, characterDelta: 1 });
95+
}
96+
6897
function editComparer(leftOperand: ScriptRegion, rightOperand: ScriptRegion): number {
6998
if (leftOperand.startLineNumber < rightOperand.startLineNumber) {
7099
return -1;
@@ -131,7 +160,10 @@ class DocumentLocker {
131160
}
132161
}
133162

134-
class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider, DocumentRangeFormattingEditProvider {
163+
class PSDocumentFormattingEditProvider implements
164+
DocumentFormattingEditProvider,
165+
DocumentRangeFormattingEditProvider,
166+
OnTypeFormattingEditProvider {
135167
private static documentLocker = new DocumentLocker();
136168
private static statusBarTracker = new Object();
137169
private languageClient: LanguageClient;
@@ -188,6 +220,25 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
188220
return textEdits;
189221
}
190222

223+
provideOnTypeFormattingEdits(
224+
document: TextDocument,
225+
position: Position,
226+
ch: string,
227+
options: FormattingOptions,
228+
token: CancellationToken): TextEdit[] | Thenable<TextEdit[]> {
229+
return this.getScriptRegion(document, position, ch).then(scriptRegion => {
230+
if (scriptRegion === null) {
231+
return this.emptyPromise;
232+
}
233+
234+
return this.provideDocumentRangeFormattingEdits(
235+
document,
236+
toRange(scriptRegion),
237+
options,
238+
token);
239+
});
240+
}
241+
191242
setLanguageClient(languageClient: LanguageClient): void {
192243
this.languageClient = languageClient;
193244

@@ -198,6 +249,24 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
198249
PSDocumentFormattingEditProvider.disposeAllStatusBars();
199250
}
200251

252+
private getScriptRegion(document: TextDocument, position: Position, ch: string): Thenable<ScriptRegion> {
253+
let oneBasedPosition = toOneBasedPosition(position);
254+
return this.languageClient.sendRequest(
255+
ScriptRegionRequest.type,
256+
{
257+
fileUri: document.uri.toString(),
258+
character: ch,
259+
line: oneBasedPosition.line,
260+
column: oneBasedPosition.character
261+
}).then((result: ScriptRegionRequestResult) => {
262+
if (result === null) {
263+
return null;
264+
}
265+
266+
return result.scriptRegion;
267+
});
268+
}
269+
201270
private snapRangeToEdges(range: Range, document: TextDocument): Range {
202271
return range.with({
203272
start: range.start.with({ character: 0 }),
@@ -302,11 +371,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
302371
let undoStopAfter = !this.aggregateUndoStop || (ruleIndex === this.ruleOrder.length - 1 && markerIndex === edits.length - 1);
303372
let undoStopBefore = !this.aggregateUndoStop || (ruleIndex === 0 && markerIndex === 0);
304373
let edit: ScriptRegion = edits[markerIndex];
305-
let editRange: Range = new vscode.Range(
306-
edit.startLineNumber - 1,
307-
edit.startColumnNumber - 1,
308-
edit.endLineNumber - 1,
309-
edit.endColumnNumber - 1);
374+
let editRange: Range = toRange(edit);
310375

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

@@ -392,8 +457,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
392457
}
393458

394459
export class DocumentFormatterFeature implements IFeature {
460+
private firstTriggerCharacter: string = "}";
461+
private moreTriggerCharacters: string[] = ["\n"];
395462
private formattingEditProvider: vscode.Disposable;
396463
private rangeFormattingEditProvider: vscode.Disposable;
464+
private onTypeFormattingEditProvider: vscode.Disposable;
397465
private languageClient: LanguageClient;
398466
private documentFormattingEditProvider: PSDocumentFormattingEditProvider;
399467

@@ -405,6 +473,11 @@ export class DocumentFormatterFeature implements IFeature {
405473
this.rangeFormattingEditProvider = vscode.languages.registerDocumentRangeFormattingEditProvider(
406474
"powershell",
407475
this.documentFormattingEditProvider);
476+
this.onTypeFormattingEditProvider = vscode.languages.registerOnTypeFormattingEditProvider(
477+
"powershell",
478+
this.documentFormattingEditProvider,
479+
this.firstTriggerCharacter,
480+
...this.moreTriggerCharacters);
408481
}
409482

410483
public setLanguageClient(languageclient: LanguageClient): void {
@@ -415,5 +488,6 @@ export class DocumentFormatterFeature implements IFeature {
415488
public dispose(): any {
416489
this.formattingEditProvider.dispose();
417490
this.rangeFormattingEditProvider.dispose();
491+
this.onTypeFormattingEditProvider.dispose();
418492
}
419-
}
493+
}

0 commit comments

Comments
 (0)