Skip to content

Commit

Permalink
repl: add friendly tips about how to exit repl
Browse files Browse the repository at this point in the history
Imitate python repl, when the user enters 'exit' or 'quit',
no longer prompt 'Reference Error', but
prompts 'To exit, press ^D or type .exit'.
If the user defines variables named 'exit' or 'quit' ,
only the value of the variables are output

PR-URL: nodejs#20617
Fixes: nodejs#19021
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information
monkingxue authored and BridgeAR committed May 18, 2018
1 parent 9deca87 commit 9aa4ec4
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
18 changes: 14 additions & 4 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,15 @@ function REPLServer(prompt,

function defaultEval(code, context, file, cb) {
var err, result, script, wrappedErr;
var isExitCommand = false;
var wrappedCmd = false;
var awaitPromise = false;
var input = code;
var trimmedCommand = code.trim();

if (trimmedCommand === 'exit' || trimmedCommand === 'quit') {
isExitCommand = true;
}

if (/^\s*\{/.test(code) && /\}\s*$/.test(code)) {
// It's confusing for `{ a : 1 }` to be interpreted as a block
Expand Down Expand Up @@ -313,10 +319,16 @@ function REPLServer(prompt,
breakOnSigint: self.breakEvalOnSigint
};

const localContext = self.useGlobal ? global : self.context;
if (isExitCommand && !localContext.hasOwnProperty(trimmedCommand)) {
self.outputStream.write('(To exit, press ^D or type .exit)\n');
return self.displayPrompt();
}

if (self.useGlobal) {
result = script.runInThisContext(scriptOptions);
} else {
result = script.runInContext(context, scriptOptions);
result = script.runInContext(localContext, scriptOptions);
}
} finally {
if (self.breakEvalOnSigint) {
Expand All @@ -332,12 +344,10 @@ function REPLServer(prompt,
}
} catch (e) {
err = e;

if (err && err.code === 'ERR_SCRIPT_EXECUTION_INTERRUPTED') {
// The stack trace for this case is not very useful anyway.
// The stack trace for this case is not very useful anyway.
Object.defineProperty(err, 'stack', { value: '' });
}

if (process.domain) {
debug('not recoverable, send to domain');
process.domain.emit('error', err);
Expand Down
24 changes: 24 additions & 0 deletions test/parallel/test-repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,29 @@ const strictModeTests = [
}
];

const friendlyExitTests = [
{
send: 'exit',
expect: '(To exit, press ^D or type .exit)'
},
{
send: 'quit',
expect: '(To exit, press ^D or type .exit)'
},
{
send: 'quit = 1',
expect: '1'
},
{
send: 'quit',
expect: '1'
},
{
send: 'exit',
expect: '(To exit, press ^D or type .exit)'
},
];

const errorTests = [
// Uncaught error throws and prints out
{
Expand Down Expand Up @@ -742,6 +765,7 @@ const tcpTests = [
const [ socket, replServer ] = await startUnixRepl();

await runReplTests(socket, prompt_unix, unixTests);
await runReplTests(socket, prompt_unix, friendlyExitTests);
await runReplTests(socket, prompt_unix, errorTests);
replServer.replMode = repl.REPL_MODE_STRICT;
await runReplTests(socket, prompt_unix, strictModeTests);
Expand Down

0 comments on commit 9aa4ec4

Please sign in to comment.