diff --git a/lib/internal/repl/utils.js b/lib/internal/repl/utils.js index 49a40e3030a3e2..476760a08d5934 100644 --- a/lib/internal/repl/utils.js +++ b/lib/internal/repl/utils.js @@ -136,6 +136,8 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { let previewCompletionCounter = 0; let completionPreview = null; + let wrapped = false; + function getPreviewPos() { const displayPos = repl._getDisplayPos(`${repl._prompt}${repl.line}`); const cursorPos = repl.line.length !== repl.cursor ? @@ -244,8 +246,9 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { function getInputPreview(input, callback) { // For similar reasons as `defaultEval`, wrap expressions starting with a // curly brace with parenthesis. - if (input.startsWith('{') && !input.endsWith(';')) { + if (input.startsWith('{') && !input.endsWith(';') && !wrapped) { input = `(${input})`; + wrapped = true; } sendInspectorCommand((session) => { session.post('Runtime.evaluate', { @@ -329,13 +332,19 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { return; } - getInputPreview(line, (error, inspected) => { + const inputPreviewCallback = (error, inspected) => { + if (inspected === null) { + return; + } + + wrapped = false; + // Ignore the output if the value is identical to the current line and the // former preview is not identical to this preview. - if ((line === inspected && lastInputPreview !== inspected) || - inspected === null) { + if (line === inspected && lastInputPreview !== inspected) { return; } + if (error) { debug('Error while generating preview', error); return; @@ -386,7 +395,13 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) { repl.output.write(`\n${result}`); cursorTo(repl.output, cursorPos.cols); moveCursor(repl.output, 0, -rows - 1); - }); + }; + + getInputPreview(line, inputPreviewCallback); + if (wrapped) { + getInputPreview(line, inputPreviewCallback); + } + wrapped = false; }; // -------------------------------------------------------------------------// diff --git a/test/parallel/test-repl-preview.js b/test/parallel/test-repl-preview.js index b36b99cca7c40e..185052b9b7ce45 100644 --- a/test/parallel/test-repl-preview.js +++ b/test/parallel/test-repl-preview.js @@ -125,7 +125,13 @@ async function tests(options) { '\x1B[90m{ a: true }\x1B[39m\x1B[20G\x1B[1A\x1B[1B\x1B[2K\x1B[1A;', '\x1B[90mtrue\x1B[39m\x1B[21G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r', '\x1B[33mtrue\x1B[39m', - '\x1B[1G\x1B[0Jrepl > \x1B[8G'] + '\x1B[1G\x1B[0Jrepl > \x1B[8G'], + ['{};1', [2, 4], '\x1B[33m1\x1B[39m', + '{};1', + '\x1B[90m1\x1B[39m\x1B[12G\x1B[1A\x1B[1B\x1B[2K\x1B[1A\r', + '\x1B[33m1\x1B[39m', + '\x1B[1G\x1B[0Jrepl > \x1B[8G' + ] ]; const hasPreview = repl.terminal && diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index b8498db4b9041a..bbd410cadcee2d 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -457,6 +457,28 @@ const errorTests = [ /'thefourtheye'/ ] }, + // Check for wrapped objects. + { + send: '{ a: 1 }.a', // ({ a: 1 }.a); + expect: '1' + }, + { + send: '{ a: 1 }.a;', // { a: 1 }.a; + expect: [ + kSource, + kArrow, + '', + /^Uncaught SyntaxError: / + ] + }, + { + send: '{ a: 1 }["a"] === 1', // ({ a: 1 }['a'] === 1); + expect: 'true' + }, + { + send: '{ a: 1 }["a"] === 1;', // { a: 1 }; ['a'] === 1; + expect: 'false' + }, // Empty lines in the REPL should be allowed { send: '\n\r\n\r\n',