@@ -25,6 +25,7 @@ const {
2525 ArrayIsArray,
2626 ArrayPrototypePop,
2727 ArrayPrototypePush,
28+ ArrayPrototypeReduce,
2829 Error,
2930 ErrorCaptureStackTrace,
3031 FunctionPrototypeBind,
@@ -36,6 +37,8 @@ const {
3637 ObjectSetPrototypeOf,
3738 ObjectValues,
3839 ReflectApply,
40+ RegExp,
41+ RegExpPrototypeSymbolReplace,
3942 StringPrototypeToWellFormed,
4043} = primordials ;
4144
@@ -137,8 +140,7 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
137140 // If the format is not an array, convert it to an array
138141 const formatArray = ArrayIsArray ( format ) ? format : [ format ] ;
139142
140- let left = '' ;
141- let right = '' ;
143+ const codes = [ ] ;
142144 for ( const key of formatArray ) {
143145 if ( key === 'none' ) continue ;
144146 const formatCodes = inspect . colors [ key ] ;
@@ -147,11 +149,56 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
147149 validateOneOf ( key , 'format' , ObjectKeys ( inspect . colors ) ) ;
148150 }
149151 if ( skipColorize ) continue ;
150- left += escapeStyleCode ( formatCodes [ 0 ] ) ;
151- right = `${ escapeStyleCode ( formatCodes [ 1 ] ) } ${ right } ` ;
152+ ArrayPrototypePush ( codes , formatCodes ) ;
152153 }
153154
154- return skipColorize ? text : `${ left } ${ text } ${ right } ` ;
155+ if ( skipColorize ) {
156+ return text ;
157+ }
158+
159+ // Build opening codes
160+ let openCodes = '' ;
161+ for ( let i = 0 ; i < codes . length ; i ++ ) {
162+ openCodes += escapeStyleCode ( codes [ i ] [ 0 ] ) ;
163+ }
164+
165+ // Process the text to handle nested styles
166+ let processedText ;
167+ if ( codes . length > 0 ) {
168+ processedText = ArrayPrototypeReduce (
169+ codes ,
170+ ( text , code ) => RegExpPrototypeSymbolReplace (
171+ // Find the reset code
172+ new RegExp ( `\\u001b\\[${ code [ 1 ] } m` , 'g' ) ,
173+ text ,
174+ ( match , offset ) => {
175+ // Check if there's more content after this reset
176+ if ( offset + match . length < text . length ) {
177+ if (
178+ code [ 0 ] === inspect . colors . dim [ 0 ] ||
179+ code [ 0 ] === inspect . colors . bold [ 0 ]
180+ ) {
181+ // Dim and bold are not mutually exclusive, so we need to reapply
182+ return `${ match } ${ escapeStyleCode ( code [ 0 ] ) } ` ;
183+ }
184+ return `${ escapeStyleCode ( code [ 0 ] ) } ` ;
185+ }
186+ return match ;
187+ } ,
188+ ) ,
189+ text ,
190+ ) ;
191+ } else {
192+ processedText = text ;
193+ }
194+
195+ // Build closing codes in reverse order
196+ let closeCodes = '' ;
197+ for ( let i = codes . length - 1 ; i >= 0 ; i -- ) {
198+ closeCodes += escapeStyleCode ( codes [ i ] [ 1 ] ) ;
199+ }
200+
201+ return `${ openCodes } ${ processedText } ${ closeCodes } ` ;
155202}
156203
157204/**
0 commit comments