Skip to content

Commit 83119db

Browse files
monkingxueMylesBorins
authored andcommitted
repl: add friendly tips about how to exit repl
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: #20617Fixes: #19021 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent 1ae076b commit 83119db

2 files changed

Lines changed: 38 additions & 4 deletions

File tree

‎lib/repl.js‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,15 @@ function REPLServer(prompt,
215215

216216
functiondefaultEval(code,context,file,cb){
217217
varerr,result,script,wrappedErr;
218+
varisExitCommand=false;
218219
varwrappedCmd=false;
219220
varawaitPromise=false;
220221
varinput=code;
222+
vartrimmedCommand=code.trim();
223+
224+
if(trimmedCommand==='exit'||trimmedCommand==='quit'){
225+
isExitCommand=true;
226+
}
221227

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

322+
constlocalContext=self.useGlobal ? global : self.context;
323+
if(isExitCommand&&!localContext.hasOwnProperty(trimmedCommand)){
324+
self.outputStream.write('(To exit, press ^D or type .exit)\n');
325+
returnself.displayPrompt();
326+
}
327+
316328
if(self.useGlobal){
317329
result=script.runInThisContext(scriptOptions);
318330
}else{
319-
result=script.runInContext(context,scriptOptions);
331+
result=script.runInContext(localContext,scriptOptions);
320332
}
321333
}finally{
322334
if(self.breakEvalOnSigint){
@@ -332,12 +344,10 @@ function REPLServer(prompt,
332344
}
333345
}catch(e){
334346
err=e;
335-
336347
if(err&&err.code==='ERR_SCRIPT_EXECUTION_INTERRUPTED'){
337-
// The stack trace for this case is not very useful anyway.
348+
// The stack trace for this case is not very useful anyway.
338349
Object.defineProperty(err,'stack',{value: ''});
339350
}
340-
341351
if(process.domain){
342352
debug('not recoverable, send to domain');
343353
process.domain.emit('error',err);

‎test/parallel/test-repl.js‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,29 @@ const strictModeTests = [
132132
}
133133
];
134134

135+
constfriendlyExitTests=[
136+
{
137+
send: 'exit',
138+
expect: '(To exit, press ^D or type .exit)'
139+
},
140+
{
141+
send: 'quit',
142+
expect: '(To exit, press ^D or type .exit)'
143+
},
144+
{
145+
send: 'quit = 1',
146+
expect: '1'
147+
},
148+
{
149+
send: 'quit',
150+
expect: '1'
151+
},
152+
{
153+
send: 'exit',
154+
expect: '(To exit, press ^D or type .exit)'
155+
},
156+
];
157+
135158
consterrorTests=[
136159
// Uncaught error throws and prints out
137160
{
@@ -742,6 +765,7 @@ const tcpTests = [
742765
const[socket,replServer]=awaitstartUnixRepl();
743766

744767
awaitrunReplTests(socket,prompt_unix,unixTests);
768+
awaitrunReplTests(socket,prompt_unix,friendlyExitTests);
745769
awaitrunReplTests(socket,prompt_unix,errorTests);
746770
replServer.replMode=repl.REPL_MODE_STRICT;
747771
awaitrunReplTests(socket,prompt_unix,strictModeTests);

0 commit comments

Comments
 (0)