@pierre/diffs 1.0.6 → 1.1.0-beta.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.
Files changed (154) hide show
  1. package/dist/components/File.d.ts +4 -2
  2. package/dist/components/File.d.ts.map +1 -1
  3. package/dist/components/File.js +80 -34
  4. package/dist/components/File.js.map +1 -1
  5. package/dist/components/FileDiff.d.ts +50 -28
  6. package/dist/components/FileDiff.d.ts.map +1 -1
  7. package/dist/components/FileDiff.js +222 -80
  8. package/dist/components/FileDiff.js.map +1 -1
  9. package/dist/components/FileStream.d.ts +1 -0
  10. package/dist/components/FileStream.d.ts.map +1 -1
  11. package/dist/components/FileStream.js +10 -6
  12. package/dist/components/FileStream.js.map +1 -1
  13. package/dist/components/web-components.d.ts.map +1 -1
  14. package/dist/components/web-components.js +1 -1
  15. package/dist/components/web-components.js.map +1 -1
  16. package/dist/constants.d.ts +8 -2
  17. package/dist/constants.d.ts.map +1 -1
  18. package/dist/constants.js +10 -1
  19. package/dist/constants.js.map +1 -1
  20. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
  21. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts.map +1 -1
  22. package/dist/highlighter/languages/getResolvedOrResolveLanguage.js.map +1 -1
  23. package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
  24. package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
  25. package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
  26. package/dist/highlighter/languages/resolveLanguages.js +1 -1
  27. package/dist/highlighter/languages/resolveLanguages.js.map +1 -1
  28. package/dist/highlighter/shared_highlighter.js +1 -1
  29. package/dist/highlighter/shared_highlighter.js.map +1 -1
  30. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +1 -1
  31. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
  32. package/dist/index.d.ts +19 -10
  33. package/dist/index.js +14 -5
  34. package/dist/managers/LineSelectionManager.d.ts.map +1 -1
  35. package/dist/managers/LineSelectionManager.js +8 -9
  36. package/dist/managers/LineSelectionManager.js.map +1 -1
  37. package/dist/managers/ScrollSyncManager.d.ts +1 -0
  38. package/dist/managers/ScrollSyncManager.d.ts.map +1 -1
  39. package/dist/managers/ScrollSyncManager.js +14 -6
  40. package/dist/managers/ScrollSyncManager.js.map +1 -1
  41. package/dist/react/MultiFileDiff.js +2 -2
  42. package/dist/react/MultiFileDiff.js.map +1 -1
  43. package/dist/react/index.d.ts +2 -2
  44. package/dist/react/utils/renderDiffChildren.d.ts +4 -4
  45. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  46. package/dist/react/utils/renderDiffChildren.js +3 -3
  47. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  48. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  49. package/dist/renderers/DiffHunksRenderer.d.ts +7 -6
  50. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  51. package/dist/renderers/DiffHunksRenderer.js +263 -337
  52. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  53. package/dist/renderers/FileRenderer.d.ts +1 -0
  54. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  55. package/dist/renderers/FileRenderer.js +11 -4
  56. package/dist/renderers/FileRenderer.js.map +1 -1
  57. package/dist/ssr/index.d.ts +2 -2
  58. package/dist/style.js +1 -1
  59. package/dist/style.js.map +1 -1
  60. package/dist/types.d.ts +247 -43
  61. package/dist/types.d.ts.map +1 -1
  62. package/dist/utils/areDiffLineAnnotationsEqual.d.ts +7 -0
  63. package/dist/utils/areDiffLineAnnotationsEqual.d.ts.map +1 -0
  64. package/dist/utils/areDiffLineAnnotationsEqual.js +8 -0
  65. package/dist/utils/areDiffLineAnnotationsEqual.js.map +1 -0
  66. package/dist/utils/areHunkDataEqual.d.ts +7 -0
  67. package/dist/utils/areHunkDataEqual.d.ts.map +1 -0
  68. package/dist/utils/areHunkDataEqual.js +8 -0
  69. package/dist/utils/areHunkDataEqual.js.map +1 -0
  70. package/dist/utils/areLineAnnotationsEqual.d.ts +7 -0
  71. package/dist/utils/areLineAnnotationsEqual.d.ts.map +1 -0
  72. package/dist/utils/areLineAnnotationsEqual.js +8 -0
  73. package/dist/utils/areLineAnnotationsEqual.js.map +1 -0
  74. package/dist/utils/arePrePropertiesEqual.d.ts +7 -0
  75. package/dist/utils/arePrePropertiesEqual.d.ts.map +1 -0
  76. package/dist/utils/arePrePropertiesEqual.js +9 -0
  77. package/dist/utils/arePrePropertiesEqual.js.map +1 -0
  78. package/dist/utils/areRenderRangesEqual.d.ts +7 -0
  79. package/dist/utils/areRenderRangesEqual.d.ts.map +1 -0
  80. package/dist/utils/areRenderRangesEqual.js +9 -0
  81. package/dist/utils/areRenderRangesEqual.js.map +1 -0
  82. package/dist/utils/areVirtualWindowSpecsEqual.d.ts +7 -0
  83. package/dist/utils/areVirtualWindowSpecsEqual.d.ts.map +1 -0
  84. package/dist/utils/areVirtualWindowSpecsEqual.js +9 -0
  85. package/dist/utils/areVirtualWindowSpecsEqual.js.map +1 -0
  86. package/dist/utils/areWorkerStatsEqual.d.ts +8 -0
  87. package/dist/utils/areWorkerStatsEqual.d.ts.map +1 -0
  88. package/dist/utils/areWorkerStatsEqual.js +9 -0
  89. package/dist/utils/areWorkerStatsEqual.js.map +1 -0
  90. package/dist/utils/createTransformerWithState.js +1 -1
  91. package/dist/utils/createTransformerWithState.js.map +1 -1
  92. package/dist/utils/createWindowFromScrollPosition.d.ts +22 -0
  93. package/dist/utils/createWindowFromScrollPosition.d.ts.map +1 -0
  94. package/dist/utils/createWindowFromScrollPosition.js +26 -0
  95. package/dist/utils/createWindowFromScrollPosition.js.map +1 -0
  96. package/dist/utils/diffAcceptRejectHunk.js +36 -21
  97. package/dist/utils/diffAcceptRejectHunk.js.map +1 -1
  98. package/dist/utils/formatCSSVariablePrefix.d.ts +1 -1
  99. package/dist/utils/formatCSSVariablePrefix.js +2 -2
  100. package/dist/utils/formatCSSVariablePrefix.js.map +1 -1
  101. package/dist/utils/getHighlighterThemeStyles.js +12 -12
  102. package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
  103. package/dist/utils/getOrCreateCodeNode.d.ts +14 -0
  104. package/dist/utils/getOrCreateCodeNode.d.ts.map +1 -0
  105. package/dist/utils/getOrCreateCodeNode.js +13 -0
  106. package/dist/utils/getOrCreateCodeNode.js.map +1 -0
  107. package/dist/utils/getTotalLineCountFromHunks.js +1 -1
  108. package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
  109. package/dist/utils/hast_utils.d.ts +2 -1
  110. package/dist/utils/hast_utils.d.ts.map +1 -1
  111. package/dist/utils/hast_utils.js +10 -1
  112. package/dist/utils/hast_utils.js.map +1 -1
  113. package/dist/utils/isDefaultRenderRange.d.ts +7 -0
  114. package/dist/utils/isDefaultRenderRange.d.ts.map +1 -0
  115. package/dist/utils/isDefaultRenderRange.js +8 -0
  116. package/dist/utils/isDefaultRenderRange.js.map +1 -0
  117. package/dist/utils/iterateOverDiff.d.ts +39 -0
  118. package/dist/utils/iterateOverDiff.d.ts.map +1 -0
  119. package/dist/utils/iterateOverDiff.js +356 -0
  120. package/dist/utils/iterateOverDiff.js.map +1 -0
  121. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  122. package/dist/utils/parseDiffFromFile.js +8 -6
  123. package/dist/utils/parseDiffFromFile.js.map +1 -1
  124. package/dist/utils/parsePatchFiles.d.ts +15 -3
  125. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  126. package/dist/utils/parsePatchFiles.js +207 -158
  127. package/dist/utils/parsePatchFiles.js.map +1 -1
  128. package/dist/utils/processLine.js +4 -3
  129. package/dist/utils/processLine.js.map +1 -1
  130. package/dist/utils/renderDiffWithHighlighter.d.ts +7 -2
  131. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  132. package/dist/utils/renderDiffWithHighlighter.js +151 -229
  133. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  134. package/dist/utils/renderFileWithHighlighter.js +2 -2
  135. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  136. package/dist/utils/setWrapperNodeProps.d.ts +3 -7
  137. package/dist/utils/setWrapperNodeProps.d.ts.map +1 -1
  138. package/dist/utils/setWrapperNodeProps.js +1 -1
  139. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  140. package/dist/worker/WorkerPoolManager.d.ts +9 -2
  141. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  142. package/dist/worker/WorkerPoolManager.js +124 -45
  143. package/dist/worker/WorkerPoolManager.js.map +1 -1
  144. package/dist/worker/types.d.ts +7 -0
  145. package/dist/worker/types.d.ts.map +1 -1
  146. package/dist/worker/worker-portable.js +652 -260
  147. package/dist/worker/worker-portable.js.map +1 -1
  148. package/dist/worker/worker.js +529 -249
  149. package/dist/worker/worker.js.map +1 -1
  150. package/package.json +21 -2
  151. package/dist/utils/createCodeNode.d.ts +0 -12
  152. package/dist/utils/createCodeNode.d.ts.map +0 -1
  153. package/dist/utils/createCodeNode.js +0 -12
  154. package/dist/utils/createCodeNode.js.map +0 -1
@@ -8,6 +8,10 @@ const DEFAULT_THEMES = {
8
8
  dark: "pierre-dark",
9
9
  light: "pierre-light"
10
10
  };
11
+ const DEFAULT_EXPANDED_REGION = Object.freeze({
12
+ fromStart: 0,
13
+ fromEnd: 0
14
+ });
11
15
 
12
16
  //#endregion
13
17
  //#region src/highlighter/languages/constants.ts
@@ -89,14 +93,15 @@ function findCodeElement(nodes) {
89
93
  //#endregion
90
94
  //#region src/utils/processLine.ts
91
95
  function processLine(node, line, state) {
92
- const lineInfo = typeof state.lineInfo === "function" ? state.lineInfo(line) : state.lineInfo[line];
96
+ const lineInfo = typeof state.lineInfo === "function" ? state.lineInfo(line) : state.lineInfo[line - 1];
93
97
  if (lineInfo == null) {
94
- console.error({
98
+ const errorMessage = `processLine: line ${line}, contains no state.lineInfo`;
99
+ console.error(errorMessage, {
95
100
  node,
96
101
  line,
97
102
  state
98
103
  });
99
- throw new Error(`processLine: line ${line}, contains no state.lineInfo`);
104
+ throw new Error(errorMessage);
100
105
  }
101
106
  node.tagName = "span";
102
107
  node.properties["data-column-content"] = "";
@@ -127,7 +132,7 @@ function processLine(node, line, state) {
127
132
  //#endregion
128
133
  //#region src/utils/createTransformerWithState.ts
129
134
  function createTransformerWithState(useCSSClasses = false) {
130
- const state = { lineInfo: {} };
135
+ const state = { lineInfo: [] };
131
136
  const transformers = [{
132
137
  line(node) {
133
138
  delete node.properties.class;
@@ -176,8 +181,8 @@ const tokenStyleNormalizer = {
176
181
 
177
182
  //#endregion
178
183
  //#region src/utils/formatCSSVariablePrefix.ts
179
- function formatCSSVariablePrefix(prefix = "diffs") {
180
- return `--${prefix}-`;
184
+ function formatCSSVariablePrefix(type) {
185
+ return `--${type === "token" ? "diffs-token" : "diffs"}-`;
181
186
  }
182
187
 
183
188
  //#endregion
@@ -526,30 +531,30 @@ function getHighlighterThemeStyles({ theme = DEFAULT_THEMES, highlighter: highli
526
531
  const themeData = highlighter$1.getTheme(theme);
527
532
  styles += `color:${themeData.fg};`;
528
533
  styles += `background-color:${themeData.bg};`;
529
- styles += `${formatCSSVariablePrefix(prefix)}fg:${themeData.fg};`;
530
- styles += `${formatCSSVariablePrefix(prefix)}bg:${themeData.bg};`;
534
+ styles += `${formatCSSVariablePrefix("global")}fg:${themeData.fg};`;
535
+ styles += `${formatCSSVariablePrefix("global")}bg:${themeData.bg};`;
531
536
  styles += getThemeVariables(themeData, prefix);
532
537
  } else {
533
538
  let themeData = highlighter$1.getTheme(theme.dark);
534
- styles += `${formatCSSVariablePrefix(prefix)}dark:${themeData.fg};`;
535
- styles += `${formatCSSVariablePrefix(prefix)}dark-bg:${themeData.bg};`;
536
- styles += getThemeVariables(themeData, prefix, "dark");
539
+ styles += `${formatCSSVariablePrefix("global")}dark:${themeData.fg};`;
540
+ styles += `${formatCSSVariablePrefix("global")}dark-bg:${themeData.bg};`;
541
+ styles += getThemeVariables(themeData, "dark");
537
542
  themeData = highlighter$1.getTheme(theme.light);
538
- styles += `${formatCSSVariablePrefix(prefix)}light:${themeData.fg};`;
539
- styles += `${formatCSSVariablePrefix(prefix)}light-bg:${themeData.bg};`;
540
- styles += getThemeVariables(themeData, prefix, "light");
543
+ styles += `${formatCSSVariablePrefix("global")}light:${themeData.fg};`;
544
+ styles += `${formatCSSVariablePrefix("global")}light-bg:${themeData.bg};`;
545
+ styles += getThemeVariables(themeData, "light");
541
546
  }
542
547
  return styles;
543
548
  }
544
- function getThemeVariables(themeData, prefix, modePrefix) {
549
+ function getThemeVariables(themeData, modePrefix) {
545
550
  modePrefix = modePrefix != null ? `${modePrefix}-` : "";
546
551
  let styles = "";
547
552
  const additionGreen = themeData.colors?.["gitDecoration.addedResourceForeground"] ?? themeData.colors?.["terminal.ansiGreen"];
548
- if (additionGreen != null) styles += `${formatCSSVariablePrefix(prefix)}${modePrefix}addition-color:${additionGreen};`;
553
+ if (additionGreen != null) styles += `${formatCSSVariablePrefix("global")}${modePrefix}addition-color:${additionGreen};`;
549
554
  const deletionRed = themeData.colors?.["gitDecoration.deletedResourceForeground"] ?? themeData.colors?.["terminal.ansiRed"];
550
- if (deletionRed != null) styles += `${formatCSSVariablePrefix(prefix)}${modePrefix}deletion-color:${deletionRed};`;
555
+ if (deletionRed != null) styles += `${formatCSSVariablePrefix("global")}${modePrefix}deletion-color:${deletionRed};`;
551
556
  const modifiedBlue = themeData.colors?.["gitDecoration.modifiedResourceForeground"] ?? themeData.colors?.["terminal.ansiBlue"];
552
- if (modifiedBlue != null) styles += `${formatCSSVariablePrefix(prefix)}${modePrefix}modified-color:${modifiedBlue};`;
557
+ if (modifiedBlue != null) styles += `${formatCSSVariablePrefix("global")}${modePrefix}modified-color:${modifiedBlue};`;
553
558
  return styles;
554
559
  }
555
560
 
@@ -566,6 +571,360 @@ function getLineNodes(nodes) {
566
571
  throw new Error("getLineNodes: Unable to find children");
567
572
  }
568
573
 
574
+ //#endregion
575
+ //#region src/utils/iterateOverDiff.ts
576
+ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infinity, expandedHunks, callback }) {
577
+ const state = {
578
+ finalHunk: diff.hunks.at(-1),
579
+ viewportStart: startingLine,
580
+ viewportEnd: startingLine + totalLines,
581
+ isWindowedHighlight: startingLine > 0 || totalLines < Infinity,
582
+ splitCount: 0,
583
+ unifiedCount: 0,
584
+ shouldBreak() {
585
+ if (!state.isWindowedHighlight) return false;
586
+ const breakUnified = state.unifiedCount >= startingLine + totalLines;
587
+ const breakSplit = state.splitCount >= startingLine + totalLines;
588
+ if (diffStyle === "unified") return breakUnified;
589
+ else if (diffStyle === "split") return breakSplit;
590
+ else return breakUnified && breakSplit;
591
+ },
592
+ shouldSkip(unifiedHeight, splitHeight) {
593
+ if (!state.isWindowedHighlight) return false;
594
+ const skipUnified = state.unifiedCount + unifiedHeight < startingLine;
595
+ const skipSplit = state.splitCount + splitHeight < startingLine;
596
+ if (diffStyle === "unified") return skipUnified;
597
+ else if (diffStyle === "split") return skipSplit;
598
+ else return skipUnified && skipSplit;
599
+ },
600
+ incrementCounts(unifiedValue, splitValue) {
601
+ if (diffStyle === "unified" || diffStyle === "both") state.unifiedCount += unifiedValue;
602
+ if (diffStyle === "split" || diffStyle === "both") state.splitCount += splitValue;
603
+ },
604
+ isInWindow(unifiedHeight, splitHeight) {
605
+ if (!state.isWindowedHighlight) return true;
606
+ const unifiedInWindow = state.isInUnifiedWindow(unifiedHeight);
607
+ const splitInWindow = state.isInSplitWindow(splitHeight);
608
+ if (diffStyle === "unified") return unifiedInWindow;
609
+ else if (diffStyle === "split") return splitInWindow;
610
+ else return unifiedInWindow || splitInWindow;
611
+ },
612
+ isInUnifiedWindow(unifiedHeight) {
613
+ return !state.isWindowedHighlight || state.unifiedCount >= startingLine - unifiedHeight && state.unifiedCount < startingLine + totalLines;
614
+ },
615
+ isInSplitWindow(splitHeight) {
616
+ return !state.isWindowedHighlight || state.splitCount >= startingLine - splitHeight && state.splitCount < startingLine + totalLines;
617
+ },
618
+ emit(props, silent = false) {
619
+ if (!silent) if (diffStyle === "unified") state.incrementCounts(1, 0);
620
+ else if (diffStyle === "split") state.incrementCounts(0, 1);
621
+ else state.incrementCounts(1, 1);
622
+ return callback(props) ?? false;
623
+ }
624
+ };
625
+ hunkIterator: for (const [hunkIndex, hunk] of diff.hunks.entries()) {
626
+ if (state.shouldBreak()) break;
627
+ const leadingRegion = getExpandedRegion(diff.isPartial, hunk.collapsedBefore, expandedHunks, hunkIndex);
628
+ const trailingRegion = (() => {
629
+ if (hunk !== state.finalHunk || !hasFinalCollapsedHunk(diff)) return;
630
+ const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
631
+ const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
632
+ if (additionRemaining !== deletionRemaining) throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
633
+ const trailingRangeSize = Math.min(additionRemaining, deletionRemaining);
634
+ return getExpandedRegion(diff.isPartial, trailingRangeSize, expandedHunks, diff.hunks.length);
635
+ })();
636
+ const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;
637
+ function getTrailingCollapsedAfter(unifiedLineIndex$1, splitLineIndex$1) {
638
+ if (trailingRegion == null || trailingRegion.collapsedLines <= 0 || trailingRegion.fromStart + trailingRegion.fromEnd > 0) return 0;
639
+ if (diffStyle === "unified") return unifiedLineIndex$1 === hunk.unifiedLineStart + hunk.unifiedLineCount - 1 ? trailingRegion.collapsedLines : 0;
640
+ return splitLineIndex$1 === hunk.splitLineStart + hunk.splitLineCount - 1 ? trailingRegion.collapsedLines : 0;
641
+ }
642
+ function getPendingCollapsed() {
643
+ if (leadingRegion.collapsedLines === 0) return 0;
644
+ const value = leadingRegion.collapsedLines;
645
+ leadingRegion.collapsedLines = 0;
646
+ return value;
647
+ }
648
+ if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {
649
+ let unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.rangeSize;
650
+ let splitLineIndex$1 = hunk.splitLineStart - leadingRegion.rangeSize;
651
+ let deletionLineIndex$1 = hunk.deletionLineIndex - leadingRegion.rangeSize;
652
+ let additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.rangeSize;
653
+ let deletionLineNumber$1 = hunk.deletionStart - leadingRegion.rangeSize;
654
+ let additionLineNumber$1 = hunk.additionStart - leadingRegion.rangeSize;
655
+ let index = 0;
656
+ while (index < leadingRegion.fromStart) {
657
+ if (state.isInWindow(0, 0)) {
658
+ if (state.emit({
659
+ hunkIndex,
660
+ hunk,
661
+ collapsedBefore: 0,
662
+ collapsedAfter: 0,
663
+ unifiedDeletionLineIndex: unifiedLineIndex$1 + index,
664
+ unifiedAdditionLineIndex: unifiedLineIndex$1 + index,
665
+ splitLineIndex: splitLineIndex$1 + index,
666
+ deletionLineIndex: deletionLineIndex$1 + index,
667
+ additionLineIndex: additionLineIndex$1 + index,
668
+ deletionLineNumber: deletionLineNumber$1 + index,
669
+ additionLineNumber: additionLineNumber$1 + index,
670
+ type: "context-expanded",
671
+ noEOFCRAddition: false,
672
+ noEOFCRDeletion: false
673
+ })) break hunkIterator;
674
+ } else state.incrementCounts(1, 1);
675
+ index++;
676
+ }
677
+ unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.fromEnd;
678
+ splitLineIndex$1 = hunk.splitLineStart - leadingRegion.fromEnd;
679
+ deletionLineIndex$1 = hunk.deletionLineIndex - leadingRegion.fromEnd;
680
+ additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.fromEnd;
681
+ deletionLineNumber$1 = hunk.deletionStart - leadingRegion.fromEnd;
682
+ additionLineNumber$1 = hunk.additionStart - leadingRegion.fromEnd;
683
+ index = 0;
684
+ while (index < leadingRegion.fromEnd) {
685
+ if (state.isInWindow(0, 0)) {
686
+ if (state.emit({
687
+ hunkIndex,
688
+ hunk,
689
+ collapsedBefore: getPendingCollapsed(),
690
+ collapsedAfter: 0,
691
+ unifiedDeletionLineIndex: unifiedLineIndex$1 + index,
692
+ unifiedAdditionLineIndex: unifiedLineIndex$1 + index,
693
+ splitLineIndex: splitLineIndex$1 + index,
694
+ deletionLineIndex: deletionLineIndex$1 + index,
695
+ additionLineIndex: additionLineIndex$1 + index,
696
+ deletionLineNumber: deletionLineNumber$1 + index,
697
+ additionLineNumber: additionLineNumber$1 + index,
698
+ type: "context-expanded",
699
+ noEOFCRAddition: false,
700
+ noEOFCRDeletion: false
701
+ })) break hunkIterator;
702
+ } else state.incrementCounts(1, 1);
703
+ index++;
704
+ }
705
+ } else {
706
+ state.incrementCounts(expandedLineCount, expandedLineCount);
707
+ getPendingCollapsed();
708
+ }
709
+ let unifiedLineIndex = hunk.unifiedLineStart;
710
+ let splitLineIndex = hunk.splitLineStart;
711
+ let deletionLineIndex = hunk.deletionLineIndex;
712
+ let additionLineIndex = hunk.additionLineIndex;
713
+ let deletionLineNumber = hunk.deletionStart;
714
+ let additionLineNumber = hunk.additionStart;
715
+ const lastContent = hunk.hunkContent.at(-1);
716
+ for (const content of hunk.hunkContent) {
717
+ if (state.shouldBreak()) break hunkIterator;
718
+ const isLastContent = content === lastContent;
719
+ if (content.type === "context") {
720
+ if (!state.shouldSkip(content.lines, content.lines)) {
721
+ let index = 0;
722
+ while (index < content.lines) {
723
+ if (state.isInWindow(0, 0)) {
724
+ const isLastLine = isLastContent && index === content.lines - 1;
725
+ const unifiedRowIndex = unifiedLineIndex + index;
726
+ const splitRowIndex = splitLineIndex + index;
727
+ if (state.emit({
728
+ hunkIndex,
729
+ hunk,
730
+ collapsedBefore: getPendingCollapsed(),
731
+ collapsedAfter: getTrailingCollapsedAfter(unifiedRowIndex, splitRowIndex),
732
+ unifiedDeletionLineIndex: unifiedRowIndex,
733
+ unifiedAdditionLineIndex: unifiedRowIndex,
734
+ splitLineIndex: splitRowIndex,
735
+ deletionLineIndex: deletionLineIndex + index,
736
+ additionLineIndex: additionLineIndex + index,
737
+ deletionLineNumber: deletionLineNumber + index,
738
+ additionLineNumber: additionLineNumber + index,
739
+ type: "context",
740
+ noEOFCRAddition: isLastLine && hunk.noEOFCRAdditions,
741
+ noEOFCRDeletion: isLastLine && hunk.noEOFCRDeletions
742
+ })) break hunkIterator;
743
+ } else state.incrementCounts(1, 1);
744
+ index++;
745
+ }
746
+ } else {
747
+ state.incrementCounts(content.lines, content.lines);
748
+ getPendingCollapsed();
749
+ }
750
+ unifiedLineIndex += content.lines;
751
+ splitLineIndex += content.lines;
752
+ deletionLineIndex += content.lines;
753
+ additionLineIndex += content.lines;
754
+ deletionLineNumber += content.lines;
755
+ additionLineNumber += content.lines;
756
+ } else {
757
+ const splitCount = Math.max(content.deletions, content.additions);
758
+ const unifiedCount = content.deletions + content.additions;
759
+ if (!state.shouldSkip(unifiedCount, splitCount)) {
760
+ const iterationRanges = getChangeIterationRanges(state, content, diffStyle);
761
+ for (const [rangeStart, rangeEnd] of iterationRanges) for (let index = rangeStart; index < rangeEnd; index++) {
762
+ const collapsedAfter = getTrailingCollapsedAfter(unifiedLineIndex + index, diffStyle === "unified" ? splitLineIndex + (index < content.deletions ? index : index - content.deletions) : splitLineIndex + index);
763
+ if (state.emit(getChangeLineData({
764
+ hunkIndex,
765
+ hunk,
766
+ collapsedBefore: getPendingCollapsed(),
767
+ collapsedAfter,
768
+ diffStyle,
769
+ index,
770
+ unifiedLineIndex,
771
+ splitLineIndex,
772
+ additionLineIndex,
773
+ deletionLineIndex,
774
+ additionLineNumber,
775
+ deletionLineNumber,
776
+ content,
777
+ isLastContent,
778
+ unifiedCount,
779
+ splitCount
780
+ }), true)) break hunkIterator;
781
+ }
782
+ }
783
+ getPendingCollapsed();
784
+ state.incrementCounts(unifiedCount, splitCount);
785
+ unifiedLineIndex += unifiedCount;
786
+ splitLineIndex += splitCount;
787
+ deletionLineIndex += content.deletions;
788
+ additionLineIndex += content.additions;
789
+ deletionLineNumber += content.deletions;
790
+ additionLineNumber += content.additions;
791
+ }
792
+ }
793
+ if (trailingRegion != null) {
794
+ const { collapsedLines, fromStart, fromEnd } = trailingRegion;
795
+ const len = fromStart + fromEnd;
796
+ let index = 0;
797
+ while (index < len) {
798
+ if (state.shouldBreak()) break hunkIterator;
799
+ if (state.isInWindow(0, 0)) {
800
+ const isLastLine = index === len - 1;
801
+ if (state.emit({
802
+ hunkIndex: diff.hunks.length,
803
+ hunk: void 0,
804
+ collapsedBefore: 0,
805
+ collapsedAfter: isLastLine ? collapsedLines : 0,
806
+ unifiedDeletionLineIndex: unifiedLineIndex + index,
807
+ unifiedAdditionLineIndex: unifiedLineIndex + index,
808
+ splitLineIndex: splitLineIndex + index,
809
+ additionLineIndex: additionLineIndex + index,
810
+ deletionLineIndex: deletionLineIndex + index,
811
+ additionLineNumber: additionLineNumber + index,
812
+ deletionLineNumber: deletionLineNumber + index,
813
+ type: "context-expanded",
814
+ noEOFCRAddition: false,
815
+ noEOFCRDeletion: false
816
+ })) break hunkIterator;
817
+ } else state.incrementCounts(1, 1);
818
+ index++;
819
+ }
820
+ }
821
+ }
822
+ }
823
+ function getExpandedRegion(isPartial, rangeSize, expandedHunks, hunkIndex) {
824
+ rangeSize = Math.max(rangeSize, 0);
825
+ if (rangeSize === 0 || isPartial) return {
826
+ fromStart: 0,
827
+ fromEnd: 0,
828
+ rangeSize,
829
+ collapsedLines: Math.max(rangeSize, 0)
830
+ };
831
+ if (expandedHunks === true) return {
832
+ fromStart: rangeSize,
833
+ fromEnd: 0,
834
+ rangeSize,
835
+ collapsedLines: 0
836
+ };
837
+ const region = expandedHunks?.get(hunkIndex);
838
+ const fromStart = Math.min(Math.max(region?.fromStart ?? 0, 0), rangeSize);
839
+ const fromEnd = Math.min(Math.max(region?.fromEnd ?? 0, 0), rangeSize);
840
+ const expandedCount = fromStart + fromEnd;
841
+ const renderAll = expandedCount >= rangeSize;
842
+ return {
843
+ fromStart: renderAll ? rangeSize : fromStart,
844
+ fromEnd: renderAll ? 0 : fromEnd,
845
+ rangeSize,
846
+ collapsedLines: Math.max(rangeSize - expandedCount, 0)
847
+ };
848
+ }
849
+ function hasFinalCollapsedHunk(diff) {
850
+ const lastHunk = diff.hunks.at(-1);
851
+ if (lastHunk == null || diff.isPartial || diff.additionLines.length === 0 || diff.deletionLines.length === 0) return false;
852
+ return lastHunk.additionLineIndex + lastHunk.additionCount < diff.additionLines.length || lastHunk.deletionLineIndex + lastHunk.deletionCount < diff.deletionLines.length;
853
+ }
854
+ function getChangeIterationRanges(state, content, diffStyle) {
855
+ if (!state.isWindowedHighlight) return [[0, diffStyle === "unified" ? content.deletions + content.additions : Math.max(content.deletions, content.additions)]];
856
+ const useUnified = diffStyle !== "split";
857
+ const useSplit = diffStyle !== "unified";
858
+ const iterationSpace = diffStyle === "unified" ? "unified" : "split";
859
+ const iterationRanges = [];
860
+ function getVisibleRange(start, count) {
861
+ if (start + count <= state.viewportStart || start >= state.viewportEnd) return;
862
+ const visibleStart = Math.max(0, state.viewportStart - start);
863
+ const visibleEnd = Math.min(count, state.viewportEnd - start);
864
+ return visibleEnd > visibleStart ? [visibleStart, visibleEnd] : void 0;
865
+ }
866
+ function mapRangeToIteration(range, kind) {
867
+ if (iterationSpace === "split") return range;
868
+ return kind === "additions" ? [range[0] + content.deletions, range[1] + content.deletions] : range;
869
+ }
870
+ function pushRange(range, kind) {
871
+ if (range == null) return;
872
+ const [start, end] = mapRangeToIteration(range, kind);
873
+ if (end > start) iterationRanges.push([start, end]);
874
+ }
875
+ if (useUnified) {
876
+ pushRange(getVisibleRange(state.unifiedCount, content.deletions), "deletions");
877
+ pushRange(getVisibleRange(state.unifiedCount + content.deletions, content.additions), "additions");
878
+ }
879
+ if (useSplit) {
880
+ pushRange(getVisibleRange(state.splitCount, content.deletions), "deletions");
881
+ pushRange(getVisibleRange(state.splitCount, content.additions), "additions");
882
+ }
883
+ if (iterationRanges.length === 0) return iterationRanges;
884
+ iterationRanges.sort((a, b) => a[0] - b[0]);
885
+ const merged = [iterationRanges[0]];
886
+ for (const [start, end] of iterationRanges.slice(1)) {
887
+ const last = merged[merged.length - 1];
888
+ if (start <= last[1]) last[1] = Math.max(last[1], end);
889
+ else merged.push([start, end]);
890
+ }
891
+ return merged;
892
+ }
893
+ function getChangeLineData({ hunkIndex, hunk, collapsedAfter, collapsedBefore, diffStyle, index, unifiedLineIndex, splitLineIndex, additionLineIndex, deletionLineIndex, additionLineNumber, deletionLineNumber, content, isLastContent, unifiedCount, splitCount }) {
894
+ if (diffStyle === "unified") return {
895
+ type: "change",
896
+ hunkIndex,
897
+ hunk,
898
+ collapsedAfter,
899
+ collapsedBefore,
900
+ unifiedDeletionLineIndex: index < content.deletions ? unifiedLineIndex + index : void 0,
901
+ unifiedAdditionLineIndex: index >= content.deletions ? unifiedLineIndex + index : void 0,
902
+ splitLineIndex: splitLineIndex + (index < content.deletions ? index : index - content.deletions),
903
+ additionLineIndex: index >= content.deletions ? additionLineIndex + (index - content.deletions) : void 0,
904
+ additionLineNumber: index >= content.deletions ? additionLineNumber + (index - content.deletions) : void 0,
905
+ deletionLineIndex: index < content.deletions ? deletionLineIndex + index : void 0,
906
+ deletionLineNumber: index < content.deletions ? deletionLineNumber + index : void 0,
907
+ noEOFCRDeletion: isLastContent && index === content.deletions - 1 && hunk.noEOFCRDeletions,
908
+ noEOFCRAddition: isLastContent && index === unifiedCount - 1 && hunk.noEOFCRAdditions
909
+ };
910
+ return {
911
+ type: "change",
912
+ hunkIndex,
913
+ hunk,
914
+ collapsedAfter,
915
+ collapsedBefore,
916
+ unifiedDeletionLineIndex: index < content.deletions ? unifiedLineIndex + index : void 0,
917
+ unifiedAdditionLineIndex: index < content.additions ? unifiedLineIndex + content.deletions + index : void 0,
918
+ splitLineIndex: splitLineIndex + index,
919
+ additionLineIndex: index < content.additions ? additionLineIndex + index : void 0,
920
+ additionLineNumber: index < content.additions ? additionLineNumber + index : void 0,
921
+ deletionLineIndex: index < content.deletions ? deletionLineIndex + index : void 0,
922
+ deletionLineNumber: index < content.deletions ? deletionLineNumber + index : void 0,
923
+ noEOFCRDeletion: isLastContent && index === splitCount - 1 && hunk.noEOFCRDeletions,
924
+ noEOFCRAddition: isLastContent && index === splitCount - 1 && hunk.noEOFCRAdditions
925
+ };
926
+ }
927
+
569
928
  //#endregion
570
929
  //#region src/utils/parseDiffDecorations.ts
571
930
  function createDiffSpanDecoration({ line, spanStart, spanLength }) {
@@ -598,7 +957,16 @@ function pushOrJoinSpan({ item, arr, enableJoin, isNeutral = false, isLastItem =
598
957
 
599
958
  //#endregion
600
959
  //#region src/utils/renderDiffWithHighlighter.ts
601
- function renderDiffWithHighlighter(diff, highlighter$1, options, forcePlainText = false) {
960
+ const DEFAULT_PLAIN_TEXT_OPTIONS = { forcePlainText: false };
961
+ function renderDiffWithHighlighter(diff, highlighter$1, options, { forcePlainText, startingLine, totalLines, expandedHunks } = DEFAULT_PLAIN_TEXT_OPTIONS) {
962
+ if (forcePlainText) {
963
+ startingLine ??= 0;
964
+ totalLines ??= Infinity;
965
+ } else {
966
+ startingLine = 0;
967
+ totalLines = Infinity;
968
+ }
969
+ const isWindowedHighlight = startingLine > 0 || totalLines < Infinity;
602
970
  const baseThemeType = (() => {
603
971
  const theme = options.theme ?? DEFAULT_THEMES;
604
972
  if (typeof theme === "string") return highlighter$1.getTheme(theme).type;
@@ -607,92 +975,120 @@ function renderDiffWithHighlighter(diff, highlighter$1, options, forcePlainText
607
975
  theme: options.theme,
608
976
  highlighter: highlighter$1
609
977
  });
610
- if (diff.newLines != null && diff.oldLines != null) {
611
- const { oldContent, newContent, oldInfo, newInfo, oldDecorations, newDecorations } = processLines({
612
- hunks: diff.hunks,
613
- oldLines: diff.oldLines,
614
- newLines: diff.newLines,
615
- lineDiffType: options.lineDiffType
616
- });
617
- return {
618
- code: renderTwoFiles({
619
- oldFile: {
620
- name: diff.prevName ?? diff.name,
621
- contents: oldContent
622
- },
623
- oldInfo,
624
- oldDecorations,
625
- newFile: {
626
- name: diff.name,
627
- contents: newContent
628
- },
629
- newInfo,
630
- newDecorations,
631
- highlighter: highlighter$1,
632
- options,
633
- languageOverride: forcePlainText ? "text" : diff.lang
634
- }),
635
- themeStyles,
636
- baseThemeType
637
- };
978
+ const lineDiffType = forcePlainText && !isWindowedHighlight && (diff.unifiedLineCount > 1e3 || diff.splitLineCount > 1e3) ? "none" : options.lineDiffType;
979
+ const code = {
980
+ deletionLines: [],
981
+ additionLines: []
982
+ };
983
+ const shouldGroupAll = !forcePlainText && !diff.isPartial;
984
+ const expandedHunksForIteration = forcePlainText ? expandedHunks : void 0;
985
+ const buckets = /* @__PURE__ */ new Map();
986
+ function getBucketForHunk(hunkIndex) {
987
+ const index = shouldGroupAll ? 0 : hunkIndex;
988
+ const bucket = buckets.get(index) ?? createBucket();
989
+ buckets.set(index, bucket);
990
+ return bucket;
638
991
  }
639
- const hunks = [];
640
- let splitLineIndex = 0;
641
- let unifiedLineIndex = 0;
642
- for (const hunk of diff.hunks) {
643
- const { oldContent, newContent, oldInfo, newInfo, oldDecorations, newDecorations, splitLineIndex: newSplitLineIndex, unifiedLineIndex: newUnifiedLineIndex } = processLines({
644
- hunks: [hunk],
645
- splitLineIndex,
646
- unifiedLineIndex,
647
- lineDiffType: options.lineDiffType
648
- });
649
- const oldFile = {
992
+ function appendContent(lineContent, lineIndex, segments, contentWrapper) {
993
+ if (isWindowedHighlight) {
994
+ let segment = segments.at(-1);
995
+ if (segment == null || segment.targetIndex + segment.count !== lineIndex) {
996
+ segment = {
997
+ targetIndex: lineIndex,
998
+ originalOffset: contentWrapper.length,
999
+ count: 0
1000
+ };
1001
+ segments.push(segment);
1002
+ }
1003
+ segment.count++;
1004
+ }
1005
+ contentWrapper.push(lineContent);
1006
+ }
1007
+ iterateOverDiff({
1008
+ diff,
1009
+ diffStyle: "both",
1010
+ startingLine,
1011
+ totalLines,
1012
+ expandedHunks: isWindowedHighlight ? expandedHunksForIteration : true,
1013
+ callback: ({ hunkIndex, additionLineIndex, deletionLineIndex, additionLineNumber, deletionLineNumber, unifiedAdditionLineIndex, unifiedDeletionLineIndex, splitLineIndex, type }) => {
1014
+ const bucket = getBucketForHunk(hunkIndex);
1015
+ if (type === "change" && lineDiffType !== "none" && additionLineIndex != null && deletionLineIndex != null) computeLineDiffDecorations({
1016
+ additionLine: diff.additionLines[additionLineIndex],
1017
+ deletionLine: diff.deletionLines[deletionLineIndex],
1018
+ deletionLineIndex: bucket.deletionContent.length,
1019
+ additionLineIndex: bucket.additionContent.length,
1020
+ deletionDecorations: bucket.deletionDecorations,
1021
+ additionDecorations: bucket.additionDecorations,
1022
+ lineDiffType
1023
+ });
1024
+ if (deletionLineIndex != null && deletionLineNumber != null && unifiedDeletionLineIndex != null) {
1025
+ appendContent(diff.deletionLines[deletionLineIndex], deletionLineIndex, bucket.deletionSegments, bucket.deletionContent);
1026
+ bucket.deletionInfo.push({
1027
+ type: type === "change" ? "change-deletion" : type,
1028
+ lineNumber: deletionLineNumber,
1029
+ altLineNumber: type === "change" ? void 0 : additionLineNumber ?? void 0,
1030
+ lineIndex: `${unifiedDeletionLineIndex},${splitLineIndex}`
1031
+ });
1032
+ }
1033
+ if (additionLineIndex != null && additionLineNumber != null && unifiedAdditionLineIndex != null) {
1034
+ appendContent(diff.additionLines[additionLineIndex], additionLineIndex, bucket.additionSegments, bucket.additionContent);
1035
+ bucket.additionInfo.push({
1036
+ type: type === "change" ? "change-addition" : type,
1037
+ lineNumber: additionLineNumber,
1038
+ altLineNumber: type === "change" ? void 0 : deletionLineNumber ?? void 0,
1039
+ lineIndex: `${unifiedAdditionLineIndex},${splitLineIndex}`
1040
+ });
1041
+ }
1042
+ }
1043
+ });
1044
+ for (const bucket of buckets.values()) {
1045
+ if (bucket.deletionContent.length === 0 && bucket.additionContent.length === 0) continue;
1046
+ const deletionFile = {
650
1047
  name: diff.prevName ?? diff.name,
651
- contents: oldContent
1048
+ contents: bucket.deletionContent.value
652
1049
  };
653
- const newFile = {
1050
+ const additionFile = {
654
1051
  name: diff.name,
655
- contents: newContent
1052
+ contents: bucket.additionContent.value
656
1053
  };
657
- hunks.push(renderTwoFiles({
658
- oldFile,
659
- oldInfo,
660
- oldDecorations,
661
- newFile,
662
- newInfo,
663
- newDecorations,
1054
+ const { deletionLines, additionLines } = renderTwoFiles({
1055
+ deletionFile,
1056
+ deletionInfo: bucket.deletionInfo,
1057
+ deletionDecorations: bucket.deletionDecorations,
1058
+ additionFile,
1059
+ additionInfo: bucket.additionInfo,
1060
+ additionDecorations: bucket.additionDecorations,
664
1061
  highlighter: highlighter$1,
665
1062
  options,
666
1063
  languageOverride: forcePlainText ? "text" : diff.lang
667
- }));
668
- splitLineIndex = newSplitLineIndex;
669
- unifiedLineIndex = newUnifiedLineIndex;
1064
+ });
1065
+ if (shouldGroupAll) {
1066
+ code.deletionLines = deletionLines;
1067
+ code.additionLines = additionLines;
1068
+ continue;
1069
+ }
1070
+ if (bucket.deletionSegments.length > 0) for (const seg of bucket.deletionSegments) for (let i = 0; i < seg.count; i++) code.deletionLines[seg.targetIndex + i] = deletionLines[seg.originalOffset + i];
1071
+ else code.deletionLines.push(...deletionLines);
1072
+ if (bucket.additionSegments.length > 0) for (const seg of bucket.additionSegments) for (let i = 0; i < seg.count; i++) code.additionLines[seg.targetIndex + i] = additionLines[seg.originalOffset + i];
1073
+ else code.additionLines.push(...additionLines);
670
1074
  }
671
1075
  return {
672
- code: (() => {
673
- if (hunks.length <= 1) {
674
- const hunk = hunks[0] ?? {
675
- oldLines: [],
676
- newLines: []
677
- };
678
- if (hunk.newLines.length === 0 || hunk.oldLines.length === 0) return hunk;
679
- }
680
- return { hunks };
681
- })(),
1076
+ code,
682
1077
  themeStyles,
683
1078
  baseThemeType
684
1079
  };
685
1080
  }
686
- function computeLineDiffDecorations({ oldLine, newLine, oldLineIndex, newLineIndex, oldDecorations, newDecorations, lineDiffType }) {
687
- if (oldLine == null || newLine == null || lineDiffType === "none") return;
688
- oldLine = cleanLastNewline(oldLine);
689
- newLine = cleanLastNewline(newLine);
690
- const lineDiff = lineDiffType === "char" ? diffChars(oldLine, newLine) : diffWordsWithSpace(oldLine, newLine);
1081
+ function computeLineDiffDecorations({ deletionLine, additionLine, deletionLineIndex, additionLineIndex, deletionDecorations, additionDecorations, lineDiffType }) {
1082
+ if (deletionLine == null || additionLine == null || lineDiffType === "none") return;
1083
+ deletionLine = cleanLastNewline(deletionLine);
1084
+ additionLine = cleanLastNewline(additionLine);
1085
+ const lineDiff = lineDiffType === "char" ? diffChars(deletionLine, additionLine) : diffWordsWithSpace(deletionLine, additionLine);
691
1086
  const deletionSpans = [];
692
1087
  const additionSpans = [];
693
1088
  const enableJoin = lineDiffType === "word-alt";
1089
+ const lastItem = lineDiff.at(-1);
694
1090
  for (const item of lineDiff) {
695
- const isLastItem = item === lineDiff[lineDiff.length - 1];
1091
+ const isLastItem = item === lastItem;
696
1092
  if (!item.added && !item.removed) {
697
1093
  pushOrJoinSpan({
698
1094
  item,
@@ -723,8 +1119,8 @@ function computeLineDiffDecorations({ oldLine, newLine, oldLineIndex, newLineInd
723
1119
  }
724
1120
  let spanIndex = 0;
725
1121
  for (const span of deletionSpans) {
726
- if (span[0] === 1) oldDecorations.push(createDiffSpanDecoration({
727
- line: oldLineIndex - 1,
1122
+ if (span[0] === 1) deletionDecorations.push(createDiffSpanDecoration({
1123
+ line: deletionLineIndex,
728
1124
  spanStart: spanIndex,
729
1125
  spanLength: span[1].length
730
1126
  }));
@@ -732,159 +1128,43 @@ function computeLineDiffDecorations({ oldLine, newLine, oldLineIndex, newLineInd
732
1128
  }
733
1129
  spanIndex = 0;
734
1130
  for (const span of additionSpans) {
735
- if (span[0] === 1) newDecorations.push(createDiffSpanDecoration({
736
- line: newLineIndex - 1,
1131
+ if (span[0] === 1) additionDecorations.push(createDiffSpanDecoration({
1132
+ line: additionLineIndex,
737
1133
  spanStart: spanIndex,
738
1134
  spanLength: span[1].length
739
1135
  }));
740
1136
  spanIndex += span[1].length;
741
1137
  }
742
1138
  }
743
- function processLines({ hunks, oldLines, newLines, splitLineIndex = 0, unifiedLineIndex = 0, lineDiffType }) {
744
- const oldInfo = {};
745
- const newInfo = {};
746
- const oldDecorations = [];
747
- const newDecorations = [];
748
- let newLineIndex = 1;
749
- let oldLineIndex = 1;
750
- let newLineNumber = 1;
751
- let oldLineNumber = 1;
752
- let oldContent = "";
753
- let newContent = "";
754
- for (const hunk of hunks) {
755
- while (oldLines != null && newLines != null && newLineIndex < hunk.additionStart && oldLineIndex < hunk.deletionStart) {
756
- oldInfo[oldLineIndex] = {
757
- type: "context-expanded",
758
- lineNumber: oldLineNumber,
759
- altLineNumber: newLineNumber,
760
- lineIndex: `${unifiedLineIndex},${splitLineIndex}`
761
- };
762
- newInfo[newLineIndex] = {
763
- type: "context-expanded",
764
- lineNumber: newLineNumber,
765
- altLineNumber: oldLineNumber,
766
- lineIndex: `${unifiedLineIndex},${splitLineIndex}`
767
- };
768
- oldContent += oldLines[oldLineIndex - 1];
769
- newContent += newLines[newLineIndex - 1];
770
- oldLineIndex++;
771
- newLineIndex++;
772
- oldLineNumber++;
773
- newLineNumber++;
774
- splitLineIndex++;
775
- unifiedLineIndex++;
776
- }
777
- oldLineNumber = hunk.deletionStart;
778
- newLineNumber = hunk.additionStart;
779
- for (const hunkContent of hunk.hunkContent) if (hunkContent.type === "context") for (const line of hunkContent.lines) {
780
- oldInfo[oldLineIndex] = {
781
- type: "context",
782
- lineNumber: oldLineNumber,
783
- altLineNumber: newLineNumber,
784
- lineIndex: `${unifiedLineIndex},${splitLineIndex}`
785
- };
786
- newInfo[newLineIndex] = {
787
- type: "context",
788
- lineNumber: newLineNumber,
789
- altLineNumber: oldLineNumber,
790
- lineIndex: `${unifiedLineIndex},${splitLineIndex}`
791
- };
792
- oldContent += line;
793
- newContent += line;
794
- oldLineIndex++;
795
- newLineIndex++;
796
- newLineNumber++;
797
- oldLineNumber++;
798
- splitLineIndex++;
799
- unifiedLineIndex++;
800
- }
801
- else {
802
- const len = Math.max(hunkContent.additions.length, hunkContent.deletions.length);
803
- let i = 0;
804
- let _unifiedLineIndex = unifiedLineIndex;
805
- while (i < len) {
806
- const oldLine = hunkContent.deletions[i];
807
- const newLine = hunkContent.additions[i];
808
- computeLineDiffDecorations({
809
- newLine,
810
- oldLine,
811
- oldLineIndex,
812
- newLineIndex,
813
- oldDecorations,
814
- newDecorations,
815
- lineDiffType
816
- });
817
- if (oldLine != null) {
818
- oldInfo[oldLineIndex] = {
819
- type: "change-deletion",
820
- lineNumber: oldLineNumber,
821
- lineIndex: `${_unifiedLineIndex},${splitLineIndex}`
822
- };
823
- oldContent += oldLine;
824
- oldLineIndex++;
825
- oldLineNumber++;
826
- }
827
- if (newLine != null) {
828
- newInfo[newLineIndex] = {
829
- type: "change-addition",
830
- lineNumber: newLineNumber,
831
- lineIndex: `${_unifiedLineIndex + hunkContent.deletions.length},${splitLineIndex}`
832
- };
833
- newContent += newLine;
834
- newLineIndex++;
835
- newLineNumber++;
836
- }
837
- splitLineIndex++;
838
- _unifiedLineIndex++;
839
- i++;
840
- }
841
- unifiedLineIndex += hunkContent.additions.length + hunkContent.deletions.length;
842
- }
843
- if (oldLines == null || newLines == null || hunk !== hunks[hunks.length - 1]) continue;
844
- while (oldLineIndex <= oldLines.length || newLineIndex <= oldLines.length) {
845
- const oldLine = oldLines[oldLineIndex - 1];
846
- const newLine = newLines[newLineIndex - 1];
847
- if (oldLine == null && newLine == null) break;
848
- if (oldLine != null) {
849
- oldInfo[oldLineIndex] = {
850
- type: "context-expanded",
851
- lineNumber: oldLineNumber,
852
- altLineNumber: newLineNumber,
853
- lineIndex: `${unifiedLineIndex},${splitLineIndex}`
854
- };
855
- oldContent += oldLine;
856
- oldLineIndex++;
857
- oldLineNumber++;
858
- }
859
- if (newLine != null) {
860
- newInfo[newLineIndex] = {
861
- type: "context-expanded",
862
- lineNumber: newLineNumber,
863
- altLineNumber: oldLineNumber,
864
- lineIndex: `${unifiedLineIndex},${splitLineIndex}`
865
- };
866
- newContent += newLine;
867
- newLineIndex++;
868
- newLineNumber++;
869
- }
870
- splitLineIndex++;
871
- unifiedLineIndex++;
872
- }
873
- }
1139
+ function createBucket() {
874
1140
  return {
875
- oldContent,
876
- newContent,
877
- oldInfo,
878
- newInfo,
879
- oldDecorations,
880
- newDecorations,
881
- splitLineIndex,
882
- unifiedLineIndex
1141
+ deletionContent: {
1142
+ push(value) {
1143
+ this.value += value;
1144
+ this.length++;
1145
+ },
1146
+ value: "",
1147
+ length: 0
1148
+ },
1149
+ additionContent: {
1150
+ push(value) {
1151
+ this.value += value;
1152
+ this.length++;
1153
+ },
1154
+ value: "",
1155
+ length: 0
1156
+ },
1157
+ deletionInfo: [],
1158
+ additionInfo: [],
1159
+ deletionDecorations: [],
1160
+ additionDecorations: [],
1161
+ deletionSegments: [],
1162
+ additionSegments: []
883
1163
  };
884
1164
  }
885
- function renderTwoFiles({ oldFile, newFile, oldInfo, newInfo, highlighter: highlighter$1, oldDecorations, newDecorations, languageOverride, options: { theme: themeOrThemes = DEFAULT_THEMES,...options } }) {
886
- const oldLang = languageOverride ?? getFiletypeFromFileName(oldFile.name);
887
- const newLang = languageOverride ?? getFiletypeFromFileName(newFile.name);
1165
+ function renderTwoFiles({ deletionFile, additionFile, deletionInfo, additionInfo, highlighter: highlighter$1, deletionDecorations, additionDecorations, languageOverride, options: { theme: themeOrThemes = DEFAULT_THEMES,...options } }) {
1166
+ const deletionLang = languageOverride ?? getFiletypeFromFileName(deletionFile.name);
1167
+ const additionLang = languageOverride ?? getFiletypeFromFileName(additionFile.name);
888
1168
  const { state, transformers } = createTransformerWithState();
889
1169
  const hastConfig = (() => {
890
1170
  return typeof themeOrThemes === "string" ? {
@@ -894,7 +1174,7 @@ function renderTwoFiles({ oldFile, newFile, oldInfo, newInfo, highlighter: highl
894
1174
  transformers,
895
1175
  decorations: void 0,
896
1176
  defaultColor: false,
897
- cssVariablePrefix: formatCSSVariablePrefix()
1177
+ cssVariablePrefix: formatCSSVariablePrefix("token")
898
1178
  } : {
899
1179
  ...options,
900
1180
  lang: "text",
@@ -902,23 +1182,23 @@ function renderTwoFiles({ oldFile, newFile, oldInfo, newInfo, highlighter: highl
902
1182
  transformers,
903
1183
  decorations: void 0,
904
1184
  defaultColor: false,
905
- cssVariablePrefix: formatCSSVariablePrefix()
1185
+ cssVariablePrefix: formatCSSVariablePrefix("token")
906
1186
  };
907
1187
  })();
908
1188
  return {
909
- oldLines: (() => {
910
- if (oldFile.contents === "") return [];
911
- hastConfig.lang = oldLang;
912
- state.lineInfo = oldInfo;
913
- hastConfig.decorations = oldDecorations;
914
- return getLineNodes(highlighter$1.codeToHast(cleanLastNewline(oldFile.contents), hastConfig));
1189
+ deletionLines: (() => {
1190
+ if (deletionFile.contents === "") return [];
1191
+ hastConfig.lang = deletionLang;
1192
+ state.lineInfo = deletionInfo;
1193
+ hastConfig.decorations = deletionDecorations;
1194
+ return getLineNodes(highlighter$1.codeToHast(cleanLastNewline(deletionFile.contents), hastConfig));
915
1195
  })(),
916
- newLines: (() => {
917
- if (newFile.contents === "") return [];
918
- hastConfig.lang = newLang;
919
- hastConfig.decorations = newDecorations;
920
- state.lineInfo = newInfo;
921
- return getLineNodes(highlighter$1.codeToHast(cleanLastNewline(newFile.contents), hastConfig));
1196
+ additionLines: (() => {
1197
+ if (additionFile.contents === "") return [];
1198
+ hastConfig.lang = additionLang;
1199
+ hastConfig.decorations = additionDecorations;
1200
+ state.lineInfo = additionInfo;
1201
+ return getLineNodes(highlighter$1.codeToHast(cleanLastNewline(additionFile.contents), hastConfig));
922
1202
  })()
923
1203
  };
924
1204
  }
@@ -946,7 +1226,7 @@ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES
946
1226
  theme,
947
1227
  transformers,
948
1228
  defaultColor: false,
949
- cssVariablePrefix: formatCSSVariablePrefix(),
1229
+ cssVariablePrefix: formatCSSVariablePrefix("token"),
950
1230
  tokenizeMaxLineLength
951
1231
  };
952
1232
  return {
@@ -954,7 +1234,7 @@ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES
954
1234
  themes: theme,
955
1235
  transformers,
956
1236
  defaultColor: false,
957
- cssVariablePrefix: formatCSSVariablePrefix(),
1237
+ cssVariablePrefix: formatCSSVariablePrefix("token"),
958
1238
  tokenizeMaxLineLength
959
1239
  };
960
1240
  })();