@pierre/diffs 1.2.12 → 1.3.0-beta.10
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/components/CodeView.d.ts +91 -6
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +300 -38
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +14 -3
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +98 -12
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +68 -19
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +363 -25
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/FileStream.d.ts.map +1 -1
- package/dist/components/FileStream.js +2 -1
- package/dist/components/FileStream.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +2 -2
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +2 -2
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtualizedFile.d.ts +4 -2
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +59 -47
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +27 -5
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +262 -56
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +4 -1
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +21 -4
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -1
- package/dist/constants.js.map +1 -1
- package/dist/editor/command.d.ts +7 -0
- package/dist/editor/command.d.ts.map +1 -0
- package/dist/editor/command.js +54 -0
- package/dist/editor/command.js.map +1 -0
- package/dist/editor/editStack.d.ts +71 -0
- package/dist/editor/editStack.d.ts.map +1 -0
- package/dist/editor/editStack.js +218 -0
- package/dist/editor/editStack.js.map +1 -0
- package/dist/editor/editor.d.ts +105 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +2545 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/editor2.js +6 -0
- package/dist/editor/editor2.js.map +1 -0
- package/dist/editor/index.d.ts +5 -0
- package/dist/editor/index.js +3 -0
- package/dist/editor/languages.d.ts +26 -0
- package/dist/editor/languages.d.ts.map +1 -0
- package/dist/editor/languages.js +363 -0
- package/dist/editor/languages.js.map +1 -0
- package/dist/editor/lineAnnotations.d.ts +9 -0
- package/dist/editor/lineAnnotations.d.ts.map +1 -0
- package/dist/editor/lineAnnotations.js +212 -0
- package/dist/editor/lineAnnotations.js.map +1 -0
- package/dist/editor/marker.d.ts +38 -0
- package/dist/editor/marker.d.ts.map +1 -0
- package/dist/editor/marker.js +245 -0
- package/dist/editor/marker.js.map +1 -0
- package/dist/editor/matchBrackets.d.ts +9 -0
- package/dist/editor/matchBrackets.d.ts.map +1 -0
- package/dist/editor/matchBrackets.js +138 -0
- package/dist/editor/matchBrackets.js.map +1 -0
- package/dist/editor/pieceTable.d.ts +41 -0
- package/dist/editor/pieceTable.d.ts.map +1 -0
- package/dist/editor/pieceTable.js +671 -0
- package/dist/editor/pieceTable.js.map +1 -0
- package/dist/editor/platform.d.ts +19 -0
- package/dist/editor/platform.d.ts.map +1 -0
- package/dist/editor/platform.js +57 -0
- package/dist/editor/platform.js.map +1 -0
- package/dist/editor/popover.d.ts +65 -0
- package/dist/editor/popover.d.ts.map +1 -0
- package/dist/editor/popover.js +187 -0
- package/dist/editor/popover.js.map +1 -0
- package/dist/editor/searchPanel.d.ts +40 -0
- package/dist/editor/searchPanel.d.ts.map +1 -0
- package/dist/editor/searchPanel.js +318 -0
- package/dist/editor/searchPanel.js.map +1 -0
- package/dist/editor/selection.d.ts +211 -0
- package/dist/editor/selection.d.ts.map +1 -0
- package/dist/editor/selection.js +1626 -0
- package/dist/editor/selection.js.map +1 -0
- package/dist/editor/selectionAction.d.ts +46 -0
- package/dist/editor/selectionAction.d.ts.map +1 -0
- package/dist/editor/selectionAction.js +64 -0
- package/dist/editor/selectionAction.js.map +1 -0
- package/dist/editor/sprite.d.ts +8 -0
- package/dist/editor/sprite.d.ts.map +1 -0
- package/dist/editor/sprite.js +45 -0
- package/dist/editor/sprite.js.map +1 -0
- package/dist/editor/stateStorage.d.ts +15 -0
- package/dist/editor/stateStorage.d.ts.map +1 -0
- package/dist/editor/stateStorage.js +65 -0
- package/dist/editor/stateStorage.js.map +1 -0
- package/dist/editor/textDocument.d.ts +77 -0
- package/dist/editor/textDocument.d.ts.map +1 -0
- package/dist/editor/textDocument.js +271 -0
- package/dist/editor/textDocument.js.map +1 -0
- package/dist/editor/textMeasure.d.ts +61 -0
- package/dist/editor/textMeasure.d.ts.map +1 -0
- package/dist/editor/textMeasure.js +209 -0
- package/dist/editor/textMeasure.js.map +1 -0
- package/dist/editor/tokenizer.d.ts +41 -0
- package/dist/editor/tokenizer.d.ts.map +1 -0
- package/dist/editor/tokenizer.js +513 -0
- package/dist/editor/tokenizer.js.map +1 -0
- package/dist/editor/utils.d.ts +21 -0
- package/dist/editor/utils.d.ts.map +1 -0
- package/dist/editor/utils.js +68 -0
- package/dist/editor/utils.js.map +1 -0
- package/dist/index.d.ts +10 -8
- package/dist/index.js +12 -10
- package/dist/managers/InteractionManager.d.ts +7 -0
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +22 -1
- package/dist/managers/InteractionManager.js.map +1 -1
- package/dist/managers/ResizeManager.d.ts +10 -2
- package/dist/managers/ResizeManager.d.ts.map +1 -1
- package/dist/managers/ResizeManager.js +33 -13
- package/dist/managers/ResizeManager.js.map +1 -1
- package/dist/managers/UniversalRenderingManager.d.ts +2 -1
- package/dist/managers/UniversalRenderingManager.d.ts.map +1 -1
- package/dist/managers/UniversalRenderingManager.js +6 -1
- package/dist/managers/UniversalRenderingManager.js.map +1 -1
- package/dist/react/CodeView.d.ts +26 -1
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +82 -19
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/EditContext.d.ts +15 -0
- package/dist/react/EditContext.d.ts.map +1 -0
- package/dist/react/EditContext.js +23 -0
- package/dist/react/EditContext.js.map +1 -0
- package/dist/react/File.d.ts +3 -1
- package/dist/react/File.d.ts.map +1 -1
- package/dist/react/File.js +4 -2
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.d.ts +4 -1
- package/dist/react/FileDiff.d.ts.map +1 -1
- package/dist/react/FileDiff.js +4 -2
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +7 -5
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js +4 -2
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.d.ts +4 -1
- package/dist/react/PatchDiff.d.ts.map +1 -1
- package/dist/react/PatchDiff.js +4 -2
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/UnresolvedFile.d.ts +1 -0
- package/dist/react/UnresolvedFile.d.ts.map +1 -1
- package/dist/react/UnresolvedFile.js +2 -1
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +2 -1
- package/dist/react/types.d.ts +3 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.d.ts +2 -0
- package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.js +16 -8
- package/dist/react/utils/renderDiffChildren.js.map +1 -1
- package/dist/react/utils/renderFileChildren.d.ts +2 -0
- package/dist/react/utils/renderFileChildren.d.ts.map +1 -1
- package/dist/react/utils/renderFileChildren.js +16 -8
- package/dist/react/utils/renderFileChildren.js.map +1 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +3 -1
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +30 -6
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +4 -1
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +30 -5
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +28 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +244 -22
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +8 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +155 -45
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/preloadDiffs.d.ts +11 -10
- package/dist/ssr/preloadDiffs.d.ts.map +1 -1
- package/dist/ssr/preloadDiffs.js +15 -7
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/types.d.ts +282 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/applyLineTextWithNewline.d.ts +5 -0
- package/dist/utils/applyLineTextWithNewline.d.ts.map +1 -0
- package/dist/utils/applyLineTextWithNewline.js +11 -0
- package/dist/utils/applyLineTextWithNewline.js.map +1 -0
- package/dist/utils/areHunkDataEqual.js +1 -1
- package/dist/utils/areHunkDataEqual.js.map +1 -1
- package/dist/utils/areManagedSnapshotsEqual.d.ts +2 -2
- package/dist/utils/areManagedSnapshotsEqual.d.ts.map +1 -1
- package/dist/utils/areManagedSnapshotsEqual.js +5 -0
- package/dist/utils/areManagedSnapshotsEqual.js.map +1 -1
- package/dist/utils/awaitWithTimeout.d.ts +5 -0
- package/dist/utils/awaitWithTimeout.d.ts.map +1 -0
- package/dist/utils/awaitWithTimeout.js +15 -0
- package/dist/utils/awaitWithTimeout.js.map +1 -0
- package/dist/utils/cleanLastNewline.js +6 -1
- package/dist/utils/cleanLastNewline.js.map +1 -1
- package/dist/utils/cloneFileDiffMetadata.d.ts +7 -0
- package/dist/utils/cloneFileDiffMetadata.d.ts.map +1 -0
- package/dist/utils/cloneFileDiffMetadata.js +16 -0
- package/dist/utils/cloneFileDiffMetadata.js.map +1 -0
- package/dist/utils/computeEstimatedDiffHeights.d.ts +3 -1
- package/dist/utils/computeEstimatedDiffHeights.d.ts.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.js +8 -1
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
- package/dist/utils/computeFileOffsets.d.ts +21 -0
- package/dist/utils/computeFileOffsets.d.ts.map +1 -0
- package/dist/utils/computeFileOffsets.js +51 -0
- package/dist/utils/computeFileOffsets.js.map +1 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts +5 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.d.ts.map +1 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.js +19 -0
- package/dist/utils/createCodeViewHeaderFooterHostElement.js.map +1 -0
- package/dist/utils/createFileHeaderElement.d.ts.map +1 -1
- package/dist/utils/createFileHeaderElement.js +5 -1
- package/dist/utils/createFileHeaderElement.js.map +1 -1
- package/dist/utils/createTransformerWithState.js +9 -0
- package/dist/utils/createTransformerWithState.js.map +1 -1
- package/dist/utils/editSessionHunks.d.ts +84 -0
- package/dist/utils/editSessionHunks.d.ts.map +1 -0
- package/dist/utils/editSessionHunks.js +366 -0
- package/dist/utils/editSessionHunks.js.map +1 -0
- package/dist/utils/getDiffFileInput.d.ts +14 -0
- package/dist/utils/getDiffFileInput.d.ts.map +1 -0
- package/dist/utils/getDiffFileInput.js +24 -0
- package/dist/utils/getDiffFileInput.js.map +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js +1 -0
- package/dist/utils/getDiffHunksRendererOptions.js.map +1 -1
- package/dist/utils/getFiletypeFromFileName.d.ts.map +1 -1
- package/dist/utils/getFiletypeFromFileName.js +2 -0
- package/dist/utils/getFiletypeFromFileName.js.map +1 -1
- package/dist/utils/hydratePartialDiff.d.ts +10 -0
- package/dist/utils/hydratePartialDiff.d.ts.map +1 -0
- package/dist/utils/hydratePartialDiff.js +140 -0
- package/dist/utils/hydratePartialDiff.js.map +1 -0
- package/dist/utils/iterateOverDiff.js +3 -3
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/parseDiffFromFile.d.ts +1 -1
- package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseDiffFromFile.js +26 -5
- package/dist/utils/parseDiffFromFile.js.map +1 -1
- package/dist/utils/parsePatchFiles.d.ts.map +1 -1
- package/dist/utils/parsePatchFiles.js +2 -0
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/realignChangeContent.d.ts +28 -0
- package/dist/utils/realignChangeContent.d.ts.map +1 -0
- package/dist/utils/realignChangeContent.js +142 -0
- package/dist/utils/realignChangeContent.js.map +1 -0
- package/dist/utils/renderDiffWithHighlighter.js +1 -1
- package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
- package/dist/utils/renderFileWithHighlighter.js +5 -14
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +24 -0
- package/dist/utils/updateDiffHunks.d.ts.map +1 -0
- package/dist/utils/updateDiffHunks.js +235 -0
- package/dist/utils/updateDiffHunks.js.map +1 -0
- package/dist/utils/virtualDiffLayout.d.ts +40 -1
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
- package/dist/utils/virtualDiffLayout.js +96 -1
- package/dist/utils/virtualDiffLayout.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts +7 -2
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +83 -18
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/index.d.ts +2 -2
- package/dist/worker/types.d.ts +11 -1
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +46 -66
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +46 -66
- package/dist/worker/worker.js.map +1 -1
- package/package.json +12 -5
- package/dist/utils/iterateOverFile.d.ts +0 -50
- package/dist/utils/iterateOverFile.d.ts.map +0 -1
- package/dist/utils/iterateOverFile.js +0 -49
- package/dist/utils/iterateOverFile.js.map +0 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { cleanLastNewline } from "./cleanLastNewline.js";
|
|
2
|
+
import { parseDiffFromFile } from "./parseDiffFromFile.js";
|
|
3
|
+
import { hasTrailingContextMismatch } from "./virtualDiffLayout.js";
|
|
4
|
+
//#region src/utils/updateDiffHunks.ts
|
|
5
|
+
/** Rebuilds all hunk metadata from the current deletion/addition line arrays. */
|
|
6
|
+
function recomputeDiffHunks(diff, parseDiffOptions) {
|
|
7
|
+
const recomputed = parseDiffFromFile({
|
|
8
|
+
name: diff.prevName ?? diff.name,
|
|
9
|
+
contents: diff.deletionLines.join("")
|
|
10
|
+
}, {
|
|
11
|
+
name: diff.name,
|
|
12
|
+
contents: diff.additionLines.join(""),
|
|
13
|
+
lang: diff.lang
|
|
14
|
+
}, parseDiffOptions);
|
|
15
|
+
return {
|
|
16
|
+
hunks: recomputed.hunks,
|
|
17
|
+
splitLineCount: recomputed.splitLineCount,
|
|
18
|
+
unifiedLineCount: recomputed.unifiedLineCount,
|
|
19
|
+
additionLines: recomputed.additionLines,
|
|
20
|
+
deletionLines: recomputed.deletionLines,
|
|
21
|
+
type: recomputed.type
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function buildTopAlignedAdditionSentinel(lineCount, deletionContents) {
|
|
25
|
+
const count = Math.max(lineCount, 1);
|
|
26
|
+
let sentinel = Array.from({ length: count }, (_, index) => `${" ".repeat(index + 1)}\n`).join("");
|
|
27
|
+
if (sentinel === deletionContents) sentinel = Array.from({ length: count }, (_, index) => `\u0000${" ".repeat(index)}\n`).join("");
|
|
28
|
+
return sentinel;
|
|
29
|
+
}
|
|
30
|
+
function hasOnlyBlankAdditionContents(additionLines) {
|
|
31
|
+
for (const line of additionLines) if (line.trim().length > 0) return false;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
function shouldTopAlignAdditionRecompute(diff, additionLines) {
|
|
35
|
+
return additionLines.length > 0 && additionLines.length < diff.deletionLines.length && hasOnlyBlankAdditionContents(additionLines);
|
|
36
|
+
}
|
|
37
|
+
function recomputeTopAlignedAdditionDiff(diff, additionLines, parseDiffOptions) {
|
|
38
|
+
const deletionContents = diff.deletionLines.join("");
|
|
39
|
+
const additionSentinel = buildTopAlignedAdditionSentinel(additionLines.length, deletionContents);
|
|
40
|
+
const recomputed = parseDiffFromFile({
|
|
41
|
+
name: diff.prevName ?? diff.name,
|
|
42
|
+
contents: deletionContents
|
|
43
|
+
}, {
|
|
44
|
+
name: diff.name,
|
|
45
|
+
contents: additionSentinel,
|
|
46
|
+
lang: diff.lang
|
|
47
|
+
}, parseDiffOptions);
|
|
48
|
+
return {
|
|
49
|
+
hunks: recomputed.hunks,
|
|
50
|
+
splitLineCount: recomputed.splitLineCount,
|
|
51
|
+
unifiedLineCount: recomputed.unifiedLineCount,
|
|
52
|
+
additionLines,
|
|
53
|
+
deletionLines: recomputed.deletionLines,
|
|
54
|
+
type: recomputed.type
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function recomputeEmptyDocumentDiff(diff, parseDiffOptions) {
|
|
58
|
+
return recomputeTopAlignedAdditionDiff(diff, [""], parseDiffOptions);
|
|
59
|
+
}
|
|
60
|
+
/** Rebuilds diff hunks after an edit, top-aligning sparse addition sides when needed. */
|
|
61
|
+
function recomputeDiffHunksForEdit(diff, parseDiffOptions) {
|
|
62
|
+
if (diff.additionLines.length === 0) return recomputeEmptyDocumentDiff(diff, parseDiffOptions);
|
|
63
|
+
if (shouldTopAlignAdditionRecompute(diff, diff.additionLines)) return recomputeTopAlignedAdditionDiff(diff, diff.additionLines, parseDiffOptions);
|
|
64
|
+
const additionLines = diff.additionLines;
|
|
65
|
+
const recomputed = recomputeDiffHunks(diff, parseDiffOptions);
|
|
66
|
+
preserveTrailingEditorBlankLine(recomputed, additionLines);
|
|
67
|
+
return recomputed;
|
|
68
|
+
}
|
|
69
|
+
function hasTrailingEditorBlankLine(additionLines) {
|
|
70
|
+
return additionLines.length > 1 && additionLines.at(-1) === "";
|
|
71
|
+
}
|
|
72
|
+
function preserveTrailingEditorBlankLine(recomputed, additionLines) {
|
|
73
|
+
if (!hasTrailingEditorBlankLine(additionLines)) return;
|
|
74
|
+
const extraLineCount = additionLines.length - recomputed.additionLines.length;
|
|
75
|
+
if (extraLineCount <= 0) return;
|
|
76
|
+
const extraAdditionLineIndex = recomputed.additionLines.length;
|
|
77
|
+
const lastHunk = recomputed.hunks.at(-1);
|
|
78
|
+
if (lastHunk == null) return;
|
|
79
|
+
if (lastHunk.additionLineIndex + lastHunk.additionCount !== extraAdditionLineIndex) return;
|
|
80
|
+
for (const content of lastHunk.hunkContent) if (content.type === "change" && content.additions < content.deletions && content.additionLineIndex + content.additions === extraAdditionLineIndex) {
|
|
81
|
+
recomputed.additionLines = additionLines;
|
|
82
|
+
content.additions += extraLineCount;
|
|
83
|
+
lastHunk.additionCount += extraLineCount;
|
|
84
|
+
lastHunk.additionLines += extraLineCount;
|
|
85
|
+
recomputeDiffRenderLineCounts(recomputed);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Updates hunk metadata after addition lines change; re-parses affected hunks only. */
|
|
90
|
+
function updateDiffHunks(diff, changedAdditionLineIndexes, parseDiffOptions) {
|
|
91
|
+
if (diff.isPartial) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
92
|
+
if (diff.deletionLines.length !== diff.additionLines.length) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
93
|
+
const changedLines = Array.from(changedAdditionLineIndexes);
|
|
94
|
+
if (changedLines.length === 0) return applyHunkUpdateResult(diff, {
|
|
95
|
+
hunks: diff.hunks,
|
|
96
|
+
splitLineCount: diff.splitLineCount,
|
|
97
|
+
unifiedLineCount: diff.unifiedLineCount,
|
|
98
|
+
type: diff.type
|
|
99
|
+
});
|
|
100
|
+
for (const line of changedLines) {
|
|
101
|
+
const additionLine = diff.additionLines[line];
|
|
102
|
+
const deletionLine = diff.deletionLines[line];
|
|
103
|
+
if (additionLine == null || deletionLine == null) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
104
|
+
if (cleanLastNewline(additionLine) === cleanLastNewline(deletionLine)) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
105
|
+
}
|
|
106
|
+
const affectedHunkIndexes = getAffectedHunkIndexes(diff, changedLines);
|
|
107
|
+
if (affectedHunkIndexes.size === 0) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
108
|
+
for (const hunkIndex of affectedHunkIndexes) if (!reparseHunkRegion(diff, hunkIndex, parseDiffOptions)) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
109
|
+
recomputeDiffRenderLineCounts(diff);
|
|
110
|
+
if (hasTrailingContextMismatch(diff)) return applyHunkUpdateResult(diff, recomputeDiffHunks(diff, parseDiffOptions));
|
|
111
|
+
return applyHunkUpdateResult(diff, {
|
|
112
|
+
hunks: diff.hunks,
|
|
113
|
+
splitLineCount: diff.splitLineCount,
|
|
114
|
+
unifiedLineCount: diff.unifiedLineCount,
|
|
115
|
+
type: diff.type
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function applyHunkUpdateResult(diff, result) {
|
|
119
|
+
Object.assign(diff, result);
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
function getAffectedHunkIndexes(diff, changedAdditionLineIndexes) {
|
|
123
|
+
const indexes = /* @__PURE__ */ new Set();
|
|
124
|
+
for (const line of changedAdditionLineIndexes) {
|
|
125
|
+
const hunkIndex = findHunkIndexForAdditionLine(diff, line);
|
|
126
|
+
if (hunkIndex == null) return /* @__PURE__ */ new Set();
|
|
127
|
+
indexes.add(hunkIndex);
|
|
128
|
+
}
|
|
129
|
+
return indexes;
|
|
130
|
+
}
|
|
131
|
+
function findHunkIndexForAdditionLine(diff, line) {
|
|
132
|
+
for (const [hunkIndex, hunk] of diff.hunks.entries()) {
|
|
133
|
+
const end = hunk.additionLineIndex + hunk.additionCount;
|
|
134
|
+
if (line >= hunk.additionLineIndex && line < end) return hunkIndex;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function reparseHunkRegion(diff, hunkIndex, parseDiffOptions) {
|
|
138
|
+
const hunk = diff.hunks[hunkIndex];
|
|
139
|
+
if (hunk == null) return false;
|
|
140
|
+
const deletionSlice = diff.deletionLines.slice(hunk.deletionLineIndex, hunk.deletionLineIndex + hunk.deletionCount);
|
|
141
|
+
const additionSlice = diff.additionLines.slice(hunk.additionLineIndex, hunk.additionLineIndex + hunk.additionCount);
|
|
142
|
+
const reparsed = parseDiffFromFile({
|
|
143
|
+
name: diff.prevName ?? diff.name,
|
|
144
|
+
contents: deletionSlice.join("")
|
|
145
|
+
}, {
|
|
146
|
+
name: diff.name,
|
|
147
|
+
contents: additionSlice.join(""),
|
|
148
|
+
lang: diff.lang
|
|
149
|
+
}, {
|
|
150
|
+
...parseDiffOptions,
|
|
151
|
+
context: 0
|
|
152
|
+
});
|
|
153
|
+
const reparsedHunk = reparsed.hunks[0];
|
|
154
|
+
if (reparsedHunk == null || reparsed.hunks.length !== 1) return false;
|
|
155
|
+
applyReparsedHunk(hunk, reparsedHunk);
|
|
156
|
+
syncHunkNoEOFCRFromFullFile(diff, hunkIndex);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
function syncHunkNoEOFCRFromFullFile(diff, hunkIndex) {
|
|
160
|
+
const hunk = diff.hunks[hunkIndex];
|
|
161
|
+
if (hunk == null) return;
|
|
162
|
+
if (!(hunkIndex === diff.hunks.length - 1)) {
|
|
163
|
+
hunk.noEOFCRAdditions = false;
|
|
164
|
+
hunk.noEOFCRDeletions = false;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const lastAdditionLine = diff.additionLines.at(-1);
|
|
168
|
+
const lastDeletionLine = diff.deletionLines.at(-1);
|
|
169
|
+
hunk.noEOFCRAdditions = lastAdditionLine != null && lastAdditionLine !== "" && !lastAdditionLine.endsWith("\n");
|
|
170
|
+
hunk.noEOFCRDeletions = lastDeletionLine != null && lastDeletionLine !== "" && !lastDeletionLine.endsWith("\n");
|
|
171
|
+
}
|
|
172
|
+
function applyReparsedHunk(target, parsed) {
|
|
173
|
+
const additionOffset = target.additionLineIndex;
|
|
174
|
+
const deletionOffset = target.deletionLineIndex;
|
|
175
|
+
target.hunkContent = parsed.hunkContent.map((content) => offsetHunkContent(content, additionOffset, deletionOffset));
|
|
176
|
+
target.additionLineIndex = additionOffset + parsed.additionLineIndex;
|
|
177
|
+
target.additionStart = target.additionStart + parsed.additionLineIndex;
|
|
178
|
+
target.additionCount = parsed.additionCount;
|
|
179
|
+
target.additionLines = parsed.additionLines;
|
|
180
|
+
if (parsed.deletionLineIndex >= 0) {
|
|
181
|
+
target.deletionLineIndex = deletionOffset + parsed.deletionLineIndex;
|
|
182
|
+
target.deletionStart = target.deletionStart + parsed.deletionLineIndex;
|
|
183
|
+
}
|
|
184
|
+
target.deletionCount = parsed.deletionCount;
|
|
185
|
+
target.deletionLines = parsed.deletionLines;
|
|
186
|
+
target.noEOFCRAdditions = parsed.noEOFCRAdditions;
|
|
187
|
+
target.noEOFCRDeletions = parsed.noEOFCRDeletions;
|
|
188
|
+
recomputeHunkRenderLineCounts(target);
|
|
189
|
+
}
|
|
190
|
+
function offsetHunkContent(content, additionOffset, deletionOffset) {
|
|
191
|
+
return {
|
|
192
|
+
...content,
|
|
193
|
+
additionLineIndex: content.additionLineIndex + additionOffset,
|
|
194
|
+
deletionLineIndex: content.deletionLineIndex + deletionOffset
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function recomputeHunkRenderLineCounts(hunk) {
|
|
198
|
+
let splitLineCount = 0;
|
|
199
|
+
let unifiedLineCount = 0;
|
|
200
|
+
for (const content of hunk.hunkContent) if (content.type === "context") {
|
|
201
|
+
splitLineCount += content.lines;
|
|
202
|
+
unifiedLineCount += content.lines;
|
|
203
|
+
} else {
|
|
204
|
+
splitLineCount += Math.max(content.additions, content.deletions);
|
|
205
|
+
unifiedLineCount += content.additions + content.deletions;
|
|
206
|
+
}
|
|
207
|
+
hunk.splitLineCount = splitLineCount;
|
|
208
|
+
hunk.unifiedLineCount = unifiedLineCount;
|
|
209
|
+
}
|
|
210
|
+
function recomputeDiffRenderLineCounts(diff) {
|
|
211
|
+
let splitTotal = 0;
|
|
212
|
+
let unifiedTotal = 0;
|
|
213
|
+
let lastHunkAdditionEnd = 0;
|
|
214
|
+
for (const hunk of diff.hunks) {
|
|
215
|
+
hunk.collapsedBefore = Math.max(hunk.additionStart - 1 - lastHunkAdditionEnd, 0);
|
|
216
|
+
hunk.splitLineStart = splitTotal + hunk.collapsedBefore;
|
|
217
|
+
hunk.unifiedLineStart = unifiedTotal + hunk.collapsedBefore;
|
|
218
|
+
recomputeHunkRenderLineCounts(hunk);
|
|
219
|
+
splitTotal += hunk.collapsedBefore + hunk.splitLineCount;
|
|
220
|
+
unifiedTotal += hunk.collapsedBefore + hunk.unifiedLineCount;
|
|
221
|
+
lastHunkAdditionEnd = hunk.additionStart + hunk.additionCount - 1;
|
|
222
|
+
}
|
|
223
|
+
if (diff.hunks.length > 0) {
|
|
224
|
+
const lastHunk = diff.hunks[diff.hunks.length - 1];
|
|
225
|
+
const collapsedAfter = Math.max(diff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount), 0);
|
|
226
|
+
splitTotal += collapsedAfter;
|
|
227
|
+
unifiedTotal += collapsedAfter;
|
|
228
|
+
}
|
|
229
|
+
diff.splitLineCount = splitTotal;
|
|
230
|
+
diff.unifiedLineCount = unifiedTotal;
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
export { offsetHunkContent, preserveTrailingEditorBlankLine, recomputeDiffHunks, recomputeDiffHunksForEdit, recomputeDiffRenderLineCounts, recomputeEmptyDocumentDiff, recomputeHunkRenderLineCounts, recomputeTopAlignedAdditionDiff, shouldTopAlignAdditionRecompute, syncHunkNoEOFCRFromFullFile, updateDiffHunks };
|
|
234
|
+
|
|
235
|
+
//# sourceMappingURL=updateDiffHunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateDiffHunks.js","names":[],"sources":["../../src/utils/updateDiffHunks.ts"],"sourcesContent":["import type { CreatePatchOptionsNonabortable } from 'diff';\n\nimport type {\n ChangeContent,\n ContextContent,\n FileDiffMetadata,\n Hunk,\n} from '../types';\nimport { cleanLastNewline } from './cleanLastNewline';\nimport { parseDiffFromFile } from './parseDiffFromFile';\nimport { hasTrailingContextMismatch } from './virtualDiffLayout';\n\ntype HunkContent = ContextContent | ChangeContent;\n\ntype HunkMetadataUpdate = Pick<\n FileDiffMetadata,\n 'hunks' | 'splitLineCount' | 'unifiedLineCount' | 'type'\n>;\n\ntype FullDiffHunkUpdate = HunkMetadataUpdate &\n Pick<FileDiffMetadata, 'additionLines' | 'deletionLines'>;\n\n/** Rebuilds all hunk metadata from the current deletion/addition line arrays. */\nexport function recomputeDiffHunks(\n diff: FileDiffMetadata,\n parseDiffOptions?: CreatePatchOptionsNonabortable\n): FullDiffHunkUpdate {\n const recomputed = parseDiffFromFile(\n {\n name: diff.prevName ?? diff.name,\n contents: diff.deletionLines.join(''),\n },\n {\n name: diff.name,\n contents: diff.additionLines.join(''),\n lang: diff.lang,\n },\n parseDiffOptions\n );\n return {\n hunks: recomputed.hunks,\n splitLineCount: recomputed.splitLineCount,\n unifiedLineCount: recomputed.unifiedLineCount,\n additionLines: recomputed.additionLines,\n deletionLines: recomputed.deletionLines,\n type: recomputed.type,\n };\n}\n\n// Builds placeholder addition contents that diff as one top-aligned change row per\n// line. Bare `\\\\n` sentinels align as context against the first deletion lines,\n// which pushes the real addition rows down in split view.\nfunction buildTopAlignedAdditionSentinel(\n lineCount: number,\n deletionContents: string\n): string {\n const count = Math.max(lineCount, 1);\n let sentinel = Array.from(\n { length: count },\n (_, index) => `${' '.repeat(index + 1)}\\n`\n ).join('');\n if (sentinel === deletionContents) {\n sentinel = Array.from(\n { length: count },\n (_, index) => `\\u0000${' '.repeat(index)}\\n`\n ).join('');\n }\n return sentinel;\n}\n\nfunction hasOnlyBlankAdditionContents(additionLines: string[]): boolean {\n for (const line of additionLines) {\n if (line.trim().length > 0) {\n return false;\n }\n }\n return true;\n}\n\n// After delete-all the editable side is blank and much shorter than the deletion\n// side. A normal recompute can still treat newline-only additions as context and\n// render the first editable row deep in split view instead of at the top.\nexport function shouldTopAlignAdditionRecompute(\n diff: FileDiffMetadata,\n additionLines: string[]\n): boolean {\n return (\n additionLines.length > 0 &&\n additionLines.length < diff.deletionLines.length &&\n hasOnlyBlankAdditionContents(additionLines)\n );\n}\n\n// Rebuilds hunk metadata while keeping the editable addition rows top-aligned in\n// split view. The sentinel only shapes hunks; the caller's addition lines are\n// preserved so the editor document stays the source of truth.\nexport function recomputeTopAlignedAdditionDiff(\n diff: FileDiffMetadata,\n additionLines: string[],\n parseDiffOptions?: CreatePatchOptionsNonabortable\n): FullDiffHunkUpdate {\n const deletionContents = diff.deletionLines.join('');\n const additionSentinel = buildTopAlignedAdditionSentinel(\n additionLines.length,\n deletionContents\n );\n const recomputed = parseDiffFromFile(\n {\n name: diff.prevName ?? diff.name,\n contents: deletionContents,\n },\n {\n name: diff.name,\n contents: additionSentinel,\n lang: diff.lang,\n },\n parseDiffOptions\n );\n return {\n hunks: recomputed.hunks,\n splitLineCount: recomputed.splitLineCount,\n unifiedLineCount: recomputed.unifiedLineCount,\n additionLines,\n deletionLines: recomputed.deletionLines,\n type: recomputed.type,\n };\n}\n\n// Rebuilds hunk metadata when the editable side has been emptied of all text.\n//\n// The editor always keeps one (empty) line for an empty document, but an empty\n// string splits into zero addition lines, so a normal recompute produces a diff\n// with no addition rows at all. Rendering that leaves the attached editor with\n// no line element to host its caret.\nexport function recomputeEmptyDocumentDiff(\n diff: FileDiffMetadata,\n parseDiffOptions?: CreatePatchOptionsNonabortable\n): FullDiffHunkUpdate {\n return recomputeTopAlignedAdditionDiff(diff, [''], parseDiffOptions);\n}\n\n/** Rebuilds diff hunks after an edit, top-aligning sparse addition sides when needed. */\nexport function recomputeDiffHunksForEdit(\n diff: FileDiffMetadata,\n parseDiffOptions?: CreatePatchOptionsNonabortable\n): FullDiffHunkUpdate {\n if (diff.additionLines.length === 0) {\n return recomputeEmptyDocumentDiff(diff, parseDiffOptions);\n }\n if (shouldTopAlignAdditionRecompute(diff, diff.additionLines)) {\n return recomputeTopAlignedAdditionDiff(\n diff,\n diff.additionLines,\n parseDiffOptions\n );\n }\n const additionLines = diff.additionLines;\n const recomputed = recomputeDiffHunks(diff, parseDiffOptions);\n preserveTrailingEditorBlankLine(recomputed, additionLines);\n return recomputed;\n}\n\nfunction hasTrailingEditorBlankLine(additionLines: string[]): boolean {\n return additionLines.length > 1 && additionLines.at(-1) === '';\n}\n\n// Re-adds the editor's phantom trailing empty line (a document ending in a\n// newline exposes one extra empty line) as an addition row when the last\n// hunk's final change block can absorb it, so the caret keeps a rendered row.\nexport function preserveTrailingEditorBlankLine(\n recomputed: Pick<\n FullDiffHunkUpdate,\n 'hunks' | 'additionLines' | 'splitLineCount' | 'unifiedLineCount'\n >,\n additionLines: string[]\n): void {\n if (!hasTrailingEditorBlankLine(additionLines)) {\n return;\n }\n const extraLineCount = additionLines.length - recomputed.additionLines.length;\n if (extraLineCount <= 0) {\n return;\n }\n const extraAdditionLineIndex = recomputed.additionLines.length;\n\n const lastHunk = recomputed.hunks.at(-1);\n if (lastHunk == null) {\n return;\n }\n\n const lastHunkAdditionEnd =\n lastHunk.additionLineIndex + lastHunk.additionCount;\n if (lastHunkAdditionEnd !== extraAdditionLineIndex) {\n return;\n }\n\n for (const content of lastHunk.hunkContent) {\n if (\n content.type === 'change' &&\n content.additions < content.deletions &&\n content.additionLineIndex + content.additions === extraAdditionLineIndex\n ) {\n recomputed.additionLines = additionLines;\n content.additions += extraLineCount;\n lastHunk.additionCount += extraLineCount;\n lastHunk.additionLines += extraLineCount;\n recomputeDiffRenderLineCounts(recomputed);\n return;\n }\n }\n}\n\n/** Updates hunk metadata after addition lines change; re-parses affected hunks only. */\nexport function updateDiffHunks(\n diff: FileDiffMetadata,\n changedAdditionLineIndexes: Iterable<number>,\n parseDiffOptions?: CreatePatchOptionsNonabortable\n): HunkMetadataUpdate {\n if (diff.isPartial) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n\n if (diff.deletionLines.length !== diff.additionLines.length) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n\n const changedLines = Array.from(changedAdditionLineIndexes);\n if (changedLines.length === 0) {\n return applyHunkUpdateResult(diff, {\n hunks: diff.hunks,\n splitLineCount: diff.splitLineCount,\n unifiedLineCount: diff.unifiedLineCount,\n type: diff.type,\n });\n }\n for (const line of changedLines) {\n const additionLine = diff.additionLines[line];\n const deletionLine = diff.deletionLines[line];\n if (additionLine == null || deletionLine == null) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n // Restoring a line to the old side can merge/split hunks across context windows.\n if (cleanLastNewline(additionLine) === cleanLastNewline(deletionLine)) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n }\n\n const affectedHunkIndexes = getAffectedHunkIndexes(diff, changedLines);\n if (affectedHunkIndexes.size === 0) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n\n for (const hunkIndex of affectedHunkIndexes) {\n const updated = reparseHunkRegion(diff, hunkIndex, parseDiffOptions);\n if (!updated) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n }\n\n recomputeDiffRenderLineCounts(diff);\n\n if (hasTrailingContextMismatch(diff)) {\n return applyHunkUpdateResult(\n diff,\n recomputeDiffHunks(diff, parseDiffOptions)\n );\n }\n\n return applyHunkUpdateResult(diff, {\n hunks: diff.hunks,\n splitLineCount: diff.splitLineCount,\n unifiedLineCount: diff.unifiedLineCount,\n type: diff.type,\n });\n}\n\nfunction applyHunkUpdateResult<T extends HunkMetadataUpdate>(\n diff: FileDiffMetadata,\n result: T\n): T {\n Object.assign(diff, result);\n return result;\n}\n\nfunction getAffectedHunkIndexes(\n diff: FileDiffMetadata,\n changedAdditionLineIndexes: Iterable<number>\n): Set<number> {\n const indexes = new Set<number>();\n for (const line of changedAdditionLineIndexes) {\n const hunkIndex = findHunkIndexForAdditionLine(diff, line);\n if (hunkIndex == null) {\n return new Set();\n }\n indexes.add(hunkIndex);\n }\n return indexes;\n}\n\nfunction findHunkIndexForAdditionLine(\n diff: FileDiffMetadata,\n line: number\n): number | undefined {\n for (const [hunkIndex, hunk] of diff.hunks.entries()) {\n const end = hunk.additionLineIndex + hunk.additionCount;\n if (line >= hunk.additionLineIndex && line < end) {\n return hunkIndex;\n }\n }\n return undefined;\n}\n\nfunction reparseHunkRegion(\n diff: FileDiffMetadata,\n hunkIndex: number,\n parseDiffOptions?: CreatePatchOptionsNonabortable\n): boolean {\n const hunk = diff.hunks[hunkIndex];\n if (hunk == null) {\n return false;\n }\n\n const deletionSlice = diff.deletionLines.slice(\n hunk.deletionLineIndex,\n hunk.deletionLineIndex + hunk.deletionCount\n );\n const additionSlice = diff.additionLines.slice(\n hunk.additionLineIndex,\n hunk.additionLineIndex + hunk.additionCount\n );\n\n const reparsed = parseDiffFromFile(\n {\n name: diff.prevName ?? diff.name,\n contents: deletionSlice.join(''),\n },\n {\n name: diff.name,\n contents: additionSlice.join(''),\n lang: diff.lang,\n },\n { ...parseDiffOptions, context: 0 }\n );\n\n const reparsedHunk = reparsed.hunks[0];\n if (reparsedHunk == null || reparsed.hunks.length !== 1) {\n return false;\n }\n\n applyReparsedHunk(hunk, reparsedHunk);\n syncHunkNoEOFCRFromFullFile(diff, hunkIndex);\n return true;\n}\n\nexport function syncHunkNoEOFCRFromFullFile(\n diff: FileDiffMetadata,\n hunkIndex: number\n): void {\n const hunk = diff.hunks[hunkIndex];\n if (hunk == null) {\n return;\n }\n\n const isLastHunk = hunkIndex === diff.hunks.length - 1;\n if (!isLastHunk) {\n hunk.noEOFCRAdditions = false;\n hunk.noEOFCRDeletions = false;\n return;\n }\n\n const lastAdditionLine = diff.additionLines.at(-1);\n const lastDeletionLine = diff.deletionLines.at(-1);\n hunk.noEOFCRAdditions =\n lastAdditionLine != null &&\n lastAdditionLine !== '' &&\n !lastAdditionLine.endsWith('\\n');\n hunk.noEOFCRDeletions =\n lastDeletionLine != null &&\n lastDeletionLine !== '' &&\n !lastDeletionLine.endsWith('\\n');\n}\n\nfunction applyReparsedHunk(target: Hunk, parsed: Hunk): void {\n const additionOffset = target.additionLineIndex;\n const deletionOffset = target.deletionLineIndex;\n\n target.hunkContent = parsed.hunkContent.map((content) =>\n offsetHunkContent(content, additionOffset, deletionOffset)\n );\n target.additionLineIndex = additionOffset + parsed.additionLineIndex;\n target.additionStart = target.additionStart + parsed.additionLineIndex;\n target.additionCount = parsed.additionCount;\n target.additionLines = parsed.additionLines;\n if (parsed.deletionLineIndex >= 0) {\n target.deletionLineIndex = deletionOffset + parsed.deletionLineIndex;\n target.deletionStart = target.deletionStart + parsed.deletionLineIndex;\n }\n target.deletionCount = parsed.deletionCount;\n target.deletionLines = parsed.deletionLines;\n target.noEOFCRAdditions = parsed.noEOFCRAdditions;\n target.noEOFCRDeletions = parsed.noEOFCRDeletions;\n\n recomputeHunkRenderLineCounts(target);\n}\n\nexport function offsetHunkContent(\n content: HunkContent,\n additionOffset: number,\n deletionOffset: number\n): HunkContent {\n return {\n ...content,\n additionLineIndex: content.additionLineIndex + additionOffset,\n deletionLineIndex: content.deletionLineIndex + deletionOffset,\n };\n}\n\nexport function recomputeHunkRenderLineCounts(hunk: Hunk): void {\n let splitLineCount = 0;\n let unifiedLineCount = 0;\n\n for (const content of hunk.hunkContent) {\n if (content.type === 'context') {\n splitLineCount += content.lines;\n unifiedLineCount += content.lines;\n } else {\n splitLineCount += Math.max(content.additions, content.deletions);\n unifiedLineCount += content.additions + content.deletions;\n }\n }\n\n hunk.splitLineCount = splitLineCount;\n hunk.unifiedLineCount = unifiedLineCount;\n}\n\nexport function recomputeDiffRenderLineCounts(\n diff: Pick<\n FileDiffMetadata,\n 'hunks' | 'splitLineCount' | 'unifiedLineCount' | 'additionLines'\n >\n): void {\n let splitTotal = 0;\n let unifiedTotal = 0;\n let lastHunkAdditionEnd = 0;\n\n for (const hunk of diff.hunks) {\n hunk.collapsedBefore = Math.max(\n hunk.additionStart - 1 - lastHunkAdditionEnd,\n 0\n );\n hunk.splitLineStart = splitTotal + hunk.collapsedBefore;\n hunk.unifiedLineStart = unifiedTotal + hunk.collapsedBefore;\n\n recomputeHunkRenderLineCounts(hunk);\n\n splitTotal += hunk.collapsedBefore + hunk.splitLineCount;\n unifiedTotal += hunk.collapsedBefore + hunk.unifiedLineCount;\n lastHunkAdditionEnd = hunk.additionStart + hunk.additionCount - 1;\n }\n\n if (diff.hunks.length > 0) {\n const lastHunk = diff.hunks[diff.hunks.length - 1];\n const collapsedAfter = Math.max(\n diff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount),\n 0\n );\n splitTotal += collapsedAfter;\n unifiedTotal += collapsedAfter;\n }\n\n diff.splitLineCount = splitTotal;\n diff.unifiedLineCount = unifiedTotal;\n}\n"],"mappings":";;;;;AAuBA,SAAgB,mBACd,MACA,kBACoB;CACpB,MAAM,aAAa,kBACjB;EACE,MAAM,KAAK,YAAY,KAAK;EAC5B,UAAU,KAAK,cAAc,KAAK,EAAE;CACtC,GACA;EACE,MAAM,KAAK;EACX,UAAU,KAAK,cAAc,KAAK,EAAE;EACpC,MAAM,KAAK;CACb,GACA,gBACF;CACA,OAAO;EACL,OAAO,WAAW;EAClB,gBAAgB,WAAW;EAC3B,kBAAkB,WAAW;EAC7B,eAAe,WAAW;EAC1B,eAAe,WAAW;EAC1B,MAAM,WAAW;CACnB;AACF;AAKA,SAAS,gCACP,WACA,kBACQ;CACR,MAAM,QAAQ,KAAK,IAAI,WAAW,CAAC;CACnC,IAAI,WAAW,MAAM,KACnB,EAAE,QAAQ,MAAM,IACf,GAAG,UAAU,GAAG,IAAI,OAAO,QAAQ,CAAC,EAAE,GACzC,CAAC,CAAC,KAAK,EAAE;CACT,IAAI,aAAa,kBACf,WAAW,MAAM,KACf,EAAE,QAAQ,MAAM,IACf,GAAG,UAAU,SAAS,IAAI,OAAO,KAAK,EAAE,GAC3C,CAAC,CAAC,KAAK,EAAE;CAEX,OAAO;AACT;AAEA,SAAS,6BAA6B,eAAkC;CACtE,KAAK,MAAM,QAAQ,eACjB,IAAI,KAAK,KAAK,CAAC,CAAC,SAAS,GACvB,OAAO;CAGX,OAAO;AACT;AAKA,SAAgB,gCACd,MACA,eACS;CACT,OACE,cAAc,SAAS,KACvB,cAAc,SAAS,KAAK,cAAc,UAC1C,6BAA6B,aAAa;AAE9C;AAKA,SAAgB,gCACd,MACA,eACA,kBACoB;CACpB,MAAM,mBAAmB,KAAK,cAAc,KAAK,EAAE;CACnD,MAAM,mBAAmB,gCACvB,cAAc,QACd,gBACF;CACA,MAAM,aAAa,kBACjB;EACE,MAAM,KAAK,YAAY,KAAK;EAC5B,UAAU;CACZ,GACA;EACE,MAAM,KAAK;EACX,UAAU;EACV,MAAM,KAAK;CACb,GACA,gBACF;CACA,OAAO;EACL,OAAO,WAAW;EAClB,gBAAgB,WAAW;EAC3B,kBAAkB,WAAW;EAC7B;EACA,eAAe,WAAW;EAC1B,MAAM,WAAW;CACnB;AACF;AAQA,SAAgB,2BACd,MACA,kBACoB;CACpB,OAAO,gCAAgC,MAAM,CAAC,EAAE,GAAG,gBAAgB;AACrE;;AAGA,SAAgB,0BACd,MACA,kBACoB;CACpB,IAAI,KAAK,cAAc,WAAW,GAChC,OAAO,2BAA2B,MAAM,gBAAgB;CAE1D,IAAI,gCAAgC,MAAM,KAAK,aAAa,GAC1D,OAAO,gCACL,MACA,KAAK,eACL,gBACF;CAEF,MAAM,gBAAgB,KAAK;CAC3B,MAAM,aAAa,mBAAmB,MAAM,gBAAgB;CAC5D,gCAAgC,YAAY,aAAa;CACzD,OAAO;AACT;AAEA,SAAS,2BAA2B,eAAkC;CACpE,OAAO,cAAc,SAAS,KAAK,cAAc,GAAG,EAAE,MAAM;AAC9D;AAKA,SAAgB,gCACd,YAIA,eACM;CACN,IAAI,CAAC,2BAA2B,aAAa,GAC3C;CAEF,MAAM,iBAAiB,cAAc,SAAS,WAAW,cAAc;CACvE,IAAI,kBAAkB,GACpB;CAEF,MAAM,yBAAyB,WAAW,cAAc;CAExD,MAAM,WAAW,WAAW,MAAM,GAAG,EAAE;CACvC,IAAI,YAAY,MACd;CAKF,IADE,SAAS,oBAAoB,SAAS,kBACZ,wBAC1B;CAGF,KAAK,MAAM,WAAW,SAAS,aAC7B,IACE,QAAQ,SAAS,YACjB,QAAQ,YAAY,QAAQ,aAC5B,QAAQ,oBAAoB,QAAQ,cAAc,wBAClD;EACA,WAAW,gBAAgB;EAC3B,QAAQ,aAAa;EACrB,SAAS,iBAAiB;EAC1B,SAAS,iBAAiB;EAC1B,8BAA8B,UAAU;EACxC;CACF;AAEJ;;AAGA,SAAgB,gBACd,MACA,4BACA,kBACoB;CACpB,IAAI,KAAK,WACP,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;CAGF,IAAI,KAAK,cAAc,WAAW,KAAK,cAAc,QACnD,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;CAGF,MAAM,eAAe,MAAM,KAAK,0BAA0B;CAC1D,IAAI,aAAa,WAAW,GAC1B,OAAO,sBAAsB,MAAM;EACjC,OAAO,KAAK;EACZ,gBAAgB,KAAK;EACrB,kBAAkB,KAAK;EACvB,MAAM,KAAK;CACb,CAAC;CAEH,KAAK,MAAM,QAAQ,cAAc;EAC/B,MAAM,eAAe,KAAK,cAAc;EACxC,MAAM,eAAe,KAAK,cAAc;EACxC,IAAI,gBAAgB,QAAQ,gBAAgB,MAC1C,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;EAGF,IAAI,iBAAiB,YAAY,MAAM,iBAAiB,YAAY,GAClE,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;CAEJ;CAEA,MAAM,sBAAsB,uBAAuB,MAAM,YAAY;CACrE,IAAI,oBAAoB,SAAS,GAC/B,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;CAGF,KAAK,MAAM,aAAa,qBAEtB,IAAI,CADY,kBAAkB,MAAM,WAAW,gBACxC,GACT,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;CAIJ,8BAA8B,IAAI;CAElC,IAAI,2BAA2B,IAAI,GACjC,OAAO,sBACL,MACA,mBAAmB,MAAM,gBAAgB,CAC3C;CAGF,OAAO,sBAAsB,MAAM;EACjC,OAAO,KAAK;EACZ,gBAAgB,KAAK;EACrB,kBAAkB,KAAK;EACvB,MAAM,KAAK;CACb,CAAC;AACH;AAEA,SAAS,sBACP,MACA,QACG;CACH,OAAO,OAAO,MAAM,MAAM;CAC1B,OAAO;AACT;AAEA,SAAS,uBACP,MACA,4BACa;CACb,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,QAAQ,4BAA4B;EAC7C,MAAM,YAAY,6BAA6B,MAAM,IAAI;EACzD,IAAI,aAAa,MACf,uBAAO,IAAI,IAAI;EAEjB,QAAQ,IAAI,SAAS;CACvB;CACA,OAAO;AACT;AAEA,SAAS,6BACP,MACA,MACoB;CACpB,KAAK,MAAM,CAAC,WAAW,SAAS,KAAK,MAAM,QAAQ,GAAG;EACpD,MAAM,MAAM,KAAK,oBAAoB,KAAK;EAC1C,IAAI,QAAQ,KAAK,qBAAqB,OAAO,KAC3C,OAAO;CAEX;AAEF;AAEA,SAAS,kBACP,MACA,WACA,kBACS;CACT,MAAM,OAAO,KAAK,MAAM;CACxB,IAAI,QAAQ,MACV,OAAO;CAGT,MAAM,gBAAgB,KAAK,cAAc,MACvC,KAAK,mBACL,KAAK,oBAAoB,KAAK,aAChC;CACA,MAAM,gBAAgB,KAAK,cAAc,MACvC,KAAK,mBACL,KAAK,oBAAoB,KAAK,aAChC;CAEA,MAAM,WAAW,kBACf;EACE,MAAM,KAAK,YAAY,KAAK;EAC5B,UAAU,cAAc,KAAK,EAAE;CACjC,GACA;EACE,MAAM,KAAK;EACX,UAAU,cAAc,KAAK,EAAE;EAC/B,MAAM,KAAK;CACb,GACA;EAAE,GAAG;EAAkB,SAAS;CAAE,CACpC;CAEA,MAAM,eAAe,SAAS,MAAM;CACpC,IAAI,gBAAgB,QAAQ,SAAS,MAAM,WAAW,GACpD,OAAO;CAGT,kBAAkB,MAAM,YAAY;CACpC,4BAA4B,MAAM,SAAS;CAC3C,OAAO;AACT;AAEA,SAAgB,4BACd,MACA,WACM;CACN,MAAM,OAAO,KAAK,MAAM;CACxB,IAAI,QAAQ,MACV;CAIF,IAAI,EADe,cAAc,KAAK,MAAM,SAAS,IACpC;EACf,KAAK,mBAAmB;EACxB,KAAK,mBAAmB;EACxB;CACF;CAEA,MAAM,mBAAmB,KAAK,cAAc,GAAG,EAAE;CACjD,MAAM,mBAAmB,KAAK,cAAc,GAAG,EAAE;CACjD,KAAK,mBACH,oBAAoB,QACpB,qBAAqB,MACrB,CAAC,iBAAiB,SAAS,IAAI;CACjC,KAAK,mBACH,oBAAoB,QACpB,qBAAqB,MACrB,CAAC,iBAAiB,SAAS,IAAI;AACnC;AAEA,SAAS,kBAAkB,QAAc,QAAoB;CAC3D,MAAM,iBAAiB,OAAO;CAC9B,MAAM,iBAAiB,OAAO;CAE9B,OAAO,cAAc,OAAO,YAAY,KAAK,YAC3C,kBAAkB,SAAS,gBAAgB,cAAc,CAC3D;CACA,OAAO,oBAAoB,iBAAiB,OAAO;CACnD,OAAO,gBAAgB,OAAO,gBAAgB,OAAO;CACrD,OAAO,gBAAgB,OAAO;CAC9B,OAAO,gBAAgB,OAAO;CAC9B,IAAI,OAAO,qBAAqB,GAAG;EACjC,OAAO,oBAAoB,iBAAiB,OAAO;EACnD,OAAO,gBAAgB,OAAO,gBAAgB,OAAO;CACvD;CACA,OAAO,gBAAgB,OAAO;CAC9B,OAAO,gBAAgB,OAAO;CAC9B,OAAO,mBAAmB,OAAO;CACjC,OAAO,mBAAmB,OAAO;CAEjC,8BAA8B,MAAM;AACtC;AAEA,SAAgB,kBACd,SACA,gBACA,gBACa;CACb,OAAO;EACL,GAAG;EACH,mBAAmB,QAAQ,oBAAoB;EAC/C,mBAAmB,QAAQ,oBAAoB;CACjD;AACF;AAEA,SAAgB,8BAA8B,MAAkB;CAC9D,IAAI,iBAAiB;CACrB,IAAI,mBAAmB;CAEvB,KAAK,MAAM,WAAW,KAAK,aACzB,IAAI,QAAQ,SAAS,WAAW;EAC9B,kBAAkB,QAAQ;EAC1B,oBAAoB,QAAQ;CAC9B,OAAO;EACL,kBAAkB,KAAK,IAAI,QAAQ,WAAW,QAAQ,SAAS;EAC/D,oBAAoB,QAAQ,YAAY,QAAQ;CAClD;CAGF,KAAK,iBAAiB;CACtB,KAAK,mBAAmB;AAC1B;AAEA,SAAgB,8BACd,MAIM;CACN,IAAI,aAAa;CACjB,IAAI,eAAe;CACnB,IAAI,sBAAsB;CAE1B,KAAK,MAAM,QAAQ,KAAK,OAAO;EAC7B,KAAK,kBAAkB,KAAK,IAC1B,KAAK,gBAAgB,IAAI,qBACzB,CACF;EACA,KAAK,iBAAiB,aAAa,KAAK;EACxC,KAAK,mBAAmB,eAAe,KAAK;EAE5C,8BAA8B,IAAI;EAElC,cAAc,KAAK,kBAAkB,KAAK;EAC1C,gBAAgB,KAAK,kBAAkB,KAAK;EAC5C,sBAAsB,KAAK,gBAAgB,KAAK,gBAAgB;CAClE;CAEA,IAAI,KAAK,MAAM,SAAS,GAAG;EACzB,MAAM,WAAW,KAAK,MAAM,KAAK,MAAM,SAAS;EAChD,MAAM,iBAAiB,KAAK,IAC1B,KAAK,cAAc,UAChB,SAAS,oBAAoB,SAAS,gBACzC,CACF;EACA,cAAc;EACd,gBAAgB;CAClB;CAEA,KAAK,iBAAiB;CACtB,KAAK,mBAAmB;AAC1B"}
|
|
@@ -46,6 +46,7 @@ declare function getExpandedRegion({
|
|
|
46
46
|
collapsedContextThreshold
|
|
47
47
|
}: GetExpandedRegionProps): ExpandedRegionResult;
|
|
48
48
|
declare function hasTrailingContext(fileDiff: FileDiffMetadata): boolean;
|
|
49
|
+
declare function hasTrailingContextMismatch(fileDiff: FileDiffMetadata): boolean;
|
|
49
50
|
declare function getTrailingContextRangeSize({
|
|
50
51
|
fileDiff,
|
|
51
52
|
errorPrefix
|
|
@@ -57,6 +58,44 @@ declare function getTrailingExpandedRegion({
|
|
|
57
58
|
collapsedContextThreshold,
|
|
58
59
|
errorPrefix
|
|
59
60
|
}: GetTrailingExpandedRegionProps): ExpandedRegionResult | undefined;
|
|
61
|
+
interface IsAdditionLineRenderableProps {
|
|
62
|
+
fileDiff: FileDiffMetadata;
|
|
63
|
+
/** One-based line number in the new file. */
|
|
64
|
+
lineNumber: number;
|
|
65
|
+
expandedHunks: Map<number, HunkExpansionRegion> | true | undefined;
|
|
66
|
+
collapsedContextThreshold: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether a one-based new-file line currently has (or will have on scroll) a
|
|
70
|
+
* rendered row under the given expansion state — the editor-facing
|
|
71
|
+
* visibility oracle. False only for lines hidden inside a collapsed
|
|
72
|
+
* unchanged region; lines outside the diff's modeled range report true so
|
|
73
|
+
* callers keep their existing missing-row handling. Computed from the same
|
|
74
|
+
* inputs as `iterateOverDiff` so layout math and the oracle cannot diverge.
|
|
75
|
+
*/
|
|
76
|
+
declare function isAdditionLineRenderable({
|
|
77
|
+
fileDiff,
|
|
78
|
+
lineNumber,
|
|
79
|
+
expandedHunks,
|
|
80
|
+
collapsedContextThreshold
|
|
81
|
+
}: IsAdditionLineRenderableProps): boolean;
|
|
82
|
+
interface GetNearestRenderableAdditionLineProps extends IsAdditionLineRenderableProps {
|
|
83
|
+
direction: 'up' | 'down';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The nearest renderable new-file line at or beyond `lineNumber` in the
|
|
87
|
+
* given direction (one-based), or undefined when every line that way is
|
|
88
|
+
* hidden inside collapsed regions. Sequential caret motion uses this to skip
|
|
89
|
+
* over collapsed regions like code folds; it walks the hunk metadata once
|
|
90
|
+
* instead of probing line by line across a gap.
|
|
91
|
+
*/
|
|
92
|
+
declare function getNearestRenderableAdditionLine({
|
|
93
|
+
fileDiff,
|
|
94
|
+
lineNumber,
|
|
95
|
+
direction,
|
|
96
|
+
expandedHunks,
|
|
97
|
+
collapsedContextThreshold
|
|
98
|
+
}: GetNearestRenderableAdditionLineProps): number | undefined;
|
|
60
99
|
declare function getHunkSeparatorHeight({
|
|
61
100
|
type,
|
|
62
101
|
metrics
|
|
@@ -82,5 +121,5 @@ declare function getTrailingHunkSeparatorLayout({
|
|
|
82
121
|
metrics
|
|
83
122
|
}: HunkSeparatorBaseProps): HunkSeparatorLayout | undefined;
|
|
84
123
|
//#endregion
|
|
85
|
-
export { ExpandedRegionResult, GetExpandedRegionProps, GetTrailingContextRangeSizeProps, GetTrailingExpandedRegionProps, HunkSeparatorLayout, getExpandedRegion, getHunkSeparatorGap, getHunkSeparatorHeight, getLeadingHunkSeparatorLayout, getTrailingContextRangeSize, getTrailingExpandedRegion, getTrailingHunkSeparatorLayout, hasLeadingHunkSeparator, hasTrailingContext, hasTrailingHunkSeparator };
|
|
124
|
+
export { ExpandedRegionResult, GetExpandedRegionProps, GetNearestRenderableAdditionLineProps, GetTrailingContextRangeSizeProps, GetTrailingExpandedRegionProps, HunkSeparatorLayout, IsAdditionLineRenderableProps, getExpandedRegion, getHunkSeparatorGap, getHunkSeparatorHeight, getLeadingHunkSeparatorLayout, getNearestRenderableAdditionLine, getTrailingContextRangeSize, getTrailingExpandedRegion, getTrailingHunkSeparatorLayout, hasLeadingHunkSeparator, hasTrailingContext, hasTrailingContextMismatch, hasTrailingHunkSeparator, isAdditionLineRenderable };
|
|
86
125
|
//# sourceMappingURL=virtualDiffLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualDiffLayout.d.ts","names":[],"sources":["../../src/utils/virtualDiffLayout.ts"],"mappings":";;;UAQiB,oBAAA;EACf,SAAA;EACA,OAAA;EACA,SAAA;EACA,cAAA;EACA,SAAA;AAAA;AAAA,UAGe,sBAAA;EACf,SAAA;EACA,SAAA;EACA,aAAA,EAAe,GAAG,SAAS,mBAAA;EAC3B,SAAA;EACA,yBAAA;AAAA;AAAA,UAGe,gCAAA;EACf,QAAA,EAAU,gBAAgB;EAC1B,WAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,gCAAgC;EACtF,SAAA;EACA,aAAA,EAAe,sBAAA;EACf,yBAAA;AAAA;AAAA,UAGe,mBAAA;EACf,MAAA;EACA,SAAA;EACA,QAAA;EACA,WAAA;AAAA;AAAA,UAGQ,sBAAA;EACR,IAAA,EAAM,cAAA;EACN,OAAA,EAAS,kBAAkB;AAAA;AAAA,UAGnB,+BAAA,SAAwC,sBAAsB;EACtE,SAAA;EACA,SAAA;AAAA;AAAA,iBAKc,iBAAA;EACd,SAAA;EACA,SAAA;EACA,aAAA;EACA,SAAA;EACA;AAAA,GACC,sBAAA,GAAyB,oBAAA;AAAA,iBA6CZ,kBAAA,CAAmB,QAA0B,EAAhB,gBAAgB;AAAA,
|
|
1
|
+
{"version":3,"file":"virtualDiffLayout.d.ts","names":[],"sources":["../../src/utils/virtualDiffLayout.ts"],"mappings":";;;UAQiB,oBAAA;EACf,SAAA;EACA,OAAA;EACA,SAAA;EACA,cAAA;EACA,SAAA;AAAA;AAAA,UAGe,sBAAA;EACf,SAAA;EACA,SAAA;EACA,aAAA,EAAe,GAAG,SAAS,mBAAA;EAC3B,SAAA;EACA,yBAAA;AAAA;AAAA,UAGe,gCAAA;EACf,QAAA,EAAU,gBAAgB;EAC1B,WAAA;AAAA;AAAA,UAGe,8BAAA,SAAuC,gCAAgC;EACtF,SAAA;EACA,aAAA,EAAe,sBAAA;EACf,yBAAA;AAAA;AAAA,UAGe,mBAAA;EACf,MAAA;EACA,SAAA;EACA,QAAA;EACA,WAAA;AAAA;AAAA,UAGQ,sBAAA;EACR,IAAA,EAAM,cAAA;EACN,OAAA,EAAS,kBAAkB;AAAA;AAAA,UAGnB,+BAAA,SAAwC,sBAAsB;EACtE,SAAA;EACA,SAAA;AAAA;AAAA,iBAKc,iBAAA;EACd,SAAA;EACA,SAAA;EACA,aAAA;EACA,SAAA;EACA;AAAA,GACC,sBAAA,GAAyB,oBAAA;AAAA,iBA6CZ,kBAAA,CAAmB,QAA0B,EAAhB,gBAAgB;AAAA,iBAsB7C,0BAAA,CACd,QAA0B,EAAhB,gBAAgB;AAAA,iBA4BZ,2BAAA;EACd,QAAA;EACA;AAAA,GACC,gCAAA;AAAA,iBA8Ba,yBAAA;EACd,QAAA;EACA,SAAA;EACA,aAAA;EACA,yBAAA;EACA;AAAA,GACC,8BAAA,GAAiC,oBAAA;AAAA,UA0CnB,6BAAA;EACf,QAAA,EAAU,gBAAA;EA9Me;EAgNzB,UAAA;EACA,aAAA,EAAe,GAAA,SAAY,mBAAA;EAC3B,yBAAA;AAAA;;;;;;;AA3MW;AACZ;iBAqNe,wBAAA;EACd,QAAA;EACA,UAAA;EACA,aAAA;EACA;AAAA,GACC,6BAAA;AAAA,UA8Cc,qCAAA,SAA8C,6BAA6B;EAC1F,SAAS;AAAA;;;;;AArQkB;AAAA;;iBA+Qb,gCAAA;EACd,QAAA;EACA,UAAA;EACA,SAAA;EACA,aAAA;EACA;AAAA,GACC,qCAAA;AAAA,iBAqEa,sBAAA;EACd,IAAA;EACA;AAAA,GACC,sBAAA;AAAA,iBAIa,mBAAA;EACd,IAAA;EACA;AAAA,GACC,sBAAA;AAAA,iBAMa,uBAAA;EACd,IAAA;EACA,SAAA;EACA;AAAA,GACC,IAAA,CAAK,+BAAA;AAAA,iBAaQ,wBAAA,CAAyB,IAAoB,EAAd,cAAc;AAAA,iBAK7C,6BAAA;EACd,IAAA;EACA,OAAA;EACA,SAAA;EACA;AAAA,GACC,+BAAA,GAAkC,mBAAA;AAAA,iBAmBrB,8BAAA;EACd,IAAA;EACA;AAAA,GACC,sBAAA,GAAyB,mBAAA"}
|
|
@@ -36,6 +36,14 @@ function hasTrailingContext(fileDiff) {
|
|
|
36
36
|
const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
|
|
37
37
|
return additionRemaining > 0 || deletionRemaining > 0;
|
|
38
38
|
}
|
|
39
|
+
function hasTrailingContextMismatch(fileDiff) {
|
|
40
|
+
const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
|
|
41
|
+
if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) return false;
|
|
42
|
+
const additionRemaining = fileDiff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount);
|
|
43
|
+
const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
|
|
44
|
+
if (additionRemaining <= 0 && deletionRemaining <= 0) return false;
|
|
45
|
+
return additionRemaining !== deletionRemaining;
|
|
46
|
+
}
|
|
39
47
|
function getTrailingContextRangeSize({ fileDiff, errorPrefix }) {
|
|
40
48
|
const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
|
|
41
49
|
if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) return 0;
|
|
@@ -69,6 +77,93 @@ function getTrailingExpandedRegion({ fileDiff, hunkIndex, expandedHunks, collaps
|
|
|
69
77
|
renderAll: fromStart >= trailingRangeSize
|
|
70
78
|
};
|
|
71
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether a one-based new-file line currently has (or will have on scroll) a
|
|
82
|
+
* rendered row under the given expansion state — the editor-facing
|
|
83
|
+
* visibility oracle. False only for lines hidden inside a collapsed
|
|
84
|
+
* unchanged region; lines outside the diff's modeled range report true so
|
|
85
|
+
* callers keep their existing missing-row handling. Computed from the same
|
|
86
|
+
* inputs as `iterateOverDiff` so layout math and the oracle cannot diverge.
|
|
87
|
+
*/
|
|
88
|
+
function isAdditionLineRenderable({ fileDiff, lineNumber, expandedHunks, collapsedContextThreshold }) {
|
|
89
|
+
if (expandedHunks === true || fileDiff.isPartial) return true;
|
|
90
|
+
for (const [hunkIndex, hunk] of fileDiff.hunks.entries()) {
|
|
91
|
+
if (lineNumber < hunk.additionStart) {
|
|
92
|
+
const region = getExpandedRegion({
|
|
93
|
+
isPartial: fileDiff.isPartial,
|
|
94
|
+
rangeSize: hunk.collapsedBefore,
|
|
95
|
+
expandedHunks,
|
|
96
|
+
hunkIndex,
|
|
97
|
+
collapsedContextThreshold
|
|
98
|
+
});
|
|
99
|
+
const gapStart = hunk.additionStart - region.rangeSize;
|
|
100
|
+
return region.renderAll || lineNumber < gapStart + region.fromStart || lineNumber >= hunk.additionStart - region.fromEnd;
|
|
101
|
+
}
|
|
102
|
+
if (lineNumber < hunk.additionStart + hunk.additionCount) return true;
|
|
103
|
+
}
|
|
104
|
+
const trailingRegion = getTrailingExpandedRegion({
|
|
105
|
+
fileDiff,
|
|
106
|
+
hunkIndex: fileDiff.hunks.length - 1,
|
|
107
|
+
expandedHunks,
|
|
108
|
+
collapsedContextThreshold,
|
|
109
|
+
errorPrefix: "isAdditionLineRenderable"
|
|
110
|
+
});
|
|
111
|
+
if (trailingRegion == null || trailingRegion.renderAll) return true;
|
|
112
|
+
const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
|
|
113
|
+
const trailingStart = lastHunk.additionStart + lastHunk.additionCount;
|
|
114
|
+
return lineNumber < trailingStart + trailingRegion.fromStart || lineNumber >= trailingStart + trailingRegion.rangeSize;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* The nearest renderable new-file line at or beyond `lineNumber` in the
|
|
118
|
+
* given direction (one-based), or undefined when every line that way is
|
|
119
|
+
* hidden inside collapsed regions. Sequential caret motion uses this to skip
|
|
120
|
+
* over collapsed regions like code folds; it walks the hunk metadata once
|
|
121
|
+
* instead of probing line by line across a gap.
|
|
122
|
+
*/
|
|
123
|
+
function getNearestRenderableAdditionLine({ fileDiff, lineNumber, direction, expandedHunks, collapsedContextThreshold }) {
|
|
124
|
+
if (expandedHunks === true || fileDiff.isPartial) return lineNumber;
|
|
125
|
+
const ranges = [];
|
|
126
|
+
let modeledEnd = 1;
|
|
127
|
+
for (const [hunkIndex, hunk] of fileDiff.hunks.entries()) {
|
|
128
|
+
const region = getExpandedRegion({
|
|
129
|
+
isPartial: fileDiff.isPartial,
|
|
130
|
+
rangeSize: hunk.collapsedBefore,
|
|
131
|
+
expandedHunks,
|
|
132
|
+
hunkIndex,
|
|
133
|
+
collapsedContextThreshold
|
|
134
|
+
});
|
|
135
|
+
const gapStart = hunk.additionStart - region.rangeSize;
|
|
136
|
+
if (region.renderAll) ranges.push([gapStart, hunk.additionStart]);
|
|
137
|
+
else {
|
|
138
|
+
if (region.fromStart > 0) ranges.push([gapStart, gapStart + region.fromStart]);
|
|
139
|
+
if (region.fromEnd > 0) ranges.push([hunk.additionStart - region.fromEnd, hunk.additionStart]);
|
|
140
|
+
}
|
|
141
|
+
ranges.push([hunk.additionStart, hunk.additionStart + hunk.additionCount]);
|
|
142
|
+
modeledEnd = hunk.additionStart + hunk.additionCount;
|
|
143
|
+
}
|
|
144
|
+
const trailingRegion = getTrailingExpandedRegion({
|
|
145
|
+
fileDiff,
|
|
146
|
+
hunkIndex: fileDiff.hunks.length - 1,
|
|
147
|
+
expandedHunks,
|
|
148
|
+
collapsedContextThreshold,
|
|
149
|
+
errorPrefix: "getNearestRenderableAdditionLine"
|
|
150
|
+
});
|
|
151
|
+
if (trailingRegion != null) {
|
|
152
|
+
const trailingStart = modeledEnd;
|
|
153
|
+
modeledEnd = trailingStart + trailingRegion.rangeSize;
|
|
154
|
+
if (trailingRegion.renderAll) ranges.push([trailingStart, modeledEnd]);
|
|
155
|
+
else if (trailingRegion.fromStart > 0) ranges.push([trailingStart, trailingStart + trailingRegion.fromStart]);
|
|
156
|
+
}
|
|
157
|
+
if (lineNumber >= modeledEnd) return lineNumber;
|
|
158
|
+
if (direction === "down") {
|
|
159
|
+
for (const [start, end] of ranges) if (end > lineNumber) return Math.max(start, lineNumber);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
for (let index = ranges.length - 1; index >= 0; index--) {
|
|
163
|
+
const [start, end] = ranges[index];
|
|
164
|
+
if (start <= lineNumber) return Math.min(end - 1, lineNumber);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
72
167
|
function getHunkSeparatorHeight({ type, metrics }) {
|
|
73
168
|
return metrics.hunkSeparatorHeight ?? getDefaultHunkSeparatorHeight(type);
|
|
74
169
|
}
|
|
@@ -128,6 +223,6 @@ function getTrailingHunkSeparatorLayout({ type, metrics }) {
|
|
|
128
223
|
};
|
|
129
224
|
}
|
|
130
225
|
//#endregion
|
|
131
|
-
export { getExpandedRegion, getHunkSeparatorGap, getHunkSeparatorHeight, getLeadingHunkSeparatorLayout, getTrailingContextRangeSize, getTrailingExpandedRegion, getTrailingHunkSeparatorLayout, hasLeadingHunkSeparator, hasTrailingContext, hasTrailingHunkSeparator };
|
|
226
|
+
export { getExpandedRegion, getHunkSeparatorGap, getHunkSeparatorHeight, getLeadingHunkSeparatorLayout, getNearestRenderableAdditionLine, getTrailingContextRangeSize, getTrailingExpandedRegion, getTrailingHunkSeparatorLayout, hasLeadingHunkSeparator, hasTrailingContext, hasTrailingContextMismatch, hasTrailingHunkSeparator, isAdditionLineRenderable };
|
|
132
227
|
|
|
133
228
|
//# sourceMappingURL=virtualDiffLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualDiffLayout.js","names":[],"sources":["../../src/utils/virtualDiffLayout.ts"],"sourcesContent":["import type {\n FileDiffMetadata,\n HunkExpansionRegion,\n HunkSeparators,\n VirtualFileMetrics,\n} from '../types';\nimport { getDefaultHunkSeparatorHeight } from './computeVirtualFileMetrics';\n\nexport interface ExpandedRegionResult {\n fromStart: number;\n fromEnd: number;\n rangeSize: number;\n collapsedLines: number;\n renderAll: boolean;\n}\n\nexport interface GetExpandedRegionProps {\n isPartial: boolean;\n rangeSize: number;\n expandedHunks: Map<number, HunkExpansionRegion> | true | undefined;\n hunkIndex: number;\n collapsedContextThreshold: number;\n}\n\nexport interface GetTrailingContextRangeSizeProps {\n fileDiff: FileDiffMetadata;\n errorPrefix: string;\n}\n\nexport interface GetTrailingExpandedRegionProps extends GetTrailingContextRangeSizeProps {\n hunkIndex: number;\n expandedHunks: GetExpandedRegionProps['expandedHunks'];\n collapsedContextThreshold: number;\n}\n\nexport interface HunkSeparatorLayout {\n height: number;\n gapBefore: number;\n gapAfter: number;\n totalHeight: number;\n}\n\ninterface HunkSeparatorBaseProps {\n type: HunkSeparators;\n metrics: VirtualFileMetrics;\n}\n\ninterface LeadingHunkSeparatorLayoutProps extends HunkSeparatorBaseProps {\n hunkIndex: number;\n hunkSpecs: string | undefined;\n}\n\n// Converts a collapsed unchanged range into the slices that should render near\n// the start and end of that range for the active hunk expansion state.\nexport function getExpandedRegion({\n isPartial,\n rangeSize,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n}: GetExpandedRegionProps): ExpandedRegionResult {\n const normalizedRangeSize = Math.max(rangeSize, 0);\n if (normalizedRangeSize === 0 || isPartial) {\n return {\n fromStart: 0,\n fromEnd: 0,\n rangeSize: normalizedRangeSize,\n collapsedLines: normalizedRangeSize,\n renderAll: false,\n };\n }\n\n if (\n expandedHunks === true ||\n normalizedRangeSize <= collapsedContextThreshold\n ) {\n return {\n fromStart: normalizedRangeSize,\n fromEnd: 0,\n rangeSize: normalizedRangeSize,\n collapsedLines: 0,\n renderAll: true,\n };\n }\n\n const region = expandedHunks?.get(hunkIndex);\n const fromStart = Math.min(\n Math.max(region?.fromStart ?? 0, 0),\n normalizedRangeSize\n );\n const fromEnd = Math.min(\n Math.max(region?.fromEnd ?? 0, 0),\n normalizedRangeSize\n );\n const expandedCount = fromStart + fromEnd;\n const renderAll = expandedCount >= normalizedRangeSize;\n return {\n fromStart: renderAll ? normalizedRangeSize : fromStart,\n fromEnd: renderAll ? 0 : fromEnd,\n rangeSize: normalizedRangeSize,\n collapsedLines: Math.max(normalizedRangeSize - expandedCount, 0),\n renderAll,\n };\n}\n\nexport function hasTrailingContext(fileDiff: FileDiffMetadata): boolean {\n const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return false;\n }\n\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n\n return additionRemaining > 0 || deletionRemaining > 0;\n}\n\n// Measures the unchanged tail after the final hunk. Both sides must have the\n// same remaining length because trailing context represents paired lines.\nexport function getTrailingContextRangeSize({\n fileDiff,\n errorPrefix,\n}: GetTrailingContextRangeSizeProps): number {\n const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return 0;\n }\n\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n\n if (additionRemaining <= 0 && deletionRemaining <= 0) {\n return 0;\n }\n\n if (additionRemaining !== deletionRemaining) {\n throw new Error(\n `${errorPrefix}: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`\n );\n }\n return Math.min(additionRemaining, deletionRemaining);\n}\n\nexport function getTrailingExpandedRegion({\n fileDiff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix,\n}: GetTrailingExpandedRegionProps): ExpandedRegionResult | undefined {\n if (hunkIndex !== fileDiff.hunks.length - 1) {\n return undefined;\n }\n\n const trailingRangeSize = getTrailingContextRangeSize({\n fileDiff,\n errorPrefix,\n });\n if (trailingRangeSize <= 0) {\n return undefined;\n }\n\n if (\n expandedHunks === true ||\n trailingRangeSize <= collapsedContextThreshold\n ) {\n return {\n fromStart: trailingRangeSize,\n fromEnd: 0,\n rangeSize: trailingRangeSize,\n collapsedLines: 0,\n renderAll: true,\n };\n }\n\n // The final trailing separator only exposes upward partial expansion. Treat it\n // as a bottom-only pseudo-hunk and ignore unsupported downward expansion.\n const region = expandedHunks?.get(fileDiff.hunks.length);\n const fromStart = Math.min(\n Math.max(region?.fromStart ?? 0, 0),\n trailingRangeSize\n );\n return {\n fromStart,\n fromEnd: 0,\n rangeSize: trailingRangeSize,\n collapsedLines: trailingRangeSize - fromStart,\n renderAll: fromStart >= trailingRangeSize,\n };\n}\n\nexport function getHunkSeparatorHeight({\n type,\n metrics,\n}: HunkSeparatorBaseProps): number {\n return metrics.hunkSeparatorHeight ?? getDefaultHunkSeparatorHeight(type);\n}\n\nexport function getHunkSeparatorGap({\n type,\n metrics,\n}: HunkSeparatorBaseProps): number {\n return type === 'simple' || type === 'metadata' || type === 'line-info-basic'\n ? 0\n : metrics.spacing;\n}\n\nexport function hasLeadingHunkSeparator({\n type,\n hunkIndex,\n hunkSpecs,\n}: Omit<LeadingHunkSeparatorLayoutProps, 'metrics'>): boolean {\n switch (type) {\n case 'simple':\n return hunkIndex > 0;\n case 'metadata':\n return hunkSpecs != null;\n case 'line-info':\n case 'line-info-basic':\n case 'custom':\n return true;\n }\n}\n\nexport function hasTrailingHunkSeparator(type: HunkSeparators): boolean {\n return type !== 'simple' && type !== 'metadata';\n}\n\n// Mirrors the renderer/CSS spacing rules for the separator shown before a hunk.\nexport function getLeadingHunkSeparatorLayout({\n type,\n metrics,\n hunkIndex,\n hunkSpecs,\n}: LeadingHunkSeparatorLayoutProps): HunkSeparatorLayout | undefined {\n if (!hasLeadingHunkSeparator({ type, hunkIndex, hunkSpecs })) {\n return undefined;\n }\n\n const height = getHunkSeparatorHeight({ type, metrics });\n const gap = getHunkSeparatorGap({ type, metrics });\n const gapBefore = hunkIndex > 0 ? gap : 0;\n const gapAfter = gap;\n return {\n height,\n gapBefore,\n gapAfter,\n totalHeight: gapBefore + height + gapAfter,\n };\n}\n\n// Mirrors the renderer/CSS spacing rules for the separator shown after the last\n// hunk when trailing unchanged context is collapsed.\nexport function getTrailingHunkSeparatorLayout({\n type,\n metrics,\n}: HunkSeparatorBaseProps): HunkSeparatorLayout | undefined {\n if (!hasTrailingHunkSeparator(type)) {\n return undefined;\n }\n\n const height = getHunkSeparatorHeight({ type, metrics });\n const gapBefore = getHunkSeparatorGap({ type, metrics });\n return {\n height,\n gapBefore,\n gapAfter: 0,\n totalHeight: gapBefore + height,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"virtualDiffLayout.js","names":[],"sources":["../../src/utils/virtualDiffLayout.ts"],"sourcesContent":["import type {\n FileDiffMetadata,\n HunkExpansionRegion,\n HunkSeparators,\n VirtualFileMetrics,\n} from '../types';\nimport { getDefaultHunkSeparatorHeight } from './computeVirtualFileMetrics';\n\nexport interface ExpandedRegionResult {\n fromStart: number;\n fromEnd: number;\n rangeSize: number;\n collapsedLines: number;\n renderAll: boolean;\n}\n\nexport interface GetExpandedRegionProps {\n isPartial: boolean;\n rangeSize: number;\n expandedHunks: Map<number, HunkExpansionRegion> | true | undefined;\n hunkIndex: number;\n collapsedContextThreshold: number;\n}\n\nexport interface GetTrailingContextRangeSizeProps {\n fileDiff: FileDiffMetadata;\n errorPrefix: string;\n}\n\nexport interface GetTrailingExpandedRegionProps extends GetTrailingContextRangeSizeProps {\n hunkIndex: number;\n expandedHunks: GetExpandedRegionProps['expandedHunks'];\n collapsedContextThreshold: number;\n}\n\nexport interface HunkSeparatorLayout {\n height: number;\n gapBefore: number;\n gapAfter: number;\n totalHeight: number;\n}\n\ninterface HunkSeparatorBaseProps {\n type: HunkSeparators;\n metrics: VirtualFileMetrics;\n}\n\ninterface LeadingHunkSeparatorLayoutProps extends HunkSeparatorBaseProps {\n hunkIndex: number;\n hunkSpecs: string | undefined;\n}\n\n// Converts a collapsed unchanged range into the slices that should render near\n// the start and end of that range for the active hunk expansion state.\nexport function getExpandedRegion({\n isPartial,\n rangeSize,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n}: GetExpandedRegionProps): ExpandedRegionResult {\n const normalizedRangeSize = Math.max(rangeSize, 0);\n if (normalizedRangeSize === 0 || isPartial) {\n return {\n fromStart: 0,\n fromEnd: 0,\n rangeSize: normalizedRangeSize,\n collapsedLines: normalizedRangeSize,\n renderAll: false,\n };\n }\n\n if (\n expandedHunks === true ||\n normalizedRangeSize <= collapsedContextThreshold\n ) {\n return {\n fromStart: normalizedRangeSize,\n fromEnd: 0,\n rangeSize: normalizedRangeSize,\n collapsedLines: 0,\n renderAll: true,\n };\n }\n\n const region = expandedHunks?.get(hunkIndex);\n const fromStart = Math.min(\n Math.max(region?.fromStart ?? 0, 0),\n normalizedRangeSize\n );\n const fromEnd = Math.min(\n Math.max(region?.fromEnd ?? 0, 0),\n normalizedRangeSize\n );\n const expandedCount = fromStart + fromEnd;\n const renderAll = expandedCount >= normalizedRangeSize;\n return {\n fromStart: renderAll ? normalizedRangeSize : fromStart,\n fromEnd: renderAll ? 0 : fromEnd,\n rangeSize: normalizedRangeSize,\n collapsedLines: Math.max(normalizedRangeSize - expandedCount, 0),\n renderAll,\n };\n}\n\nexport function hasTrailingContext(fileDiff: FileDiffMetadata): boolean {\n const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return false;\n }\n\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n\n return additionRemaining > 0 || deletionRemaining > 0;\n}\n\n// Returns true when trailing-context line counts disagree between sides.\nexport function hasTrailingContextMismatch(\n fileDiff: FileDiffMetadata\n): boolean {\n const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return false;\n }\n\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n\n if (additionRemaining <= 0 && deletionRemaining <= 0) {\n return false;\n }\n\n return additionRemaining !== deletionRemaining;\n}\n\n// Measures the unchanged tail after the final hunk. Both sides must have the\n// same remaining length because trailing context represents paired lines.\nexport function getTrailingContextRangeSize({\n fileDiff,\n errorPrefix,\n}: GetTrailingContextRangeSizeProps): number {\n const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];\n if (\n lastHunk == null ||\n fileDiff.isPartial ||\n fileDiff.additionLines.length === 0 ||\n fileDiff.deletionLines.length === 0\n ) {\n return 0;\n }\n\n const additionRemaining =\n fileDiff.additionLines.length -\n (lastHunk.additionLineIndex + lastHunk.additionCount);\n const deletionRemaining =\n fileDiff.deletionLines.length -\n (lastHunk.deletionLineIndex + lastHunk.deletionCount);\n\n if (additionRemaining <= 0 && deletionRemaining <= 0) {\n return 0;\n }\n\n if (additionRemaining !== deletionRemaining) {\n throw new Error(\n `${errorPrefix}: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`\n );\n }\n return Math.min(additionRemaining, deletionRemaining);\n}\n\nexport function getTrailingExpandedRegion({\n fileDiff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix,\n}: GetTrailingExpandedRegionProps): ExpandedRegionResult | undefined {\n if (hunkIndex !== fileDiff.hunks.length - 1) {\n return undefined;\n }\n\n const trailingRangeSize = getTrailingContextRangeSize({\n fileDiff,\n errorPrefix,\n });\n if (trailingRangeSize <= 0) {\n return undefined;\n }\n\n if (\n expandedHunks === true ||\n trailingRangeSize <= collapsedContextThreshold\n ) {\n return {\n fromStart: trailingRangeSize,\n fromEnd: 0,\n rangeSize: trailingRangeSize,\n collapsedLines: 0,\n renderAll: true,\n };\n }\n\n // The final trailing separator only exposes upward partial expansion. Treat it\n // as a bottom-only pseudo-hunk and ignore unsupported downward expansion.\n const region = expandedHunks?.get(fileDiff.hunks.length);\n const fromStart = Math.min(\n Math.max(region?.fromStart ?? 0, 0),\n trailingRangeSize\n );\n return {\n fromStart,\n fromEnd: 0,\n rangeSize: trailingRangeSize,\n collapsedLines: trailingRangeSize - fromStart,\n renderAll: fromStart >= trailingRangeSize,\n };\n}\n\nexport interface IsAdditionLineRenderableProps {\n fileDiff: FileDiffMetadata;\n /** One-based line number in the new file. */\n lineNumber: number;\n expandedHunks: Map<number, HunkExpansionRegion> | true | undefined;\n collapsedContextThreshold: number;\n}\n\n/**\n * Whether a one-based new-file line currently has (or will have on scroll) a\n * rendered row under the given expansion state — the editor-facing\n * visibility oracle. False only for lines hidden inside a collapsed\n * unchanged region; lines outside the diff's modeled range report true so\n * callers keep their existing missing-row handling. Computed from the same\n * inputs as `iterateOverDiff` so layout math and the oracle cannot diverge.\n */\nexport function isAdditionLineRenderable({\n fileDiff,\n lineNumber,\n expandedHunks,\n collapsedContextThreshold,\n}: IsAdditionLineRenderableProps): boolean {\n if (expandedHunks === true || fileDiff.isPartial) {\n return true;\n }\n\n for (const [hunkIndex, hunk] of fileDiff.hunks.entries()) {\n if (lineNumber < hunk.additionStart) {\n // Inside the collapsed gap before this hunk: renderable only within\n // the expanded slices at the gap's edges.\n const region = getExpandedRegion({\n isPartial: fileDiff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const gapStart = hunk.additionStart - region.rangeSize;\n return (\n region.renderAll ||\n lineNumber < gapStart + region.fromStart ||\n lineNumber >= hunk.additionStart - region.fromEnd\n );\n }\n if (lineNumber < hunk.additionStart + hunk.additionCount) {\n return true;\n }\n }\n\n const trailingRegion = getTrailingExpandedRegion({\n fileDiff,\n hunkIndex: fileDiff.hunks.length - 1,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'isAdditionLineRenderable',\n });\n if (trailingRegion == null || trailingRegion.renderAll) {\n return true;\n }\n const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];\n const trailingStart = lastHunk.additionStart + lastHunk.additionCount;\n return (\n lineNumber < trailingStart + trailingRegion.fromStart ||\n lineNumber >= trailingStart + trailingRegion.rangeSize\n );\n}\n\nexport interface GetNearestRenderableAdditionLineProps extends IsAdditionLineRenderableProps {\n direction: 'up' | 'down';\n}\n\n/**\n * The nearest renderable new-file line at or beyond `lineNumber` in the\n * given direction (one-based), or undefined when every line that way is\n * hidden inside collapsed regions. Sequential caret motion uses this to skip\n * over collapsed regions like code folds; it walks the hunk metadata once\n * instead of probing line by line across a gap.\n */\nexport function getNearestRenderableAdditionLine({\n fileDiff,\n lineNumber,\n direction,\n expandedHunks,\n collapsedContextThreshold,\n}: GetNearestRenderableAdditionLineProps): number | undefined {\n if (expandedHunks === true || fileDiff.isPartial) {\n return lineNumber;\n }\n\n // Renderable [start, end) line ranges in ascending order, plus the\n // exclusive end of the modeled range — anything past it (the editor's\n // phantom document-end line) counts as renderable.\n const ranges: Array<[start: number, end: number]> = [];\n let modeledEnd = 1;\n for (const [hunkIndex, hunk] of fileDiff.hunks.entries()) {\n const region = getExpandedRegion({\n isPartial: fileDiff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const gapStart = hunk.additionStart - region.rangeSize;\n if (region.renderAll) {\n ranges.push([gapStart, hunk.additionStart]);\n } else {\n if (region.fromStart > 0) {\n ranges.push([gapStart, gapStart + region.fromStart]);\n }\n if (region.fromEnd > 0) {\n ranges.push([hunk.additionStart - region.fromEnd, hunk.additionStart]);\n }\n }\n ranges.push([hunk.additionStart, hunk.additionStart + hunk.additionCount]);\n modeledEnd = hunk.additionStart + hunk.additionCount;\n }\n const trailingRegion = getTrailingExpandedRegion({\n fileDiff,\n hunkIndex: fileDiff.hunks.length - 1,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'getNearestRenderableAdditionLine',\n });\n if (trailingRegion != null) {\n const trailingStart = modeledEnd;\n modeledEnd = trailingStart + trailingRegion.rangeSize;\n if (trailingRegion.renderAll) {\n ranges.push([trailingStart, modeledEnd]);\n } else if (trailingRegion.fromStart > 0) {\n ranges.push([trailingStart, trailingStart + trailingRegion.fromStart]);\n }\n }\n\n if (lineNumber >= modeledEnd) {\n return lineNumber;\n }\n if (direction === 'down') {\n for (const [start, end] of ranges) {\n if (end > lineNumber) {\n return Math.max(start, lineNumber);\n }\n }\n return undefined;\n }\n for (let index = ranges.length - 1; index >= 0; index--) {\n const [start, end] = ranges[index];\n if (start <= lineNumber) {\n return Math.min(end - 1, lineNumber);\n }\n }\n return undefined;\n}\n\nexport function getHunkSeparatorHeight({\n type,\n metrics,\n}: HunkSeparatorBaseProps): number {\n return metrics.hunkSeparatorHeight ?? getDefaultHunkSeparatorHeight(type);\n}\n\nexport function getHunkSeparatorGap({\n type,\n metrics,\n}: HunkSeparatorBaseProps): number {\n return type === 'simple' || type === 'metadata' || type === 'line-info-basic'\n ? 0\n : metrics.spacing;\n}\n\nexport function hasLeadingHunkSeparator({\n type,\n hunkIndex,\n hunkSpecs,\n}: Omit<LeadingHunkSeparatorLayoutProps, 'metrics'>): boolean {\n switch (type) {\n case 'simple':\n return hunkIndex > 0;\n case 'metadata':\n return hunkSpecs != null;\n case 'line-info':\n case 'line-info-basic':\n case 'custom':\n return true;\n }\n}\n\nexport function hasTrailingHunkSeparator(type: HunkSeparators): boolean {\n return type !== 'simple' && type !== 'metadata';\n}\n\n// Mirrors the renderer/CSS spacing rules for the separator shown before a hunk.\nexport function getLeadingHunkSeparatorLayout({\n type,\n metrics,\n hunkIndex,\n hunkSpecs,\n}: LeadingHunkSeparatorLayoutProps): HunkSeparatorLayout | undefined {\n if (!hasLeadingHunkSeparator({ type, hunkIndex, hunkSpecs })) {\n return undefined;\n }\n\n const height = getHunkSeparatorHeight({ type, metrics });\n const gap = getHunkSeparatorGap({ type, metrics });\n const gapBefore = hunkIndex > 0 ? gap : 0;\n const gapAfter = gap;\n return {\n height,\n gapBefore,\n gapAfter,\n totalHeight: gapBefore + height + gapAfter,\n };\n}\n\n// Mirrors the renderer/CSS spacing rules for the separator shown after the last\n// hunk when trailing unchanged context is collapsed.\nexport function getTrailingHunkSeparatorLayout({\n type,\n metrics,\n}: HunkSeparatorBaseProps): HunkSeparatorLayout | undefined {\n if (!hasTrailingHunkSeparator(type)) {\n return undefined;\n }\n\n const height = getHunkSeparatorHeight({ type, metrics });\n const gapBefore = getHunkSeparatorGap({ type, metrics });\n return {\n height,\n gapBefore,\n gapAfter: 0,\n totalHeight: gapBefore + height,\n };\n}\n"],"mappings":"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"}
|
|
@@ -69,10 +69,12 @@ declare class WorkerPoolManager {
|
|
|
69
69
|
private initializeWorkers;
|
|
70
70
|
private drainQueue;
|
|
71
71
|
highlightFileAST(instance: FileRendererInstance, file: FileContents): void;
|
|
72
|
-
primeFileHighlightCache(file: FileContents): void
|
|
72
|
+
primeFileHighlightCache(file: FileContents): Promise<void>;
|
|
73
|
+
private getOrCreateFileHighlightCacheTask;
|
|
73
74
|
getPlainFileAST(file: FileContents, startingLine: number, totalLines: number, lines?: string[]): ThemedFileResult | undefined;
|
|
74
75
|
highlightDiffAST(instance: DiffRendererInstance, diff: FileDiffMetadata): void;
|
|
75
|
-
primeDiffHighlightCache(diff: FileDiffMetadata): void
|
|
76
|
+
primeDiffHighlightCache(diff: FileDiffMetadata): Promise<void>;
|
|
77
|
+
private getOrCreateDiffHighlightCacheTask;
|
|
76
78
|
getPlainDiffAST(diff: FileDiffMetadata, startingLine: number, totalLines: number, expandedHunks?: Map<number, HunkExpansionRegion> | true, collapsedContextThreshold?: number): ThemedDiffResult | undefined;
|
|
77
79
|
terminate(): void;
|
|
78
80
|
private isCurrentLifecycle;
|
|
@@ -102,6 +104,9 @@ declare class WorkerPoolManager {
|
|
|
102
104
|
private detachInstanceFromRenderTask;
|
|
103
105
|
private removeQueuedTask;
|
|
104
106
|
private removeActiveTask;
|
|
107
|
+
private createRenderTaskCallbacks;
|
|
108
|
+
private resolveRenderTaskCallbacks;
|
|
109
|
+
private rejectRenderTaskCallbacks;
|
|
105
110
|
private invalidateRenderTasks;
|
|
106
111
|
private clearQueuedInstanceRequests;
|
|
107
112
|
private clearHighlightKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerPoolManager.d.ts","names":[],"sources":["../../src/worker/WorkerPoolManager.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"WorkerPoolManager.d.ts","names":[],"sources":["../../src/worker/WorkerPoolManager.ts"],"mappings":"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"}
|