@heyhuynhgiabuu/pi-diff 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.ts +55 -27
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -169,6 +169,16 @@ function deriveBgFromFg(fgAnsi: string, intensity: number): string {
|
|
|
169
169
|
return `\x1b[48;2;${r};${g};${b}m`;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
/** Mix an accent color into a base color at the given intensity (0.0–1.0).
|
|
173
|
+
* Returns an ANSI 24-bit background escape. Used to derive diff backgrounds
|
|
174
|
+
* that blend with the tool box background (toolSuccessBg). */
|
|
175
|
+
function mixBg(base: { r: number; g: number; b: number }, accent: { r: number; g: number; b: number }, intensity: number): string {
|
|
176
|
+
const r = Math.round(base.r + (accent.r - base.r) * intensity);
|
|
177
|
+
const g = Math.round(base.g + (accent.g - base.g) * intensity);
|
|
178
|
+
const b = Math.round(base.b + (accent.b - base.b) * intensity);
|
|
179
|
+
return `\x1b[48;2;${r};${g};${b}m`;
|
|
180
|
+
}
|
|
181
|
+
|
|
172
182
|
/** Whether auto-derive from theme is still pending (runs lazily on first render). */
|
|
173
183
|
let _autoDerivePending = true;
|
|
174
184
|
|
|
@@ -176,37 +186,44 @@ let _autoDerivePending = true;
|
|
|
176
186
|
let _hasExplicitBgConfig = false;
|
|
177
187
|
|
|
178
188
|
/** Auto-derive all diff background colors from the pi theme's fg diff colors.
|
|
179
|
-
*
|
|
189
|
+
* Reads toolSuccessBg as the base and mixes accent colors into it.
|
|
190
|
+
* Falls back to black (0,0,0) as base if toolSuccessBg is unavailable. */
|
|
180
191
|
function autoDeriveBgFromTheme(theme: any): void {
|
|
181
192
|
if (!theme?.getFgAnsi) return;
|
|
182
193
|
try {
|
|
183
194
|
const fgAdd = theme.getFgAnsi("toolDiffAdded");
|
|
184
195
|
const fgDel = theme.getFgAnsi("toolDiffRemoved");
|
|
196
|
+
const addRgb = parseAnsiRgb(fgAdd);
|
|
197
|
+
const delRgb = parseAnsiRgb(fgDel);
|
|
198
|
+
if (!addRgb || !delRgb) return;
|
|
185
199
|
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
200
|
+
// Read toolSuccessBg as the base background color
|
|
201
|
+
let base = { r: 0, g: 0, b: 0 };
|
|
202
|
+
if (theme.getBgAnsi) {
|
|
203
|
+
try {
|
|
204
|
+
const bgAnsi = theme.getBgAnsi("toolSuccessBg");
|
|
205
|
+
const parsed = parseAnsiRgb(bgAnsi);
|
|
206
|
+
if (parsed) {
|
|
207
|
+
base = parsed;
|
|
208
|
+
BG_BASE = bgAnsi;
|
|
209
|
+
}
|
|
210
|
+
} catch { /* no toolSuccessBg — use black */ }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Line backgrounds — subtle accent mixed into base (8–10%)
|
|
214
|
+
BG_ADD = mixBg(base, addRgb, 0.08);
|
|
215
|
+
BG_DEL = mixBg(base, delRgb, 0.10);
|
|
191
216
|
|
|
192
217
|
// Word-level highlights — more visible (20–22%)
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const bgDelW = deriveBgFromFg(fgDel, 0.22);
|
|
196
|
-
if (bgDelW) BG_DEL_W = bgDelW;
|
|
218
|
+
BG_ADD_W = mixBg(base, addRgb, 0.20);
|
|
219
|
+
BG_DEL_W = mixBg(base, delRgb, 0.22);
|
|
197
220
|
|
|
198
221
|
// Gutters — subtler than lines (5–6%)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const bgGD = deriveBgFromFg(fgDel, 0.06);
|
|
202
|
-
if (bgGD) BG_GUTTER_DEL = bgGD;
|
|
222
|
+
BG_GUTTER_ADD = mixBg(base, addRgb, 0.05);
|
|
223
|
+
BG_GUTTER_DEL = mixBg(base, delRgb, 0.06);
|
|
203
224
|
|
|
204
|
-
// Empty filler
|
|
205
|
-
|
|
206
|
-
if (addRgb) {
|
|
207
|
-
const lum = Math.round((addRgb.r * 0.3 + addRgb.g * 0.6 + addRgb.b * 0.1) * 0.04);
|
|
208
|
-
BG_EMPTY = `\x1b[48;2;${lum};${lum};${lum}m`;
|
|
209
|
-
}
|
|
225
|
+
// Empty filler and context — match the base
|
|
226
|
+
BG_EMPTY = BG_BASE;
|
|
210
227
|
|
|
211
228
|
// Rebuild derived constants
|
|
212
229
|
DIVIDER = `${FG_RULE}│${RST}`;
|
|
@@ -392,6 +409,7 @@ const ANSI_RE = new RegExp(`${ESC_RE}\\[[0-9;]*m`, "g");
|
|
|
392
409
|
const ANSI_CAPTURE_RE = new RegExp(`${ESC_RE}\\[([^m]*)m`, "g");
|
|
393
410
|
const ANSI_PARAM_CAPTURE_RE = new RegExp(`${ESC_RE}\\[([0-9;]*)m`, "g");
|
|
394
411
|
const BG_DEFAULT = "\x1b[49m"; // reset to terminal default background
|
|
412
|
+
let BG_BASE = BG_DEFAULT; // tool box base bg — updated from theme's toolSuccessBg
|
|
395
413
|
|
|
396
414
|
// ---------------------------------------------------------------------------
|
|
397
415
|
// Theme-aware diff colors
|
|
@@ -407,8 +425,18 @@ interface DiffColors {
|
|
|
407
425
|
let DEFAULT_DIFF_COLORS: DiffColors = { fgAdd: FG_ADD, fgDel: FG_DEL, fgCtx: FG_DIM };
|
|
408
426
|
|
|
409
427
|
/** Resolve diff fg colors from theme (if available), falling back to hardcoded ANSI.
|
|
410
|
-
* On first call with a valid theme, auto-derives bg colors if no explicit config was set.
|
|
428
|
+
* On first call with a valid theme, auto-derives bg colors if no explicit config was set.
|
|
429
|
+
* Always reads toolSuccessBg for BG_BASE (used for context line backgrounds). */
|
|
411
430
|
function resolveDiffColors(theme?: any): DiffColors {
|
|
431
|
+
// Always read toolSuccessBg for BG_BASE (even with explicit config)
|
|
432
|
+
if (theme?.getBgAnsi && BG_BASE === BG_DEFAULT) {
|
|
433
|
+
try {
|
|
434
|
+
const bgAnsi = theme.getBgAnsi("toolSuccessBg");
|
|
435
|
+
const parsed = parseAnsiRgb(bgAnsi);
|
|
436
|
+
if (parsed) BG_BASE = bgAnsi;
|
|
437
|
+
} catch { /* ignore */ }
|
|
438
|
+
}
|
|
439
|
+
|
|
412
440
|
// Auto-derive bg colors from theme on first render (if no explicit preset/overrides)
|
|
413
441
|
if (_autoDerivePending && theme?.getFgAnsi) {
|
|
414
442
|
autoDeriveBgFromTheme(theme);
|
|
@@ -954,7 +982,7 @@ async function renderUnified(
|
|
|
954
982
|
bodyBg = "",
|
|
955
983
|
): void {
|
|
956
984
|
const borderFg = sign === "-" ? dc.fgDel : sign === "+" ? dc.fgAdd : "";
|
|
957
|
-
const border = borderFg ? `${borderFg}${BORDER_BAR}${RST}` : `${
|
|
985
|
+
const border = borderFg ? `${borderFg}${BORDER_BAR}${RST}` : `${BG_BASE} `;
|
|
958
986
|
const numFg = borderFg || FG_LNUM;
|
|
959
987
|
const gutter = `${border}${gutterBg}${lnum(num, nw, numFg)}${signFg}${sign}${RST} ${DIVIDER} `;
|
|
960
988
|
const contGutter = `${border}${gutterBg}${" ".repeat(nw + 1)}${RST} ${DIVIDER} `;
|
|
@@ -982,7 +1010,7 @@ async function renderUnified(
|
|
|
982
1010
|
// Context line — dimmed, single line number
|
|
983
1011
|
if (l.type === "ctx") {
|
|
984
1012
|
const hl = oldHL[oI] ?? l.content;
|
|
985
|
-
emitRow(l.newNum, " ",
|
|
1013
|
+
emitRow(l.newNum, " ", BG_BASE, dc.fgCtx, `${BG_BASE}${DIM}${hl}`, BG_BASE);
|
|
986
1014
|
oI++;
|
|
987
1015
|
nI++;
|
|
988
1016
|
idx++;
|
|
@@ -1126,15 +1154,15 @@ async function renderSplit(
|
|
|
1126
1154
|
|
|
1127
1155
|
const isDel = line.type === "del",
|
|
1128
1156
|
isAdd = line.type === "add";
|
|
1129
|
-
const gBg = isDel ? BG_GUTTER_DEL : isAdd ? BG_GUTTER_ADD :
|
|
1130
|
-
const cBg = isDel ? BG_DEL : isAdd ? BG_ADD :
|
|
1157
|
+
const gBg = isDel ? BG_GUTTER_DEL : isAdd ? BG_GUTTER_ADD : BG_BASE;
|
|
1158
|
+
const cBg = isDel ? BG_DEL : isAdd ? BG_ADD : BG_BASE;
|
|
1131
1159
|
const sFg = isDel ? dc.fgDel : isAdd ? dc.fgAdd : dc.fgCtx;
|
|
1132
1160
|
const sign = isDel ? "-" : isAdd ? "+" : " ";
|
|
1133
1161
|
const num = isDel ? line.oldNum : isAdd ? line.newNum : side === "left" ? line.oldNum : line.newNum;
|
|
1134
1162
|
|
|
1135
1163
|
// Border bar + colored line numbers for changed lines
|
|
1136
1164
|
const borderFg = isDel ? dc.fgDel : isAdd ? dc.fgAdd : "";
|
|
1137
|
-
const border = borderFg ? `${borderFg}${BORDER_BAR}${RST}` : ` ${
|
|
1165
|
+
const border = borderFg ? `${borderFg}${BORDER_BAR}${RST}` : ` ${BG_BASE}`;
|
|
1138
1166
|
const numFg = borderFg || FG_LNUM;
|
|
1139
1167
|
|
|
1140
1168
|
let body: string;
|
|
@@ -1143,7 +1171,7 @@ async function renderSplit(
|
|
|
1143
1171
|
} else if (isDel || isAdd) {
|
|
1144
1172
|
body = `${cBg}${hl}`;
|
|
1145
1173
|
} else {
|
|
1146
|
-
body = `${
|
|
1174
|
+
body = `${BG_BASE}${DIM}${hl}`;
|
|
1147
1175
|
}
|
|
1148
1176
|
|
|
1149
1177
|
const gutter = `${border}${gBg}${lnum(num, nw, numFg)}${sFg}${BOLD}${sign}${RST} ${FG_RULE}│${RST} `;
|