@@ -108,6 +108,9 @@ function escapeStyleCode(code) {
108108 return `\u001b[${ code } m` ;
109109}
110110
111+ // eslint-disable-next-line no-control-regex
112+ const endingRegex = / \u001b \[ [ 3 4 ] 9 m / g;
113+
111114/**
112115 * @param {string | string[] } format
113116 * @param {string } text
@@ -134,24 +137,58 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
134137 skipColorize = ! lazyUtilColors ( ) . shouldColorize ( stream ) ;
135138 }
136139
140+ if ( skipColorize ) {
141+ return text ;
142+ }
143+
137144 // If the format is not an array, convert it to an array
138145 const formatArray = ArrayIsArray ( format ) ? format : [ format ] ;
139146
140- let left = '' ;
141- let right = '' ;
147+ // Collect the codes we're applying
148+ const codes = [ ] ;
142149 for ( const key of formatArray ) {
143150 if ( key === 'none' ) continue ;
144151 const formatCodes = inspect . colors [ key ] ;
145152 // If the format is not a valid style, throw an error
146153 if ( formatCodes == null ) {
147154 validateOneOf ( key , 'format' , ObjectKeys ( inspect . colors ) ) ;
148155 }
149- if ( skipColorize ) continue ;
150- left += escapeStyleCode ( formatCodes [ 0 ] ) ;
151- right = `${ escapeStyleCode ( formatCodes [ 1 ] ) } ${ right } ` ;
156+
157+ codes . push ( formatCodes ) ;
158+ }
159+
160+ if ( codes . length === 0 ) {
161+ return text ;
162+ }
163+
164+ // Build opening codes
165+ let openCodes = '' ;
166+ for ( const { 0 : open } of codes ) {
167+ openCodes += escapeStyleCode ( open ) ;
168+ }
169+
170+ // Process the text to handle nested styles
171+ const processedText = text . replace ( endingRegex , ( match , offset ) => {
172+ // Check if there's more content after this reset
173+ if ( offset + match . length < text . length ) {
174+ for ( const { 0 : open } of codes ) {
175+ // Check if this is a foreground color (30-37, 90-97) or Background color (40-47, 100-107)
176+ if ( ( open >= 30 && open <= 37 ) || ( open >= 90 && open <= 97 ) ||
177+ ( open >= 40 && open <= 47 ) || ( open >= 100 && open <= 107 ) ) {
178+ return escapeStyleCode ( open ) ;
179+ }
180+ }
181+ }
182+ return match ;
183+ } ) ;
184+
185+ // Build closing codes in reverse order
186+ let closeCodes = '' ;
187+ for ( let i = codes . length - 1 ; i >= 0 ; i -- ) {
188+ closeCodes += escapeStyleCode ( codes [ i ] [ 1 ] ) ;
152189 }
153190
154- return skipColorize ? text : `${ left } ${ text } ${ right } ` ;
191+ return `${ openCodes } ${ processedText } ${ closeCodes } ` ;
155192}
156193
157194/**
0 commit comments