@@ -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