Skip to content

Commit 82f8821

Browse files
BridgeARdanbev
authored andcommitted
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: nodejs#26375 Reviewed-By: James M Snell <[email protected]>
1 parent 6de8801 commit 82f8821

File tree

6 files changed

+82
-13
lines changed

6 files changed

+82
-13
lines changed

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');

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,

lib/internal/repl/recoverable.js 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
};

lib/repl.js

+23-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ const { sendInspectorCommand } = require('internal/util/inspector');
7272
const experimentalREPLAwait = require('internal/options').getOptionValue(
7373
'--experimental-repl-await'
7474
);
75-
const { isRecoverableError } = require('internal/repl/recoverable');
75+
const {
76+
isRecoverableError,
77+
kStandaloneREPL
78+
} = require('internal/repl/utils');
7679
const {
7780
getOwnNonIndexProperties,
7881
propertyFilter: {
@@ -505,10 +508,25 @@ function REPLServer(prompt,
505508
}
506509
self.useColors = !!options.useColors;
507510

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

514532
function filterInternalStackFrames(structuredStack) {

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',
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)