Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
util: add compact depth mode
This overloads the `compact` option from `util.inspect()`. If it's
set to a number, it is going to align all most inner entries on the
same lign if they adhere to the following:

* The entries do not exceed the `breakLength` options value.
* The entry is one of the local most inner levels up the the one
  provided in `compact`.
  • Loading branch information
BridgeAR committed Feb 28, 2019
commit fd1ac3d11216057ebfde850c71efaf82a93c4d4c
15 changes: 10 additions & 5 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ stream.write('With ES6');
<!-- YAML
added: v0.3.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/26269
description: The `compact` option accepts numbers for a new output mode.
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/24971
description: Internal properties no longer appear in the context argument
Expand Down Expand Up @@ -461,11 +464,13 @@ changes:
* `breakLength` {integer} The length at which an object's keys are split
across multiple lines. Set to `Infinity` to format an object as a single
line. **Default:** `60` for legacy compatibility.
* `compact` {boolean} Setting this to `false` causes each object key to
be displayed on a new line. It will also add new lines to text that is
longer than `breakLength`. Note that no text will be reduced below 16
characters, no matter the `breakLength` size. For more information, see the
example below. **Default:** `true`.
* `compact` {boolean|integer} Setting this to `false` causes each object key
to be displayed on a new line. It will also add new lines to text that is
longer than `breakLength`. If set to a number, the most `n` inner elements
are united on a single line as long as all properties fit into
`breakLength`. Note that no text will be reduced below 16 characters, no
matter the `breakLength` size. For more information, see the example below.
**Default:** `true`.
* `sorted` {boolean|Function} If set to `true` or a function, all properties
of an object, and `Set` and `Map` entries are sorted in the resulting
string. If set to `true` the [default sort][] is used. If set to a function,
Expand Down
34 changes: 25 additions & 9 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ function inspect(value, opts) {
budget: {},
indentationLvl: 0,
seen: [],
currentDepth: 0,
stylize: stylizeNoColor,
showHidden: inspectDefaultOptions.showHidden,
depth: inspectDefaultOptions.depth,
Expand Down Expand Up @@ -769,6 +770,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
recurseTimes += 1;

ctx.seen.push(value);
ctx.currentDepth = recurseTimes;
let output;
const indentationLvl = ctx.indentationLvl;
try {
Expand All @@ -792,7 +794,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
}
}

const res = reduceToSingleString(ctx, output, base, braces);
const combine = typeof ctx.compact === 'number' &&
ctx.currentDepth - recurseTimes < ctx.compact;

const res = reduceToSingleString(ctx, output, base, braces, combine);
const budget = ctx.budget[ctx.indentationLvl] || 0;
const newLength = budget + res.length;
ctx.budget[ctx.indentationLvl] = newLength;
Expand Down Expand Up @@ -833,7 +838,7 @@ function formatBigInt(fn, value) {

function formatPrimitive(fn, value, ctx) {
if (typeof value === 'string') {
if (ctx.compact === false &&
if (ctx.compact !== true &&
ctx.indentationLvl + value.length > ctx.breakLength &&
value.length > kMinLineLength) {
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl;
Expand Down Expand Up @@ -1143,7 +1148,7 @@ function formatProperty(ctx, value, recurseTimes, key, type) {
const desc = Object.getOwnPropertyDescriptor(value, key) ||
{ value: value[key], enumerable: true };
if (desc.value !== undefined) {
const diff = (type !== kObjectType || ctx.compact === false) ? 2 : 3;
const diff = (type !== kObjectType || ctx.compact !== true) ? 2 : 3;
ctx.indentationLvl += diff;
str = formatValue(ctx, desc.value, recurseTimes);
if (diff === 3) {
Expand Down Expand Up @@ -1200,16 +1205,27 @@ function formatProperty(ctx, value, recurseTimes, key, type) {
return `${name}:${extra}${str}`;
}

function reduceToSingleString(ctx, output, base, braces) {
function reduceToSingleString(ctx, output, base, braces, combine = false) {
const breakLength = ctx.breakLength;
let i = 0;
if (ctx.compact === false) {
const indentation = ' '.repeat(ctx.indentationLvl);
let res = `${base ? `${base} ` : ''}${braces[0]}\n${indentation} `;
if (ctx.compact !== true) {
if (combine) {
const totalLength = output.reduce((sum, cur) => sum + cur.length, 0);
if (totalLength + output.length * 2 < breakLength) {
let res = `${base ? `${base} ` : ''}${braces[0]} `;
for (; i < output.length - 1; i++) {
res += `${output[i]}, `;
}
res += `${output[i]} ${braces[1]}`;
return res;
}
}
const indentation = `\n${' '.repeat(ctx.indentationLvl)}`;
let res = `${base ? `${base} ` : ''}${braces[0]}${indentation} `;
for (; i < output.length - 1; i++) {
res += `${output[i]},\n${indentation} `;
res += `${output[i]},${indentation} `;
}
res += `${output[i]}\n${indentation}${braces[1]}`;
res += `${output[i]}${indentation}${braces[1]}`;
return res;
}
if (output.length * 2 <= breakLength) {
Expand Down
36 changes: 36 additions & 0 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,42 @@ util.inspect(process);

assert.strict.equal(out, expected);

out = util.inspect(map, { compact: 2, showHidden: true, depth: 9 });

expected = [
'Map {',
' Promise {',
' [',
' [',
' 1,',
' Set { [ 1, 2, [length]: 2 ], [size]: 1 },',
' [length]: 2',
' ],',
' [length]: 1',
' ]',
' } => Uint8Array [',
' [BYTES_PER_ELEMENT]: 1,',
' [length]: 0,',
' [byteLength]: 0,',
' [byteOffset]: 0,',
' [buffer]: ArrayBuffer { byteLength: 0, foo: true }',
' ],',
' [Set Iterator] { [ 1, 2, [length]: 2 ] } => [Map Iterator] {',
' Uint8Array [',
' [BYTES_PER_ELEMENT]: 1,',
' [length]: 0,',
' [byteLength]: 0,',
' [byteOffset]: 0,',
' [buffer]: ArrayBuffer { byteLength: 0, foo: true }',
' ],',
' [Circular]',
' },',
' [size]: 2',
'}'
].join('\n');

assert.strict.equal(out, expected);

out = util.inspect(map, { showHidden: true, depth: 9, breakLength: 4 });
expected = [
'Map {',
Expand Down