Skip to content

Commit 48414f0

Browse files
committed
repl: REPL enhancements
* Welcome message with version and help guide * `displayWelcomeMessage` flag is used to turn on/off * Differentiate execute & continue actions * ^M or enter key to execute the command * ^J to continue building multiline expression. * `executeOnTimeout` value is used to determine the end of expression when `terminal` is false. * Pretty stack trace. * REPL specific stack frames are removed before emitting to output stream. * Recoverable errors. * No more recoverable errors & no false positives. * Defined commands(like .exit, .load) are meaningful only at the top level. * Remove `.break` command. Welcome message template ------------------------ ```js $ node Welcome to Node.js <<version>> (<<vm name>> VM, <<vm version>>) Type ^M or enter to execute, ^J to continue, ^C to exit Or try ``` Pretty stack trace ------------------ ```js $ node -i > throw new Error('tiny stack') Error: tiny stack at repl:1:7 > var x y; var x y; ^ SyntaxError: Unexpected identifier > ```
1 parent 2d039ff commit 48414f0

32 files changed

+839
-671
lines changed

doc/api/repl.md

+22-38
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@ customizable evaluation functions.
2727

2828
The following special commands are supported by all REPL instances:
2929

30-
* `.break` - When in the process of inputting a multi-line expression, entering
31-
the `.break` command (or pressing the `<ctrl>-C` key combination) will abort
32-
further input or processing of that expression.
33-
* `.clear` - Resets the REPL `context` to an empty object and clears any
34-
multi-line expression currently being input.
30+
* `.clear` - Resets the local REPL `context` to an empty object.
3531
* `.exit` - Close the I/O stream, causing the REPL to exit.
3632
* `.help` - Show this list of special commands.
3733
* `.save` - Save the current REPL session to a file:
@@ -56,7 +52,7 @@ welcome('Node.js User');
5652

5753
The following key combinations in the REPL have these special effects:
5854

59-
* `<ctrl>-C` - When pressed once, has the same effect as the `.break` command.
55+
* `<ctrl>-C` - When pressed once, it will break the current command.
6056
When pressed twice on a blank line, has the same effect as the `.exit`
6157
command.
6258
* `<ctrl>-D` - Has the same effect as the `.exit` command.
@@ -178,34 +174,6 @@ function myEval(cmd, context, filename, callback) {
178174
repl.start({prompt: '> ', eval: myEval});
179175
```
180176

181-
#### Recoverable Errors
182-
183-
As a user is typing input into the REPL prompt, pressing the `<enter>` key will
184-
send the current line of input to the `eval` function. In order to support
185-
multi-line input, the eval function can return an instance of `repl.Recoverable`
186-
to the provided callback function:
187-
188-
```js
189-
function myEval(cmd, context, filename, callback) {
190-
let result;
191-
try {
192-
result = vm.runInThisContext(cmd);
193-
} catch (e) {
194-
if (isRecoverableError(e)) {
195-
return callback(new repl.Recoverable(e));
196-
}
197-
}
198-
callback(null, result);
199-
}
200-
201-
function isRecoverableError(error) {
202-
if (error.name === 'SyntaxError') {
203-
return /^(Unexpected end of input|Unexpected token)/.test(error.message);
204-
}
205-
return false;
206-
}
207-
```
208-
209177
### Customizing REPL Output
210178

211179
By default, `repl.REPLServer` instances format output using the
@@ -420,6 +388,18 @@ changes:
420388
* `breakEvalOnSigint` - Stop evaluating the current piece of code when
421389
`SIGINT` is received, i.e. `Ctrl+C` is pressed. This cannot be used together
422390
with a custom `eval` function. Defaults to `false`.
391+
* `executeOnTimeout` {number} If `terminal` is false,`executeOnTimeout`
392+
delay is used to determine the end of expression. Defaults to 50ms.
393+
`executeOnTimeout` will be coerced to `[100, 2000]` range.
394+
* `displayWelcomeMessage` {boolean} If `true`, welcome message will be
395+
displayed. Defaults to `false`.
396+
```js
397+
> node
398+
Welcome to Node.js <<version>> (<<vm name>> VM, <<vm version>>)
399+
Type ^M or enter to execute, ^J to continue, ^C to exit
400+
Or try .help for help, more at https://nodejs.org/dist/<<version>>/docs/api/repl.html
401+
>
402+
```
423403

424404
The `repl.start()` method creates and starts a `repl.REPLServer` instance.
425405

@@ -440,11 +420,15 @@ without passing any arguments (or by passing the `-i` argument):
440420

441421
```js
442422
$ node
443-
> const a = [1, 2, 3];
423+
Welcome to Node.js v6.5.0 (v8 VM, 5.1.281.81)
424+
Type ^M or enter to execute, ^J to continue, ^C to exit
425+
Or try .help for help, more at https://nodejs.org/dist/v6.5.0/docs/api/repl.html
426+
427+
> a = [1, 2, 3]; // ^M or ⏎
444428
[ 1, 2, 3 ]
445-
> a.forEach((v) => {
446-
... console.log(v);
447-
... });
429+
> a.forEach((v) => { // ^J to continue
430+
console.log(v);
431+
});
448432
1
449433
2
450434
3

lib/_debugger.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,8 @@ function Interface(stdin, stdout, args) {
765765
output: this.stdout,
766766
eval: (code, ctx, file, cb) => this.controlEval(code, ctx, file, cb),
767767
useGlobal: false,
768-
ignoreUndefined: true
768+
ignoreUndefined: true,
769+
displayWelcomeMessage: false,
769770
};
770771
if (parseInt(process.env['NODE_NO_READLINE'], 10)) {
771772
opts.terminal = false;

lib/internal/repl.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ function createRepl(env, opts, cb) {
2424
ignoreUndefined: false,
2525
terminal: process.stdout.isTTY,
2626
useGlobal: true,
27-
breakEvalOnSigint: true
27+
breakEvalOnSigint: true,
28+
displayWelcomeMessage: process.execArgv.indexOf('-i') === -1,
2829
}, opts);
2930

3031
if (parseInt(env.NODE_NO_READLINE)) {

lib/readline.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ function emitKeypressEvents(stream, iface) {
989989
clearTimeout(timeoutId);
990990

991991
if (iface) {
992-
iface._sawKeyPress = r.length === 1;
992+
iface._sawKeyPress = r.length === 1 || (r[0] === '\x1b');
993993
}
994994

995995
for (var i = 0; i < r.length; i++) {

0 commit comments

Comments
 (0)