22// Licensed under the MIT License.
33
44import { inject , injectable } from 'inversify' ;
5- import { EOL } from 'os' ;
65import { Range , TextEditor , Uri } from 'vscode' ;
76import { IApplicationShell , IDocumentManager } from '../../common/application/types' ;
87import { PythonLanguage } from '../../common/constants' ;
98import '../../common/extensions' ;
9+ import { IServiceContainer } from '../../ioc/types' ;
1010import { ICodeExecutionHelper } from '../types' ;
1111
1212@injectable ( )
1313export class CodeExecutionHelper implements ICodeExecutionHelper {
14- constructor ( @inject ( IDocumentManager ) private documentManager : IDocumentManager ,
15- @inject ( IApplicationShell ) private applicationShell : IApplicationShell ) {
16-
14+ private readonly documentManager : IDocumentManager ;
15+ private readonly applicationShell : IApplicationShell ;
16+ constructor ( @inject ( IServiceContainer ) serviceContainer : IServiceContainer ) {
17+ this . documentManager = serviceContainer . get < IDocumentManager > ( IDocumentManager ) ;
18+ this . applicationShell = serviceContainer . get < IApplicationShell > ( IApplicationShell ) ;
1719 }
18- public normalizeLines ( code : string ) : string {
19- const codeLines = code . splitLines ( { trim : false , removeEmptyEntries : false } ) ;
20- const codeLinesWithoutEmptyLines = codeLines . filter ( line => line . trim ( ) . length > 0 ) ;
21- return codeLinesWithoutEmptyLines . join ( EOL ) ;
20+ public async normalizeLines ( code : string , resource ?: Uri ) : Promise < string > {
21+ try {
22+ if ( code . trim ( ) . length === 0 ) {
23+ return '' ;
24+ }
25+ const regex = / ( \n ) ( [ \t ] * \r ? \n ) ( [ \t ] + \S + ) / gm;
26+ return code . replace ( regex , ( _ , a , b , c ) => {
27+ return `${ a } ${ c } ` ;
28+ } ) ;
29+ } catch ( ex ) {
30+ console . error ( ex , 'Python: Failed to normalize code for execution in terminal' ) ;
31+ return code ;
32+ }
2233 }
2334
2435 public async getFileToExecute ( ) : Promise < Uri | undefined > {
@@ -35,6 +46,9 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
3546 this . applicationShell . showErrorMessage ( 'The active file is not a Python source file' ) ;
3647 return ;
3748 }
49+ if ( activeEditor . document . isDirty ) {
50+ await activeEditor . document . save ( ) ;
51+ }
3852 return activeEditor . document . uri ;
3953 }
4054
@@ -53,4 +67,10 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
5367 }
5468 return code ;
5569 }
70+ public async saveFileIfDirty ( file : Uri ) : Promise < void > {
71+ const docs = this . documentManager . textDocuments . filter ( d => d . uri . path === file . path ) ;
72+ if ( docs . length === 1 && docs [ 0 ] . isDirty ) {
73+ await docs [ 0 ] . save ( ) ;
74+ }
75+ }
5676}
0 commit comments