Skip to content

Commit 6ee1639

Browse files
author
Kapil Borle
committed
Update range based on changes in number of lines
1 parent 1d4cd4c commit 6ee1639

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/features/DocumentFormatter.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
134134
private static documentLocker = new DocumentLocker();
135135
private static statusBarTracker = new Object();
136136
private languageClient: LanguageClient;
137+
private lineDiff: number;
137138

138139
// The order in which the rules will be executed starting from the first element.
139140
private readonly ruleOrder: string[] = [
@@ -153,6 +154,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
153154

154155
constructor(aggregateUndoStop = true) {
155156
this.aggregateUndoStop = aggregateUndoStop;
157+
this.lineDiff = 0;
156158
}
157159

158160
provideDocumentFormattingEdits(
@@ -179,6 +181,12 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
179181
return this.emptyPromise;
180182
}
181183

184+
// Extend the range such that it starts at the first character of the
185+
// start line of the range.
186+
if (range !== null) {
187+
range = this.snapRangeToLineStart(range);
188+
}
189+
182190
let textEdits: Thenable<TextEdit[]> = this.executeRulesInOrder(editor, range, options, 0);
183191
this.lockDocument(document, textEdits);
184192
PSDocumentFormattingEditProvider.showStatusBar(document, textEdits);
@@ -195,6 +203,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
195203
PSDocumentFormattingEditProvider.disposeAllStatusBars();
196204
}
197205

206+
private snapRangeToLineStart(range: Range): Range {
207+
// TODO snap to the last character of the end line too!
208+
return range.with({start: range.start.with({character: 0})});
209+
}
210+
198211
private getEditor(document: TextDocument): TextEditor {
199212
return Window.visibleTextEditors.find((e, n, obj) => { return e.document === document; });
200213
}
@@ -248,12 +261,14 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
248261
// we need to update the range as the edits might
249262
// have changed the original layout
250263
if (range !== null) {
251-
let tempRange: Range = this.getSelectionRange(document);
252-
if (tempRange !== null) {
253-
range = tempRange;
264+
if (this.lineDiff !== 0) {
265+
range = range.with({end: range.end.translate({lineDelta: this.lineDiff})});
254266
}
255267
}
256268

269+
// reset line difference to 0
270+
this.lineDiff = 0;
271+
257272
// we do not return a valid array because our text edits
258273
// need to be executed in a particular order and it is
259274
// easier if we perform the edits ourselves
@@ -292,7 +307,13 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
292307
edit.startColumnNumber - 1,
293308
edit.endLineNumber - 1,
294309
edit.endColumnNumber - 1);
310+
295311
if (range === null || range.contains(editRange)) {
312+
313+
// accumulate the changes in number of lines
314+
// get the difference between the number of lines in the replacement text and
315+
// that of the original text
316+
this.lineDiff += this.getNumLines(edit.text) - (editRange.end.line - editRange.start.line + 1);
296317
return editor.edit((editBuilder) => {
297318
editBuilder.replace(
298319
editRange,
@@ -310,6 +331,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
310331
}
311332
}
312333

334+
private getNumLines(text: string): number {
335+
return text.split("\r?\n").length;
336+
}
337+
338+
// TODO Remove method as it is not used anymore
313339
private getSelectionRange(document: TextDocument): Range {
314340
let editor = vscode.window.visibleTextEditors.find(editor => editor.document === document);
315341
if (editor !== undefined) {

0 commit comments

Comments
 (0)