@@ -5,7 +5,7 @@ import * as path from "path";
55import * as fs from "fs" ;
66import { sendCommand } from "./../common/childProc" ;
77import * as settings from "./../common/configSettings" ;
8- import { getTextEdits } from "./../common/editor" ;
8+ import { getTextEditsFromPatch , getTempFileWithDocumentContents } from "./../common/editor" ;
99
1010export abstract class BaseFormatter {
1111 public Id : string ;
@@ -23,22 +23,31 @@ export abstract class BaseFormatter {
2323 protected provideDocumentFormattingEdits ( document : vscode . TextDocument , options : vscode . FormattingOptions , token : vscode . CancellationToken , cmdLine : string ) : Thenable < vscode . TextEdit [ ] > {
2424 // Todo: Save the contents of the file to a temporary file and format that instead saving the actual file
2525 // This could unnecessarily trigger other behaviours
26- return document . save ( ) . then ( saved => {
27- let filePath = document . uri . fsPath ;
28- if ( ! fs . existsSync ( filePath ) ) {
29- vscode . window . showErrorMessage ( `File ${ filePath } does not exist` ) ;
26+ this . outputChannel . clear ( ) ;
27+
28+ // autopep8 and yapf have the ability to read from the process input stream and return the formatted code out of the output stream
29+ // However they don't support returning the diff of the formatted text when reading data from the input stream
30+ // Yes getting text formatted that way avoids having to create a temporary file, however the diffing will have
31+ // to be done here in node (extension), i.e. extension cpu, i.e. les responsive solution
32+ let tmpFileCreated = document . isDirty ;
33+ let filePromise = tmpFileCreated ? getTempFileWithDocumentContents ( document ) : Promise . resolve ( document . fileName ) ;
34+ return filePromise . then ( filePath => {
35+ if ( token . isCancellationRequested ) {
36+ return [ filePath , "" ] ;
37+ }
38+ return Promise . all < string > ( [ Promise . resolve ( filePath ) , sendCommand ( cmdLine + ` "${ filePath } "` , vscode . workspace . rootPath ) ] ) ;
39+ } ) . then ( data => {
40+ // Delete the temporary file created
41+ if ( tmpFileCreated ) {
42+ fs . unlink ( data [ 0 ] ) ;
43+ }
44+ if ( token . isCancellationRequested ) {
3045 return [ ] ;
3146 }
32-
33- this . outputChannel . clear ( ) ;
34- let fileDir = path . dirname ( document . uri . fsPath ) ;
35-
36- return sendCommand ( cmdLine , fileDir ) . then ( data => {
37- return getTextEdits ( document . getText ( ) , data ) ;
38- } ) . catch ( errorMsg => {
39- this . outputChannel . appendLine ( errorMsg ) ;
40- throw new Error ( `There was an error in formatting the document. View the Python output window for details.` ) ;
41- } ) ;
47+ return getTextEditsFromPatch ( document . getText ( ) , data [ 1 ] ) ;
48+ } ) . catch ( error => {
49+ this . outputChannel . appendLine ( error ) ;
50+ throw new Error ( `There was an error in formatting the document. View the Python output window for details.` ) ;
4251 } ) ;
4352 }
4453}
0 commit comments