File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -90,7 +90,7 @@ export class TerminalService implements ITerminalService, Disposable {
9090 ) : Promise < TerminalShellExecution | undefined > {
9191 if ( isPythonShell ) {
9292 if ( this . isReplReady ) {
93- this . terminal ?. sendText ( commandLine ) ;
93+ this . sendPythonShellCommand ( commandLine ) ;
9494 traceVerbose ( `Python REPL sendText: ${ commandLine } ` ) ;
9595 } else {
9696 // Queue command to run once REPL is ready.
@@ -156,11 +156,21 @@ export class TerminalService implements ITerminalService, Disposable {
156156 const commandLine = this . pythonReplCommandQueue . shift ( ) ;
157157 if ( commandLine ) {
158158 traceVerbose ( `Executing queued REPL command: ${ commandLine } ` ) ;
159- this . terminal ?. sendText ( commandLine ) ;
159+ this . sendPythonShellCommand ( commandLine ) ;
160160 }
161161 }
162162 }
163163
164+ // PyREPL requires Enter to arrive after the bracketed-paste sequence has been fully processed.
165+ private sendPythonShellCommand ( commandLine : string ) : void {
166+ if ( commandLine . startsWith ( '\u001b[200~' ) && commandLine . endsWith ( '\u001b[201~' ) ) {
167+ this . terminal ?. sendText ( commandLine , false ) ;
168+ this . terminal ?. sendText ( '' , true ) ;
169+ } else {
170+ this . terminal ?. sendText ( commandLine ) ;
171+ }
172+ }
173+
164174 private async executeCommandInternal ( commandLine : string ) : Promise < TerminalShellExecution | undefined > {
165175 const terminal = this . terminal ;
166176 if ( ! terminal ) {
Original file line number Diff line number Diff line change @@ -338,6 +338,27 @@ suite('Terminal Service', () => {
338338 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . once ( ) ) ;
339339 } ) ;
340340
341+ test ( 'Ensure bracketed paste and Enter are sent separately to the Python shell' , async ( ) => {
342+ terminalHelper
343+ . setup ( ( helper ) => helper . getEnvironmentActivationCommands ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
344+ . returns ( ( ) => Promise . resolve ( undefined ) ) ;
345+ service = new TerminalService ( mockServiceContainer . object ) ;
346+ const textToSend = '\u001b[200~print("hello")\u001b[201~' ;
347+ terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
348+ terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
349+
350+ await service . ensureTerminal ( ) ;
351+ const executePromise = service . executeCommand ( textToSend , true ) ;
352+ onDidWriteTerminalDataEmitter . fire ( { terminal : terminal . object , data : '>>> ' } ) ;
353+ await executePromise ;
354+
355+ terminal . verify (
356+ ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) , TypeMoq . It . isValue ( false ) ) ,
357+ TypeMoq . Times . once ( ) ,
358+ ) ;
359+ terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( '' ) , TypeMoq . It . isValue ( true ) ) , TypeMoq . Times . once ( ) ) ;
360+ } ) ;
361+
341362 test ( 'Ensure sendText IS called even when Python shell integration and terminal shell integration are both enabled - Window' , async ( ) => {
342363 isWindowsStub . returns ( true ) ;
343364 pythonConfig
You can’t perform that action at this time.
0 commit comments