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
|
<!-- YAML
|
||||||
added: v0.3.0
|
added: v0.3.0
|
||||||
changes:
|
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
|
- version: REPLACEME
|
||||||
pr-url: https://github.com/nodejs/node/pull/24971
|
pr-url: https://github.com/nodejs/node/pull/24971
|
||||||
description: Internal properties no longer appear in the context argument
|
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
|
* `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
|
across multiple lines. Set to `Infinity` to format an object as a single
|
||||||
line. **Default:** `60` for legacy compatibility.
|
line. **Default:** `60` for legacy compatibility.
|
||||||
* `compact` {boolean} Setting this to `false` causes each object key to
|
* `compact` {boolean|integer} Setting this to `false` causes each object key
|
||||||
be displayed on a new line. It will also add new lines to text that is
|
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
|
longer than `breakLength`. If set to a number, the most `n` inner elements
|
||||||
characters, no matter the `breakLength` size. For more information, see the
|
are united on a single line as long as all properties fit into
|
||||||
example below. **Default:** `true`.
|
`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
|
* `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
|
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,
|
string. If set to `true` the [default sort][] is used. If set to a function,
|
||||||
|
@ -164,6 +164,7 @@ function inspect(value, opts) {
|
|||||||
budget: {},
|
budget: {},
|
||||||
indentationLvl: 0,
|
indentationLvl: 0,
|
||||||
seen: [],
|
seen: [],
|
||||||
|
currentDepth: 0,
|
||||||
stylize: stylizeNoColor,
|
stylize: stylizeNoColor,
|
||||||
showHidden: inspectDefaultOptions.showHidden,
|
showHidden: inspectDefaultOptions.showHidden,
|
||||||
depth: inspectDefaultOptions.depth,
|
depth: inspectDefaultOptions.depth,
|
||||||
@ -769,6 +770,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
|||||||
recurseTimes += 1;
|
recurseTimes += 1;
|
||||||
|
|
||||||
ctx.seen.push(value);
|
ctx.seen.push(value);
|
||||||
|
ctx.currentDepth = recurseTimes;
|
||||||
let output;
|
let output;
|
||||||
const indentationLvl = ctx.indentationLvl;
|
const indentationLvl = ctx.indentationLvl;
|
||||||
try {
|
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 budget = ctx.budget[ctx.indentationLvl] || 0;
|
||||||
const newLength = budget + res.length;
|
const newLength = budget + res.length;
|
||||||
ctx.budget[ctx.indentationLvl] = newLength;
|
ctx.budget[ctx.indentationLvl] = newLength;
|
||||||
@ -833,7 +838,7 @@ function formatBigInt(fn, value) {
|
|||||||
|
|
||||||
function formatPrimitive(fn, value, ctx) {
|
function formatPrimitive(fn, value, ctx) {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
if (ctx.compact === false &&
|
if (ctx.compact !== true &&
|
||||||
ctx.indentationLvl + value.length > ctx.breakLength &&
|
ctx.indentationLvl + value.length > ctx.breakLength &&
|
||||||
value.length > kMinLineLength) {
|
value.length > kMinLineLength) {
|
||||||
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl;
|
const rawMaxLineLength = ctx.breakLength - ctx.indentationLvl;
|
||||||
@ -1143,7 +1148,7 @@ function formatProperty(ctx, value, recurseTimes, key, type) {
|
|||||||
const desc = Object.getOwnPropertyDescriptor(value, key) ||
|
const desc = Object.getOwnPropertyDescriptor(value, key) ||
|
||||||
{ value: value[key], enumerable: true };
|
{ value: value[key], enumerable: true };
|
||||||
if (desc.value !== undefined) {
|
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;
|
ctx.indentationLvl += diff;
|
||||||
str = formatValue(ctx, desc.value, recurseTimes);
|
str = formatValue(ctx, desc.value, recurseTimes);
|
||||||
if (diff === 3) {
|
if (diff === 3) {
|
||||||
@ -1200,16 +1205,27 @@ function formatProperty(ctx, value, recurseTimes, key, type) {
|
|||||||
return `${name}:${extra}${str}`;
|
return `${name}:${extra}${str}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function reduceToSingleString(ctx, output, base, braces) {
|
function reduceToSingleString(ctx, output, base, braces, combine = false) {
|
||||||
const breakLength = ctx.breakLength;
|
const breakLength = ctx.breakLength;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
if (ctx.compact === false) {
|
if (ctx.compact !== true) {
|
||||||
const indentation = ' '.repeat(ctx.indentationLvl);
|
if (combine) {
|
||||||
let res = `${base ? `${base} ` : ''}${braces[0]}\n${indentation} `;
|
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++) {
|
for (; i < output.length - 1; i++) {
|
||||||
res += `${output[i]},\n${indentation} `;
|
res += `${output[i]}, `;
|
||||||
}
|
}
|
||||||
res += `${output[i]}\n${indentation}${braces[1]}`;
|
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]},${indentation} `;
|
||||||
|
}
|
||||||
|
res += `${output[i]}${indentation}${braces[1]}`;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (output.length * 2 <= breakLength) {
|
if (output.length * 2 <= breakLength) {
|
||||||
|
@ -1498,6 +1498,42 @@ util.inspect(process);
|
|||||||
|
|
||||||
assert.strict.equal(out, expected);
|
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 });
|
out = util.inspect(map, { showHidden: true, depth: 9, breakLength: 4 });
|
||||||
expected = [
|
expected = [
|
||||||
'Map {',
|
'Map {',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user