diff --git a/lib/node_modules/@stdlib/repl/lib/commands/example.js b/lib/node_modules/@stdlib/repl/lib/commands/example.js index ee96d81c5e2e..28307dfac132 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/example.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/example.js @@ -57,6 +57,7 @@ function command( repl, cmds ) { function onCommand( alias ) { var aliases; var entry; + var lines; var out; var len; var N; @@ -133,6 +134,7 @@ function command( repl, cmds ) { } } if ( out ) { + lines = []; out = out.split( RE_EOL ); len = out.length; i = -1; @@ -149,13 +151,27 @@ function command( repl, cmds ) { * @private * @param {string} cmd - command * @param {boolean} success - boolean indicating whether the command successfully executed + * @returns {void} */ function next() { + var j; i += 1; if ( i < len ) { // Forward the next line to the REPL readline interface in order to mimic user input... if ( out[ i ] ) { - repl._rli.write( out[ i ]+'\n' ); + lines.push( out[ i ] ); + + // If line is part of a multi-line input, wait for the next line... + if ( repl._multilineHandler.isMultilineInput( lines.join( '\n' ) ) ) { + return next(); + } + for ( j = 0; j < lines.length; j++ ) { + repl._rli.write( lines[ j ] ); + repl._rli.write( '\n', { + 'name': 'return' + }); + } + lines = []; repl.once( 'drain', next ); } else { nextTick( next ); diff --git a/lib/node_modules/@stdlib/repl/lib/multiline_handler.js b/lib/node_modules/@stdlib/repl/lib/multiline_handler.js index 239496548394..d78009de4959 100644 --- a/lib/node_modules/@stdlib/repl/lib/multiline_handler.js +++ b/lib/node_modules/@stdlib/repl/lib/multiline_handler.js @@ -394,56 +394,6 @@ setNonEnumerableReadOnly( MultilineHandler.prototype, '_triggerMultiline', funct this._rli.line = this._rli.line.substring( 0, this._rli.cursor ); }); -/** -* Checks if the command is incomplete and a multi-line input. -* -* @private -* @name _isMultilineInput -* @memberof MultilineHandler.prototype -* @type {Function} -* @param {string} cmd - command -* @returns {boolean} boolean indicating whether the command is a multi-line input -*/ -setNonEnumerableReadOnly( MultilineHandler.prototype, '_isMultilineInput', function isMultilineInput( cmd ) { - var node; - var tmp; - var ast; - - debug( 'Attempting to detect multi-line input...' ); - if ( RE_WHITESPACE.test( cmd ) ) { - debug( 'Multi-line input not detected.' ); - return false; - } - if ( RE_SINGLE_LINE_COMMENT.test( cmd ) || RE_MULTI_LINE_COMMENT.test( cmd ) ) { // eslint-disable-line max-len - debug( 'Multi-line input not detected.' ); - return false; - } - // Check if the command has valid syntax... - tmp = processCommand( cmd ); - if ( !( tmp instanceof Error ) ) { - debug( 'Multi-line input not detected.' ); - return false; - } - if ( hasMultilineError( cmd, AOPTS ) ) { - debug( 'Detected multi-line input. Triggering multi-line mode...' ); - return true; - } - // Still possible that a user is attempting to enter an object literal across multiple lines... - ast = parseLoose( cmd, AOPTS ); - - // Check for a trailing node which is being interpreted as a block statement, as this could be an object literal... - node = ast.body[ ast.body.length-1 ]; - if ( node.type === 'BlockStatement' && node.end === ast.end ) { - tmp = cmd.slice( node.start, node.end ); - if ( hasMultilineError( tmp, AOPTS ) ) { - debug( 'Detected multi-line input. Triggering multi-line mode...' ); - return true; - } - } - debug( 'Multi-line input not detected.' ); - return false; -}); - /** * Resets input buffers. * @@ -581,6 +531,55 @@ setNonEnumerableReadOnly( MultilineHandler.prototype, 'isPasting', function isPa return this._multiline.pasteMode; }); +/** +* Checks if the command is incomplete and a multi-line input. +* +* @name isMultilineInput +* @memberof MultilineHandler.prototype +* @type {Function} +* @param {string} cmd - command +* @returns {boolean} boolean indicating whether the command is a multi-line input +*/ +setNonEnumerableReadOnly( MultilineHandler.prototype, 'isMultilineInput', function isMultilineInput( cmd ) { + var node; + var tmp; + var ast; + + debug( 'Attempting to detect multi-line input...' ); + if ( RE_WHITESPACE.test( cmd ) ) { + debug( 'Multi-line input not detected.' ); + return false; + } + if ( RE_SINGLE_LINE_COMMENT.test( cmd ) || RE_MULTI_LINE_COMMENT.test( cmd ) ) { // eslint-disable-line max-len + debug( 'Multi-line input not detected.' ); + return false; + } + // Check if the command has valid syntax... + tmp = processCommand( cmd ); + if ( !( tmp instanceof Error ) ) { + debug( 'Multi-line input not detected.' ); + return false; + } + if ( hasMultilineError( cmd, AOPTS ) ) { + debug( 'Detected multi-line input. Triggering multi-line mode...' ); + return true; + } + // Still possible that a user is attempting to enter an object literal across multiple lines... + ast = parseLoose( cmd, AOPTS ); + + // Check for a trailing node which is being interpreted as a block statement, as this could be an object literal... + node = ast.body[ ast.body.length-1 ]; + if ( node.type === 'BlockStatement' && node.end === ast.end ) { + tmp = cmd.slice( node.start, node.end ); + if ( hasMultilineError( tmp, AOPTS ) ) { + debug( 'Detected multi-line input. Triggering multi-line mode...' ); + return true; + } + } + debug( 'Multi-line input not detected.' ); + return false; +}); + /** * Processes input line data. * @@ -737,9 +736,10 @@ setNonEnumerableReadOnly( MultilineHandler.prototype, 'beforeKeypress', function case 'return': cmd = copy( this._cmd ); cmd[ this._lineIndex ] = this._rli.line; + this._lines[ this._lineIndex ] = this._rli.line; // If we are in paste mode or the command is incomplete, trigger multi-line mode... - if ( !this._multiline.pasteMode && !this._isMultilineInput( cmd.join( '\n' ) ) ) { + if ( !this._multiline.pasteMode && !this.isMultilineInput( cmd.join( '\n' ) ) ) { this._ttyWrite.call( this._rli, data, key ); return; }