@@ -68,7 +68,8 @@ const inspectDefaultOptions = Object.seal({
6868 customInspect : true ,
6969 showProxy : false ,
7070 maxArrayLength : 100 ,
71- breakLength : 60
71+ breakLength : 60 ,
72+ compact : true
7273} ) ;
7374
7475const propertyIsEnumerable = Object . prototype . propertyIsEnumerable ;
@@ -86,6 +87,10 @@ const strEscapeSequencesReplacer = /[\x00-\x1f\x27\x5c]/g;
8687const keyStrRegExp = / ^ [ a - z A - Z _ ] [ a - z A - Z _ 0 - 9 ] * $ / ;
8788const numberRegExp = / ^ ( 0 | [ 1 - 9 ] [ 0 - 9 ] * ) $ / ;
8889
90+ const readableRegExps = { } ;
91+
92+ const MIN_LINE_LENGTH = 16 ;
93+
8994// Escaped special characters. Use empty strings to fill up unused entries.
9095const meta = [
9196 '\\u0000' , '\\u0001' , '\\u0002' , '\\u0003' , '\\u0004' ,
@@ -276,7 +281,8 @@ function inspect(value, opts) {
276281 showProxy : inspectDefaultOptions . showProxy ,
277282 maxArrayLength : inspectDefaultOptions . maxArrayLength ,
278283 breakLength : inspectDefaultOptions . breakLength ,
279- indentationLvl : 0
284+ indentationLvl : 0 ,
285+ compact : inspectDefaultOptions . compact
280286 } ;
281287 // Legacy...
282288 if ( arguments . length > 2 ) {
@@ -374,7 +380,7 @@ function ensureDebugIsInitialized() {
374380function formatValue ( ctx , value , recurseTimes , ln ) {
375381 // Primitive types cannot have properties
376382 if ( typeof value !== 'object' && typeof value !== 'function' ) {
377- return formatPrimitive ( ctx . stylize , value ) ;
383+ return formatPrimitive ( ctx . stylize , value , ctx ) ;
378384 }
379385 if ( value === null ) {
380386 return ctx . stylize ( 'null' , 'null' ) ;
@@ -481,10 +487,10 @@ function formatValue(ctx, value, recurseTimes, ln) {
481487 } catch ( e ) { /* ignore */ }
482488
483489 if ( typeof raw === 'string' ) {
484- const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
490+ const formatted = formatPrimitive ( stylizeNoColor , raw , ctx ) ;
485491 if ( keyLength === raw . length )
486492 return ctx . stylize ( `[String: ${ formatted } ]` , 'string' ) ;
487- base = ` [String: ${ formatted } ]` ;
493+ base = `[String: ${ formatted } ]` ;
488494 // For boxed Strings, we have to remove the 0-n indexed entries,
489495 // since they just noisy up the output and are redundant
490496 // Make boxed primitive Strings look like such
@@ -505,25 +511,25 @@ function formatValue(ctx, value, recurseTimes, ln) {
505511 const name = `${ constructor . name } ${ value . name ? `: ${ value . name } ` : '' } ` ;
506512 if ( keyLength === 0 )
507513 return ctx . stylize ( `[${ name } ]` , 'special' ) ;
508- base = ` [${ name } ]` ;
514+ base = `[${ name } ]` ;
509515 } else if ( isRegExp ( value ) ) {
510516 // Make RegExps say that they are RegExps
511517 if ( keyLength === 0 || recurseTimes < 0 )
512518 return ctx . stylize ( regExpToString . call ( value ) , 'regexp' ) ;
513- base = ` ${ regExpToString . call ( value ) } ` ;
519+ base = `${ regExpToString . call ( value ) } ` ;
514520 } else if ( isDate ( value ) ) {
515521 if ( keyLength === 0 ) {
516522 if ( Number . isNaN ( value . getTime ( ) ) )
517523 return ctx . stylize ( value . toString ( ) , 'date' ) ;
518524 return ctx . stylize ( dateToISOString . call ( value ) , 'date' ) ;
519525 }
520526 // Make dates with properties first say the date
521- base = ` ${ dateToISOString . call ( value ) } ` ;
527+ base = `${ dateToISOString . call ( value ) } ` ;
522528 } else if ( isError ( value ) ) {
523529 // Make error with message first say the error
524530 if ( keyLength === 0 )
525531 return formatError ( value ) ;
526- base = ` ${ formatError ( value ) } ` ;
532+ base = `${ formatError ( value ) } ` ;
527533 } else if ( isAnyArrayBuffer ( value ) ) {
528534 // Fast path for ArrayBuffer and SharedArrayBuffer.
529535 // Can't do the same for DataView because it has a non-primitive
@@ -553,13 +559,13 @@ function formatValue(ctx, value, recurseTimes, ln) {
553559 const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
554560 if ( keyLength === 0 )
555561 return ctx . stylize ( `[Number: ${ formatted } ]` , 'number' ) ;
556- base = ` [Number: ${ formatted } ]` ;
562+ base = `[Number: ${ formatted } ]` ;
557563 } else if ( typeof raw === 'boolean' ) {
558564 // Make boxed primitive Booleans look like such
559565 const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
560566 if ( keyLength === 0 )
561567 return ctx . stylize ( `[Boolean: ${ formatted } ]` , 'boolean' ) ;
562- base = ` [Boolean: ${ formatted } ]` ;
568+ base = `[Boolean: ${ formatted } ]` ;
563569 } else if ( typeof raw === 'symbol' ) {
564570 const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
565571 return ctx . stylize ( `[Symbol: ${ formatted } ]` , 'symbol' ) ;
@@ -603,9 +609,42 @@ function formatNumber(fn, value) {
603609 return fn ( `${ value } ` , 'number' ) ;
604610}
605611
606- function formatPrimitive ( fn , value ) {
607- if ( typeof value === 'string' )
612+ function formatPrimitive ( fn , value , ctx ) {
613+ if ( typeof value === 'string' ) {
614+ if ( ctx . compact === false &&
615+ value . length > MIN_LINE_LENGTH &&
616+ ctx . indentationLvl + value . length > ctx . breakLength ) {
617+ // eslint-disable-next-line max-len
618+ const minLineLength = Math . max ( ctx . breakLength - ctx . indentationLvl , MIN_LINE_LENGTH ) ;
619+ // eslint-disable-next-line max-len
620+ const averageLineLength = Math . ceil ( value . length / Math . ceil ( value . length / minLineLength ) ) ;
621+ const divisor = Math . max ( averageLineLength , MIN_LINE_LENGTH ) ;
622+ var res = '' ;
623+ if ( readableRegExps [ divisor ] === undefined ) {
624+ // Build a new RegExp that naturally breaks text into multiple lines.
625+ //
626+ // Rules
627+ // 1. Greedy match all text up the max line length that ends with a
628+ // whitespace or the end of the string.
629+ // 2. If none matches, non-greedy match any text up to a whitespace or
630+ // the end of the string.
631+ //
632+ // eslint-disable-next-line max-len, no-unescaped-regexp-dot
633+ readableRegExps [ divisor ] = new RegExp ( `(.|\\n){1,${ divisor } }(\\s|$)|(\\n|.)+?(\\s|$)` , 'gm' ) ;
634+ }
635+ const indent = ' ' . repeat ( ctx . indentationLvl ) ;
636+ const matches = value . match ( readableRegExps [ divisor ] ) ;
637+ if ( matches . length > 1 ) {
638+ res += `${ fn ( strEscape ( matches [ 0 ] ) , 'string' ) } +\n` ;
639+ for ( var i = 1 ; i < matches . length - 1 ; i ++ ) {
640+ res += `${ indent } ${ fn ( strEscape ( matches [ i ] ) , 'string' ) } +\n` ;
641+ }
642+ res += `${ indent } ${ fn ( strEscape ( matches [ i ] ) , 'string' ) } ` ;
643+ return res ;
644+ }
645+ }
608646 return fn ( strEscape ( value ) , 'string' ) ;
647+ }
609648 if ( typeof value === 'number' )
610649 return formatNumber ( fn , value ) ;
611650 if ( typeof value === 'boolean' )
@@ -806,7 +845,7 @@ function formatProperty(ctx, value, recurseTimes, key, array) {
806845 const desc = Object . getOwnPropertyDescriptor ( value , key ) ||
807846 { value : value [ key ] , enumerable : true } ;
808847 if ( desc . value !== undefined ) {
809- const diff = array === 0 ? 3 : 2 ;
848+ const diff = array !== 0 || ctx . compact === false ? 2 : 3 ;
810849 ctx . indentationLvl += diff ;
811850 str = formatValue ( ctx , desc . value , recurseTimes , array === 0 ) ;
812851 ctx . indentationLvl -= diff ;
@@ -839,25 +878,36 @@ function formatProperty(ctx, value, recurseTimes, key, array) {
839878
840879function reduceToSingleString ( ctx , output , base , braces , addLn ) {
841880 const breakLength = ctx . breakLength ;
881+ var i = 0 ;
882+ if ( ctx . compact === false ) {
883+ const indentation = ' ' . repeat ( ctx . indentationLvl ) ;
884+ var res = `${ base ? `${ base } ` : '' } ${ braces [ 0 ] } \n${ indentation } ` ;
885+ for ( ; i < output . length - 1 ; i ++ ) {
886+ res += `${ output [ i ] } ,\n${ indentation } ` ;
887+ }
888+ res += `${ output [ i ] } \n${ indentation } ${ braces [ 1 ] } ` ;
889+ return res ;
890+ }
842891 if ( output . length * 2 <= breakLength ) {
843892 var length = 0 ;
844- for ( var i = 0 ; i < output . length && length <= breakLength ; i ++ ) {
893+ for ( ; i < output . length && length <= breakLength ; i ++ ) {
845894 if ( ctx . colors ) {
846895 length += removeColors ( output [ i ] ) . length + 1 ;
847896 } else {
848897 length += output [ i ] . length + 1 ;
849898 }
850899 }
851900 if ( length <= breakLength )
852- return `${ braces [ 0 ] } ${ base } ${ join ( output , ', ' ) } ${ braces [ 1 ] } ` ;
901+ return `${ braces [ 0 ] } ${ base ? ` ${ base } ` : '' } ${ join ( output , ', ' ) } ` +
902+ braces [ 1 ] ;
853903 }
854904 // If the opening "brace" is too large, like in the case of "Set {",
855905 // we need to force the first item to be on the next line or the
856906 // items will not line up correctly.
857907 const indentation = ' ' . repeat ( ctx . indentationLvl ) ;
858908 const extraLn = addLn === true ? `\n${ indentation } ` : '' ;
859909 const ln = base === '' && braces [ 0 ] . length === 1 ?
860- ' ' : `${ base } \n${ indentation } ` ;
910+ ' ' : `${ base ? ` ${ base } ` : base } \n${ indentation } ` ;
861911 const str = join ( output , `,\n${ indentation } ` ) ;
862912 return `${ extraLn } ${ braces [ 0 ] } ${ ln } ${ str } ${ braces [ 1 ] } ` ;
863913}
0 commit comments