@@ -5,7 +5,7 @@ import type { ReadLineOptions } from 'readline';
55import type { ReplOptions , REPLServer } from 'repl' ;
66import type { start as originalStart } from 'repl' ;
77import { promisify } from 'util' ;
8- import type { KeypressKey } from './repl-paste-support' ;
8+ import { prototypeChain , type KeypressKey } from './repl-paste-support' ;
99
1010// Utility, inverse of Readonly<T>
1111type Mutable < T > = {
@@ -407,3 +407,39 @@ function wrapPauseInput<Args extends any[], Ret>(
407407 }
408408 } ;
409409}
410+
411+ // Not related to paste support, but rather for integrating with the MongoshNodeRepl's
412+ // line-by-line input handling. Calling this methods adds hooks to `repl` that are called
413+ // when the REPL is ready to evaluate further input. Eventually, like the other code
414+ // in this file, we should upstream this into Node.js core and/or evaluate the need for
415+ // it entirely.
416+ export function addReplEventForEvalReady (
417+ repl : REPLServer ,
418+ before : ( ) => boolean ,
419+ after : ( ) => void
420+ ) : void {
421+ const wrapMethodWithLineByLineInputNextLine = (
422+ repl : REPLServer ,
423+ key : keyof REPLServer
424+ ) => {
425+ if ( ! repl [ key ] ) return ;
426+ const originalMethod = repl [ key ] . bind ( repl ) ;
427+ ( repl as any ) [ key ] = ( ...args : any [ ] ) => {
428+ if ( ! before ( ) ) {
429+ return ;
430+ }
431+ const result = originalMethod ( ...args ) ;
432+ after ( ) ;
433+ return result ;
434+ } ;
435+ } ;
436+ // https://github.com/nodejs/node/blob/88f4cef8b96b2bb9d4a92f6848ce4d63a82879a8/lib/internal/readline/interface.js#L954
437+ // added in https://github.com/nodejs/node/commit/96be7836d794509dd455e66d91c2975419feed64
438+ // handles newlines inside multi-line input and replaces `.displayPrompt()` which was
439+ // previously used to print the prompt for multi-line input.
440+ const addNewLineOnTTYKey = [ ...prototypeChain ( repl ) ]
441+ . flatMap ( ( proto ) => Object . getOwnPropertySymbols ( proto ) )
442+ . find ( ( s ) => String ( s ) . includes ( '(_addNewLineOnTTY)' ) ) as keyof REPLServer ;
443+ wrapMethodWithLineByLineInputNextLine ( repl , 'displayPrompt' ) ;
444+ wrapMethodWithLineByLineInputNextLine ( repl , addNewLineOnTTYKey ) ;
445+ }
0 commit comments