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`. PR-URL: https://github.com/nodejs/node/pull/26269 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
f4257a2af1
commit
4db10ed9ad
@ -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
|
||||
@ -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,
|
||||
|
@ -164,6 +164,7 @@ function inspect(value, opts) {
|
||||
budget: {},
|
||||
indentationLvl: 0,
|
||||
seen: [],
|
||||
currentDepth: 0,
|
||||
stylize: stylizeNoColor,
|
||||
showHidden: inspectDefaultOptions.showHidden,
|
||||
depth: inspectDefaultOptions.depth,
|
||||
@ -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 {
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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) {
|
||||
@ -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} `;
|
||||
for (; i < output.length - 1; i++) {
|
||||
res += `${output[i]},\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;
|
||||
}
|
||||
}
|
||||
res += `${output[i]}\n${indentation}${braces[1]}`;
|
||||
const indentation = `\n${' '.repeat(ctx.indentationLvl)}`;
|
||||
let res = `${base ? `${base} ` : ''}${braces[0]}${indentation} `;
|
||||
for (; i < output.length - 1; i++) {
|
||||
res += `${output[i]},${indentation} `;
|
||||
}
|
||||
res += `${output[i]}${indentation}${braces[1]}`;
|
||||
return res;
|
||||
}
|
||||
if (output.length * 2 <= breakLength) {
|
||||
|
@ -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 {',
|
||||
|
Loading…
x
Reference in New Issue
Block a user