@heyhuynhgiabuu/pi-diff 0.5.1 → 0.5.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/README.md +54 -50
- package/dist/core/diff.d.ts +50 -0
- package/dist/core/diff.d.ts.map +1 -1
- package/dist/core/diff.js +274 -3
- package/dist/core/diff.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -113
- package/dist/index.js.map +1 -1
- package/dist/review/hunk-preview.d.ts +1 -1
- package/dist/review/hunk-preview.d.ts.map +1 -1
- package/dist/review/hunk-preview.js +30 -24
- package/dist/review/hunk-preview.js.map +1 -1
- package/dist/review/interactive.d.ts.map +1 -1
- package/dist/review/interactive.js +1 -5
- package/dist/review/interactive.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -168,19 +168,19 @@ All custom theme colors must be `#rrggbb` hex values.
|
|
|
168
168
|
|
|
169
169
|
```ts
|
|
170
170
|
// Open the read-only review markdown for working-tree changes, including untracked files
|
|
171
|
-
review_git_diff({})
|
|
171
|
+
review_git_diff({});
|
|
172
172
|
|
|
173
173
|
// Review branch changes as main...HEAD
|
|
174
|
-
review_git_diff({ base: "main" })
|
|
174
|
+
review_git_diff({ base: "main" });
|
|
175
175
|
|
|
176
176
|
// Focus a file from the changed-file list
|
|
177
|
-
review_git_diff({ file: "src/index.ts" })
|
|
177
|
+
review_git_diff({ file: "src/index.ts" });
|
|
178
178
|
|
|
179
179
|
// Focus a hunk ID shown by the panel
|
|
180
|
-
review_git_diff({ file: "src/index.ts", hunkId: "src/index.ts:10:12" })
|
|
180
|
+
review_git_diff({ file: "src/index.ts", hunkId: "src/index.ts:10:12" });
|
|
181
181
|
|
|
182
182
|
// Return the older full markdown export with raw unified diff included
|
|
183
|
-
review_git_diff({ base: "main", includeRawDiff: true })
|
|
183
|
+
review_git_diff({ base: "main", includeRawDiff: true });
|
|
184
184
|
```
|
|
185
185
|
|
|
186
186
|
- No `base` means working-tree review, including untracked files.
|
|
@@ -228,12 +228,13 @@ New content ──┘ │
|
|
|
228
228
|
|
|
229
229
|
### Views
|
|
230
230
|
|
|
231
|
-
| View
|
|
232
|
-
|
|
233
|
-
| **Split**
|
|
234
|
-
| **Unified** | `write` tool | Single column with `+`/`-` gutter. Compact, works at any terminal width.
|
|
231
|
+
| View | Used by | Description |
|
|
232
|
+
| ----------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
233
|
+
| **Split** | `edit` tool | Side-by-side with old on left, new on right. Diagonal stripes fill empty slots. Auto-falls back to unified when terminal < 150 cols or > 20% of lines would wrap. |
|
|
234
|
+
| **Unified** | `write` tool | Single column with `+`/`-` gutter. Compact, works at any terminal width. |
|
|
235
235
|
|
|
236
236
|
Both views show:
|
|
237
|
+
|
|
237
238
|
- Colored border bars (`▌`) for changed lines
|
|
238
239
|
- Line numbers in the gutter
|
|
239
240
|
- Hunk separators (`··· N unmodified lines ···`)
|
|
@@ -252,12 +253,12 @@ pi-diff ships with built-in theme presets optimized for different terminal backg
|
|
|
252
253
|
}
|
|
253
254
|
```
|
|
254
255
|
|
|
255
|
-
| Preset
|
|
256
|
-
|
|
257
|
-
| `default`
|
|
258
|
-
| `midnight` | Pure black (`#000000`) terminals | Subtle tints that don't overwhelm on black
|
|
259
|
-
| `subtle`
|
|
260
|
-
| `neon`
|
|
256
|
+
| Preset | Best for | Description |
|
|
257
|
+
| ---------- | -------------------------------- | --------------------------------------------------------- |
|
|
258
|
+
| `default` | Dark theme bases (~`#1e1e2e`) | Original pi-diff colors — balanced contrast |
|
|
259
|
+
| `midnight` | Pure black (`#000000`) terminals | Subtle tints that don't overwhelm on black |
|
|
260
|
+
| `subtle` | Any dark theme | Minimal backgrounds — barely-there tints for a clean look |
|
|
261
|
+
| `neon` | Low-contrast displays | Higher contrast backgrounds for better visibility |
|
|
261
262
|
|
|
262
263
|
### Per-Color Overrides
|
|
263
264
|
|
|
@@ -294,6 +295,7 @@ Override individual diff colors in `.pi/settings.json` using hex `#RRGGBB` value
|
|
|
294
295
|
When no `diffTheme` or `diffColors` is set, pi-diff **automatically derives** background colors from your pi theme's diff foreground colors and tool-state backgrounds. Added/context surfaces use `toolSuccessBg`; removed surfaces use `toolErrorBg`. This ensures diffs look good with any pi theme and terminal background — no configuration needed.
|
|
295
296
|
|
|
296
297
|
The auto-derive uses different intensity levels:
|
|
298
|
+
|
|
297
299
|
- **Line backgrounds**: 8–10% of the theme's diff fg color mixed into the matching tool-state background (subtle tint)
|
|
298
300
|
- **Word highlights**: 20–22% (more visible for changed characters)
|
|
299
301
|
- **Gutters**: 5–6% (subtler than line backgrounds)
|
|
@@ -314,31 +316,31 @@ All settings are also controllable via environment variables. Add them to your s
|
|
|
314
316
|
|
|
315
317
|
### Theme
|
|
316
318
|
|
|
317
|
-
| Variable
|
|
318
|
-
|
|
319
|
+
| Variable | Default | Description |
|
|
320
|
+
| ------------ | ------------- | ---------------------------------------------------------------------- |
|
|
319
321
|
| `DIFF_THEME` | `github-dark` | Shiki theme name (e.g., `dracula`, `one-dark-pro`, `catppuccin-mocha`) |
|
|
320
322
|
|
|
321
323
|
### Colors
|
|
322
324
|
|
|
323
325
|
Override any diff color with hex `#RRGGBB` format:
|
|
324
326
|
|
|
325
|
-
| Variable
|
|
326
|
-
|
|
327
|
-
| `DIFF_BG_ADD`
|
|
328
|
-
| `DIFF_BG_DEL`
|
|
329
|
-
| `DIFF_BG_ADD_HL`
|
|
330
|
-
| `DIFF_BG_DEL_HL`
|
|
331
|
-
| `DIFF_BG_GUTTER_ADD` | `#12201a` | Gutter background for added lines
|
|
332
|
-
| `DIFF_BG_GUTTER_DEL` | `#261616` | Gutter background for removed lines
|
|
333
|
-
| `DIFF_FG_ADD`
|
|
334
|
-
| `DIFF_FG_DEL`
|
|
327
|
+
| Variable | Default | Description |
|
|
328
|
+
| -------------------- | --------- | ------------------------------------------- |
|
|
329
|
+
| `DIFF_BG_ADD` | `#162620` | Background for added lines |
|
|
330
|
+
| `DIFF_BG_DEL` | `#2d1919` | Background for removed lines |
|
|
331
|
+
| `DIFF_BG_ADD_HL` | `#234b32` | Word-level emphasis on added text |
|
|
332
|
+
| `DIFF_BG_DEL_HL` | `#502323` | Word-level emphasis on removed text |
|
|
333
|
+
| `DIFF_BG_GUTTER_ADD` | `#12201a` | Gutter background for added lines |
|
|
334
|
+
| `DIFF_BG_GUTTER_DEL` | `#261616` | Gutter background for removed lines |
|
|
335
|
+
| `DIFF_FG_ADD` | `#64b478` | Foreground for `+` signs and add indicators |
|
|
336
|
+
| `DIFF_FG_DEL` | `#c86464` | Foreground for `-` signs and del indicators |
|
|
335
337
|
|
|
336
338
|
### Layout
|
|
337
339
|
|
|
338
|
-
| Variable
|
|
339
|
-
|
|
340
|
-
| `DIFF_SPLIT_MIN_WIDTH`
|
|
341
|
-
| `DIFF_SPLIT_MIN_CODE_WIDTH` | `60`
|
|
340
|
+
| Variable | Default | Description |
|
|
341
|
+
| --------------------------- | ------- | ------------------------------------------- |
|
|
342
|
+
| `DIFF_SPLIT_MIN_WIDTH` | `150` | Minimum terminal columns to use split view |
|
|
343
|
+
| `DIFF_SPLIT_MIN_CODE_WIDTH` | `60` | Minimum code columns per side in split view |
|
|
342
344
|
|
|
343
345
|
### Example `.envrc`
|
|
344
346
|
|
|
@@ -363,26 +365,26 @@ src/
|
|
|
363
365
|
|
|
364
366
|
### Key internals
|
|
365
367
|
|
|
366
|
-
| Component
|
|
367
|
-
|
|
368
|
-
| `parseDiff()`
|
|
369
|
-
| `hlBlock()`
|
|
370
|
-
| `injectBg()`
|
|
371
|
-
| `wordDiffAnalysis()` | Single-pass word diff → similarity score + character ranges
|
|
372
|
-
| `renderSplit()`
|
|
373
|
-
| `renderUnified()`
|
|
374
|
-
| `wrapAnsi()`
|
|
375
|
-
| `shouldUseSplit()`
|
|
368
|
+
| Component | Purpose |
|
|
369
|
+
| -------------------- | -------------------------------------------------------------------------------- |
|
|
370
|
+
| `parseDiff()` | Converts old/new content to structured `DiffLine[]` using `diff.structuredPatch` |
|
|
371
|
+
| `hlBlock()` | Shiki ANSI highlighting with LRU cache (192 entries) |
|
|
372
|
+
| `injectBg()` | Composites diff backgrounds into Shiki ANSI output (fg + bg layering) |
|
|
373
|
+
| `wordDiffAnalysis()` | Single-pass word diff → similarity score + character ranges |
|
|
374
|
+
| `renderSplit()` | Side-by-side renderer with diagonal stripe fillers |
|
|
375
|
+
| `renderUnified()` | Stacked single-column renderer |
|
|
376
|
+
| `wrapAnsi()` | ANSI-aware line wrapping with state carry-forward |
|
|
377
|
+
| `shouldUseSplit()` | Heuristic: split vs unified based on terminal width and wrap ratio |
|
|
376
378
|
|
|
377
379
|
### Rendering constants
|
|
378
380
|
|
|
379
|
-
| Constant
|
|
380
|
-
|
|
381
|
-
| `MAX_PREVIEW_LINES` | 60
|
|
382
|
-
| `MAX_RENDER_LINES`
|
|
383
|
-
| `MAX_HL_CHARS`
|
|
384
|
-
| `CACHE_LIMIT`
|
|
385
|
-
| `WORD_DIFF_MIN_SIM` | 0.15
|
|
381
|
+
| Constant | Value | Description |
|
|
382
|
+
| ------------------- | ------ | ------------------------------------------ |
|
|
383
|
+
| `MAX_PREVIEW_LINES` | 60 | Max lines in edit preview (split view) |
|
|
384
|
+
| `MAX_RENDER_LINES` | 150 | Max lines in write result (unified view) |
|
|
385
|
+
| `MAX_HL_CHARS` | 80,000 | Skip syntax highlighting above this |
|
|
386
|
+
| `CACHE_LIMIT` | 192 | LRU cache entries for highlighted blocks |
|
|
387
|
+
| `WORD_DIFF_MIN_SIM` | 0.15 | Minimum similarity for word-level emphasis |
|
|
386
388
|
|
|
387
389
|
## Exports
|
|
388
390
|
|
|
@@ -391,7 +393,8 @@ The extension exports a `__testing` object for unit testing:
|
|
|
391
393
|
```typescript
|
|
392
394
|
import { __testing } from "@heyhuynhgiabuu/pi-diff";
|
|
393
395
|
|
|
394
|
-
const { parseDiff, renderSplit, renderUnified, normalizeShikiContrast } =
|
|
396
|
+
const { parseDiff, renderSplit, renderUnified, normalizeShikiContrast } =
|
|
397
|
+
__testing;
|
|
395
398
|
```
|
|
396
399
|
|
|
397
400
|
## Development
|
|
@@ -437,7 +440,8 @@ export default function piDiffExtension(pi: any): void {
|
|
|
437
440
|
```
|
|
438
441
|
|
|
439
442
|
Extensions can:
|
|
440
|
-
|
|
443
|
+
|
|
444
|
+
- **Register tools** — `pi.registerTool(definition)`
|
|
441
445
|
- **Listen to events** — `pi.on("session_start" | "input" | "before_tool_call" | ...)`
|
|
442
446
|
- **Register commands** — `pi.registerCommand("/name", handler)`
|
|
443
447
|
- **Register providers** — `pi.registerProvider("name", config)`
|
package/dist/core/diff.d.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
/** Hunk metadata attached to separator DiffLines. */
|
|
2
|
+
export interface HunkMeta {
|
|
3
|
+
oldStart: number;
|
|
4
|
+
oldLines: number;
|
|
5
|
+
newStart: number;
|
|
6
|
+
newLines: number;
|
|
7
|
+
/** Function context from hunk header, e.g. "function foo() {" */
|
|
8
|
+
context?: string;
|
|
9
|
+
}
|
|
1
10
|
export interface DiffLine {
|
|
2
11
|
type: "add" | "del" | "ctx" | "sep";
|
|
3
12
|
oldNum: number | null;
|
|
4
13
|
newNum: number | null;
|
|
5
14
|
content: string;
|
|
15
|
+
/** Hunk metadata — present on first sep and between-hunk seps if available. */
|
|
16
|
+
hunkMeta?: HunkMeta;
|
|
6
17
|
}
|
|
7
18
|
export interface ParsedDiff {
|
|
8
19
|
lines: DiffLine[];
|
|
@@ -10,5 +21,44 @@ export interface ParsedDiff {
|
|
|
10
21
|
removed: number;
|
|
11
22
|
chars: number;
|
|
12
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a unified diff/patch string into one or more ParsedDiff.
|
|
26
|
+
* Each file in the patch gets its own entry.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parsePatchFiles(patch: string): ParsedDiff[];
|
|
29
|
+
/** Style for rendering hunk separators between change blocks. */
|
|
30
|
+
export type HunkSeparatorStyle = "auto" | "simple" | "gap" | "context" | "metadata";
|
|
31
|
+
/**
|
|
32
|
+
* Resolve hunk separator style from env var PI_DIFF_SEP_STYLE.
|
|
33
|
+
* Call once during extension init, or with force=true to re-read.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveSepStyle(): HunkSeparatorStyle;
|
|
36
|
+
/**
|
|
37
|
+
* Get the current separator style (resolved once via resolveSepStyle()).
|
|
38
|
+
*/
|
|
39
|
+
export declare function getSepStyle(): HunkSeparatorStyle;
|
|
40
|
+
/**
|
|
41
|
+
* Generate a hunk separator label for the unified view.
|
|
42
|
+
* Returns the full label including spacing, or "···" for empty/default.
|
|
43
|
+
* If `content` is non-empty, it is used directly (e.g. "───── Edit 2 ─────").
|
|
44
|
+
*/
|
|
45
|
+
export declare function sepLabelUnified(style: HunkSeparatorStyle, hunkMeta: HunkMeta | undefined, gap: number | null, content?: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Generate a hunk separator label for the split view.
|
|
48
|
+
* Wraps the content in "··· ... ···".
|
|
49
|
+
* If `content` is non-empty, it is used directly (e.g. "───── Edit 2 ─────").
|
|
50
|
+
*/
|
|
51
|
+
export declare function sepLabelSplit(style: HunkSeparatorStyle, hunkMeta: HunkMeta | undefined, gap: number | null, content?: string): string;
|
|
52
|
+
/** A paired block of deletions and additions within a hunk. */
|
|
53
|
+
export interface HunkBlock {
|
|
54
|
+
deletions: DiffLine[];
|
|
55
|
+
additions: DiffLine[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Walk a ParsedDiff and extract hunk blocks.
|
|
59
|
+
* Each block is a group of consecutive deletes followed by consecutive adds.
|
|
60
|
+
* Context and separator lines are skipped.
|
|
61
|
+
*/
|
|
62
|
+
export declare function computeHunkBlocks(diff: ParsedDiff): HunkBlock[];
|
|
13
63
|
export declare function parseDiff(oldContent: string, newContent: string, ctx?: number): ParsedDiff;
|
|
14
64
|
//# sourceMappingURL=diff.d.ts.map
|
package/dist/core/diff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAMA,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAeD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAyB3D;AA+FD,iEAAiE;AACjE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC;AAIpF;;;GAGG;AACH,wBAAgB,eAAe,IAAI,kBAAkB,CAQpD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,kBAAkB,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,OAAO,CAAC,EAAE,MAAM,GACd,MAAM,CA2BR;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,OAAO,CAAC,EAAE,MAAM,GACd,MAAM,CA4BR;AASD,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACzB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,CA8B/D;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,UAAU,CA2CrF"}
|
package/dist/core/diff.js
CHANGED
|
@@ -1,16 +1,287 @@
|
|
|
1
1
|
import * as Diff from "diff";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Unified diff patch parsing
|
|
4
|
+
//
|
|
5
|
+
// Parses git/unified diff strings (output of `git diff`, `Diff.formatPatch`,
|
|
6
|
+
// or similar) into our internal ParsedDiff representation. Preserves hunk
|
|
7
|
+
// function context from hunk headers.
|
|
8
|
+
//
|
|
9
|
+
// Handles these formats:
|
|
10
|
+
// diff --git a/file.ts b/file.ts \n --- a/file.ts \n +++ b/file.ts
|
|
11
|
+
// --- a/file.ts \n +++ b/file.ts (no diff --git prefix)
|
|
12
|
+
// @@ -start,count +start,count @@ func_name (with or without func context)
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* Parse a unified diff/patch string into one or more ParsedDiff.
|
|
16
|
+
* Each file in the patch gets its own entry.
|
|
17
|
+
*/
|
|
18
|
+
export function parsePatchFiles(patch) {
|
|
19
|
+
if (!patch || !patch.trim())
|
|
20
|
+
return [];
|
|
21
|
+
// Split into file sections
|
|
22
|
+
const lines = patch.split("\n");
|
|
23
|
+
const sections = [];
|
|
24
|
+
let cur = [];
|
|
25
|
+
// Split by "+++ " or "diff --git " (start of a new file)
|
|
26
|
+
for (let i = 0; i < lines.length; i++) {
|
|
27
|
+
const l = lines[i];
|
|
28
|
+
if (l.startsWith("diff --git ") || (l.startsWith("--- ") && cur.length > 0 && cur[0]?.startsWith("+++"))) {
|
|
29
|
+
if (cur.length > 0)
|
|
30
|
+
sections.push(cur);
|
|
31
|
+
cur = [];
|
|
32
|
+
}
|
|
33
|
+
cur.push(l);
|
|
34
|
+
}
|
|
35
|
+
if (cur.length > 0)
|
|
36
|
+
sections.push(cur);
|
|
37
|
+
const result = [];
|
|
38
|
+
for (const sec of sections) {
|
|
39
|
+
const parsed = parseOneFile(sec);
|
|
40
|
+
if (parsed)
|
|
41
|
+
result.push(parsed);
|
|
42
|
+
}
|
|
43
|
+
return result.length > 0 ? result : [parseOneFile(lines) ?? emptyDiff()];
|
|
44
|
+
}
|
|
45
|
+
/** Parse a single file section into a ParsedDiff. */
|
|
46
|
+
function parseOneFile(lines) {
|
|
47
|
+
const all = [];
|
|
48
|
+
let added = 0, removed = 0;
|
|
49
|
+
let i = 0;
|
|
50
|
+
while (i < lines.length) {
|
|
51
|
+
const raw = lines[i];
|
|
52
|
+
const hdr = parseHunkHeader(raw);
|
|
53
|
+
if (!hdr) {
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// Emit sep for this hunk's metadata (synthetic at position 0 for first)
|
|
58
|
+
if (all.length === 0 || all.filter((l) => l.type !== "sep").length > 0) {
|
|
59
|
+
// After some non-sep content, push a sep for the next hunk
|
|
60
|
+
all.push({ type: "sep", oldNum: null, newNum: null, content: "", hunkMeta: hdr });
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Already have only seps (first hunk) — update the last sep's metadata
|
|
64
|
+
all[all.length - 1] = { type: "sep", oldNum: null, newNum: null, content: "", hunkMeta: hdr };
|
|
65
|
+
}
|
|
66
|
+
let oL = hdr.oldStart;
|
|
67
|
+
let nL = hdr.newStart;
|
|
68
|
+
// Advance past the hunk header
|
|
69
|
+
i++;
|
|
70
|
+
// Process hunk content lines (until next hunk header or end)
|
|
71
|
+
while (i < lines.length) {
|
|
72
|
+
const line = lines[i];
|
|
73
|
+
if (line.startsWith("@@"))
|
|
74
|
+
break; // next hunk header — outer loop handles it
|
|
75
|
+
if (line.startsWith("\\ ")) {
|
|
76
|
+
i++;
|
|
77
|
+
continue; // "\"
|
|
78
|
+
}
|
|
79
|
+
if (/^(---|\+\+\+|diff --git|index |new file|old mode|new mode|deleted|rename|similarity|copy)/.test(line)) {
|
|
80
|
+
i++;
|
|
81
|
+
continue; // skip headers/metadata
|
|
82
|
+
}
|
|
83
|
+
if (line.length === 0 || line[0] === " ") {
|
|
84
|
+
all.push({ type: "ctx", oldNum: oL++, newNum: nL++, content: line.slice(1) });
|
|
85
|
+
}
|
|
86
|
+
else if (line[0] === "+") {
|
|
87
|
+
all.push({ type: "add", oldNum: null, newNum: nL++, content: line.slice(1) });
|
|
88
|
+
added++;
|
|
89
|
+
}
|
|
90
|
+
else if (line[0] === "-") {
|
|
91
|
+
all.push({ type: "del", oldNum: oL++, newNum: null, content: line.slice(1) });
|
|
92
|
+
removed++;
|
|
93
|
+
}
|
|
94
|
+
i++;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (all.length === 0)
|
|
98
|
+
return null;
|
|
99
|
+
// Compute chars from content lines only (not seps)
|
|
100
|
+
let chars = 0;
|
|
101
|
+
for (const l of all) {
|
|
102
|
+
if (l.type !== "sep")
|
|
103
|
+
chars += l.content.length;
|
|
104
|
+
}
|
|
105
|
+
return { lines: all, added, removed, chars };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Parse a hunk header line like:
|
|
109
|
+
* @@ -oldStart,oldCount +newStart,newCount @@ optional func context
|
|
110
|
+
*/
|
|
111
|
+
function parseHunkHeader(line) {
|
|
112
|
+
const m = line.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@(?:\s+(.*))?$/);
|
|
113
|
+
if (!m)
|
|
114
|
+
return null;
|
|
115
|
+
const oldStart = Number(m[1]);
|
|
116
|
+
const oldLines = m[2] ? Number(m[2]) : 1;
|
|
117
|
+
const newStart = Number(m[3]);
|
|
118
|
+
const newLines = m[4] ? Number(m[4]) : 1;
|
|
119
|
+
const context = m[5]?.trim() || undefined;
|
|
120
|
+
return { oldStart, oldLines, newStart, newLines, context };
|
|
121
|
+
}
|
|
122
|
+
function emptyDiff() {
|
|
123
|
+
return { lines: [], added: 0, removed: 0, chars: 0 };
|
|
124
|
+
}
|
|
125
|
+
let _sepStyle = "auto";
|
|
126
|
+
/**
|
|
127
|
+
* Resolve hunk separator style from env var PI_DIFF_SEP_STYLE.
|
|
128
|
+
* Call once during extension init, or with force=true to re-read.
|
|
129
|
+
*/
|
|
130
|
+
export function resolveSepStyle() {
|
|
131
|
+
const fromEnv = process.env.PI_DIFF_SEP_STYLE;
|
|
132
|
+
if (fromEnv && ["auto", "simple", "gap", "context", "metadata"].includes(fromEnv)) {
|
|
133
|
+
_sepStyle = fromEnv;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
_sepStyle = "auto";
|
|
137
|
+
}
|
|
138
|
+
return _sepStyle;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the current separator style (resolved once via resolveSepStyle()).
|
|
142
|
+
*/
|
|
143
|
+
export function getSepStyle() {
|
|
144
|
+
return _sepStyle;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Generate a hunk separator label for the unified view.
|
|
148
|
+
* Returns the full label including spacing, or "···" for empty/default.
|
|
149
|
+
* If `content` is non-empty, it is used directly (e.g. "───── Edit 2 ─────").
|
|
150
|
+
*/
|
|
151
|
+
export function sepLabelUnified(style, hunkMeta, gap, content) {
|
|
152
|
+
// Custom content (e.g. multi-edit separators) takes precedence
|
|
153
|
+
if (content)
|
|
154
|
+
return ` ${content} `;
|
|
155
|
+
const ctx = hunkMeta?.context;
|
|
156
|
+
switch (style) {
|
|
157
|
+
case "simple":
|
|
158
|
+
return "···";
|
|
159
|
+
case "gap":
|
|
160
|
+
if (gap && gap > 0)
|
|
161
|
+
return ` ${gap} unmodified lines `;
|
|
162
|
+
return "···";
|
|
163
|
+
case "context":
|
|
164
|
+
if (ctx)
|
|
165
|
+
return ` ${ctx} `;
|
|
166
|
+
if (gap && gap > 0)
|
|
167
|
+
return ` ${gap} unmodified lines `;
|
|
168
|
+
return "···";
|
|
169
|
+
case "metadata": {
|
|
170
|
+
if (!hunkMeta)
|
|
171
|
+
return "···";
|
|
172
|
+
const hdr = `@@ -${hunkMeta.oldStart},${hunkMeta.oldLines} +${hunkMeta.newStart},${hunkMeta.newLines} @@`;
|
|
173
|
+
const label = ctx ? `${hdr} ${ctx}` : hdr;
|
|
174
|
+
return ` ${label} `;
|
|
175
|
+
}
|
|
176
|
+
case "auto":
|
|
177
|
+
default:
|
|
178
|
+
if (ctx && gap && gap > 0)
|
|
179
|
+
return ` ${ctx} — +${gap} lines `;
|
|
180
|
+
if (ctx)
|
|
181
|
+
return ` ${ctx} `;
|
|
182
|
+
if (gap && gap > 0)
|
|
183
|
+
return ` +${gap} lines `;
|
|
184
|
+
return "···";
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Generate a hunk separator label for the split view.
|
|
189
|
+
* Wraps the content in "··· ... ···".
|
|
190
|
+
* If `content` is non-empty, it is used directly (e.g. "───── Edit 2 ─────").
|
|
191
|
+
*/
|
|
192
|
+
export function sepLabelSplit(style, hunkMeta, gap, content) {
|
|
193
|
+
// Custom content (e.g. multi-edit separators) takes precedence
|
|
194
|
+
if (content)
|
|
195
|
+
return `${content}`;
|
|
196
|
+
const ctx = hunkMeta?.context;
|
|
197
|
+
switch (style) {
|
|
198
|
+
case "simple":
|
|
199
|
+
return "···";
|
|
200
|
+
case "gap":
|
|
201
|
+
if (gap && gap > 0)
|
|
202
|
+
return `··· ${gap} lines ···`;
|
|
203
|
+
return "···";
|
|
204
|
+
case "context":
|
|
205
|
+
if (ctx && gap && gap > 0)
|
|
206
|
+
return `··· ${ctx} — ${gap} lines ···`;
|
|
207
|
+
if (ctx)
|
|
208
|
+
return `··· ${ctx} ···`;
|
|
209
|
+
if (gap && gap > 0)
|
|
210
|
+
return `··· ${gap} lines ···`;
|
|
211
|
+
return "···";
|
|
212
|
+
case "metadata": {
|
|
213
|
+
if (!hunkMeta)
|
|
214
|
+
return "···";
|
|
215
|
+
const hdr = `@@ -${hunkMeta.oldStart},${hunkMeta.oldLines} +${hunkMeta.newStart},${hunkMeta.newLines} @@`;
|
|
216
|
+
const content = ctx ? `${hdr} ${ctx}` : hdr;
|
|
217
|
+
return `··· ${content} ···`;
|
|
218
|
+
}
|
|
219
|
+
case "auto":
|
|
220
|
+
default:
|
|
221
|
+
if (ctx && gap && gap > 0)
|
|
222
|
+
return `··· ${ctx} — +${gap} lines ···`;
|
|
223
|
+
if (ctx)
|
|
224
|
+
return `··· ${ctx} ···`;
|
|
225
|
+
if (gap && gap > 0)
|
|
226
|
+
return `··· +${gap} lines ···`;
|
|
227
|
+
return "···";
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Walk a ParsedDiff and extract hunk blocks.
|
|
232
|
+
* Each block is a group of consecutive deletes followed by consecutive adds.
|
|
233
|
+
* Context and separator lines are skipped.
|
|
234
|
+
*/
|
|
235
|
+
export function computeHunkBlocks(diff) {
|
|
236
|
+
const blocks = [];
|
|
237
|
+
let i = 0;
|
|
238
|
+
const lines = diff.lines;
|
|
239
|
+
while (i < lines.length) {
|
|
240
|
+
if (lines[i].type === "sep" || lines[i].type === "ctx") {
|
|
241
|
+
i++;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
// Collect consecutive deletions
|
|
245
|
+
const deletions = [];
|
|
246
|
+
while (i < lines.length && lines[i].type === "del") {
|
|
247
|
+
deletions.push(lines[i]);
|
|
248
|
+
i++;
|
|
249
|
+
}
|
|
250
|
+
// Collect consecutive additions
|
|
251
|
+
const additions = [];
|
|
252
|
+
while (i < lines.length && lines[i].type === "add") {
|
|
253
|
+
additions.push(lines[i]);
|
|
254
|
+
i++;
|
|
255
|
+
}
|
|
256
|
+
if (deletions.length === 0 && additions.length === 0)
|
|
257
|
+
continue;
|
|
258
|
+
blocks.push({ deletions, additions });
|
|
259
|
+
}
|
|
260
|
+
return blocks;
|
|
261
|
+
}
|
|
2
262
|
export function parseDiff(oldContent, newContent, ctx = 3) {
|
|
3
263
|
const patch = Diff.structuredPatch("", "", oldContent, newContent, "", "", { context: ctx });
|
|
4
264
|
const lines = [];
|
|
5
265
|
let added = 0;
|
|
6
266
|
let removed = 0;
|
|
7
267
|
for (let hi = 0; hi < patch.hunks.length; hi++) {
|
|
268
|
+
const h = patch.hunks[hi];
|
|
269
|
+
const meta = {
|
|
270
|
+
oldStart: h.oldStart,
|
|
271
|
+
oldLines: h.oldLines,
|
|
272
|
+
newStart: h.newStart,
|
|
273
|
+
newLines: h.newLines,
|
|
274
|
+
};
|
|
275
|
+
// Emit hunk metadata as a synthetic sep (position 0 for first hunk,
|
|
276
|
+
// between-hunk sep for subsequent). This ensures every hunk has metadata.
|
|
8
277
|
if (hi > 0) {
|
|
9
278
|
const prev = patch.hunks[hi - 1];
|
|
10
|
-
const gap =
|
|
11
|
-
lines.push({ type: "sep", oldNum: null, newNum: gap > 0 ? gap : null, content: "" });
|
|
279
|
+
const gap = h.oldStart - (prev.oldStart + prev.oldLines);
|
|
280
|
+
lines.push({ type: "sep", oldNum: null, newNum: gap > 0 ? gap : null, content: "", hunkMeta: meta });
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
lines.push({ type: "sep", oldNum: null, newNum: null, content: "", hunkMeta: meta });
|
|
12
284
|
}
|
|
13
|
-
const h = patch.hunks[hi];
|
|
14
285
|
let oL = h.oldStart;
|
|
15
286
|
let nL = h.newStart;
|
|
16
287
|
for (const raw of h.lines) {
|
package/dist/core/diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAgB7B,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,UAAkB,EAAE,GAAG,GAAG,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7F,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;QAChD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC;QACpB,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,GAAG,KAAK,8BAA8B;gBAAE,SAAS;YACrD,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvE,KAAK,EAAE,CAAC;YACT,CAAC;iBAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvE,OAAO,EAAE,CAAC;YACX,CAAC;iBAAM,CAAC;gBACP,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;AAChF,CAAC"}
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* • Async rendering with invalidate() for non-blocking preview
|
|
22
22
|
*/
|
|
23
23
|
import type { BundledLanguage } from "shiki";
|
|
24
|
-
import { type ParsedDiff, parseDiff } from "./core/diff.js";
|
|
24
|
+
import { computeHunkBlocks, type ParsedDiff, getSepStyle, parseDiff, parsePatchFiles, resolveSepStyle } from "./core/diff.js";
|
|
25
25
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
26
26
|
/** Resolved ANSI colors for diff rendering — theme overrides hardcoded defaults. */
|
|
27
27
|
interface DiffColors {
|
|
@@ -33,8 +33,12 @@ declare function normalizeShikiContrast(ansi: string): string;
|
|
|
33
33
|
declare function renderUnified(diff: ParsedDiff, language: BundledLanguage | undefined, max?: number, dc?: DiffColors): Promise<string>;
|
|
34
34
|
declare function renderSplit(diff: ParsedDiff, language: BundledLanguage | undefined, max?: number, dc?: DiffColors): Promise<string>;
|
|
35
35
|
export declare const __testing: {
|
|
36
|
+
computeHunkBlocks: typeof computeHunkBlocks;
|
|
36
37
|
normalizeShikiContrast: typeof normalizeShikiContrast;
|
|
38
|
+
getSepStyle: typeof getSepStyle;
|
|
37
39
|
parseDiff: typeof parseDiff;
|
|
40
|
+
parsePatchFiles: typeof parsePatchFiles;
|
|
41
|
+
resolveSepStyle: typeof resolveSepStyle;
|
|
38
42
|
renderSplit: typeof renderSplit;
|
|
39
43
|
renderUnified: typeof renderUnified;
|
|
40
44
|
};
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAiB,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAiB,KAAK,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAkC,MAAM,gBAAgB,CAAC;AAC7K,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AA2cpE,oFAAoF;AACpF,UAAU,UAAU;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAuKD,iBAAS,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpD;AAuVD,iBAAe,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,GAAG,SAAmB,EACtB,EAAE,GAAE,UAAgC,GAClC,OAAO,CAAC,MAAM,CAAC,CA6HjB;AAMD,iBAAe,WAAW,CACzB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,GAAG,SAAoB,EACvB,EAAE,GAAE,UAAgC,GAClC,OAAO,CAAC,MAAM,CAAC,CAkKjB;AAMD,eAAO,MAAM,SAAS;;;;;;;;;CASrB,CAAC;AAIF,wBAA8B,qBAAqB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4gBnF"}
|