@@ -191,6 +191,15 @@ function countLines(source: string): number {
191
191
return lines
192
192
}
193
193
194
+ const captureColors = [
195
+ chalk . red ,
196
+ chalk . green ,
197
+ chalk . yellow ,
198
+ chalk . blue ,
199
+ chalk . magenta ,
200
+ chalk . cyan ,
201
+ ]
202
+
194
203
function formatNodeMatch (
195
204
source : string ,
196
205
lineCount : number ,
@@ -203,23 +212,71 @@ function formatNodeMatch(
203
212
start : { line : startLine , column : startCol } ,
204
213
} ,
205
214
} = match . node
215
+ const { captures, arrayCaptures } = match
206
216
const start = nodeStart - startCol
207
217
const eolRegex = / \r \n ? | \n / gm
208
218
eolRegex . lastIndex = nodeEnd
209
219
const eolMatch = eolRegex . exec ( source )
210
220
const end = eolMatch ? eolMatch . index : nodeEnd
211
221
222
+ let captureColor = 0
223
+
224
+ const captureRanges = [ ]
225
+ if ( captures ) {
226
+ for ( const [ key , node ] of Object . entries ( captures ) ) {
227
+ const { start, end } = node as any
228
+ captureRanges . push ( {
229
+ key,
230
+ start,
231
+ end,
232
+ color : captureColors [ captureColor ++ ] || chalk . gray ,
233
+ } )
234
+ }
235
+ }
236
+ if ( arrayCaptures ) {
237
+ for ( const [ key , nodes ] of Object . entries ( arrayCaptures ) ) {
238
+ const first = nodes [ 0 ]
239
+ const last = nodes [ nodes . length - 1 ]
240
+ if ( ! first || ! last ) continue
241
+ const { start } = first as any
242
+ const { end } = last as any
243
+ captureRanges . push ( {
244
+ key,
245
+ start,
246
+ end,
247
+ color : captureColors [ captureColor ++ ] || chalk . gray ,
248
+ } )
249
+ }
250
+ }
251
+
252
+ captureRanges . sort ( ( a , b ) => a . start - b . start )
253
+
254
+ let lastIndex = nodeStart
255
+ const parts = [ ]
256
+ for ( const { start, end, color } of captureRanges ) {
257
+ parts . push ( source . substring ( lastIndex , start ) )
258
+ parts . push ( color ( source . substring ( start , end ) ) )
259
+ lastIndex = end
260
+ }
261
+ parts . push ( source . substring ( lastIndex , nodeEnd ) )
262
+
212
263
const bolded =
213
264
source . substring ( start , nodeStart ) +
214
- chalk . bold ( source . substring ( nodeStart , nodeEnd ) ) +
265
+ chalk . bold ( parts . join ( '' ) ) +
215
266
source . substring ( nodeEnd , end )
216
267
217
268
const lines = bolded . split ( / \r \n ? | \n / gm)
218
269
219
270
const lineNumberLength = String ( lineCount ) . length
220
271
221
272
let line = startLine
222
- return lines
273
+ const result = lines
223
274
. map ( ( l ) => `${ String ( line ++ ) . padStart ( lineNumberLength , ' ' ) } | ${ l } ` )
224
275
. join ( '\n' )
276
+
277
+ return captureRanges . length
278
+ ? `${ ' ' . repeat ( lineNumberLength ) } | ${ captureRanges
279
+ . map ( ( { key, color } ) => color ( key ) )
280
+ . join ( ' ' ) } \n${ result } `
281
+ : result
225
282
}
0 commit comments