@oh-my-pi/hashline 15.10.4 → 15.10.5
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/dist/types/diff-preview.d.ts +6 -4
- package/dist/types/types.d.ts +4 -2
- package/package.json +1 -1
- package/src/diff-preview.ts +84 -21
- package/src/types.ts +4 -2
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Re-number a unified diff that uses the `+<lineNum>|content` /
|
|
3
3
|
* `-<lineNum>|content` / ` <lineNum>|content` line format into a compact
|
|
4
|
-
* preview
|
|
5
|
-
*
|
|
6
|
-
* so a follow-up edit can reuse
|
|
4
|
+
* current-file preview. Removed lines are counted for stats and post-edit
|
|
5
|
+
* offset tracking, but omitted from the preview. Added and context lines are
|
|
6
|
+
* anchored to their post-edit positions so a follow-up edit can reuse visible
|
|
7
|
+
* concrete lines directly. Long contiguous added runs are summarized with a
|
|
8
|
+
* `…` marker instead of echoing every inserted line.
|
|
7
9
|
*
|
|
8
10
|
* This is intentionally decoupled from the diff producer: anything that
|
|
9
11
|
* emits the `<sign><lineNum>|<content>` shape works.
|
|
10
12
|
*/
|
|
11
13
|
import type { CompactDiffOptions, CompactDiffPreview } from "./types";
|
|
12
|
-
export declare function buildCompactDiffPreview(diff: string,
|
|
14
|
+
export declare function buildCompactDiffPreview(diff: string, options?: CompactDiffOptions): CompactDiffPreview;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -103,9 +103,11 @@ export interface CompactDiffPreview {
|
|
|
103
103
|
addedLines: number;
|
|
104
104
|
removedLines: number;
|
|
105
105
|
}
|
|
106
|
-
/** Optional knobs for {@link buildCompactDiffPreview}.
|
|
106
|
+
/** Optional knobs for {@link buildCompactDiffPreview}. */
|
|
107
107
|
export interface CompactDiffOptions {
|
|
108
|
-
/**
|
|
108
|
+
/** Added lines kept on each side of a long added-run elision (default 2). */
|
|
109
|
+
maxAddedRunContext?: number;
|
|
110
|
+
/** Back-compat alias for {@link maxAddedRunContext}. */
|
|
109
111
|
maxUnchangedRun?: number;
|
|
110
112
|
}
|
|
111
113
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/hashline",
|
|
4
|
-
"version": "15.10.
|
|
4
|
+
"version": "15.10.5",
|
|
5
5
|
"description": "Hashline: a compact, line-anchored patch language and applier. Pluggable FS/IO so it works over disk, in-memory, or any custom backend.",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
package/src/diff-preview.ts
CHANGED
|
@@ -1,49 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Re-number a unified diff that uses the `+<lineNum>|content` /
|
|
3
3
|
* `-<lineNum>|content` / ` <lineNum>|content` line format into a compact
|
|
4
|
-
* preview
|
|
5
|
-
*
|
|
6
|
-
* so a follow-up edit can reuse
|
|
4
|
+
* current-file preview. Removed lines are counted for stats and post-edit
|
|
5
|
+
* offset tracking, but omitted from the preview. Added and context lines are
|
|
6
|
+
* anchored to their post-edit positions so a follow-up edit can reuse visible
|
|
7
|
+
* concrete lines directly. Long contiguous added runs are summarized with a
|
|
8
|
+
* `…` marker instead of echoing every inserted line.
|
|
7
9
|
*
|
|
8
10
|
* This is intentionally decoupled from the diff producer: anything that
|
|
9
11
|
* emits the `<sign><lineNum>|<content>` shape works.
|
|
10
12
|
*/
|
|
11
13
|
import type { CompactDiffOptions, CompactDiffPreview } from "./types";
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
const DEFAULT_ADDED_RUN_CONTEXT_LINES = 2;
|
|
16
|
+
|
|
17
|
+
const PREVIEW_ELISION_MARKER = "…";
|
|
18
|
+
const RAW_ELISION_MARKERS = new Set(["...", PREVIEW_ELISION_MARKER, `+${PREVIEW_ELISION_MARKER}`]);
|
|
19
|
+
|
|
20
|
+
function appendPreviewLine(output: string[], line: string): void {
|
|
21
|
+
const normalized = RAW_ELISION_MARKERS.has(line) ? PREVIEW_ELISION_MARKER : line;
|
|
22
|
+
if (normalized === PREVIEW_ELISION_MARKER && output[output.length - 1] === PREVIEW_ELISION_MARKER) return;
|
|
23
|
+
output.push(normalized);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ParsedDiffLine {
|
|
27
|
+
kind: "+" | "-" | " ";
|
|
28
|
+
lineNumber: number;
|
|
29
|
+
content: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function normalizeAddedRunContext(value: number | undefined): number {
|
|
33
|
+
if (value === undefined || !Number.isFinite(value)) return DEFAULT_ADDED_RUN_CONTEXT_LINES;
|
|
34
|
+
return Math.max(1, Math.trunc(value));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseNumberedDiffLine(line: string): ParsedDiffLine | undefined {
|
|
38
|
+
const kind = line[0];
|
|
39
|
+
if (kind !== "+" && kind !== "-" && kind !== " ") return undefined;
|
|
40
|
+
|
|
41
|
+
const body = line.slice(1);
|
|
42
|
+
const sep = body.indexOf("|");
|
|
43
|
+
if (sep === -1) return undefined;
|
|
44
|
+
|
|
45
|
+
const lineNumber = Number.parseInt(body.slice(0, sep), 10);
|
|
46
|
+
if (!Number.isFinite(lineNumber)) return undefined;
|
|
47
|
+
|
|
48
|
+
return { kind, lineNumber, content: body.slice(sep + 1) };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function appendAddedRun(output: string[], run: string[], edgeLines: number): void {
|
|
52
|
+
if (run.length === 0) return;
|
|
53
|
+
|
|
54
|
+
const collapseThreshold = edgeLines * 2 + 1;
|
|
55
|
+
if (run.length <= collapseThreshold) {
|
|
56
|
+
for (const text of run) appendPreviewLine(output, text);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < edgeLines; i++) appendPreviewLine(output, run[i]);
|
|
61
|
+
appendPreviewLine(output, PREVIEW_ELISION_MARKER);
|
|
62
|
+
for (let i = run.length - edgeLines; i < run.length; i++) appendPreviewLine(output, run[i]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function buildCompactDiffPreview(diff: string, options: CompactDiffOptions = {}): CompactDiffPreview {
|
|
14
66
|
const lines = diff.length === 0 ? [] : diff.split("\n");
|
|
67
|
+
const addedRunContext = normalizeAddedRunContext(options.maxAddedRunContext ?? options.maxUnchangedRun);
|
|
15
68
|
let addedLines = 0;
|
|
16
69
|
let removedLines = 0;
|
|
70
|
+
const formatted: string[] = [];
|
|
71
|
+
const addedRun: string[] = [];
|
|
72
|
+
|
|
73
|
+
const flushAddedRun = (): void => {
|
|
74
|
+
appendAddedRun(formatted, addedRun, addedRunContext);
|
|
75
|
+
addedRun.length = 0;
|
|
76
|
+
};
|
|
17
77
|
|
|
18
78
|
// External diff producers number `+` lines with the post-edit line number,
|
|
19
79
|
// `-` lines with the pre-edit line number, and context lines with the
|
|
20
80
|
// pre-edit line number. To emit fresh line numbers usable for follow-up
|
|
21
81
|
// edits, convert context-line numbers to post-edit positions by tracking
|
|
22
82
|
// the running offset (added so far - removed so far) as we walk the diff.
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const lineNumber = Number.parseInt(body.slice(0, sep), 10);
|
|
32
|
-
const content = body.slice(sep + 1);
|
|
83
|
+
for (const line of lines) {
|
|
84
|
+
const parsed = parseNumberedDiffLine(line);
|
|
85
|
+
if (!parsed) {
|
|
86
|
+
flushAddedRun();
|
|
87
|
+
appendPreviewLine(formatted, line);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
33
90
|
|
|
34
|
-
switch (kind) {
|
|
35
|
-
case "+":
|
|
91
|
+
switch (parsed.kind) {
|
|
92
|
+
case "+": {
|
|
36
93
|
addedLines++;
|
|
37
|
-
|
|
94
|
+
addedRun.push(`${parsed.lineNumber}:${parsed.content}`);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
38
97
|
case "-":
|
|
98
|
+
flushAddedRun();
|
|
39
99
|
removedLines++;
|
|
40
|
-
|
|
100
|
+
break;
|
|
41
101
|
default: {
|
|
42
|
-
|
|
43
|
-
|
|
102
|
+
flushAddedRun();
|
|
103
|
+
const newLineNumber = parsed.lineNumber + addedLines - removedLines;
|
|
104
|
+
appendPreviewLine(formatted, `${newLineNumber}:${parsed.content}`);
|
|
105
|
+
break;
|
|
44
106
|
}
|
|
45
107
|
}
|
|
46
|
-
}
|
|
108
|
+
}
|
|
109
|
+
flushAddedRun();
|
|
47
110
|
|
|
48
111
|
return { preview: formatted.join("\n"), addedLines, removedLines };
|
|
49
112
|
}
|
package/src/types.ts
CHANGED
|
@@ -103,9 +103,11 @@ export interface CompactDiffPreview {
|
|
|
103
103
|
removedLines: number;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
/** Optional knobs for {@link buildCompactDiffPreview}.
|
|
106
|
+
/** Optional knobs for {@link buildCompactDiffPreview}. */
|
|
107
107
|
export interface CompactDiffOptions {
|
|
108
|
-
/**
|
|
108
|
+
/** Added lines kept on each side of a long added-run elision (default 2). */
|
|
109
|
+
maxAddedRunContext?: number;
|
|
110
|
+
/** Back-compat alias for {@link maxAddedRunContext}. */
|
|
109
111
|
maxUnchangedRun?: number;
|
|
110
112
|
}
|
|
111
113
|
|