Skip to content

Commit a0b1191

Browse files
committed
repl: add replDefaults to customize the writer
So far it was not possible to modify the inspection defaults used by the REPL from the running instance itself. This introduces a new property on `util.inspect` which is only used inside the REPL and which allows to modify the used inspection defaults at any point of time. PR-URL: #26375 Reviewed-By: James M Snell <[email protected]>
1 parent 203fa63 commit a0b1191

File tree

6 files changed

+82
-13
lines changed

6 files changed

+82
-13
lines changed

Diff for: doc/api/repl.md

+25-6
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,32 @@ function isRecoverableError(error) {
256256

257257
By default, [`repl.REPLServer`][] instances format output using the
258258
[`util.inspect()`][] method before writing the output to the provided `Writable`
259-
stream (`process.stdout` by default). The `useColors` boolean option can be
260-
specified at construction to instruct the default writer to use ANSI style
261-
codes to colorize the output from the `util.inspect()` method.
259+
stream (`process.stdout` by default). The `showProxy` inspection option is set
260+
to true by default and the `colors` option is set to true depending on the
261+
REPL's `useColors` option.
262262

263-
It is possible to fully customize the output of a [`repl.REPLServer`][] instance
264-
by passing a new function in using the `writer` option on construction. The
265-
following example, for instance, simply converts any input text to upper case:
263+
The `useColors` boolean option can be specified at construction to instruct the
264+
default writer to use ANSI style codes to colorize the output from the
265+
`util.inspect()` method.
266+
267+
If the REPL is run as standalone program, it is also possible to change the
268+
REPL's [inspection defaults][`util.inspect()`] from inside the REPL by using the
269+
`inspect.replDefaults` property which mirrors the `defaultOptions` from
270+
[`util.inspect()`][].
271+
272+
```console
273+
> util.inspect.replDefaults.compact = false;
274+
false
275+
> [1]
276+
[
277+
1
278+
]
279+
>
280+
```
281+
282+
To fully customize the output of a [`repl.REPLServer`][] instance pass in a new
283+
function for the `writer` option on construction. The following example, for
284+
instance, simply converts any input text to upper case:
266285

267286
```js
268287
const repl = require('repl');

Diff for: lib/internal/repl.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const REPL = require('repl');
4+
const { kStandaloneREPL } = require('internal/repl/utils');
45

56
module.exports = Object.create(REPL);
67
module.exports.createInternalRepl = createRepl;
@@ -11,6 +12,7 @@ function createRepl(env, opts, cb) {
1112
opts = null;
1213
}
1314
opts = {
15+
[kStandaloneREPL]: true,
1416
ignoreUndefined: false,
1517
terminal: process.stdout.isTTY,
1618
useGlobal: true,

Diff for: lib/internal/repl/recoverable.js renamed to lib/internal/repl/utils.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ function isRecoverableError(e, code) {
7070
}
7171

7272
module.exports = {
73-
isRecoverableError
73+
isRecoverableError,
74+
kStandaloneREPL: Symbol('kStandaloneREPL')
7475
};

Diff for: lib/repl.js

+23-5
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ const { sendInspectorCommand } = require('internal/util/inspector');
7373
const experimentalREPLAwait = require('internal/options').getOptionValue(
7474
'--experimental-repl-await'
7575
);
76-
const { isRecoverableError } = require('internal/repl/recoverable');
76+
const {
77+
isRecoverableError,
78+
kStandaloneREPL
79+
} = require('internal/repl/utils');
7780
const {
7881
getOwnNonIndexProperties,
7982
propertyFilter: {
@@ -499,10 +502,25 @@ function REPLServer(prompt,
499502
}
500503
self.useColors = !!options.useColors;
501504

502-
if (self.useColors && self.writer === writer) {
503-
// Turn on ANSI coloring.
504-
self.writer = (obj) => util.inspect(obj, self.writer.options);
505-
self.writer.options = { ...writer.options, colors: true };
505+
if (self.writer === writer) {
506+
// Conditionally turn on ANSI coloring.
507+
writer.options.colors = self.useColors;
508+
509+
if (options[kStandaloneREPL]) {
510+
Object.defineProperty(util.inspect, 'replDefaults', {
511+
get() {
512+
return writer.options;
513+
},
514+
set(options) {
515+
if (options === null || typeof options !== 'object') {
516+
throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
517+
}
518+
return Object.assign(writer.options, options);
519+
},
520+
enumerable: true,
521+
configurable: true
522+
});
523+
}
506524
}
507525

508526
function filterInternalStackFrames(structuredStack) {

Diff for: node.gyp

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
'lib/internal/repl.js',
175175
'lib/internal/repl/await.js',
176176
'lib/internal/repl/history.js',
177-
'lib/internal/repl/recoverable.js',
177+
'lib/internal/repl/utils.js',
178178
'lib/internal/socket_list.js',
179179
'lib/internal/test/binding.js',
180180
'lib/internal/test/heap.js',

Diff for: test/parallel/test-repl-inspect-defaults.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const cp = require('child_process');
5+
const child = cp.spawn(process.execPath, ['-i']);
6+
let output = '';
7+
8+
child.stdout.setEncoding('utf8');
9+
child.stdout.on('data', (data) => {
10+
output += data;
11+
});
12+
13+
child.on('exit', common.mustCall(() => {
14+
const results = output.replace(/^> /mg, '').split('\n');
15+
assert.deepStrictEqual(
16+
results,
17+
[
18+
'[ 42, 23 ]',
19+
'1',
20+
'[ 42, ... 1 more item ]',
21+
''
22+
]
23+
);
24+
}));
25+
26+
child.stdin.write('[ 42, 23 ]\n');
27+
child.stdin.write('util.inspect.replDefaults.maxArrayLength = 1\n');
28+
child.stdin.write('[ 42, 23 ]\n');
29+
child.stdin.end();

0 commit comments

Comments
 (0)