Skip to content

Commit 03e75ea

Browse files
committed
feat: console format better no color support
1 parent 7ed9b4b commit 03e75ea

1 file changed

Lines changed: 68 additions & 20 deletions

File tree

packages/jsondiffpatch/src/formatters/console.ts

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ import BaseFormatter from "./base.js";
1414
interface 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

2428
class 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

Comments
 (0)