@@ -134,6 +134,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
134
134
private static documentLocker = new DocumentLocker ( ) ;
135
135
private static statusBarTracker = new Object ( ) ;
136
136
private languageClient : LanguageClient ;
137
+ private lineDiff : number ;
137
138
138
139
// The order in which the rules will be executed starting from the first element.
139
140
private readonly ruleOrder : string [ ] = [
@@ -153,6 +154,7 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
153
154
154
155
constructor ( aggregateUndoStop = true ) {
155
156
this . aggregateUndoStop = aggregateUndoStop ;
157
+ this . lineDiff = 0 ;
156
158
}
157
159
158
160
provideDocumentFormattingEdits (
@@ -179,6 +181,12 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
179
181
return this . emptyPromise ;
180
182
}
181
183
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
+
182
190
let textEdits : Thenable < TextEdit [ ] > = this . executeRulesInOrder ( editor , range , options , 0 ) ;
183
191
this . lockDocument ( document , textEdits ) ;
184
192
PSDocumentFormattingEditProvider . showStatusBar ( document , textEdits ) ;
@@ -195,6 +203,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
195
203
PSDocumentFormattingEditProvider . disposeAllStatusBars ( ) ;
196
204
}
197
205
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
+
198
211
private getEditor ( document : TextDocument ) : TextEditor {
199
212
return Window . visibleTextEditors . find ( ( e , n , obj ) => { return e . document === document ; } ) ;
200
213
}
@@ -248,12 +261,14 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
248
261
// we need to update the range as the edits might
249
262
// have changed the original layout
250
263
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 } ) } ) ;
254
266
}
255
267
}
256
268
269
+ // reset line difference to 0
270
+ this . lineDiff = 0 ;
271
+
257
272
// we do not return a valid array because our text edits
258
273
// need to be executed in a particular order and it is
259
274
// easier if we perform the edits ourselves
@@ -292,7 +307,13 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
292
307
edit . startColumnNumber - 1 ,
293
308
edit . endLineNumber - 1 ,
294
309
edit . endColumnNumber - 1 ) ;
310
+
295
311
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 ) ;
296
317
return editor . edit ( ( editBuilder ) => {
297
318
editBuilder . replace (
298
319
editRange ,
@@ -310,6 +331,11 @@ class PSDocumentFormattingEditProvider implements DocumentFormattingEditProvider
310
331
}
311
332
}
312
333
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
313
339
private getSelectionRange ( document : TextDocument ) : Range {
314
340
let editor = vscode . window . visibleTextEditors . find ( editor => editor . document === document ) ;
315
341
if ( editor !== undefined ) {
0 commit comments