@@ -14,11 +14,15 @@ import BaseFormatter from "./base.js";
1414interface ConsoleFormatterContext extends BaseFormatterContext {
1515 indentLevel ?: number ;
1616 indentPad ?: string ;
17- outLine : ( ) => void ;
1817 indent : ( levels ?: number ) => void ;
1918 color ?: ( ( ( value : unknown ) => string ) | undefined ) [ ] ;
19+ linePrefix ?: string [ ] ;
2020 pushColor : ( color : ( ( value : unknown ) => string ) | undefined ) => void ;
2121 popColor : ( ) => void ;
22+ pushLinePrefix : ( prefix : string ) => void ;
23+ popLinePrefix : ( ) => void ;
24+ atNewLine : boolean ;
25+ newLine : ( ) => void ;
2226}
2327
2428class ConsoleFormatter extends BaseFormatter < ConsoleFormatterContext > {
@@ -36,23 +40,31 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
3640 this . indentLevel =
3741 ( this . indentLevel || 0 ) + ( typeof levels === "undefined" ? 1 : levels ) ;
3842 this . indentPad = new Array ( this . indentLevel + 1 ) . join ( " " ) ;
39- if ( ! this . outLine ) {
40- throw new Error ( "console context outLine is not defined" ) ;
41- }
42- this . outLine ( ) ;
4343 } ;
44- context . outLine = function ( ) {
45- if ( ! this . buffer ) {
46- throw new Error ( "console context buffer is not defined" ) ;
47- }
48- this . buffer . push ( `\n${ this . indentPad || "" } ` ) ;
44+ context . newLine = function ( ) {
45+ this . buffer = this . buffer || [ ] ;
46+ this . buffer . push ( "\n" ) ;
47+ this . atNewLine = true ;
4948 } ;
5049 context . out = function ( ...args ) {
50+ const color = this . color ?. [ 0 ] ;
51+ if ( this . atNewLine ) {
52+ this . atNewLine = false ;
53+ this . buffer = this . buffer || [ ] ;
54+ const linePrefix = this . linePrefix ?. [ 0 ]
55+ ? color
56+ ? color ( this . linePrefix [ 0 ] )
57+ : this . linePrefix [ 0 ]
58+ : " " ;
59+ this . buffer . push ( `${ linePrefix } ${ this . indentPad || "" } ` ) ;
60+ }
5161 for ( const arg of args ) {
5262 const lines = arg . split ( "\n" ) ;
53- let text = lines . join ( `\n${ this . indentPad || "" } ` ) ;
54- if ( this . color ?. [ 0 ] ) {
55- text = this . color [ 0 ] ( text ) ;
63+ let text = lines . join (
64+ `\n${ this . linePrefix ?. [ 0 ] ?? " " } ${ this . indentPad || "" } ` ,
65+ ) ;
66+ if ( color ) {
67+ text = color ( text ) ;
5668 }
5769 if ( ! this . buffer ) {
5870 throw new Error ( "console context buffer is not defined" ) ;
@@ -68,11 +80,18 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
6880 this . color = this . color || [ ] ;
6981 this . color . shift ( ) ;
7082 } ;
83+ context . pushLinePrefix = function ( prefix : string ) {
84+ this . linePrefix = this . linePrefix || [ ] ;
85+ this . linePrefix . unshift ( prefix ) ;
86+ } ;
87+ context . popLinePrefix = function ( ) {
88+ this . linePrefix = this . linePrefix || [ ] ;
89+ this . linePrefix . shift ( ) ;
90+ } ;
7191 }
7292
7393 typeFormattterErrorFormatter ( context : ConsoleFormatterContext , err : unknown ) {
7494 context . pushColor ( this . brushes . error ) ;
75- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
7695 context . out ( `[ERROR]${ err } ` ) ;
7796 context . popColor ( ) ;
7897 }
@@ -84,20 +103,37 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
84103 formatTextDiffString ( context : ConsoleFormatterContext , value : string ) {
85104 const lines = this . parseTextDiff ( value ) ;
86105 context . indent ( ) ;
106+ context . newLine ( ) ;
87107 for ( let i = 0 ; i < lines . length ; i ++ ) {
88108 const line = lines [ i ] ;
109+ const underline = [ ] ;
89110 if ( line === undefined ) continue ;
90111 context . pushColor ( this . brushes . textDiffLine ) ;
91- context . out ( `${ line . location . line } ,${ line . location . chr } ` ) ;
112+ const header = `${ line . location . line } ,${ line . location . chr } ` ;
113+ context . out ( header ) ;
114+ underline . push ( new Array ( header . length + 1 ) . join ( " " ) ) ;
92115 context . popColor ( ) ;
93116 const pieces = line . pieces ;
94117 for ( const piece of pieces ) {
95- context . pushColor ( this . brushes [ piece . type ] ) ;
96- context . out ( decodeURI ( piece . text ) ) ;
118+ const brush = this . brushes [ piece . type ] ;
119+ context . pushColor ( brush ) ;
120+ const decodedText = decodeURI ( piece . text ) ;
121+ context . out ( decodedText ) ;
122+ underline . push (
123+ new Array ( decodedText . length + 1 ) . join (
124+ piece . type === "added" ? "+" : piece . type === "deleted" ? "-" : " " ,
125+ ) ,
126+ ) ;
97127 context . popColor ( ) ;
98128 }
129+
130+ context . newLine ( ) ;
131+ context . pushColor ( this . brushes . textDiffLine ) ;
132+ context . out ( underline . join ( "" ) ) ;
133+ context . popColor ( ) ;
134+
99135 if ( i < lines . length - 1 ) {
100- context . outLine ( ) ;
136+ context . newLine ( ) ;
101137 }
102138 }
103139 context . indent ( - 1 ) ;
@@ -112,6 +148,7 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
112148 if ( type === "node" ) {
113149 context . out ( nodeType === "array" ? "[" : "{" ) ;
114150 context . indent ( ) ;
151+ context . newLine ( ) ;
115152 }
116153 }
117154
@@ -122,6 +159,7 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
122159 ) {
123160 if ( type === "node" ) {
124161 context . indent ( - 1 ) ;
162+ context . newLine ( ) ;
125163 context . out ( nodeType === "array" ? "]" : "}" ) ;
126164 }
127165 context . popColor ( ) ;
@@ -139,11 +177,17 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
139177 ? key . substring ( 1 )
140178 : key ;
141179
180+ if ( type === "deleted" ) {
181+ context . pushLinePrefix ( "-" ) ;
182+ } else if ( type === "added" ) {
183+ context . pushLinePrefix ( "+" ) ;
184+ }
142185 context . pushColor ( this . brushes [ type ] ) ;
143186 context . out ( `${ label } : ` ) ;
144187 if ( type === "node" ) {
145188 context . out ( nodeType === "array" ? "[" : "{" ) ;
146189 context . indent ( ) ;
190+ context . newLine ( ) ;
147191 }
148192 }
149193
@@ -157,12 +201,16 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
157201 ) {
158202 if ( type === "node" ) {
159203 context . indent ( - 1 ) ;
204+ context . newLine ( ) ;
160205 context . out ( nodeType === "array" ? "]" : `}${ isLast ? "" : "," } ` ) ;
161206 }
162207 if ( ! isLast ) {
163- context . outLine ( ) ;
208+ context . newLine ( ) ;
164209 }
165210 context . popColor ( ) ;
211+ if ( type === "deleted" || type === "added" ) {
212+ context . popLinePrefix ( ) ;
213+ }
166214 }
167215
168216 format_unchanged (
@@ -215,7 +263,7 @@ class ConsoleFormatter extends BaseFormatter<ConsoleFormatterContext> {
215263 }
216264
217265 format_moved ( context : ConsoleFormatterContext , delta : MovedDelta ) {
218- context . out ( `== > ${ delta [ 1 ] } ` ) ;
266+ context . out ( `~ > ${ delta [ 1 ] } ` ) ;
219267 }
220268
221269 format_textdiff ( context : ConsoleFormatterContext , delta : TextDiffDelta ) {
0 commit comments