dsh-diff-approval 0.14.0 → 0.15.0
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/lib/client.js +756 -281
- package/lib/index.js +69 -14
- package/lib/types/client/PendingPanel.d.ts +21 -0
- package/lib/types/client/locales.d.ts +10 -2
- package/lib/types/client/settings.d.ts +13 -0
- package/lib/types/client/split-diff.d.ts +7 -4
- package/lib/types/client/whole-file-diff.d.ts +58 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -424,6 +424,11 @@ function defaultOpenPath(path, action) {
|
|
|
424
424
|
/** Cap on one VCS command's runtime; scans (git status, svn status) can be slow
|
|
425
425
|
* on large trees but must not hang the import. */
|
|
426
426
|
const VCS_COMMAND_TIMEOUT_MS = 6e4;
|
|
427
|
+
/** Blobs up to this size are read straight off the executor's buffered stdout
|
|
428
|
+
* (the small-blob path, no temp file); larger blobs go through the checkout-index
|
|
429
|
+
* temp-file path because the executor cap truncates its stdout. Kept below the
|
|
430
|
+
* cap so the small path never truncates. */
|
|
431
|
+
const GIT_BLOB_STDOUT_SAFE = 6e4;
|
|
427
432
|
/** Quote one argument for a POSIX-ish shell, so paths with spaces or special
|
|
428
433
|
* characters survive interpolation into VCS command lines. */
|
|
429
434
|
function shq(value) {
|
|
@@ -528,7 +533,24 @@ async function gitChanges(input) {
|
|
|
528
533
|
if (worktree !== "M" && worktree !== "D") continue;
|
|
529
534
|
let oldText = "";
|
|
530
535
|
try {
|
|
531
|
-
|
|
536
|
+
let size = 0;
|
|
537
|
+
try {
|
|
538
|
+
size = Number.parseInt((await runShell(shell, `git cat-file -s :0:${shq(rel)}`, root, signal)).trim(), 10);
|
|
539
|
+
} catch {
|
|
540
|
+
size = 0;
|
|
541
|
+
}
|
|
542
|
+
if (Number.isFinite(size) && size > 0 && size <= GIT_BLOB_STDOUT_SAFE) oldText = await runShell(shell, `git show :0:${shq(rel)}`, root, signal);
|
|
543
|
+
else {
|
|
544
|
+
const tempRel = (await runShell(shell, `git checkout-index --temp --force -- ${shq(rel)}`, root, signal)).trim().split(/\s+/)[0] ?? "";
|
|
545
|
+
if (tempRel !== "") {
|
|
546
|
+
const tempFile = resolve(root, tempRel);
|
|
547
|
+
try {
|
|
548
|
+
oldText = await readText(tempFile) ?? "";
|
|
549
|
+
} finally {
|
|
550
|
+
await rm(tempFile, { force: true }).catch(() => {});
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
532
554
|
} catch {
|
|
533
555
|
oldText = "";
|
|
534
556
|
}
|
|
@@ -912,7 +934,7 @@ function apply(ctx, config) {
|
|
|
912
934
|
sessionIds: [sessionId]
|
|
913
935
|
};
|
|
914
936
|
await ensureLoaded();
|
|
915
|
-
if (store.fold(entry))
|
|
937
|
+
if (store.fold(entry)) persistSession();
|
|
916
938
|
}
|
|
917
939
|
/** The stable `FsError.code`, when the thrown value carries one. */
|
|
918
940
|
function fsErrorCodeOf(error) {
|
|
@@ -998,13 +1020,13 @@ function apply(ctx, config) {
|
|
|
998
1020
|
entry: void 0,
|
|
999
1021
|
fileText: void 0
|
|
1000
1022
|
});
|
|
1001
|
-
|
|
1023
|
+
persistSession();
|
|
1002
1024
|
continue;
|
|
1003
1025
|
}
|
|
1004
1026
|
if (live.kind === "unavailable") {
|
|
1005
1027
|
store.remove(entry.path);
|
|
1006
1028
|
purgeForEntry(entry.path);
|
|
1007
|
-
|
|
1029
|
+
persistSession();
|
|
1008
1030
|
continue;
|
|
1009
1031
|
}
|
|
1010
1032
|
const content = live.content;
|
|
@@ -1030,7 +1052,7 @@ function apply(ctx, config) {
|
|
|
1030
1052
|
},
|
|
1031
1053
|
fileText: content
|
|
1032
1054
|
});
|
|
1033
|
-
|
|
1055
|
+
persistSession();
|
|
1034
1056
|
if (redoWasPresent) redoCleared = true;
|
|
1035
1057
|
}
|
|
1036
1058
|
const state = {
|
|
@@ -1135,14 +1157,47 @@ function apply(ctx, config) {
|
|
|
1135
1157
|
* file.
|
|
1136
1158
|
* @returns resolution after the write settles (successful or logged).
|
|
1137
1159
|
*/
|
|
1138
|
-
|
|
1139
|
-
|
|
1160
|
+
const PERSIST_THROTTLE_MS = 1e3;
|
|
1161
|
+
let persistDirty = false;
|
|
1162
|
+
let persistScheduled = false;
|
|
1163
|
+
let lastPersistAt = 0;
|
|
1164
|
+
let persistTimer;
|
|
1165
|
+
/** Actually write the (dirty) store to disk; one coalesced write. */
|
|
1166
|
+
async function flushPersist() {
|
|
1167
|
+
if (!persistDirty) return;
|
|
1168
|
+
persistDirty = false;
|
|
1169
|
+
lastPersistAt = Date.now();
|
|
1140
1170
|
try {
|
|
1171
|
+
await ensureLoaded();
|
|
1141
1172
|
await persistence.save(store.all());
|
|
1142
1173
|
} catch (error) {
|
|
1143
1174
|
ctx.logger.warn(`diff-approval: persisting pending changes failed: ${errorMessage(error)}`);
|
|
1144
1175
|
}
|
|
1145
1176
|
}
|
|
1177
|
+
/** Mark the store dirty and schedule one throttled, coalesced write. Pass
|
|
1178
|
+
* `force` to write immediately (user actions need durable, immediate results). */
|
|
1179
|
+
function persistSession(force = false) {
|
|
1180
|
+
persistDirty = true;
|
|
1181
|
+
if (force) {
|
|
1182
|
+
if (persistScheduled) {
|
|
1183
|
+
clearTimeout(persistTimer);
|
|
1184
|
+
persistScheduled = false;
|
|
1185
|
+
}
|
|
1186
|
+
flushPersist();
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
if (persistScheduled) return;
|
|
1190
|
+
const delay = PERSIST_THROTTLE_MS - (Date.now() - lastPersistAt);
|
|
1191
|
+
if (delay <= 0) flushPersist();
|
|
1192
|
+
else {
|
|
1193
|
+
persistScheduled = true;
|
|
1194
|
+
persistTimer = setTimeout(() => {
|
|
1195
|
+
persistScheduled = false;
|
|
1196
|
+
flushPersist();
|
|
1197
|
+
}, delay);
|
|
1198
|
+
persistTimer.unref?.();
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1146
1201
|
ctx.on("tools/result", (exec, result) => {
|
|
1147
1202
|
if (exec.name === "str_replace_editor") {
|
|
1148
1203
|
captureEditorMutation(exec, result);
|
|
@@ -1201,7 +1256,7 @@ function apply(ctx, config) {
|
|
|
1201
1256
|
entry: void 0,
|
|
1202
1257
|
fileText: void 0
|
|
1203
1258
|
});
|
|
1204
|
-
|
|
1259
|
+
persistSession(true);
|
|
1205
1260
|
return {
|
|
1206
1261
|
ok: true,
|
|
1207
1262
|
value: { outcome: "kept" }
|
|
@@ -1247,7 +1302,7 @@ function apply(ctx, config) {
|
|
|
1247
1302
|
}
|
|
1248
1303
|
store.remove(target.id);
|
|
1249
1304
|
if (undo !== void 0) pushUndo(target.sessionId, undo.before, undo.after);
|
|
1250
|
-
|
|
1305
|
+
persistSession(true);
|
|
1251
1306
|
return {
|
|
1252
1307
|
ok: true,
|
|
1253
1308
|
value: { outcome: "reverted" }
|
|
@@ -1281,7 +1336,7 @@ function apply(ctx, config) {
|
|
|
1281
1336
|
entry: afterEntry,
|
|
1282
1337
|
fileText: void 0
|
|
1283
1338
|
});
|
|
1284
|
-
|
|
1339
|
+
persistSession();
|
|
1285
1340
|
return {
|
|
1286
1341
|
ok: true,
|
|
1287
1342
|
value: updatedOld === entry.newText ? {
|
|
@@ -1334,7 +1389,7 @@ function apply(ctx, config) {
|
|
|
1334
1389
|
return rpcError(`block revert failed: ${errorMessage(error)}`);
|
|
1335
1390
|
}
|
|
1336
1391
|
if (undo !== void 0) pushUndo(blockTarget.sessionId, undo.before, undo.after);
|
|
1337
|
-
|
|
1392
|
+
persistSession();
|
|
1338
1393
|
return {
|
|
1339
1394
|
ok: true,
|
|
1340
1395
|
value: normalizeEol(updatedNew) === normalizeEol(entry.oldText) ? {
|
|
@@ -1358,7 +1413,7 @@ function apply(ctx, config) {
|
|
|
1358
1413
|
return rpcError(`undo failed: ${errorMessage(error)}`);
|
|
1359
1414
|
}
|
|
1360
1415
|
redoStack.push(pair);
|
|
1361
|
-
|
|
1416
|
+
persistSession(true);
|
|
1362
1417
|
return {
|
|
1363
1418
|
ok: true,
|
|
1364
1419
|
value: {
|
|
@@ -1382,7 +1437,7 @@ function apply(ctx, config) {
|
|
|
1382
1437
|
return rpcError(`redo failed: ${errorMessage(error)}`);
|
|
1383
1438
|
}
|
|
1384
1439
|
undoStack.push(pair);
|
|
1385
|
-
|
|
1440
|
+
persistSession(true);
|
|
1386
1441
|
return {
|
|
1387
1442
|
ok: true,
|
|
1388
1443
|
value: {
|
|
@@ -1443,7 +1498,7 @@ function apply(ctx, config) {
|
|
|
1443
1498
|
}
|
|
1444
1499
|
}
|
|
1445
1500
|
if (imported > 0) {
|
|
1446
|
-
|
|
1501
|
+
persistSession();
|
|
1447
1502
|
const after = new Map(store.list(sessionId).map((entry) => [entry.path, entry]));
|
|
1448
1503
|
const batchBefore = [];
|
|
1449
1504
|
const batchAfter = [];
|
|
@@ -5,6 +5,7 @@ import type { DiffApprovalBlockRange, PendingFileDiff } from '../types.ts';
|
|
|
5
5
|
import type { PendingPanelFace } from './slots.ts';
|
|
6
6
|
import type { DiffApprovalKey } from './locales.ts';
|
|
7
7
|
import { computeWholeFileDiff } from './whole-file-diff.ts';
|
|
8
|
+
import type { IntraRun } from './whole-file-diff.ts';
|
|
8
9
|
import { highlightLines } from './highlight.ts';
|
|
9
10
|
/** The dsh shell's sidebar auto-collapse breakpoint (ui-layout columns.ts):
|
|
10
11
|
* below it the sidebar auto-collapses, and the file list floats on the same
|
|
@@ -30,6 +31,8 @@ interface RowModel {
|
|
|
30
31
|
diff: ReturnType<typeof computeWholeFileDiff>;
|
|
31
32
|
/** Maximal runs of changed rows (inclusive row indices); one per modification. */
|
|
32
33
|
blocks: ChangeBlock[];
|
|
34
|
+
/** Intra-line runs keyed by row index, present only for annotated del/add rows. */
|
|
35
|
+
intra: Map<number, IntraRun[]>;
|
|
33
36
|
}
|
|
34
37
|
/** One file's deferred syntax-highlight runs, one entry per side. */
|
|
35
38
|
interface HighlightRuns {
|
|
@@ -41,6 +44,14 @@ interface ChangeBlock {
|
|
|
41
44
|
start: number;
|
|
42
45
|
end: number;
|
|
43
46
|
}
|
|
47
|
+
/** One selected line range in row indices, normalized low-to-high. */
|
|
48
|
+
interface RowRange {
|
|
49
|
+
start: number;
|
|
50
|
+
end: number;
|
|
51
|
+
/** Which file's lines a split selection references: 'old' (left column), 'new'
|
|
52
|
+
* (right column); undefined in single column (always the new file). */
|
|
53
|
+
side?: 'old' | 'new';
|
|
54
|
+
}
|
|
44
55
|
/** Imperative surface the parent uses to drive block navigation from the
|
|
45
56
|
* shared toolbar/keyboard in split mode (its own `focus` is private here). */
|
|
46
57
|
export interface SplitDiffHandle {
|
|
@@ -56,9 +67,19 @@ export declare const SplitDiff: import("react").ForwardRefExoticComponent<{
|
|
|
56
67
|
tabWidthSpaces: number;
|
|
57
68
|
busy: boolean;
|
|
58
69
|
t: Translator;
|
|
70
|
+
selection: RowRange | undefined;
|
|
71
|
+
leadRows: number;
|
|
59
72
|
onBlockKeep: (sessionId: SessionId, id: string, block: DiffApprovalBlockRange) => Promise<void>;
|
|
60
73
|
onBlockRevert: (sessionId: SessionId, id: string, block: DiffApprovalBlockRange) => Promise<void>;
|
|
61
74
|
} & import("react").RefAttributes<SplitDiffHandle>>;
|
|
75
|
+
/**
|
|
76
|
+
* Reconstruct the plain text of the current selection so auto-wrap's visual
|
|
77
|
+
* line breaks never leak into the clipboard. A wrapped row renders its code as
|
|
78
|
+
* several `.subline` block elements, and the browser's default copy inserts a
|
|
79
|
+
* newline between them; those segments form one logical line, so they are joined
|
|
80
|
+
* without a newline while the real newline between diff rows is kept.
|
|
81
|
+
*/
|
|
82
|
+
export declare function selectedPlainText(): string | undefined;
|
|
62
83
|
/** Render the pending-edit review panel and its unified footer action. */
|
|
63
84
|
export declare function PendingPanel({ wide, useSessions, usePending, onRefresh, onKeep, onRevert, onBlockKeep, onBlockRevert, onOpen, onPasteReference, onUndo, onRedo, onImportVcs, onAckRedoCleared, onAckJustResolved, collapseSidebar, t, }: PendingPanelProps): import("react").JSX.Element;
|
|
64
85
|
export {};
|
|
@@ -17,7 +17,6 @@ export declare const zh: {
|
|
|
17
17
|
'panel.missingHint': string;
|
|
18
18
|
'panel.externalChanged': string;
|
|
19
19
|
'panel.dismiss': string;
|
|
20
|
-
'panel.createHint': string;
|
|
21
20
|
'panel.pasteOnCopy': string;
|
|
22
21
|
'panel.pasteOnCopyDesc': string;
|
|
23
22
|
'panel.importUntracked': string;
|
|
@@ -26,6 +25,8 @@ export declare const zh: {
|
|
|
26
25
|
'panel.tabWidthDesc': string;
|
|
27
26
|
'panel.splitMode': string;
|
|
28
27
|
'panel.splitModeDesc': string;
|
|
28
|
+
'panel.navLeadRows': string;
|
|
29
|
+
'panel.navLeadRowsDesc': string;
|
|
29
30
|
'panel.quickSummon': string;
|
|
30
31
|
'panel.quickSummonDesc': string;
|
|
31
32
|
'panel.recordShortcut': string;
|
|
@@ -37,6 +38,7 @@ export declare const zh: {
|
|
|
37
38
|
'row.removed': string;
|
|
38
39
|
'action.keep': string;
|
|
39
40
|
'action.revert': string;
|
|
41
|
+
'action.delete': string;
|
|
40
42
|
'action.keepAll': string;
|
|
41
43
|
'action.revertAll': string;
|
|
42
44
|
'action.openFile': string;
|
|
@@ -54,6 +56,8 @@ export declare const zh: {
|
|
|
54
56
|
'action.wrap': string;
|
|
55
57
|
'action.toggleOn': string;
|
|
56
58
|
'action.toggleOff': string;
|
|
59
|
+
'action.decrease': string;
|
|
60
|
+
'action.increase': string;
|
|
57
61
|
'action.importVcs': string;
|
|
58
62
|
'action.importVcsBusy': string;
|
|
59
63
|
'panel.importNone': string;
|
|
@@ -96,7 +100,6 @@ export declare const en: {
|
|
|
96
100
|
'panel.missingHint': string;
|
|
97
101
|
'panel.externalChanged': string;
|
|
98
102
|
'panel.dismiss': string;
|
|
99
|
-
'panel.createHint': string;
|
|
100
103
|
'panel.pasteOnCopy': string;
|
|
101
104
|
'panel.pasteOnCopyDesc': string;
|
|
102
105
|
'panel.importUntracked': string;
|
|
@@ -105,6 +108,8 @@ export declare const en: {
|
|
|
105
108
|
'panel.tabWidthDesc': string;
|
|
106
109
|
'panel.splitMode': string;
|
|
107
110
|
'panel.splitModeDesc': string;
|
|
111
|
+
'panel.navLeadRows': string;
|
|
112
|
+
'panel.navLeadRowsDesc': string;
|
|
108
113
|
'panel.quickSummon': string;
|
|
109
114
|
'panel.quickSummonDesc': string;
|
|
110
115
|
'panel.recordShortcut': string;
|
|
@@ -116,6 +121,7 @@ export declare const en: {
|
|
|
116
121
|
'row.removed': string;
|
|
117
122
|
'action.keep': string;
|
|
118
123
|
'action.revert': string;
|
|
124
|
+
'action.delete': string;
|
|
119
125
|
'action.keepAll': string;
|
|
120
126
|
'action.revertAll': string;
|
|
121
127
|
'action.openFile': string;
|
|
@@ -133,6 +139,8 @@ export declare const en: {
|
|
|
133
139
|
'action.wrap': string;
|
|
134
140
|
'action.toggleOn': string;
|
|
135
141
|
'action.toggleOff': string;
|
|
142
|
+
'action.decrease': string;
|
|
143
|
+
'action.increase': string;
|
|
136
144
|
'action.importVcs': string;
|
|
137
145
|
'action.importVcsBusy': string;
|
|
138
146
|
'panel.importNone': string;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/** Client preferences for the review panel, persisted in localStorage. */
|
|
2
|
+
/** Default lead rows above a jumped-to diff block (kept small and bounded). */
|
|
3
|
+
export declare const NAV_LEAD_ROWS_DEFAULT = 2;
|
|
4
|
+
export declare const NAV_LEAD_ROWS_MIN = 0;
|
|
5
|
+
export declare const NAV_LEAD_ROWS_MAX = 10;
|
|
2
6
|
/**
|
|
3
7
|
* Whether copying a reference should also paste it into the chat input and
|
|
4
8
|
* focus it. Defaults to on; only an explicit `'0'` disables it.
|
|
@@ -45,6 +49,15 @@ export declare function setTabWidth(value: number): void;
|
|
|
45
49
|
export declare function splitMode(): boolean;
|
|
46
50
|
/** Persist the split-view preference. */
|
|
47
51
|
export declare function setSplitMode(value: boolean): void;
|
|
52
|
+
/**
|
|
53
|
+
* How many rows of lead the diff block jump leaves above the jumped-to block,
|
|
54
|
+
* and how far the anchored navigation scans. Defaults to 2; an out-of-range or
|
|
55
|
+
* non-integer value falls back to the default.
|
|
56
|
+
* @returns the lead row count.
|
|
57
|
+
*/
|
|
58
|
+
export declare function navLeadRows(): number;
|
|
59
|
+
/** Persist the block-jump lead row count. */
|
|
60
|
+
export declare function setNavLeadRows(value: number): void;
|
|
48
61
|
/** Default quick-summon chord (toggle the review panel open/closed). */
|
|
49
62
|
export declare const DEFAULT_QUICK_SUMMON = "Ctrl+D";
|
|
50
63
|
/**
|
|
@@ -32,13 +32,16 @@ export interface SplitDiff {
|
|
|
32
32
|
pairOfRow: ReadonlyMap<number, number>;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Regroup the whole-file rows into aligned split pairs,
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* Regroup the whole-file rows into aligned split pairs. By order, a deletion
|
|
36
|
+
* run pairs line-by-line with a following addition run; with similarity
|
|
37
|
+
* alignment, each deletion pairs with its most-similar addition (order
|
|
38
|
+
* preserved, threshold-bounded) so a mixed insert/delete block does not force a
|
|
39
|
+
* wrong line together. A stray deletion or addition stays a one-sided pair.
|
|
38
40
|
* @param rows - the whole-file diff rows.
|
|
41
|
+
* @param alignBySimilarity - align a change block by similarity instead of order.
|
|
39
42
|
* @returns the split pairs plus the row→pair index map.
|
|
40
43
|
*/
|
|
41
|
-
export declare function computeSideBySideDiff(rows: readonly WholeFileDiffRow[]): SplitDiff;
|
|
44
|
+
export declare function computeSideBySideDiff(rows: readonly WholeFileDiffRow[], alignBySimilarity?: boolean): SplitDiff;
|
|
42
45
|
/**
|
|
43
46
|
* Pair indices whose left or right text contains the query (case-insensitive).
|
|
44
47
|
* A pair counts once however many times the query appears, so split search
|
|
@@ -47,3 +47,61 @@ export interface WholeFileDiff {
|
|
|
47
47
|
*/
|
|
48
48
|
export declare function contentKey(text: string): string;
|
|
49
49
|
export declare function computeWholeFileDiff(oldText: string, newText: string): WholeFileDiff;
|
|
50
|
+
/**
|
|
51
|
+
* One intra-line segment of a changed line, used to highlight which characters
|
|
52
|
+
* within a paired del/add line differ. A run is either unmarked context
|
|
53
|
+
* (`same`) or the characters that were removed (`del`) /
|
|
54
|
+
* added (`add`). Reassembling the runs of a del row in order yields the old
|
|
55
|
+
* line's text; the runs of the paired add row yield the new line's text.
|
|
56
|
+
*/
|
|
57
|
+
export interface IntraRun {
|
|
58
|
+
text: string;
|
|
59
|
+
kind: 'same' | 'del' | 'add';
|
|
60
|
+
}
|
|
61
|
+
/** One matched del→add row pair within a change block. */
|
|
62
|
+
interface BlockPair {
|
|
63
|
+
delIndex: number;
|
|
64
|
+
addIndex: number;
|
|
65
|
+
}
|
|
66
|
+
/** The alignment of one del/add change block: matched pairs and excess sides. */
|
|
67
|
+
export interface BlockAlignment {
|
|
68
|
+
/** Matched del→add pairs, in file order. */
|
|
69
|
+
pairs: BlockPair[];
|
|
70
|
+
/** Row indices of unmatched deletions (shown as del-only in the split view). */
|
|
71
|
+
delOnly: number[];
|
|
72
|
+
/** Row indices of unmatched additions (shown as add-only in the split view). */
|
|
73
|
+
addOnly: number[];
|
|
74
|
+
/** True when similarity matching actually ran. False for a by-order block or a
|
|
75
|
+
* block too large to match — the caller then skips the intra-line highlight so
|
|
76
|
+
* alignment and highlighting are all-or-nothing (either both or neither). */
|
|
77
|
+
usedSimilarity: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Align a del run with the following add run. By order (the baseline) pairs
|
|
81
|
+
* `del[i]`↔`add[i]`. With similarity alignment, an order-preserving best match
|
|
82
|
+
* pairs each del with the add that maximises total similarity, keeping a pair
|
|
83
|
+
* only when it clears the similarity threshold — so a lone insert or delete in
|
|
84
|
+
* a mixed block stays unaligned instead of being forced onto a wrong line.
|
|
85
|
+
* @param delRows - the run's del rows (index + text).
|
|
86
|
+
* @param addRows - the run's add rows (index + text).
|
|
87
|
+
* @param alignBySimilarity - whether to use the similarity-based matching.
|
|
88
|
+
* @returns the aligned pairs and the unmatched sides.
|
|
89
|
+
*/
|
|
90
|
+
export declare function alignChangedBlock(delRows: readonly {
|
|
91
|
+
index: number;
|
|
92
|
+
text: string;
|
|
93
|
+
}[], addRows: readonly {
|
|
94
|
+
index: number;
|
|
95
|
+
text: string;
|
|
96
|
+
}[], alignBySimilarity: boolean): BlockAlignment;
|
|
97
|
+
/**
|
|
98
|
+
* Derive intra-line runs for a whole-file row list. Each del/add block is
|
|
99
|
+
* aligned (by order, or by similarity when `alignBySimilarity`), and each
|
|
100
|
+
* matched pair is compared by `intraRunsOf`. Returns a map keyed by the row's
|
|
101
|
+
* index in `rows`, present only for rows that carry a highlight.
|
|
102
|
+
* @param rows - the unified `WholeFileDiff` row list.
|
|
103
|
+
* @param alignBySimilarity - align blocks by similarity instead of by order.
|
|
104
|
+
* @returns per-row-index intra-line runs for annotated del/add rows.
|
|
105
|
+
*/
|
|
106
|
+
export declare function computeIntraLineDiff(rows: readonly WholeFileDiffRow[], alignBySimilarity?: boolean): Map<number, IntraRun[]>;
|
|
107
|
+
export {};
|
package/package.json
CHANGED