22// Licensed under the MIT License.
33
44import { inject , injectable } from 'inversify' ;
5- import { CancellationToken , Disposable , Event , EventEmitter , Terminal , TerminalShellExecution } from 'vscode' ;
5+ import { CancellationToken , Disposable , Event , EventEmitter , Terminal , window } from 'vscode' ;
66import '../../common/extensions' ;
77import { IInterpreterService } from '../../interpreter/contracts' ;
88import { IServiceContainer } from '../../ioc/types' ;
99import { captureTelemetry } from '../../telemetry' ;
1010import { EventName } from '../../telemetry/constants' ;
11- import { ITerminalAutoActivation } from '../../terminals/types' ;
11+ import { ICodeExecutionService , ITerminalAutoActivation } from '../../terminals/types' ;
1212import { ITerminalManager } from '../application/types' ;
1313import { _SCRIPTS_DIR } from '../process/internal/scripts/constants' ;
1414import { IConfigurationService , IDisposableRegistry } from '../types' ;
1515import {
16+ IExecuteCommandResult ,
1617 ITerminalActivator ,
1718 ITerminalHelper ,
1819 ITerminalService ,
@@ -57,14 +58,18 @@ export class TerminalService implements ITerminalService, Disposable {
5758 } ) ;
5859 }
5960 }
60- public async sendCommand ( command : string , args : string [ ] , _ ?: CancellationToken ) : Promise < void > {
61+ public async sendCommand (
62+ command : string ,
63+ args : string [ ] ,
64+ _ ?: CancellationToken ,
65+ ) : Promise < IExecuteCommandResult | undefined > {
6166 await this . ensureTerminal ( ) ;
6267 const text = this . terminalHelper . buildCommandForTerminal ( this . terminalShellType , command , args ) ;
6368 if ( ! this . options ?. hideFromUser ) {
6469 this . terminal ! . show ( true ) ;
6570 }
6671
67- await this . executeCommand ( text ) ;
72+ return this . executeCommand ( text ) ;
6873 }
6974 /** @deprecated */
7075 public async sendText ( text : string ) : Promise < void > {
@@ -74,7 +79,7 @@ export class TerminalService implements ITerminalService, Disposable {
7479 }
7580 this . terminal ! . sendText ( text ) ;
7681 }
77- public async executeCommand ( commandLine : string ) : Promise < TerminalShellExecution | undefined > {
82+ public async executeCommand ( commandLine : string ) : Promise < IExecuteCommandResult | undefined > {
7883 const terminal = this . terminal ! ;
7984 if ( ! this . options ?. hideFromUser ) {
8085 terminal . show ( true ) ;
@@ -97,11 +102,26 @@ export class TerminalService implements ITerminalService, Disposable {
97102 } ) ;
98103 await promise ;
99104 }
100-
105+ // python in a shell , exit code is undefined . startCommand event happen, we call end command event
101106 if ( terminal . shellIntegration ) {
107+ // TODO: Await the python REPL execute promise here. So we know python repl launched for sure before executing other python code.
108+ // So we would not be interrupted.
109+
110+ await this . serviceContainer . get < ICodeExecutionService > ( ICodeExecutionService ) . replActive ;
111+
102112 const execution = terminal . shellIntegration . executeCommand ( commandLine ) ;
103113 traceVerbose ( `Shell Integration is enabled, executeCommand: ${ commandLine } ` ) ;
104- return execution ;
114+ return {
115+ execution,
116+ exitCode : new Promise ( ( resolve ) => {
117+ const disposable = window . onDidEndTerminalShellExecution ( ( event ) => {
118+ if ( event . execution === execution ) {
119+ disposable . dispose ( ) ;
120+ resolve ( event . exitCode ) ;
121+ }
122+ } ) ;
123+ } ) ,
124+ } ;
105125 } else {
106126 terminal . sendText ( commandLine ) ;
107127 traceVerbose ( `Shell Integration is disabled, sendText: ${ commandLine } ` ) ;
0 commit comments