@pierre/diffs 1.3.0-beta.8 → 1.3.0-rc.1
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 +12 -12
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +51 -43
- package/dist/components/CodeView.js.map +1 -1
- package/dist/components/File.d.ts +7 -2
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/File.js +36 -8
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +34 -6
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +198 -17
- 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/VirtualizedFile.d.ts +2 -1
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +9 -5
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.d.ts +14 -0
- package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +61 -3
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +14 -2
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +29 -3
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/edit/index.d.ts +5 -0
- package/dist/edit/index.js +3 -0
- package/dist/editor/command.d.ts +1 -1
- package/dist/editor/command.d.ts.map +1 -1
- package/dist/editor/command.js +11 -0
- package/dist/editor/command.js.map +1 -1
- package/dist/editor/editStack.d.ts +6 -2
- package/dist/editor/editStack.d.ts.map +1 -1
- package/dist/editor/editStack.js +54 -13
- package/dist/editor/editStack.js.map +1 -1
- package/dist/editor/editor.d.ts +51 -23
- package/dist/editor/editor.d.ts.map +1 -1
- package/dist/editor/editor.js +995 -242
- package/dist/editor/editor.js.map +1 -1
- package/dist/editor/editor2.js +1 -1
- 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.map +1 -1
- package/dist/editor/lineAnnotations.js +25 -26
- package/dist/editor/lineAnnotations.js.map +1 -1
- package/dist/editor/marker.d.ts +5 -3
- package/dist/editor/marker.d.ts.map +1 -1
- package/dist/editor/marker.js +111 -91
- package/dist/editor/marker.js.map +1 -1
- package/dist/editor/matchBrackets.d.ts +3 -2
- package/dist/editor/matchBrackets.d.ts.map +1 -1
- package/dist/editor/matchBrackets.js +2 -10
- package/dist/editor/matchBrackets.js.map +1 -1
- package/dist/editor/pieceTable.d.ts +2 -1
- package/dist/editor/pieceTable.d.ts.map +1 -1
- package/dist/editor/pieceTable.js +103 -39
- package/dist/editor/pieceTable.js.map +1 -1
- package/dist/editor/platform.js +2 -0
- package/dist/editor/platform.js.map +1 -1
- package/dist/editor/popover.d.ts +25 -5
- package/dist/editor/popover.d.ts.map +1 -1
- package/dist/editor/popover.js +60 -14
- package/dist/editor/popover.js.map +1 -1
- package/dist/editor/searchPanel.d.ts +1 -0
- package/dist/editor/searchPanel.d.ts.map +1 -1
- package/dist/editor/searchPanel.js +15 -8
- package/dist/editor/searchPanel.js.map +1 -1
- package/dist/editor/selection.d.ts +31 -11
- package/dist/editor/selection.d.ts.map +1 -1
- package/dist/editor/selection.js +198 -70
- package/dist/editor/selection.js.map +1 -1
- package/dist/editor/selectionAction.d.ts +4 -3
- package/dist/editor/selectionAction.d.ts.map +1 -1
- package/dist/editor/selectionAction.js +9 -5
- package/dist/editor/selectionAction.js.map +1 -1
- 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 +12 -77
- package/dist/editor/textDocument.d.ts.map +1 -1
- package/dist/editor/textDocument.js +76 -34
- package/dist/editor/textDocument.js.map +1 -1
- package/dist/editor/textMeasure.d.ts +7 -12
- package/dist/editor/textMeasure.d.ts.map +1 -1
- package/dist/editor/textMeasure.js +40 -32
- package/dist/editor/textMeasure.js.map +1 -1
- package/dist/editor/{tokenzier.d.ts → tokenizer.d.ts} +3 -3
- package/dist/editor/tokenizer.d.ts.map +1 -0
- package/dist/editor/{tokenzier.js → tokenizer.js} +91 -26
- package/dist/editor/tokenizer.js.map +1 -0
- package/dist/editor/utils.js +1 -1
- package/dist/editor/utils.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +7 -6
- package/dist/managers/InteractionManager.d.ts +18 -7
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.js +154 -99
- package/dist/managers/InteractionManager.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 +7 -3
- package/dist/managers/UniversalRenderingManager.js.map +1 -1
- package/dist/react/CodeView.d.ts +13 -13
- package/dist/react/CodeView.d.ts.map +1 -1
- package/dist/react/CodeView.js +38 -29
- package/dist/react/CodeView.js.map +1 -1
- package/dist/react/EditContext.d.ts +20 -0
- package/dist/react/EditContext.d.ts.map +1 -0
- package/dist/react/EditContext.js +20 -0
- package/dist/react/EditContext.js.map +1 -0
- package/dist/react/File.d.ts +2 -1
- package/dist/react/File.d.ts.map +1 -1
- package/dist/react/File.js +3 -2
- package/dist/react/File.js.map +1 -1
- package/dist/react/FileDiff.d.ts +2 -2
- package/dist/react/FileDiff.d.ts.map +1 -1
- package/dist/react/FileDiff.js +3 -2
- package/dist/react/FileDiff.js.map +1 -1
- package/dist/react/MultiFileDiff.d.ts +2 -2
- package/dist/react/MultiFileDiff.d.ts.map +1 -1
- package/dist/react/MultiFileDiff.js +3 -2
- package/dist/react/MultiFileDiff.js.map +1 -1
- package/dist/react/PatchDiff.d.ts +2 -2
- package/dist/react/PatchDiff.d.ts.map +1 -1
- package/dist/react/PatchDiff.js +3 -2
- package/dist/react/PatchDiff.js.map +1 -1
- package/dist/react/UnresolvedFile.d.ts +1 -1
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +3 -3
- package/dist/react/types.d.ts +9 -1
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +5 -3
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +28 -27
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +5 -3
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +29 -25
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.js +3 -3
- package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +33 -1
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +134 -21
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +2 -0
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +33 -11
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/FileDiffReact.js +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/preloadDiffs.js +1 -1
- package/dist/style.js +1 -1
- package/dist/types.d.ts +185 -42
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/annotationHelpers.d.ts +20 -0
- package/dist/utils/annotationHelpers.d.ts.map +1 -0
- package/dist/utils/annotationHelpers.js +29 -0
- package/dist/utils/annotationHelpers.js.map +1 -0
- package/dist/utils/computeFileOffsets.d.ts.map +1 -1
- package/dist/utils/computeFileOffsets.js +34 -5
- package/dist/utils/computeFileOffsets.js.map +1 -1
- package/dist/utils/editSessionHunks.d.ts +66 -0
- package/dist/utils/editSessionHunks.d.ts.map +1 -0
- package/dist/utils/editSessionHunks.js +437 -0
- package/dist/utils/editSessionHunks.js.map +1 -0
- package/dist/utils/getHunkSideBoundaries.d.ts +7 -0
- package/dist/utils/getHunkSideBoundaries.d.ts.map +1 -0
- package/dist/utils/getHunkSideBoundaries.js +12 -0
- package/dist/utils/getHunkSideBoundaries.js.map +1 -0
- package/dist/utils/getTotalLineCountFromHunks.d.ts.map +1 -1
- package/dist/utils/getTotalLineCountFromHunks.js +2 -1
- package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
- package/dist/utils/hydratePartialDiff.d.ts.map +1 -1
- package/dist/utils/hydratePartialDiff.js +4 -3
- package/dist/utils/hydratePartialDiff.js.map +1 -1
- package/dist/utils/isGutterUtilityPath.d.ts +5 -0
- package/dist/utils/isGutterUtilityPath.d.ts.map +1 -0
- package/dist/utils/isGutterUtilityPath.js +12 -0
- package/dist/utils/isGutterUtilityPath.js.map +1 -0
- package/dist/utils/iterateOverDiff.d.ts.map +1 -1
- package/dist/utils/iterateOverDiff.js +17 -12
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.js +9 -6
- package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
- package/dist/utils/parsePatchFiles.d.ts.map +1 -1
- package/dist/utils/parsePatchFiles.js +6 -3
- package/dist/utils/parsePatchFiles.js.map +1 -1
- package/dist/utils/realignChangeContent.d.ts +33 -0
- package/dist/utils/realignChangeContent.d.ts.map +1 -0
- package/dist/utils/realignChangeContent.js +148 -0
- package/dist/utils/realignChangeContent.js.map +1 -0
- package/dist/utils/renderDiffWithHighlighter.js +1 -1
- package/dist/utils/resolveRegion.d.ts.map +1 -1
- package/dist/utils/resolveRegion.js +18 -2
- package/dist/utils/resolveRegion.js.map +1 -1
- package/dist/utils/updateDiffHunks.d.ts +8 -2
- package/dist/utils/updateDiffHunks.d.ts.map +1 -1
- package/dist/utils/updateDiffHunks.js +9 -7
- package/dist/utils/updateDiffHunks.js.map +1 -1
- package/dist/utils/virtualDiffLayout.d.ts +42 -2
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
- package/dist/utils/virtualDiffLayout.js +101 -7
- package/dist/utils/virtualDiffLayout.js.map +1 -1
- package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
- package/dist/worker/WorkerPoolManager.js +4 -2
- package/dist/worker/WorkerPoolManager.js.map +1 -1
- package/dist/worker/types.d.ts +4 -0
- package/dist/worker/types.d.ts.map +1 -1
- package/dist/worker/worker-portable.js +60 -20
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +61 -19
- package/dist/worker/worker.js.map +1 -1
- package/package.json +13 -8
- package/dist/editor/index.d.ts +0 -3
- package/dist/editor/index.js +0 -3
- package/dist/editor/tokenzier.d.ts.map +0 -1
- package/dist/editor/tokenzier.js.map +0 -1
- package/dist/react/EditorContext.d.ts +0 -15
- package/dist/react/EditorContext.d.ts.map +0 -1
- package/dist/react/EditorContext.js +0 -23
- package/dist/react/EditorContext.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydratePartialDiff.js","names":[],"sources":["../../src/utils/hydratePartialDiff.ts"],"sourcesContent":["import type {\n FileContents,\n FileDiffLoadedFiles,\n FileDiffMetadata,\n Hunk,\n} from '../types';\nimport { cloneFileDiffMetadata } from './cloneFileDiffMetadata';\nimport { splitFileContents } from './splitFileContents';\n\ninterface HydratedHunksResult {\n hunks: Hunk[];\n splitLineCount: number;\n unifiedLineCount: number;\n}\n\n/**\n * Hydrates a partial diff in place with full file line arrays.\n */\nexport function hydratePartialDiff(\n type: 'clone' | 'merge',\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileDiffMetadata {\n const targetFileDiff =\n type === 'clone' ? cloneFileDiffMetadata(fileDiff) : fileDiff;\n\n if (!targetFileDiff.isPartial) {\n throw new Error('hydratePartialDiff: fileDiff must be partial');\n }\n\n switch (targetFileDiff.type) {\n case 'change':\n case 'rename-changed': {\n const oldFile = requireOldFile(targetFileDiff, files);\n const newFile = requireNewFile(targetFileDiff, files);\n return hydrateTwoSidedFileDiff(targetFileDiff, oldFile, newFile);\n }\n case 'rename-pure': {\n const newFile = requireNewFile(targetFileDiff, files);\n requireMissingOldFile(targetFileDiff, files);\n const lines = splitFileContents(newFile.contents);\n targetFileDiff.isPartial = false;\n targetFileDiff.deletionLines = lines;\n targetFileDiff.additionLines = lines;\n setHydratedCacheKey(targetFileDiff, null, newFile);\n return targetFileDiff;\n }\n }\n throw new Error(\n `hydratePartialDiff: ${targetFileDiff.type} diffs cannot be hydrated from loaded files`\n );\n}\n\nfunction hydrateTwoSidedFileDiff(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents,\n newFile: FileContents\n): FileDiffMetadata {\n const deletionLines = splitFileContents(oldFile.contents);\n const additionLines = splitFileContents(newFile.contents);\n const { hunks, splitLineCount, unifiedLineCount } = hydrateHunks(\n fileDiff.hunks,\n additionLines.length\n );\n\n fileDiff.hunks = hunks;\n fileDiff.splitLineCount = splitLineCount;\n fileDiff.unifiedLineCount = unifiedLineCount;\n fileDiff.isPartial = false;\n fileDiff.deletionLines = deletionLines;\n fileDiff.additionLines = additionLines;\n setHydratedCacheKey(fileDiff, oldFile, newFile);\n return fileDiff;\n}\n\nfunction hydrateHunks(\n hunks: Hunk[],\n totalAdditionLines: number\n): HydratedHunksResult {\n let splitLineCount = 0;\n let unifiedLineCount = 0;\n let lastHunkAdditionEnd = 0;\n\n const hydratedHunks: Hunk[] = [];\n\n for (const hunk of hunks) {\n const additionLineIndex = Math.max(hunk.additionStart - 1, 0);\n const deletionLineIndex = Math.max(hunk.deletionStart - 1, 0);\n let contentAdditionLineIndex = additionLineIndex;\n let contentDeletionLineIndex = deletionLineIndex;\n let hunkAdditionLines = 0;\n let hunkDeletionLines = 0;\n let hunkSplitLineCount = 0;\n let hunkUnifiedLineCount = 0;\n const hunkContent: Hunk['hunkContent'] = [];\n\n for (const content of hunk.hunkContent) {\n if (content.type === 'context') {\n hunkContent.push({\n ...content,\n additionLineIndex: contentAdditionLineIndex,\n deletionLineIndex: contentDeletionLineIndex,\n });\n contentAdditionLineIndex += content.lines;\n contentDeletionLineIndex += content.lines;\n hunkSplitLineCount += content.lines;\n hunkUnifiedLineCount += content.lines;\n continue;\n }\n\n hunkContent.push({\n ...content,\n additionLineIndex: contentAdditionLineIndex,\n deletionLineIndex: contentDeletionLineIndex,\n });\n contentAdditionLineIndex += content.additions;\n contentDeletionLineIndex += content.deletions;\n hunkAdditionLines += content.additions;\n hunkDeletionLines += content.deletions;\n hunkSplitLineCount += Math.max(content.additions, content.deletions);\n hunkUnifiedLineCount += content.additions + content.deletions;\n }\n\n const collapsedBefore = Math.max(\n hunk.additionStart - 1 - lastHunkAdditionEnd,\n 0\n );\n hydratedHunks.push({\n ...hunk,\n collapsedBefore,\n additionLineIndex,\n deletionLineIndex,\n additionLines: hunkAdditionLines,\n deletionLines: hunkDeletionLines,\n hunkContent,\n splitLineStart: splitLineCount + collapsedBefore,\n unifiedLineStart: unifiedLineCount + collapsedBefore,\n splitLineCount: hunkSplitLineCount,\n unifiedLineCount: hunkUnifiedLineCount,\n });\n\n splitLineCount += collapsedBefore + hunkSplitLineCount;\n unifiedLineCount += collapsedBefore + hunkUnifiedLineCount;\n lastHunkAdditionEnd = hunk.additionStart + hunk.additionCount - 1;\n }\n\n if (hydratedHunks.length > 0) {\n const lastHunk = hydratedHunks[hydratedHunks.length - 1];\n const lastHunkEnd = Math.max(\n lastHunk.additionStart + lastHunk.additionCount - 1,\n 0\n );\n const collapsedAfter = Math.max(totalAdditionLines - lastHunkEnd, 0);\n splitLineCount += collapsedAfter;\n unifiedLineCount += collapsedAfter;\n }\n\n return { hunks: hydratedHunks, splitLineCount, unifiedLineCount };\n}\n\nfunction requireOldFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileContents {\n if (files.oldFile == null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile`\n );\n }\n return files.oldFile;\n}\n\nfunction requireNewFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileContents {\n if (files.newFile == null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires newFile`\n );\n }\n return files.newFile;\n}\n\nfunction requireMissingOldFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): void {\n if (files.oldFile !== null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile to be null`\n );\n }\n}\n\nfunction getHydratedCacheKey(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents | null,\n newFile: FileContents | null\n): string | undefined {\n if (fileDiff.cacheKey != null) {\n return `${fileDiff.cacheKey}:hydrated`;\n }\n return getLoadedFileCacheKey(oldFile, newFile);\n}\n\nfunction setHydratedCacheKey(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents | null,\n newFile: FileContents | null\n): void {\n const cacheKey = getHydratedCacheKey(fileDiff, oldFile, newFile);\n if (cacheKey == null) {\n delete fileDiff.cacheKey;\n return;\n }\n fileDiff.cacheKey = cacheKey;\n}\n\nfunction getLoadedFileCacheKey(\n oldFile: FileContents | null,\n newFile: FileContents | null\n): string | undefined {\n if (oldFile != null && newFile != null) {\n return oldFile.cacheKey != null && newFile.cacheKey != null\n ? `${oldFile.cacheKey}:${newFile.cacheKey}`\n : undefined;\n }\n return oldFile?.cacheKey ?? newFile?.cacheKey;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hydratePartialDiff.js","names":[],"sources":["../../src/utils/hydratePartialDiff.ts"],"sourcesContent":["import type {\n FileContents,\n FileDiffLoadedFiles,\n FileDiffMetadata,\n Hunk,\n} from '../types';\nimport { cloneFileDiffMetadata } from './cloneFileDiffMetadata';\nimport {\n getHunkSideEndBoundary,\n getHunkSideStartBoundary,\n} from './getHunkSideBoundaries';\nimport { splitFileContents } from './splitFileContents';\n\ninterface HydratedHunksResult {\n hunks: Hunk[];\n splitLineCount: number;\n unifiedLineCount: number;\n}\n\n/**\n * Hydrates a partial diff in place with full file line arrays.\n */\nexport function hydratePartialDiff(\n type: 'clone' | 'merge',\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileDiffMetadata {\n const targetFileDiff =\n type === 'clone' ? cloneFileDiffMetadata(fileDiff) : fileDiff;\n\n if (!targetFileDiff.isPartial) {\n throw new Error('hydratePartialDiff: fileDiff must be partial');\n }\n\n switch (targetFileDiff.type) {\n case 'change':\n case 'rename-changed': {\n const oldFile = requireOldFile(targetFileDiff, files);\n const newFile = requireNewFile(targetFileDiff, files);\n return hydrateTwoSidedFileDiff(targetFileDiff, oldFile, newFile);\n }\n case 'rename-pure': {\n const newFile = requireNewFile(targetFileDiff, files);\n requireMissingOldFile(targetFileDiff, files);\n const lines = splitFileContents(newFile.contents);\n targetFileDiff.isPartial = false;\n targetFileDiff.deletionLines = lines;\n targetFileDiff.additionLines = lines;\n setHydratedCacheKey(targetFileDiff, null, newFile);\n return targetFileDiff;\n }\n }\n throw new Error(\n `hydratePartialDiff: ${targetFileDiff.type} diffs cannot be hydrated from loaded files`\n );\n}\n\nfunction hydrateTwoSidedFileDiff(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents,\n newFile: FileContents\n): FileDiffMetadata {\n const deletionLines = splitFileContents(oldFile.contents);\n const additionLines = splitFileContents(newFile.contents);\n const { hunks, splitLineCount, unifiedLineCount } = hydrateHunks(\n fileDiff.hunks,\n additionLines.length\n );\n\n fileDiff.hunks = hunks;\n fileDiff.splitLineCount = splitLineCount;\n fileDiff.unifiedLineCount = unifiedLineCount;\n fileDiff.isPartial = false;\n fileDiff.deletionLines = deletionLines;\n fileDiff.additionLines = additionLines;\n setHydratedCacheKey(fileDiff, oldFile, newFile);\n return fileDiff;\n}\n\nfunction hydrateHunks(\n hunks: Hunk[],\n totalAdditionLines: number\n): HydratedHunksResult {\n let splitLineCount = 0;\n let unifiedLineCount = 0;\n let lastHunkAdditionEnd = 0;\n\n const hydratedHunks: Hunk[] = [];\n\n for (const hunk of hunks) {\n const additionLineIndex = Math.max(hunk.additionStart - 1, 0);\n const deletionLineIndex = Math.max(hunk.deletionStart - 1, 0);\n let contentAdditionLineIndex = additionLineIndex;\n let contentDeletionLineIndex = deletionLineIndex;\n let hunkAdditionLines = 0;\n let hunkDeletionLines = 0;\n let hunkSplitLineCount = 0;\n let hunkUnifiedLineCount = 0;\n const hunkContent: Hunk['hunkContent'] = [];\n\n for (const content of hunk.hunkContent) {\n if (content.type === 'context') {\n hunkContent.push({\n ...content,\n additionLineIndex: contentAdditionLineIndex,\n deletionLineIndex: contentDeletionLineIndex,\n });\n contentAdditionLineIndex += content.lines;\n contentDeletionLineIndex += content.lines;\n hunkSplitLineCount += content.lines;\n hunkUnifiedLineCount += content.lines;\n continue;\n }\n\n hunkContent.push({\n ...content,\n additionLineIndex: contentAdditionLineIndex,\n deletionLineIndex: contentDeletionLineIndex,\n });\n contentAdditionLineIndex += content.additions;\n contentDeletionLineIndex += content.deletions;\n hunkAdditionLines += content.additions;\n hunkDeletionLines += content.deletions;\n hunkSplitLineCount += Math.max(content.additions, content.deletions);\n hunkUnifiedLineCount += content.additions + content.deletions;\n }\n\n const collapsedBefore = Math.max(\n getHunkSideStartBoundary(hunk.additionStart, hunk.additionCount) -\n lastHunkAdditionEnd,\n 0\n );\n hydratedHunks.push({\n ...hunk,\n collapsedBefore,\n additionLineIndex,\n deletionLineIndex,\n additionLines: hunkAdditionLines,\n deletionLines: hunkDeletionLines,\n hunkContent,\n splitLineStart: splitLineCount + collapsedBefore,\n unifiedLineStart: unifiedLineCount + collapsedBefore,\n splitLineCount: hunkSplitLineCount,\n unifiedLineCount: hunkUnifiedLineCount,\n });\n\n splitLineCount += collapsedBefore + hunkSplitLineCount;\n unifiedLineCount += collapsedBefore + hunkUnifiedLineCount;\n lastHunkAdditionEnd = getHunkSideEndBoundary(\n hunk.additionStart,\n hunk.additionCount\n );\n }\n\n if (hydratedHunks.length > 0) {\n const lastHunk = hydratedHunks[hydratedHunks.length - 1];\n const lastHunkEnd = getHunkSideEndBoundary(\n lastHunk.additionStart,\n lastHunk.additionCount\n );\n const collapsedAfter = Math.max(totalAdditionLines - lastHunkEnd, 0);\n splitLineCount += collapsedAfter;\n unifiedLineCount += collapsedAfter;\n }\n\n return { hunks: hydratedHunks, splitLineCount, unifiedLineCount };\n}\n\nfunction requireOldFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileContents {\n if (files.oldFile == null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile`\n );\n }\n return files.oldFile;\n}\n\nfunction requireNewFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): FileContents {\n if (files.newFile == null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires newFile`\n );\n }\n return files.newFile;\n}\n\nfunction requireMissingOldFile(\n fileDiff: FileDiffMetadata,\n files: FileDiffLoadedFiles\n): void {\n if (files.oldFile !== null) {\n throw new Error(\n `hydratePartialDiff: ${fileDiff.type} diff for ${fileDiff.name} requires oldFile to be null`\n );\n }\n}\n\nfunction getHydratedCacheKey(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents | null,\n newFile: FileContents | null\n): string | undefined {\n if (fileDiff.cacheKey != null) {\n return `${fileDiff.cacheKey}:hydrated`;\n }\n return getLoadedFileCacheKey(oldFile, newFile);\n}\n\nfunction setHydratedCacheKey(\n fileDiff: FileDiffMetadata,\n oldFile: FileContents | null,\n newFile: FileContents | null\n): void {\n const cacheKey = getHydratedCacheKey(fileDiff, oldFile, newFile);\n if (cacheKey == null) {\n delete fileDiff.cacheKey;\n return;\n }\n fileDiff.cacheKey = cacheKey;\n}\n\nfunction getLoadedFileCacheKey(\n oldFile: FileContents | null,\n newFile: FileContents | null\n): string | undefined {\n if (oldFile != null && newFile != null) {\n return oldFile.cacheKey != null && newFile.cacheKey != null\n ? `${oldFile.cacheKey}:${newFile.cacheKey}`\n : undefined;\n }\n return oldFile?.cacheKey ?? newFile?.cacheKey;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isGutterUtilityPath.d.ts","names":[],"sources":["../../src/utils/isGutterUtilityPath.ts"],"mappings":";iBAEgB,mBAAA,CACd,IAA0C,YAA1B,WAAW"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/utils/isGutterUtilityPath.ts
|
|
2
|
+
function isGutterUtilityPath(path) {
|
|
3
|
+
for (const element of path) {
|
|
4
|
+
if (!(element instanceof HTMLElement)) continue;
|
|
5
|
+
if (element.hasAttribute("data-utility-button") || element.hasAttribute("data-gutter-utility-slot") || element.getAttribute("slot") === "gutter-utility-slot" || element.getAttribute("name") === "gutter-utility-slot") return true;
|
|
6
|
+
}
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { isGutterUtilityPath };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=isGutterUtilityPath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isGutterUtilityPath.js","names":[],"sources":["../../src/utils/isGutterUtilityPath.ts"],"sourcesContent":["// Recognize both the built-in utility button and custom content assigned to the\n// gutter utility slot so other pointer handlers leave the gesture untouched.\nexport function isGutterUtilityPath(\n path: readonly (EventTarget | undefined)[]\n): boolean {\n for (const element of path) {\n if (!(element instanceof HTMLElement)) {\n continue;\n }\n if (\n element.hasAttribute('data-utility-button') ||\n element.hasAttribute('data-gutter-utility-slot') ||\n element.getAttribute('slot') === 'gutter-utility-slot' ||\n element.getAttribute('name') === 'gutter-utility-slot'\n ) {\n return true;\n }\n }\n return false;\n}\n"],"mappings":";AAEA,SAAgB,oBACd,MACS;CACT,KAAK,MAAM,WAAW,MAAM;EAC1B,IAAI,EAAE,mBAAmB,cACvB;EAEF,IACE,QAAQ,aAAa,qBAAqB,KAC1C,QAAQ,aAAa,0BAA0B,KAC/C,QAAQ,aAAa,MAAM,MAAM,yBACjC,QAAQ,aAAa,MAAM,MAAM,uBAEjC,OAAO;CAEX;CACA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iterateOverDiff.d.ts","names":[],"sources":["../../src/utils/iterateOverDiff.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"iterateOverDiff.d.ts","names":[],"sources":["../../src/utils/iterateOverDiff.ts"],"mappings":";;;UAaiB,gBAAA;EACf,gBAAA;EACA,cAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;AAAA;AAAA,UAGe,oBAAA;EACf,SAAA;EACA,IAAA,EAAM,IAAI;EACV,eAAA;EACA,cAAA;AAAA;AAAA,UAGQ,6BAAA,SAAsC,oBAAA;EAC9C,IAAA;EACA,YAAA,EAAc,gBAAA;EACd,YAAA,EAAc,gBAAA;AAAA;AAAA,UAGN,8BAAA,SAAuC,oBAAoB;EACnE,IAAA;EACA,YAAA,EAAc,gBAAA;EACd,YAAA;AAAA;AAAA,UAGQ,8BAAA,SAAuC,oBAAoB;EACnE,IAAA;EACA,YAAA;EACA,YAAA,EAAc,gBAAA;AAAA;AAAA,KAGJ,qBAAA,GACR,6BAAA,GACA,8BAAA,GACA,8BAAA;AAAA,KAEC,SAAA;AAAA,KAgDO,gBAAA,IAAoB,KAA4B,EAArB,qBAAqB;AAAA,UAE3C,oBAAA;EACf,IAAA,EAAM,gBAAA;EACN,SAAA,EAAW,SAAA;EACX,YAAA;EACA,UAAA;EACA,aAAA,GAAgB,GAAA,SAAY,mBAAA;EAC5B,yBAAA;EACA,QAAA,EAAU,gBAAA;AAAA;AAAA,iBAGI,eAAA;EACd,IAAA;EACA,SAAA;EACA,YAAA;EACA,UAAA;EACA,aAAA;EACA,yBAAA;EACA;AAAA,GACC,oBAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "../constants.js";
|
|
2
|
+
import { getHunkSideStartBoundary } from "./getHunkSideBoundaries.js";
|
|
2
3
|
import { getExpandedRegion, getTrailingExpandedRegion } from "./virtualDiffLayout.js";
|
|
3
4
|
//#region src/utils/iterateOverDiff.ts
|
|
4
5
|
function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infinity, expandedHunks, collapsedContextThreshold = 1, callback }) {
|
|
@@ -61,6 +62,10 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
61
62
|
const hunk = diff.hunks[hunkIndex];
|
|
62
63
|
if (hunk == null) throw new Error("iterateOverDiff: invalid hunk index");
|
|
63
64
|
if (state.shouldBreak()) break;
|
|
65
|
+
const deletionBoundary = getHunkSideStartBoundary(hunk.deletionStart, hunk.deletionCount);
|
|
66
|
+
const additionBoundary = getHunkSideStartBoundary(hunk.additionStart, hunk.additionCount);
|
|
67
|
+
const deletionStartIndex = !diff.isPartial && hunk.deletionCount === 0 ? deletionBoundary : hunk.deletionLineIndex;
|
|
68
|
+
const additionStartIndex = !diff.isPartial && hunk.additionCount === 0 ? additionBoundary : hunk.additionLineIndex;
|
|
64
69
|
const leadingRegion = getExpandedRegion({
|
|
65
70
|
isPartial: diff.isPartial,
|
|
66
71
|
rangeSize: hunk.collapsedBefore,
|
|
@@ -90,10 +95,10 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
90
95
|
if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {
|
|
91
96
|
let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;
|
|
92
97
|
let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;
|
|
93
|
-
let deletionLineIndex =
|
|
94
|
-
let additionLineIndex =
|
|
95
|
-
let deletionLineNumber =
|
|
96
|
-
let additionLineNumber =
|
|
98
|
+
let deletionLineIndex = deletionStartIndex - leadingRegion.rangeSize;
|
|
99
|
+
let additionLineIndex = additionStartIndex - leadingRegion.rangeSize;
|
|
100
|
+
let deletionLineNumber = deletionBoundary + 1 - leadingRegion.rangeSize;
|
|
101
|
+
let additionLineNumber = additionBoundary + 1 - leadingRegion.rangeSize;
|
|
97
102
|
if (walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {
|
|
98
103
|
return state.emit({
|
|
99
104
|
hunkIndex,
|
|
@@ -119,10 +124,10 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
119
124
|
})) break hunkIterator;
|
|
120
125
|
unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;
|
|
121
126
|
splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;
|
|
122
|
-
deletionLineIndex =
|
|
123
|
-
additionLineIndex =
|
|
124
|
-
deletionLineNumber =
|
|
125
|
-
additionLineNumber =
|
|
127
|
+
deletionLineIndex = deletionStartIndex - leadingRegion.fromEnd;
|
|
128
|
+
additionLineIndex = additionStartIndex - leadingRegion.fromEnd;
|
|
129
|
+
deletionLineNumber = deletionBoundary + 1 - leadingRegion.fromEnd;
|
|
130
|
+
additionLineNumber = additionBoundary + 1 - leadingRegion.fromEnd;
|
|
126
131
|
if (walkContextLines(state, leadingRegion.fromEnd, diffStyle, (index) => {
|
|
127
132
|
return state.emit({
|
|
128
133
|
hunkIndex,
|
|
@@ -154,10 +159,10 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
154
159
|
}
|
|
155
160
|
let unifiedLineIndex = hunk.unifiedLineStart;
|
|
156
161
|
let splitLineIndex = hunk.splitLineStart;
|
|
157
|
-
let deletionLineIndex =
|
|
158
|
-
let additionLineIndex =
|
|
159
|
-
let deletionLineNumber =
|
|
160
|
-
let additionLineNumber =
|
|
162
|
+
let deletionLineIndex = deletionStartIndex;
|
|
163
|
+
let additionLineIndex = additionStartIndex;
|
|
164
|
+
let deletionLineNumber = deletionBoundary + 1;
|
|
165
|
+
let additionLineNumber = additionBoundary + 1;
|
|
161
166
|
const lastContent = hunk.hunkContent.at(-1);
|
|
162
167
|
for (const content of hunk.hunkContent) {
|
|
163
168
|
if (state.shouldBreak()) break hunkIterator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iterateOverDiff.js","names":[],"sources":["../../src/utils/iterateOverDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n ChangeContent,\n FileDiffMetadata,\n Hunk,\n HunkExpansionRegion,\n} from '../types';\nimport {\n getExpandedRegion,\n getTrailingExpandedRegion,\n} from './virtualDiffLayout';\n\nexport interface DiffLineMetadata {\n unifiedLineIndex: number;\n splitLineIndex: number;\n lineIndex: number;\n lineNumber: number;\n noEOFCR: boolean;\n}\n\nexport interface DiffLineCallbackBase {\n hunkIndex: number;\n hunk: Hunk | undefined; // undefined for trailing expansion region\n collapsedBefore: number; // > 0 means separator before this line, value = hidden lines\n collapsedAfter: number; // > 0 only on final line if trailing collapsed content\n}\n\ninterface DiffLineCallbackContextChange extends DiffLineCallbackBase {\n type: 'change' | 'context' | 'context-expanded';\n deletionLine: DiffLineMetadata;\n additionLine: DiffLineMetadata;\n}\n\ninterface DiffLineCallbackChangeDeletion extends DiffLineCallbackBase {\n type: 'change';\n deletionLine: DiffLineMetadata;\n additionLine?: undefined;\n}\n\ninterface DiffLineCallbackChangeAddition extends DiffLineCallbackBase {\n type: 'change';\n deletionLine?: undefined;\n additionLine: DiffLineMetadata;\n}\n\nexport type DiffLineCallbackProps =\n | DiffLineCallbackContextChange\n | DiffLineCallbackChangeDeletion\n | DiffLineCallbackChangeAddition;\n\ntype DiffStyle = 'unified' | 'split' | 'both';\n\ntype LineIterationBounds = [startIndex: number, endIndex: number];\n\ntype ChangeContentSide = 'deletions' | 'additions';\n\ntype ContextLineCallback = (index: number) => boolean | void;\n\ninterface IterationState {\n isWindowedHighlight: boolean;\n viewportStart: number;\n viewportEnd: number;\n splitCount: number;\n unifiedCount: number;\n finalHunkIndex: number;\n shouldBreak(): boolean;\n shouldSkip(unifiedHeight: number, splitHeight: number): boolean;\n incrementCounts(unifiedValue: number, splitValue: number): void;\n isInWindow(unifiedHeight: number, splitHeight: number): boolean;\n isInUnifiedWindow(height: number): boolean;\n isInSplitWindow(height: number): boolean;\n emit(props: DiffLineCallbackProps, silent?: boolean): boolean;\n}\n\ninterface IterationStartState {\n hunkIndex: number;\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface HunkPrefixCounts {\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface IterationStartStateProps extends Omit<\n IterateOverDiffProps,\n 'callback' | 'totalLines'\n> {\n startingLine: number;\n collapsedContextThreshold: number;\n}\n\ninterface HunkPrefixCountsProps extends Pick<\n IterationStartStateProps,\n 'diff' | 'expandedHunks' | 'collapsedContextThreshold'\n> {}\n\nexport type DiffLineCallback = (props: DiffLineCallbackProps) => boolean | void;\n\nexport interface IterateOverDiffProps {\n diff: FileDiffMetadata;\n diffStyle: DiffStyle;\n startingLine?: number;\n totalLines?: number;\n expandedHunks?: Map<number, HunkExpansionRegion> | true;\n collapsedContextThreshold?: number;\n callback: DiffLineCallback;\n}\n\nexport function iterateOverDiff({\n diff,\n diffStyle,\n startingLine = 0,\n totalLines = Infinity,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n callback,\n}: IterateOverDiffProps): void {\n const iterationStart = getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n });\n const state: IterationState = {\n viewportStart: startingLine,\n viewportEnd: startingLine + totalLines,\n isWindowedHighlight: startingLine > 0 || totalLines < Infinity,\n splitCount: iterationStart.splitCount,\n unifiedCount: iterationStart.unifiedCount,\n finalHunkIndex: diff.hunks.length - 1,\n shouldBreak() {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const breakUnified = state.unifiedCount >= startingLine + totalLines;\n const breakSplit = state.splitCount >= startingLine + totalLines;\n\n if (diffStyle === 'unified') {\n return breakUnified;\n } else if (diffStyle === 'split') {\n return breakSplit;\n } else {\n return breakUnified && breakSplit;\n }\n },\n shouldSkip(unifiedCount: number, splitCount: number) {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const skipUnified =\n unifiedCount > 0 && state.unifiedCount + unifiedCount <= startingLine;\n const skipSplit =\n splitCount > 0 && state.splitCount + splitCount <= startingLine;\n\n if (diffStyle === 'unified') {\n return skipUnified;\n } else if (diffStyle === 'split') {\n return skipSplit;\n } else {\n return skipUnified && skipSplit;\n }\n },\n incrementCounts(unifiedValue: number, splitValue: number) {\n if (diffStyle === 'unified' || diffStyle === 'both') {\n state.unifiedCount += unifiedValue;\n }\n if (diffStyle === 'split' || diffStyle === 'both') {\n state.splitCount += splitValue;\n }\n },\n isInWindow(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return true;\n }\n\n const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);\n const splitInWindow = state.isInSplitWindow(splitHeight);\n\n if (diffStyle === 'unified') {\n return unifiedInWindow;\n } else if (diffStyle === 'split') {\n return splitInWindow;\n } else {\n return unifiedInWindow || splitInWindow;\n }\n },\n isInUnifiedWindow(unifiedHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.unifiedCount >= startingLine - unifiedHeight &&\n state.unifiedCount < startingLine + totalLines)\n );\n },\n isInSplitWindow(splitHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.splitCount >= startingLine - splitHeight &&\n state.splitCount < startingLine + totalLines)\n );\n },\n emit(props: DiffLineCallbackProps, silent = false): boolean {\n if (!silent) {\n if (diffStyle === 'unified') {\n state.incrementCounts(1, 0);\n } else if (diffStyle === 'split') {\n state.incrementCounts(0, 1);\n } else {\n state.incrementCounts(1, 1);\n }\n }\n return callback(props) ?? false;\n },\n };\n\n hunkIterator: for (\n let hunkIndex = iterationStart.hunkIndex;\n hunkIndex < diff.hunks.length;\n hunkIndex++\n ) {\n const hunk = diff.hunks[hunkIndex];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk index');\n }\n if (state.shouldBreak()) {\n break;\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const trailingRegion =\n hunkIndex === state.finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n\n function getTrailingCollapsedAfter(\n unifiedLineIndex: number,\n splitLineIndex: number\n ) {\n if (\n trailingRegion == null ||\n trailingRegion.collapsedLines <= 0 ||\n trailingRegion.fromStart + trailingRegion.fromEnd > 0\n ) {\n return 0;\n }\n if (diffStyle === 'unified') {\n return unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n return splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n\n let consumedCollapsed = leadingRegion.collapsedLines === 0;\n function consumePendingCollapsed() {\n if (consumedCollapsed) {\n return 0;\n }\n consumedCollapsed = true;\n return leadingRegion.collapsedLines;\n }\n\n // Emit for expanded lines\n if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {\n let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;\n let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;\n\n let deletionLineIndex = hunk.deletionLineIndex - leadingRegion.rangeSize;\n let additionLineIndex = hunk.additionLineIndex - leadingRegion.rangeSize;\n let deletionLineNumber = hunk.deletionStart - leadingRegion.rangeSize;\n let additionLineNumber = hunk.additionStart - leadingRegion.rangeSize;\n\n if (\n walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {\n return state.emit({\n hunkIndex,\n hunk: hunk,\n collapsedBefore: 0,\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n })\n ) {\n break hunkIterator;\n }\n\n unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;\n splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;\n\n deletionLineIndex = hunk.deletionLineIndex - leadingRegion.fromEnd;\n additionLineIndex = hunk.additionLineIndex - leadingRegion.fromEnd;\n deletionLineNumber = hunk.deletionStart - leadingRegion.fromEnd;\n additionLineNumber = hunk.additionStart - leadingRegion.fromEnd;\n if (\n walkContextLines(\n state,\n leadingRegion.fromEnd,\n diffStyle,\n (index) => {\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n () => {\n // The collapsed separator belongs before this fromEnd slice. If the\n // render window starts inside the slice, consume it with the skipped\n // rows so it is not attached to the first emitted row.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(expandedLineCount, expandedLineCount);\n consumePendingCollapsed();\n }\n\n let unifiedLineIndex = hunk.unifiedLineStart;\n let splitLineIndex = hunk.splitLineStart;\n\n let deletionLineIndex = hunk.deletionLineIndex;\n let additionLineIndex = hunk.additionLineIndex;\n let deletionLineNumber = hunk.deletionStart;\n let additionLineNumber = hunk.additionStart;\n const lastContent = hunk.hunkContent.at(-1);\n\n for (const content of hunk.hunkContent) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n\n const isLastContent = content === lastContent;\n\n // Hunk Context Content\n if (content.type === 'context') {\n if (!state.shouldSkip(content.lines, content.lines)) {\n if (\n walkContextLines(\n state,\n content.lines,\n diffStyle,\n (index) => {\n const isLastLine = isLastContent && index === content.lines - 1;\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex = splitLineIndex + index;\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n ),\n type: 'context',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: isLastLine && hunk.noEOFCRDeletions,\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n },\n additionLine: {\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: isLastLine && hunk.noEOFCRAdditions,\n },\n });\n },\n () => {\n // When windowing starts inside context content, the leading\n // separator was above the visible range and should not be\n // emitted on the first rendered context line.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(content.lines, content.lines);\n consumePendingCollapsed();\n }\n unifiedLineIndex += content.lines;\n splitLineIndex += content.lines;\n\n deletionLineIndex += content.lines;\n additionLineIndex += content.lines;\n deletionLineNumber += content.lines;\n additionLineNumber += content.lines;\n }\n // Hunk Change Content\n else {\n const splitCount = Math.max(content.deletions, content.additions);\n const unifiedCount = content.deletions + content.additions;\n const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);\n if (!shouldSkipChange) {\n const iterationRanges = getChangeIterationRanges(\n state,\n content,\n diffStyle\n );\n const firstRangeStart = iterationRanges[0]?.[0] ?? 0;\n if (firstRangeStart > 0) {\n // Change rows can be windowed from the middle of the block too. In\n // that case the leading separator belongs to skipped rows, not to\n // the first visible deletion/addition row.\n consumePendingCollapsed();\n }\n // Change ranges are already clipped to the active window. Counts move\n // once for the whole change block after the selected rows emit.\n for (const [rangeStart, rangeEnd] of iterationRanges) {\n for (let index = rangeStart; index < rangeEnd; index++) {\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions\n ? index\n : index - content.deletions)\n : splitLineIndex + index;\n const collapsedAfter = getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n );\n if (\n state.emit(\n getChangeLineData({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n }),\n true\n )\n ) {\n break hunkIterator;\n }\n }\n }\n }\n\n consumePendingCollapsed();\n state.incrementCounts(unifiedCount, splitCount);\n unifiedLineIndex += unifiedCount;\n splitLineIndex += splitCount;\n deletionLineIndex += content.deletions;\n additionLineIndex += content.additions;\n deletionLineNumber += content.deletions;\n additionLineNumber += content.additions;\n }\n }\n\n if (trailingRegion != null) {\n const { collapsedLines, fromStart, fromEnd } = trailingRegion;\n const len = fromStart + fromEnd;\n if (\n walkContextLines(\n state,\n len,\n diffStyle,\n (index) => {\n const isLastLine = index === len - 1;\n return state.emit({\n hunkIndex: diff.hunks.length,\n hunk: undefined,\n collapsedBefore: 0,\n collapsedAfter: isLastLine ? collapsedLines : 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n undefined,\n () => state.shouldBreak()\n )\n ) {\n break hunkIterator;\n }\n }\n }\n}\n\n// Seek the iterator to the hunk that contains `startingLine` without changing\n// the public meaning of `startingLine`: it is a dense rendered-row index, not\n// a raw split/unified line index. We first build prefix counts for each hunk\n// under the current expansion/collapse settings, binary-search those counts to\n// find the first hunk whose rendered rows cross `startingLine`, then seed the\n// running split/unified counters as if every prior hunk had already been\n// walked.\nfunction getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n}: IterationStartStateProps): IterationStartState {\n if (startingLine <= 0 || diffStyle === 'both') {\n return { hunkIndex: 0, splitCount: 0, unifiedCount: 0 };\n }\n\n const prefixCounts = getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n });\n\n let low = 0;\n let high = diff.hunks.length - 1;\n let result = diff.hunks.length;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const counts = prefixCounts[mid + 1];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid hunk prefix index');\n }\n const selectedCount =\n diffStyle === 'unified' ? counts.unifiedCount : counts.splitCount;\n\n if (selectedCount > startingLine) {\n result = mid;\n high = mid - 1;\n } else {\n low = mid + 1;\n }\n }\n\n if (result >= diff.hunks.length) {\n const counts = prefixCounts[diff.hunks.length];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid terminal hunk prefix index');\n }\n return {\n hunkIndex: diff.hunks.length,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n }\n\n const counts = prefixCounts[result];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid selected hunk prefix index');\n }\n return {\n hunkIndex: result,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n}\n\n// Build cumulative rendered-row counts at every hunk boundary for the current\n// expansion state. Entry 0 is always zero rows before the first hunk; entry N\n// is the split/unified row count after hunks [0, N). These counts let\n// getIterationStartState binary-search by dense rendered row without replaying\n// every prior hunk.\nfunction getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n}: HunkPrefixCountsProps): HunkPrefixCounts[] {\n let splitCount = 0;\n let unifiedCount = 0;\n const finalHunkIndex = diff.hunks.length - 1;\n const prefixCounts: HunkPrefixCounts[] = [\n {\n splitCount: 0,\n unifiedCount: 0,\n },\n ];\n\n for (let index = 0; index < diff.hunks.length; index++) {\n const hunk = diff.hunks[index];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk summary index');\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex: index,\n collapsedContextThreshold,\n });\n const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n splitCount += leadingCount + hunk.splitLineCount;\n unifiedCount += leadingCount + hunk.unifiedLineCount;\n\n const trailingRegion =\n index === finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex: index,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n if (trailingRegion != null) {\n const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;\n splitCount += trailingCount;\n unifiedCount += trailingCount;\n }\n\n prefixCounts.push({ splitCount, unifiedCount });\n }\n\n return prefixCounts;\n}\n\n// Clip a run of context rows to a single bounded hull around the active rendered\n// window. `diffStyle: both` can make split and unified rows visible in disjoint\n// ranges, so these bounds may include interior gaps that still need per-row\n// filtering before emitting.\nfunction getContextLineIterationBounds(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle\n): LineIterationBounds {\n if (!state.isWindowedHighlight || count <= 0) {\n return [0, count];\n }\n\n const ranges: LineIterationBounds[] = [];\n function pushRange(currentCount: number): void {\n const start = Math.max(0, state.viewportStart - currentCount);\n const end = Math.min(count, state.viewportEnd - currentCount);\n if (end > start) {\n ranges.push([start, end]);\n }\n }\n\n if (diffStyle !== 'split') {\n pushRange(state.unifiedCount);\n }\n if (diffStyle !== 'unified') {\n pushRange(state.splitCount);\n }\n\n if (ranges.length === 0) {\n return [0, 0];\n }\n\n let start = ranges[0][0];\n let end = ranges[0][1];\n for (let index = 1; index < ranges.length; index++) {\n const range = ranges[index];\n start = Math.min(start, range[0]);\n end = Math.max(end, range[1]);\n }\n return [start, end];\n}\n\n// Walk context rows through the active window while keeping split and\n// unified counters aligned. The callback only runs after the final per-row\n// window check, which keeps `diffStyle: both` gap rows from being emitted.\nfunction walkContextLines(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle,\n callback: ContextLineCallback,\n onSkippedStart?: () => void,\n shouldBreak?: () => boolean\n): boolean {\n const [startIndex, endIndex] = getContextLineIterationBounds(\n state,\n count,\n diffStyle\n );\n if (startIndex > 0) {\n state.incrementCounts(startIndex, startIndex);\n onSkippedStart?.();\n }\n\n let index = startIndex;\n while (index < count) {\n if (shouldBreak?.() === true) {\n return true;\n }\n if (index >= endIndex) {\n state.incrementCounts(count - index, count - index);\n break;\n }\n if (state.isInWindow(0, 0)) {\n if (callback(index) === true) {\n return true;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n\n return false;\n}\n\n// Clip a change block to the rows that can be visible in the active coordinate\n// space. `diffStyle: both` iterates in split row space, but includes the unified\n// ranges too so either view can render the visible change rows it needs.\nfunction getChangeIterationRanges(\n state: IterationState,\n content: ChangeContent,\n diffStyle: DiffStyle\n): LineIterationBounds[] {\n // If not a window highlight, then we should just render the entire range\n if (!state.isWindowedHighlight) {\n return [\n [\n 0,\n diffStyle === 'unified'\n ? content.deletions + content.additions\n : Math.max(content.deletions, content.additions),\n ],\n ];\n }\n const useUnified = diffStyle !== 'split';\n const useSplit = diffStyle !== 'unified';\n const iterationSpace = diffStyle === 'unified' ? 'unified' : 'split';\n const iterationRanges: LineIterationBounds[] = [];\n function getVisibleRange(\n start: number,\n count: number\n ): LineIterationBounds | undefined {\n const end = start + count;\n if (end <= state.viewportStart || start >= state.viewportEnd) {\n return undefined;\n }\n const visibleStart = Math.max(0, state.viewportStart - start);\n const visibleEnd = Math.min(count, state.viewportEnd - start);\n return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : undefined;\n }\n function mapRangeToIteration(\n range: LineIterationBounds,\n kind: ChangeContentSide\n ): LineIterationBounds {\n if (iterationSpace === 'split') {\n // For split iteration, additions/deletions are already in split row space.\n return range;\n }\n return kind === 'additions'\n ? [range[0] + content.deletions, range[1] + content.deletions]\n : range;\n }\n function pushRange(\n range: LineIterationBounds | undefined,\n kind: ChangeContentSide\n ) {\n if (range == null) {\n return;\n }\n const [start, end] = mapRangeToIteration(range, kind);\n if (end > start) {\n iterationRanges.push([start, end]);\n }\n }\n\n if (useUnified) {\n pushRange(\n getVisibleRange(state.unifiedCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(\n state.unifiedCount + content.deletions,\n content.additions\n ),\n 'additions'\n );\n }\n\n if (useSplit) {\n pushRange(\n getVisibleRange(state.splitCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(state.splitCount, content.additions),\n 'additions'\n );\n }\n\n if (iterationRanges.length === 0) {\n return iterationRanges;\n }\n\n iterationRanges.sort((a, b) => a[0] - b[0]);\n const merged: LineIterationBounds[] = [iterationRanges[0]];\n for (const [start, end] of iterationRanges.slice(1)) {\n const last = merged[merged.length - 1];\n if (start <= last[1]) {\n last[1] = Math.max(last[1], end);\n } else {\n merged.push([start, end]);\n }\n }\n\n return merged;\n}\n\ninterface GetChangeLineDataProps {\n hunkIndex: number;\n hunk: Hunk;\n collapsedBefore: number;\n collapsedAfter: number;\n diffStyle: DiffStyle;\n index: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n additionLineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n deletionLineIndex: number;\n content: ChangeContent;\n isLastContent: boolean;\n unifiedCount: number;\n splitCount: number;\n}\n\n// Build the callback payload for one change row, mapping the selected row index\n// into split/unified coordinates and addition/deletion line metadata.\nfunction getChangeLineData({\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n}: GetChangeLineDataProps): DiffLineCallbackProps {\n const unifiedDeletionLineIndex =\n index < content.deletions ? unifiedLineIndex + index : undefined;\n const unifiedAdditionLineIndex =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? unifiedLineIndex + index\n : undefined\n : index < content.additions\n ? unifiedLineIndex + content.deletions + index\n : undefined;\n\n const resolvedSplitLineIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions ? index : index - content.deletions)\n : splitLineIndex + index;\n\n const deletionLineIndexValue =\n index < content.deletions ? deletionLineIndex + index : undefined;\n const deletionLineNumberValue =\n index < content.deletions ? deletionLineNumber + index : undefined;\n const additionLineIndexValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineIndex + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineIndex + index\n : undefined;\n const additionLineNumberValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineNumber + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineNumber + index\n : undefined;\n\n const noEOFCRDeletion =\n diffStyle === 'unified'\n ? isLastContent &&\n index === content.deletions - 1 &&\n hunk.noEOFCRDeletions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions;\n const noEOFCRAddition =\n diffStyle === 'unified'\n ? isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions;\n\n const deletionLine: DiffLineMetadata | undefined =\n deletionLineIndexValue != null &&\n deletionLineNumberValue != null &&\n unifiedDeletionLineIndex != null\n ? {\n lineNumber: deletionLineNumberValue,\n lineIndex: deletionLineIndexValue,\n noEOFCR: noEOFCRDeletion,\n unifiedLineIndex: unifiedDeletionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n }\n : undefined;\n const additionLine: DiffLineMetadata | undefined =\n additionLineIndexValue != null &&\n additionLineNumberValue != null &&\n unifiedAdditionLineIndex != null\n ? {\n unifiedLineIndex: unifiedAdditionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n lineIndex: additionLineIndexValue,\n lineNumber: additionLineNumberValue,\n noEOFCR: noEOFCRAddition,\n }\n : undefined;\n\n if (deletionLine == null && additionLine != null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine: undefined,\n additionLine,\n };\n } else if (deletionLine != null && additionLine == null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine: undefined,\n };\n }\n\n if (deletionLine == null || additionLine == null) {\n throw new Error('iterateOverDiff: missing change line data');\n }\n\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"iterateOverDiff.js","names":[],"sources":["../../src/utils/iterateOverDiff.ts"],"sourcesContent":["import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from '../constants';\nimport type {\n ChangeContent,\n FileDiffMetadata,\n Hunk,\n HunkExpansionRegion,\n} from '../types';\nimport { getHunkSideStartBoundary } from './getHunkSideBoundaries';\nimport {\n getExpandedRegion,\n getTrailingExpandedRegion,\n} from './virtualDiffLayout';\n\nexport interface DiffLineMetadata {\n unifiedLineIndex: number;\n splitLineIndex: number;\n lineIndex: number;\n lineNumber: number;\n noEOFCR: boolean;\n}\n\nexport interface DiffLineCallbackBase {\n hunkIndex: number;\n hunk: Hunk | undefined; // undefined for trailing expansion region\n collapsedBefore: number; // > 0 means separator before this line, value = hidden lines\n collapsedAfter: number; // > 0 only on final line if trailing collapsed content\n}\n\ninterface DiffLineCallbackContextChange extends DiffLineCallbackBase {\n type: 'change' | 'context' | 'context-expanded';\n deletionLine: DiffLineMetadata;\n additionLine: DiffLineMetadata;\n}\n\ninterface DiffLineCallbackChangeDeletion extends DiffLineCallbackBase {\n type: 'change';\n deletionLine: DiffLineMetadata;\n additionLine?: undefined;\n}\n\ninterface DiffLineCallbackChangeAddition extends DiffLineCallbackBase {\n type: 'change';\n deletionLine?: undefined;\n additionLine: DiffLineMetadata;\n}\n\nexport type DiffLineCallbackProps =\n | DiffLineCallbackContextChange\n | DiffLineCallbackChangeDeletion\n | DiffLineCallbackChangeAddition;\n\ntype DiffStyle = 'unified' | 'split' | 'both';\n\ntype LineIterationBounds = [startIndex: number, endIndex: number];\n\ntype ChangeContentSide = 'deletions' | 'additions';\n\ntype ContextLineCallback = (index: number) => boolean | void;\n\ninterface IterationState {\n isWindowedHighlight: boolean;\n viewportStart: number;\n viewportEnd: number;\n splitCount: number;\n unifiedCount: number;\n finalHunkIndex: number;\n shouldBreak(): boolean;\n shouldSkip(unifiedHeight: number, splitHeight: number): boolean;\n incrementCounts(unifiedValue: number, splitValue: number): void;\n isInWindow(unifiedHeight: number, splitHeight: number): boolean;\n isInUnifiedWindow(height: number): boolean;\n isInSplitWindow(height: number): boolean;\n emit(props: DiffLineCallbackProps, silent?: boolean): boolean;\n}\n\ninterface IterationStartState {\n hunkIndex: number;\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface HunkPrefixCounts {\n splitCount: number;\n unifiedCount: number;\n}\n\ninterface IterationStartStateProps extends Omit<\n IterateOverDiffProps,\n 'callback' | 'totalLines'\n> {\n startingLine: number;\n collapsedContextThreshold: number;\n}\n\ninterface HunkPrefixCountsProps extends Pick<\n IterationStartStateProps,\n 'diff' | 'expandedHunks' | 'collapsedContextThreshold'\n> {}\n\nexport type DiffLineCallback = (props: DiffLineCallbackProps) => boolean | void;\n\nexport interface IterateOverDiffProps {\n diff: FileDiffMetadata;\n diffStyle: DiffStyle;\n startingLine?: number;\n totalLines?: number;\n expandedHunks?: Map<number, HunkExpansionRegion> | true;\n collapsedContextThreshold?: number;\n callback: DiffLineCallback;\n}\n\nexport function iterateOverDiff({\n diff,\n diffStyle,\n startingLine = 0,\n totalLines = Infinity,\n expandedHunks,\n collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD,\n callback,\n}: IterateOverDiffProps): void {\n const iterationStart = getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n });\n const state: IterationState = {\n viewportStart: startingLine,\n viewportEnd: startingLine + totalLines,\n isWindowedHighlight: startingLine > 0 || totalLines < Infinity,\n splitCount: iterationStart.splitCount,\n unifiedCount: iterationStart.unifiedCount,\n finalHunkIndex: diff.hunks.length - 1,\n shouldBreak() {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const breakUnified = state.unifiedCount >= startingLine + totalLines;\n const breakSplit = state.splitCount >= startingLine + totalLines;\n\n if (diffStyle === 'unified') {\n return breakUnified;\n } else if (diffStyle === 'split') {\n return breakSplit;\n } else {\n return breakUnified && breakSplit;\n }\n },\n shouldSkip(unifiedCount: number, splitCount: number) {\n if (!state.isWindowedHighlight) {\n return false;\n }\n\n const skipUnified =\n unifiedCount > 0 && state.unifiedCount + unifiedCount <= startingLine;\n const skipSplit =\n splitCount > 0 && state.splitCount + splitCount <= startingLine;\n\n if (diffStyle === 'unified') {\n return skipUnified;\n } else if (diffStyle === 'split') {\n return skipSplit;\n } else {\n return skipUnified && skipSplit;\n }\n },\n incrementCounts(unifiedValue: number, splitValue: number) {\n if (diffStyle === 'unified' || diffStyle === 'both') {\n state.unifiedCount += unifiedValue;\n }\n if (diffStyle === 'split' || diffStyle === 'both') {\n state.splitCount += splitValue;\n }\n },\n isInWindow(unifiedHeight: number, splitHeight: number) {\n if (!state.isWindowedHighlight) {\n return true;\n }\n\n const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);\n const splitInWindow = state.isInSplitWindow(splitHeight);\n\n if (diffStyle === 'unified') {\n return unifiedInWindow;\n } else if (diffStyle === 'split') {\n return splitInWindow;\n } else {\n return unifiedInWindow || splitInWindow;\n }\n },\n isInUnifiedWindow(unifiedHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.unifiedCount >= startingLine - unifiedHeight &&\n state.unifiedCount < startingLine + totalLines)\n );\n },\n isInSplitWindow(splitHeight: number) {\n return (\n !state.isWindowedHighlight ||\n (state.splitCount >= startingLine - splitHeight &&\n state.splitCount < startingLine + totalLines)\n );\n },\n emit(props: DiffLineCallbackProps, silent = false): boolean {\n if (!silent) {\n if (diffStyle === 'unified') {\n state.incrementCounts(1, 0);\n } else if (diffStyle === 'split') {\n state.incrementCounts(0, 1);\n } else {\n state.incrementCounts(1, 1);\n }\n }\n return callback(props) ?? false;\n },\n };\n\n hunkIterator: for (\n let hunkIndex = iterationStart.hunkIndex;\n hunkIndex < diff.hunks.length;\n hunkIndex++\n ) {\n const hunk = diff.hunks[hunkIndex];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk index');\n }\n if (state.shouldBreak()) {\n break;\n }\n\n const deletionBoundary = getHunkSideStartBoundary(\n hunk.deletionStart,\n hunk.deletionCount\n );\n const additionBoundary = getHunkSideStartBoundary(\n hunk.additionStart,\n hunk.additionCount\n );\n const deletionStartIndex =\n !diff.isPartial && hunk.deletionCount === 0\n ? deletionBoundary\n : hunk.deletionLineIndex;\n const additionStartIndex =\n !diff.isPartial && hunk.additionCount === 0\n ? additionBoundary\n : hunk.additionLineIndex;\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex,\n collapsedContextThreshold,\n });\n const trailingRegion =\n hunkIndex === state.finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n\n function getTrailingCollapsedAfter(\n unifiedLineIndex: number,\n splitLineIndex: number\n ) {\n if (\n trailingRegion == null ||\n trailingRegion.collapsedLines <= 0 ||\n trailingRegion.fromStart + trailingRegion.fromEnd > 0\n ) {\n return 0;\n }\n if (diffStyle === 'unified') {\n return unifiedLineIndex ===\n hunk.unifiedLineStart + hunk.unifiedLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n return splitLineIndex === hunk.splitLineStart + hunk.splitLineCount - 1\n ? trailingRegion.collapsedLines\n : 0;\n }\n\n let consumedCollapsed = leadingRegion.collapsedLines === 0;\n function consumePendingCollapsed() {\n if (consumedCollapsed) {\n return 0;\n }\n consumedCollapsed = true;\n return leadingRegion.collapsedLines;\n }\n\n // Emit for expanded lines\n if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {\n let unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.rangeSize;\n let splitLineIndex = hunk.splitLineStart - leadingRegion.rangeSize;\n\n let deletionLineIndex = deletionStartIndex - leadingRegion.rangeSize;\n let additionLineIndex = additionStartIndex - leadingRegion.rangeSize;\n let deletionLineNumber = deletionBoundary + 1 - leadingRegion.rangeSize;\n let additionLineNumber = additionBoundary + 1 - leadingRegion.rangeSize;\n\n if (\n walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {\n return state.emit({\n hunkIndex,\n hunk: hunk,\n collapsedBefore: 0,\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n })\n ) {\n break hunkIterator;\n }\n\n unifiedLineIndex = hunk.unifiedLineStart - leadingRegion.fromEnd;\n splitLineIndex = hunk.splitLineStart - leadingRegion.fromEnd;\n\n deletionLineIndex = deletionStartIndex - leadingRegion.fromEnd;\n additionLineIndex = additionStartIndex - leadingRegion.fromEnd;\n deletionLineNumber = deletionBoundary + 1 - leadingRegion.fromEnd;\n additionLineNumber = additionBoundary + 1 - leadingRegion.fromEnd;\n if (\n walkContextLines(\n state,\n leadingRegion.fromEnd,\n diffStyle,\n (index) => {\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n () => {\n // The collapsed separator belongs before this fromEnd slice. If the\n // render window starts inside the slice, consume it with the skipped\n // rows so it is not attached to the first emitted row.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(expandedLineCount, expandedLineCount);\n consumePendingCollapsed();\n }\n\n let unifiedLineIndex = hunk.unifiedLineStart;\n let splitLineIndex = hunk.splitLineStart;\n\n let deletionLineIndex = deletionStartIndex;\n let additionLineIndex = additionStartIndex;\n let deletionLineNumber = deletionBoundary + 1;\n let additionLineNumber = additionBoundary + 1;\n const lastContent = hunk.hunkContent.at(-1);\n\n for (const content of hunk.hunkContent) {\n if (state.shouldBreak()) {\n break hunkIterator;\n }\n\n const isLastContent = content === lastContent;\n\n // Hunk Context Content\n if (content.type === 'context') {\n if (!state.shouldSkip(content.lines, content.lines)) {\n if (\n walkContextLines(\n state,\n content.lines,\n diffStyle,\n (index) => {\n const isLastLine = isLastContent && index === content.lines - 1;\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex = splitLineIndex + index;\n return state.emit({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter: getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n ),\n type: 'context',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: isLastLine && hunk.noEOFCRDeletions,\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n },\n additionLine: {\n unifiedLineIndex: unifiedRowIndex,\n splitLineIndex: splitRowIndex,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: isLastLine && hunk.noEOFCRAdditions,\n },\n });\n },\n () => {\n // When windowing starts inside context content, the leading\n // separator was above the visible range and should not be\n // emitted on the first rendered context line.\n consumePendingCollapsed();\n }\n )\n ) {\n break hunkIterator;\n }\n } else {\n state.incrementCounts(content.lines, content.lines);\n consumePendingCollapsed();\n }\n unifiedLineIndex += content.lines;\n splitLineIndex += content.lines;\n\n deletionLineIndex += content.lines;\n additionLineIndex += content.lines;\n deletionLineNumber += content.lines;\n additionLineNumber += content.lines;\n }\n // Hunk Change Content\n else {\n const splitCount = Math.max(content.deletions, content.additions);\n const unifiedCount = content.deletions + content.additions;\n const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);\n if (!shouldSkipChange) {\n const iterationRanges = getChangeIterationRanges(\n state,\n content,\n diffStyle\n );\n const firstRangeStart = iterationRanges[0]?.[0] ?? 0;\n if (firstRangeStart > 0) {\n // Change rows can be windowed from the middle of the block too. In\n // that case the leading separator belongs to skipped rows, not to\n // the first visible deletion/addition row.\n consumePendingCollapsed();\n }\n // Change ranges are already clipped to the active window. Counts move\n // once for the whole change block after the selected rows emit.\n for (const [rangeStart, rangeEnd] of iterationRanges) {\n for (let index = rangeStart; index < rangeEnd; index++) {\n const unifiedRowIndex = unifiedLineIndex + index;\n const splitRowIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions\n ? index\n : index - content.deletions)\n : splitLineIndex + index;\n const collapsedAfter = getTrailingCollapsedAfter(\n unifiedRowIndex,\n splitRowIndex\n );\n if (\n state.emit(\n getChangeLineData({\n hunkIndex,\n hunk,\n collapsedBefore: consumePendingCollapsed(),\n collapsedAfter,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n }),\n true\n )\n ) {\n break hunkIterator;\n }\n }\n }\n }\n\n consumePendingCollapsed();\n state.incrementCounts(unifiedCount, splitCount);\n unifiedLineIndex += unifiedCount;\n splitLineIndex += splitCount;\n deletionLineIndex += content.deletions;\n additionLineIndex += content.additions;\n deletionLineNumber += content.deletions;\n additionLineNumber += content.additions;\n }\n }\n\n if (trailingRegion != null) {\n const { collapsedLines, fromStart, fromEnd } = trailingRegion;\n const len = fromStart + fromEnd;\n if (\n walkContextLines(\n state,\n len,\n diffStyle,\n (index) => {\n const isLastLine = index === len - 1;\n return state.emit({\n hunkIndex: diff.hunks.length,\n hunk: undefined,\n collapsedBefore: 0,\n collapsedAfter: isLastLine ? collapsedLines : 0,\n type: 'context-expanded',\n deletionLine: {\n lineNumber: deletionLineNumber + index,\n lineIndex: deletionLineIndex + index,\n noEOFCR: false,\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n },\n additionLine: {\n unifiedLineIndex: unifiedLineIndex + index,\n splitLineIndex: splitLineIndex + index,\n lineIndex: additionLineIndex + index,\n lineNumber: additionLineNumber + index,\n noEOFCR: false,\n },\n });\n },\n undefined,\n () => state.shouldBreak()\n )\n ) {\n break hunkIterator;\n }\n }\n }\n}\n\n// Seek the iterator to the hunk that contains `startingLine` without changing\n// the public meaning of `startingLine`: it is a dense rendered-row index, not\n// a raw split/unified line index. We first build prefix counts for each hunk\n// under the current expansion/collapse settings, binary-search those counts to\n// find the first hunk whose rendered rows cross `startingLine`, then seed the\n// running split/unified counters as if every prior hunk had already been\n// walked.\nfunction getIterationStartState({\n diff,\n diffStyle,\n startingLine,\n expandedHunks,\n collapsedContextThreshold,\n}: IterationStartStateProps): IterationStartState {\n if (startingLine <= 0 || diffStyle === 'both') {\n return { hunkIndex: 0, splitCount: 0, unifiedCount: 0 };\n }\n\n const prefixCounts = getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n });\n\n let low = 0;\n let high = diff.hunks.length - 1;\n let result = diff.hunks.length;\n\n while (low <= high) {\n const mid = (low + high) >> 1;\n const counts = prefixCounts[mid + 1];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid hunk prefix index');\n }\n const selectedCount =\n diffStyle === 'unified' ? counts.unifiedCount : counts.splitCount;\n\n if (selectedCount > startingLine) {\n result = mid;\n high = mid - 1;\n } else {\n low = mid + 1;\n }\n }\n\n if (result >= diff.hunks.length) {\n const counts = prefixCounts[diff.hunks.length];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid terminal hunk prefix index');\n }\n return {\n hunkIndex: diff.hunks.length,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n }\n\n const counts = prefixCounts[result];\n if (counts == null) {\n throw new Error('iterateOverDiff: invalid selected hunk prefix index');\n }\n return {\n hunkIndex: result,\n splitCount: counts.splitCount,\n unifiedCount: counts.unifiedCount,\n };\n}\n\n// Build cumulative rendered-row counts at every hunk boundary for the current\n// expansion state. Entry 0 is always zero rows before the first hunk; entry N\n// is the split/unified row count after hunks [0, N). These counts let\n// getIterationStartState binary-search by dense rendered row without replaying\n// every prior hunk.\nfunction getHunkPrefixCounts({\n diff,\n expandedHunks,\n collapsedContextThreshold,\n}: HunkPrefixCountsProps): HunkPrefixCounts[] {\n let splitCount = 0;\n let unifiedCount = 0;\n const finalHunkIndex = diff.hunks.length - 1;\n const prefixCounts: HunkPrefixCounts[] = [\n {\n splitCount: 0,\n unifiedCount: 0,\n },\n ];\n\n for (let index = 0; index < diff.hunks.length; index++) {\n const hunk = diff.hunks[index];\n if (hunk == null) {\n throw new Error('iterateOverDiff: invalid hunk summary index');\n }\n\n const leadingRegion = getExpandedRegion({\n isPartial: diff.isPartial,\n rangeSize: hunk.collapsedBefore,\n expandedHunks,\n hunkIndex: index,\n collapsedContextThreshold,\n });\n const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;\n splitCount += leadingCount + hunk.splitLineCount;\n unifiedCount += leadingCount + hunk.unifiedLineCount;\n\n const trailingRegion =\n index === finalHunkIndex\n ? getTrailingExpandedRegion({\n fileDiff: diff,\n hunkIndex: index,\n expandedHunks,\n collapsedContextThreshold,\n errorPrefix: 'iterateOverDiff',\n })\n : undefined;\n if (trailingRegion != null) {\n const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;\n splitCount += trailingCount;\n unifiedCount += trailingCount;\n }\n\n prefixCounts.push({ splitCount, unifiedCount });\n }\n\n return prefixCounts;\n}\n\n// Clip a run of context rows to a single bounded hull around the active rendered\n// window. `diffStyle: both` can make split and unified rows visible in disjoint\n// ranges, so these bounds may include interior gaps that still need per-row\n// filtering before emitting.\nfunction getContextLineIterationBounds(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle\n): LineIterationBounds {\n if (!state.isWindowedHighlight || count <= 0) {\n return [0, count];\n }\n\n const ranges: LineIterationBounds[] = [];\n function pushRange(currentCount: number): void {\n const start = Math.max(0, state.viewportStart - currentCount);\n const end = Math.min(count, state.viewportEnd - currentCount);\n if (end > start) {\n ranges.push([start, end]);\n }\n }\n\n if (diffStyle !== 'split') {\n pushRange(state.unifiedCount);\n }\n if (diffStyle !== 'unified') {\n pushRange(state.splitCount);\n }\n\n if (ranges.length === 0) {\n return [0, 0];\n }\n\n let start = ranges[0][0];\n let end = ranges[0][1];\n for (let index = 1; index < ranges.length; index++) {\n const range = ranges[index];\n start = Math.min(start, range[0]);\n end = Math.max(end, range[1]);\n }\n return [start, end];\n}\n\n// Walk context rows through the active window while keeping split and\n// unified counters aligned. The callback only runs after the final per-row\n// window check, which keeps `diffStyle: both` gap rows from being emitted.\nfunction walkContextLines(\n state: IterationState,\n count: number,\n diffStyle: DiffStyle,\n callback: ContextLineCallback,\n onSkippedStart?: () => void,\n shouldBreak?: () => boolean\n): boolean {\n const [startIndex, endIndex] = getContextLineIterationBounds(\n state,\n count,\n diffStyle\n );\n if (startIndex > 0) {\n state.incrementCounts(startIndex, startIndex);\n onSkippedStart?.();\n }\n\n let index = startIndex;\n while (index < count) {\n if (shouldBreak?.() === true) {\n return true;\n }\n if (index >= endIndex) {\n state.incrementCounts(count - index, count - index);\n break;\n }\n if (state.isInWindow(0, 0)) {\n if (callback(index) === true) {\n return true;\n }\n } else {\n state.incrementCounts(1, 1);\n }\n index++;\n }\n\n return false;\n}\n\n// Clip a change block to the rows that can be visible in the active coordinate\n// space. `diffStyle: both` iterates in split row space, but includes the unified\n// ranges too so either view can render the visible change rows it needs.\nfunction getChangeIterationRanges(\n state: IterationState,\n content: ChangeContent,\n diffStyle: DiffStyle\n): LineIterationBounds[] {\n // If not a window highlight, then we should just render the entire range\n if (!state.isWindowedHighlight) {\n return [\n [\n 0,\n diffStyle === 'unified'\n ? content.deletions + content.additions\n : Math.max(content.deletions, content.additions),\n ],\n ];\n }\n const useUnified = diffStyle !== 'split';\n const useSplit = diffStyle !== 'unified';\n const iterationSpace = diffStyle === 'unified' ? 'unified' : 'split';\n const iterationRanges: LineIterationBounds[] = [];\n function getVisibleRange(\n start: number,\n count: number\n ): LineIterationBounds | undefined {\n const end = start + count;\n if (end <= state.viewportStart || start >= state.viewportEnd) {\n return undefined;\n }\n const visibleStart = Math.max(0, state.viewportStart - start);\n const visibleEnd = Math.min(count, state.viewportEnd - start);\n return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : undefined;\n }\n function mapRangeToIteration(\n range: LineIterationBounds,\n kind: ChangeContentSide\n ): LineIterationBounds {\n if (iterationSpace === 'split') {\n // For split iteration, additions/deletions are already in split row space.\n return range;\n }\n return kind === 'additions'\n ? [range[0] + content.deletions, range[1] + content.deletions]\n : range;\n }\n function pushRange(\n range: LineIterationBounds | undefined,\n kind: ChangeContentSide\n ) {\n if (range == null) {\n return;\n }\n const [start, end] = mapRangeToIteration(range, kind);\n if (end > start) {\n iterationRanges.push([start, end]);\n }\n }\n\n if (useUnified) {\n pushRange(\n getVisibleRange(state.unifiedCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(\n state.unifiedCount + content.deletions,\n content.additions\n ),\n 'additions'\n );\n }\n\n if (useSplit) {\n pushRange(\n getVisibleRange(state.splitCount, content.deletions),\n 'deletions'\n );\n pushRange(\n getVisibleRange(state.splitCount, content.additions),\n 'additions'\n );\n }\n\n if (iterationRanges.length === 0) {\n return iterationRanges;\n }\n\n iterationRanges.sort((a, b) => a[0] - b[0]);\n const merged: LineIterationBounds[] = [iterationRanges[0]];\n for (const [start, end] of iterationRanges.slice(1)) {\n const last = merged[merged.length - 1];\n if (start <= last[1]) {\n last[1] = Math.max(last[1], end);\n } else {\n merged.push([start, end]);\n }\n }\n\n return merged;\n}\n\ninterface GetChangeLineDataProps {\n hunkIndex: number;\n hunk: Hunk;\n collapsedBefore: number;\n collapsedAfter: number;\n diffStyle: DiffStyle;\n index: number;\n unifiedLineIndex: number;\n splitLineIndex: number;\n additionLineIndex: number;\n additionLineNumber: number;\n deletionLineNumber: number;\n deletionLineIndex: number;\n content: ChangeContent;\n isLastContent: boolean;\n unifiedCount: number;\n splitCount: number;\n}\n\n// Build the callback payload for one change row, mapping the selected row index\n// into split/unified coordinates and addition/deletion line metadata.\nfunction getChangeLineData({\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n diffStyle,\n index,\n unifiedLineIndex,\n splitLineIndex,\n additionLineIndex,\n deletionLineIndex,\n additionLineNumber,\n deletionLineNumber,\n content,\n isLastContent,\n unifiedCount,\n splitCount,\n}: GetChangeLineDataProps): DiffLineCallbackProps {\n const unifiedDeletionLineIndex =\n index < content.deletions ? unifiedLineIndex + index : undefined;\n const unifiedAdditionLineIndex =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? unifiedLineIndex + index\n : undefined\n : index < content.additions\n ? unifiedLineIndex + content.deletions + index\n : undefined;\n\n const resolvedSplitLineIndex =\n diffStyle === 'unified'\n ? splitLineIndex +\n (index < content.deletions ? index : index - content.deletions)\n : splitLineIndex + index;\n\n const deletionLineIndexValue =\n index < content.deletions ? deletionLineIndex + index : undefined;\n const deletionLineNumberValue =\n index < content.deletions ? deletionLineNumber + index : undefined;\n const additionLineIndexValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineIndex + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineIndex + index\n : undefined;\n const additionLineNumberValue =\n diffStyle === 'unified'\n ? index >= content.deletions\n ? additionLineNumber + (index - content.deletions)\n : undefined\n : index < content.additions\n ? additionLineNumber + index\n : undefined;\n\n const noEOFCRDeletion =\n diffStyle === 'unified'\n ? isLastContent &&\n index === content.deletions - 1 &&\n hunk.noEOFCRDeletions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions;\n const noEOFCRAddition =\n diffStyle === 'unified'\n ? isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions\n : isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions;\n\n const deletionLine: DiffLineMetadata | undefined =\n deletionLineIndexValue != null &&\n deletionLineNumberValue != null &&\n unifiedDeletionLineIndex != null\n ? {\n lineNumber: deletionLineNumberValue,\n lineIndex: deletionLineIndexValue,\n noEOFCR: noEOFCRDeletion,\n unifiedLineIndex: unifiedDeletionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n }\n : undefined;\n const additionLine: DiffLineMetadata | undefined =\n additionLineIndexValue != null &&\n additionLineNumberValue != null &&\n unifiedAdditionLineIndex != null\n ? {\n unifiedLineIndex: unifiedAdditionLineIndex,\n splitLineIndex: resolvedSplitLineIndex,\n lineIndex: additionLineIndexValue,\n lineNumber: additionLineNumberValue,\n noEOFCR: noEOFCRAddition,\n }\n : undefined;\n\n if (deletionLine == null && additionLine != null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine: undefined,\n additionLine,\n };\n } else if (deletionLine != null && additionLine == null) {\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine: undefined,\n };\n }\n\n if (deletionLine == null || additionLine == null) {\n throw new Error('iterateOverDiff: missing change line data');\n }\n\n return {\n type: 'change',\n hunkIndex,\n hunk,\n collapsedAfter,\n collapsedBefore,\n deletionLine,\n additionLine,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseMergeConflictDiffFromFile.d.ts","names":[],"sources":["../../src/utils/parseMergeConflictDiffFromFile.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"parseMergeConflictDiffFromFile.d.ts","names":[],"sources":["../../src/utils/parseMergeConflictDiffFromFile.ts"],"mappings":";;;UAsDiB,oCAAA;EACf,QAAA,EAAU,gBAAA;EACV,WAAA,EAAa,YAAA;EACb,YAAA,EAAc,YAAA;EACd,OAAA,GAAU,uBAAA;EACV,UAAA,EAAY,sBAAA;AAAA;AAAA,UAGG,uBAAA,SAAgC,uBAAuB;EAGtE,QAAA,EAAU,mBAAA;EACV,aAAA;EACA,WAAA;IACE,KAAA;IACA,IAAA;IACA,SAAA;IACA,GAAA;EAAA;AAAA;AAAA,UAIM,kCAAA;EACR,SAAA;EACA,SAAS;AAAA;AAAA,iBAqGK,4BAAA,CACd,MAAA,EAAQ,uBAAA,EACR,QAAA,EAAU,gBAAA,GACT,kCAAA;AAAA,iBAoBa,8BAAA,CACd,IAAA,EAAM,YAAA,EACN,eAAA,YACC,oCAAoC;AAAA,iBAg0BvB,4BAAA,CACd,QAAA,EAAU,gBAAA,EACV,OAAA,GAAU,uBAAA,kBACT,sBAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getHunkSideEndBoundary, getHunkSideStartBoundary } from "./getHunkSideBoundaries.js";
|
|
1
2
|
//#region src/utils/parseMergeConflictDiffFromFile.ts
|
|
2
3
|
function getMergeConflictActionAnchor(action, fileDiff) {
|
|
3
4
|
const hunk = fileDiff.hunks[action.hunkIndex];
|
|
@@ -49,7 +50,7 @@ function parseMergeConflictDiffFromFile(file, maxContextLines = 6) {
|
|
|
49
50
|
}
|
|
50
51
|
if (s.hunks.length > 0 && s.additionLines.length > 0 && s.deletionLines.length > 0) {
|
|
51
52
|
const lastHunk = s.hunks[s.hunks.length - 1];
|
|
52
|
-
const collapsedAfter = Math.max(s.additionLines.length - (lastHunk.additionStart
|
|
53
|
+
const collapsedAfter = Math.max(s.additionLines.length - getHunkSideEndBoundary(lastHunk.additionStart, lastHunk.additionCount), 0);
|
|
53
54
|
s.splitLineCount += collapsedAfter;
|
|
54
55
|
s.unifiedLineCount += collapsedAfter;
|
|
55
56
|
}
|
|
@@ -217,20 +218,22 @@ function finalizeActiveHunk(s) {
|
|
|
217
218
|
hunkSplitLineCount += Math.max(content.additions, content.deletions);
|
|
218
219
|
hunkUnifiedLineCount += content.additions + content.deletions;
|
|
219
220
|
}
|
|
220
|
-
const
|
|
221
|
+
const additionStart = hunk.additionCount === 0 ? hunk.additionStart - 1 : hunk.additionStart;
|
|
222
|
+
const deletionStart = hunk.deletionCount === 0 ? hunk.deletionStart - 1 : hunk.deletionStart;
|
|
223
|
+
const collapsedBefore = Math.max(getHunkSideStartBoundary(additionStart, hunk.additionCount) - s.lastHunkEnd, 0);
|
|
221
224
|
const finalizedHunk = {
|
|
222
225
|
collapsedBefore,
|
|
223
|
-
additionStart
|
|
226
|
+
additionStart,
|
|
224
227
|
additionCount: hunk.additionCount,
|
|
225
228
|
additionLines: hunk.additionLines,
|
|
226
229
|
additionLineIndex: hunk.additionLineIndex,
|
|
227
|
-
deletionStart
|
|
230
|
+
deletionStart,
|
|
228
231
|
deletionCount: hunk.deletionCount,
|
|
229
232
|
deletionLines: hunk.deletionLines,
|
|
230
233
|
deletionLineIndex: hunk.deletionLineIndex,
|
|
231
234
|
hunkContent: hunk.hunkContent,
|
|
232
235
|
hunkContext: void 0,
|
|
233
|
-
hunkSpecs: `@@ -${formatHunkRange(
|
|
236
|
+
hunkSpecs: `@@ -${formatHunkRange(deletionStart, hunk.deletionCount)} +${formatHunkRange(additionStart, hunk.additionCount)} @@\n`,
|
|
234
237
|
splitLineStart: s.splitLineCount + collapsedBefore,
|
|
235
238
|
splitLineCount: hunkSplitLineCount,
|
|
236
239
|
unifiedLineStart: s.unifiedLineCount + collapsedBefore,
|
|
@@ -241,7 +244,7 @@ function finalizeActiveHunk(s) {
|
|
|
241
244
|
s.hunks.push(finalizedHunk);
|
|
242
245
|
s.splitLineCount += collapsedBefore + hunkSplitLineCount;
|
|
243
246
|
s.unifiedLineCount += collapsedBefore + hunkUnifiedLineCount;
|
|
244
|
-
s.lastHunkEnd =
|
|
247
|
+
s.lastHunkEnd = getHunkSideEndBoundary(additionStart, hunk.additionCount);
|
|
245
248
|
}
|
|
246
249
|
function splitHunkWithBufferedContext(s) {
|
|
247
250
|
if (s.activeHunk == null) return;
|