@pierre/diffs 1.2.6 → 1.3.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.
- package/dist/components/CodeView.d.ts +0 -1
- package/dist/components/CodeView.d.ts.map +1 -1
- package/dist/components/CodeView.js +0 -23
- 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 -2
- package/dist/components/File.js.map +1 -1
- package/dist/components/FileDiff.d.ts +8 -2
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js +73 -1
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +2 -2
- package/dist/components/VirtualizedFile.d.ts +2 -1
- package/dist/components/VirtualizedFile.d.ts.map +1 -1
- package/dist/components/VirtualizedFile.js +48 -48
- package/dist/components/VirtualizedFile.js.map +1 -1
- package/dist/components/VirtualizedFileDiff.js +42 -22
- package/dist/components/VirtualizedFileDiff.js.map +1 -1
- package/dist/components/Virtualizer.d.ts +1 -1
- package/dist/components/Virtualizer.d.ts.map +1 -1
- package/dist/components/Virtualizer.js +3 -5
- package/dist/components/Virtualizer.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/editor/command.d.ts +6 -0
- package/dist/editor/command.d.ts.map +1 -0
- package/dist/editor/command.js +31 -0
- package/dist/editor/command.js.map +1 -0
- package/dist/editor/css.d.ts +6 -0
- package/dist/editor/css.d.ts.map +1 -0
- package/dist/editor/css.js +218 -0
- package/dist/editor/css.js.map +1 -0
- package/dist/editor/editStack.d.ts +66 -0
- package/dist/editor/editStack.d.ts.map +1 -0
- package/dist/editor/editStack.js +218 -0
- package/dist/editor/editStack.js.map +1 -0
- package/dist/editor/editor.d.ts +22 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +1323 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/index.d.ts +3 -0
- package/dist/editor/index.js +4 -0
- package/dist/editor/lineAnnotations.d.ts +8 -0
- package/dist/editor/lineAnnotations.d.ts.map +1 -0
- package/dist/editor/lineAnnotations.js +32 -0
- package/dist/editor/lineAnnotations.js.map +1 -0
- package/dist/editor/pieceTable.d.ts +33 -0
- package/dist/editor/pieceTable.d.ts.map +1 -0
- package/dist/editor/pieceTable.js +590 -0
- package/dist/editor/pieceTable.js.map +1 -0
- package/dist/editor/platform.d.ts +12 -0
- package/dist/editor/platform.d.ts.map +1 -0
- package/dist/editor/platform.js +44 -0
- package/dist/editor/platform.js.map +1 -0
- package/dist/editor/quickEdit.d.ts +29 -0
- package/dist/editor/quickEdit.d.ts.map +1 -0
- package/dist/editor/quickEdit.js +81 -0
- package/dist/editor/quickEdit.js.map +1 -0
- package/dist/editor/searchPanel.d.ts +30 -0
- package/dist/editor/searchPanel.d.ts.map +1 -0
- package/dist/editor/searchPanel.js +219 -0
- package/dist/editor/searchPanel.js.map +1 -0
- package/dist/editor/selection.d.ts +126 -0
- package/dist/editor/selection.d.ts.map +1 -0
- package/dist/editor/selection.js +900 -0
- package/dist/editor/selection.js.map +1 -0
- package/dist/editor/textDocument.d.ts +139 -0
- package/dist/editor/textDocument.d.ts.map +1 -0
- package/dist/editor/textDocument.js +202 -0
- package/dist/editor/textDocument.js.map +1 -0
- package/dist/editor/textMeasure.d.ts +32 -0
- package/dist/editor/textMeasure.d.ts.map +1 -0
- package/dist/editor/textMeasure.js +108 -0
- package/dist/editor/textMeasure.js.map +1 -0
- package/dist/editor/tokenzier.d.ts +37 -0
- package/dist/editor/tokenzier.d.ts.map +1 -0
- package/dist/editor/tokenzier.js +348 -0
- package/dist/editor/tokenzier.js.map +1 -0
- package/dist/editor/utils.d.ts +16 -0
- package/dist/editor/utils.d.ts.map +1 -0
- package/dist/editor/utils.js +37 -0
- package/dist/editor/utils.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react/EditorContext.d.ts +16 -0
- package/dist/react/EditorContext.d.ts.map +1 -0
- package/dist/react/EditorContext.js +26 -0
- package/dist/react/EditorContext.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 +3 -1
- 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 +3 -1
- 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 +3 -1
- 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/index.d.ts +3 -2
- package/dist/react/index.js +2 -1
- package/dist/react/jsx.d.ts +0 -1
- package/dist/react/jsx.d.ts.map +1 -1
- package/dist/react/types.d.ts +1 -0
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/types.js +0 -1
- package/dist/react/utils/useFileDiffInstance.d.ts +3 -1
- package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileDiffInstance.js +31 -5
- package/dist/react/utils/useFileDiffInstance.js.map +1 -1
- package/dist/react/utils/useFileInstance.d.ts +4 -1
- package/dist/react/utils/useFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useFileInstance.js +30 -5
- package/dist/react/utils/useFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +2 -2
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +9 -5
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/FileRenderer.d.ts +5 -1
- package/dist/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/renderers/FileRenderer.js +108 -41
- package/dist/renderers/FileRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/style.js +1 -1
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +45 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cleanLastNewline.js +6 -1
- package/dist/utils/cleanLastNewline.js.map +1 -1
- package/dist/utils/computeEstimatedDiffHeights.js +20 -9
- package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
- package/dist/utils/computeFileOffsets.d.ts +13 -0
- package/dist/utils/computeFileOffsets.d.ts.map +1 -0
- package/dist/utils/computeFileOffsets.js +33 -0
- package/dist/utils/computeFileOffsets.js.map +1 -0
- package/dist/utils/createTransformerWithState.js +9 -0
- package/dist/utils/createTransformerWithState.js.map +1 -1
- package/dist/utils/iterateOverDiff.js +182 -147
- package/dist/utils/iterateOverDiff.js.map +1 -1
- package/dist/utils/renderDiffWithHighlighter.js +1 -1
- package/dist/utils/renderFileWithHighlighter.js +5 -14
- package/dist/utils/renderFileWithHighlighter.js.map +1 -1
- package/dist/utils/virtualDiffLayout.d.ts +2 -23
- package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
- package/dist/utils/virtualDiffLayout.js +1 -41
- package/dist/utils/virtualDiffLayout.js.map +1 -1
- package/dist/worker/WorkerPoolManager.js +1 -1
- package/dist/worker/{wasm-BaDzIkIn.js → wasm-D4DU5jgR.js} +2 -2
- package/dist/worker/wasm-D4DU5jgR.js.map +1 -0
- package/dist/worker/worker-portable.js +349 -363
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js +222 -243
- package/dist/worker/worker.js.map +1 -1
- package/package.json +9 -1
- package/dist/utils/iterateOverFile.d.ts +0 -50
- package/dist/utils/iterateOverFile.d.ts.map +0 -1
- package/dist/utils/iterateOverFile.js +0 -49
- package/dist/utils/iterateOverFile.js.map +0 -1
- package/dist/worker/wasm-BaDzIkIn.js.map +0 -1
package/dist/worker/worker.js
CHANGED
|
@@ -12,7 +12,6 @@ const DIFFS_DEVELOPMENT_BUILD = (() => {
|
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
14
|
})();
|
|
15
|
-
const SPLIT_WITH_NEWLINES = /(?<=\n)/;
|
|
16
15
|
const DEFAULT_THEMES = {
|
|
17
16
|
dark: "pierre-dark",
|
|
18
17
|
light: "pierre-light"
|
|
@@ -454,7 +453,12 @@ function replaceCustomExtensions(version, map) {
|
|
|
454
453
|
//#endregion
|
|
455
454
|
//#region src/utils/cleanLastNewline.ts
|
|
456
455
|
function cleanLastNewline(contents) {
|
|
457
|
-
|
|
456
|
+
let end = contents.length;
|
|
457
|
+
if (contents.charCodeAt(end - 1) === 10) {
|
|
458
|
+
end--;
|
|
459
|
+
if (contents.charCodeAt(end - 1) === 13) end--;
|
|
460
|
+
}
|
|
461
|
+
return contents.slice(0, end);
|
|
458
462
|
}
|
|
459
463
|
|
|
460
464
|
//#endregion
|
|
@@ -631,6 +635,15 @@ function createTransformerWithState(useTokenTransformer = false, useCSSClasses =
|
|
|
631
635
|
} : null
|
|
632
636
|
}];
|
|
633
637
|
if (useCSSClasses) transformers.push(tokenStyleNormalizer, toClass);
|
|
638
|
+
if (useTokenTransformer) transformers.push({ line: (node) => {
|
|
639
|
+
if (node.type === "element" && node.children.length === 0) node.children.push({
|
|
640
|
+
type: "element",
|
|
641
|
+
tagName: "br",
|
|
642
|
+
properties: {},
|
|
643
|
+
children: []
|
|
644
|
+
});
|
|
645
|
+
return node;
|
|
646
|
+
} });
|
|
634
647
|
return {
|
|
635
648
|
state,
|
|
636
649
|
transformers,
|
|
@@ -741,39 +754,6 @@ function getExpandedRegion({ isPartial, rangeSize, expandedHunks, hunkIndex, col
|
|
|
741
754
|
renderAll
|
|
742
755
|
};
|
|
743
756
|
}
|
|
744
|
-
function getTrailingContextRangeSize({ fileDiff, errorPrefix }) {
|
|
745
|
-
const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
|
|
746
|
-
if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) return 0;
|
|
747
|
-
const additionRemaining = fileDiff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount);
|
|
748
|
-
const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
|
|
749
|
-
if (additionRemaining <= 0 && deletionRemaining <= 0) return 0;
|
|
750
|
-
if (additionRemaining !== deletionRemaining) throw new Error(`${errorPrefix}: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`);
|
|
751
|
-
return Math.min(additionRemaining, deletionRemaining);
|
|
752
|
-
}
|
|
753
|
-
function getTrailingExpandedRegion({ fileDiff, hunkIndex, expandedHunks, collapsedContextThreshold, errorPrefix }) {
|
|
754
|
-
if (hunkIndex !== fileDiff.hunks.length - 1) return;
|
|
755
|
-
const trailingRangeSize = getTrailingContextRangeSize({
|
|
756
|
-
fileDiff,
|
|
757
|
-
errorPrefix
|
|
758
|
-
});
|
|
759
|
-
if (trailingRangeSize <= 0) return;
|
|
760
|
-
if (expandedHunks === true || trailingRangeSize <= collapsedContextThreshold) return {
|
|
761
|
-
fromStart: trailingRangeSize,
|
|
762
|
-
fromEnd: 0,
|
|
763
|
-
rangeSize: trailingRangeSize,
|
|
764
|
-
collapsedLines: 0,
|
|
765
|
-
renderAll: true
|
|
766
|
-
};
|
|
767
|
-
const region = expandedHunks?.get(fileDiff.hunks.length);
|
|
768
|
-
const fromStart = Math.min(Math.max(region?.fromStart ?? 0, 0), trailingRangeSize);
|
|
769
|
-
return {
|
|
770
|
-
fromStart,
|
|
771
|
-
fromEnd: 0,
|
|
772
|
-
rangeSize: trailingRangeSize,
|
|
773
|
-
collapsedLines: trailingRangeSize - fromStart,
|
|
774
|
-
renderAll: fromStart >= trailingRangeSize
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
757
|
|
|
778
758
|
//#endregion
|
|
779
759
|
//#region src/utils/iterateOverDiff.ts
|
|
@@ -786,12 +766,12 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
786
766
|
collapsedContextThreshold
|
|
787
767
|
});
|
|
788
768
|
const state = {
|
|
769
|
+
finalHunk: diff.hunks.at(-1),
|
|
789
770
|
viewportStart: startingLine,
|
|
790
771
|
viewportEnd: startingLine + totalLines,
|
|
791
772
|
isWindowedHighlight: startingLine > 0 || totalLines < Infinity,
|
|
792
773
|
splitCount: iterationStart.splitCount,
|
|
793
774
|
unifiedCount: iterationStart.unifiedCount,
|
|
794
|
-
finalHunkIndex: diff.hunks.length - 1,
|
|
795
775
|
shouldBreak() {
|
|
796
776
|
if (!state.isWindowedHighlight) return false;
|
|
797
777
|
const breakUnified = state.unifiedCount >= startingLine + totalLines;
|
|
@@ -844,24 +824,31 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
844
824
|
hunkIndex,
|
|
845
825
|
collapsedContextThreshold
|
|
846
826
|
});
|
|
847
|
-
const trailingRegion =
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
827
|
+
const trailingRegion = (() => {
|
|
828
|
+
if (hunk !== state.finalHunk || !hasFinalCollapsedHunk(diff)) return;
|
|
829
|
+
const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
|
|
830
|
+
const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
|
|
831
|
+
if (additionRemaining !== deletionRemaining) throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
|
|
832
|
+
const trailingRangeSize = Math.min(additionRemaining, deletionRemaining);
|
|
833
|
+
return getExpandedRegion({
|
|
834
|
+
isPartial: diff.isPartial,
|
|
835
|
+
rangeSize: trailingRangeSize,
|
|
836
|
+
expandedHunks,
|
|
837
|
+
hunkIndex: diff.hunks.length,
|
|
838
|
+
collapsedContextThreshold
|
|
839
|
+
});
|
|
840
|
+
})();
|
|
854
841
|
const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;
|
|
855
842
|
function getTrailingCollapsedAfter(unifiedLineIndex$1, splitLineIndex$1) {
|
|
856
843
|
if (trailingRegion == null || trailingRegion.collapsedLines <= 0 || trailingRegion.fromStart + trailingRegion.fromEnd > 0) return 0;
|
|
857
844
|
if (diffStyle === "unified") return unifiedLineIndex$1 === hunk.unifiedLineStart + hunk.unifiedLineCount - 1 ? trailingRegion.collapsedLines : 0;
|
|
858
845
|
return splitLineIndex$1 === hunk.splitLineStart + hunk.splitLineCount - 1 ? trailingRegion.collapsedLines : 0;
|
|
859
846
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
return
|
|
847
|
+
function getPendingCollapsed() {
|
|
848
|
+
if (leadingRegion.collapsedLines === 0) return 0;
|
|
849
|
+
const value = leadingRegion.collapsedLines;
|
|
850
|
+
leadingRegion.collapsedLines = 0;
|
|
851
|
+
return value;
|
|
865
852
|
}
|
|
866
853
|
if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {
|
|
867
854
|
let unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.rangeSize;
|
|
@@ -870,63 +857,81 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
870
857
|
let additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.rangeSize;
|
|
871
858
|
let deletionLineNumber$1 = hunk.deletionStart - leadingRegion.rangeSize;
|
|
872
859
|
let additionLineNumber$1 = hunk.additionStart - leadingRegion.rangeSize;
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
860
|
+
const [startIndex, endIndex] = getEqualLineIterationRange(state, leadingRegion.fromStart, diffStyle);
|
|
861
|
+
if (startIndex > 0) state.incrementCounts(startIndex, startIndex);
|
|
862
|
+
let index = startIndex;
|
|
863
|
+
while (index < leadingRegion.fromStart) {
|
|
864
|
+
if (index >= endIndex) {
|
|
865
|
+
state.incrementCounts(leadingRegion.fromStart - index, leadingRegion.fromStart - index);
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
if (state.isInWindow(0, 0)) {
|
|
869
|
+
if (state.emit({
|
|
870
|
+
hunkIndex,
|
|
871
|
+
hunk,
|
|
872
|
+
collapsedBefore: 0,
|
|
873
|
+
collapsedAfter: 0,
|
|
874
|
+
type: "context-expanded",
|
|
875
|
+
deletionLine: {
|
|
876
|
+
lineNumber: deletionLineNumber$1 + index,
|
|
877
|
+
lineIndex: deletionLineIndex$1 + index,
|
|
878
|
+
noEOFCR: false,
|
|
879
|
+
unifiedLineIndex: unifiedLineIndex$1 + index,
|
|
880
|
+
splitLineIndex: splitLineIndex$1 + index
|
|
881
|
+
},
|
|
882
|
+
additionLine: {
|
|
883
|
+
unifiedLineIndex: unifiedLineIndex$1 + index,
|
|
884
|
+
splitLineIndex: splitLineIndex$1 + index,
|
|
885
|
+
lineIndex: additionLineIndex$1 + index,
|
|
886
|
+
lineNumber: additionLineNumber$1 + index,
|
|
887
|
+
noEOFCR: false
|
|
888
|
+
}
|
|
889
|
+
})) break hunkIterator;
|
|
890
|
+
} else state.incrementCounts(1, 1);
|
|
891
|
+
index++;
|
|
892
|
+
}
|
|
896
893
|
unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.fromEnd;
|
|
897
894
|
splitLineIndex$1 = hunk.splitLineStart - leadingRegion.fromEnd;
|
|
898
895
|
deletionLineIndex$1 = hunk.deletionLineIndex - leadingRegion.fromEnd;
|
|
899
896
|
additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.fromEnd;
|
|
900
897
|
deletionLineNumber$1 = hunk.deletionStart - leadingRegion.fromEnd;
|
|
901
898
|
additionLineNumber$1 = hunk.additionStart - leadingRegion.fromEnd;
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
899
|
+
const [fromEndStartIndex, fromEndEndIndex] = getEqualLineIterationRange(state, leadingRegion.fromEnd, diffStyle);
|
|
900
|
+
if (fromEndStartIndex > 0) state.incrementCounts(fromEndStartIndex, fromEndStartIndex);
|
|
901
|
+
index = fromEndStartIndex;
|
|
902
|
+
while (index < leadingRegion.fromEnd) {
|
|
903
|
+
if (index >= fromEndEndIndex) {
|
|
904
|
+
state.incrementCounts(leadingRegion.fromEnd - index, leadingRegion.fromEnd - index);
|
|
905
|
+
break;
|
|
906
|
+
}
|
|
907
|
+
if (state.isInWindow(0, 0)) {
|
|
908
|
+
if (state.emit({
|
|
909
|
+
hunkIndex,
|
|
910
|
+
hunk,
|
|
911
|
+
collapsedBefore: getPendingCollapsed(),
|
|
912
|
+
collapsedAfter: 0,
|
|
913
|
+
type: "context-expanded",
|
|
914
|
+
deletionLine: {
|
|
915
|
+
lineNumber: deletionLineNumber$1 + index,
|
|
916
|
+
lineIndex: deletionLineIndex$1 + index,
|
|
917
|
+
noEOFCR: false,
|
|
918
|
+
unifiedLineIndex: unifiedLineIndex$1 + index,
|
|
919
|
+
splitLineIndex: splitLineIndex$1 + index
|
|
920
|
+
},
|
|
921
|
+
additionLine: {
|
|
922
|
+
unifiedLineIndex: unifiedLineIndex$1 + index,
|
|
923
|
+
splitLineIndex: splitLineIndex$1 + index,
|
|
924
|
+
lineIndex: additionLineIndex$1 + index,
|
|
925
|
+
lineNumber: additionLineNumber$1 + index,
|
|
926
|
+
noEOFCR: false
|
|
927
|
+
}
|
|
928
|
+
})) break hunkIterator;
|
|
929
|
+
} else state.incrementCounts(1, 1);
|
|
930
|
+
index++;
|
|
931
|
+
}
|
|
927
932
|
} else {
|
|
928
933
|
state.incrementCounts(expandedLineCount, expandedLineCount);
|
|
929
|
-
|
|
934
|
+
getPendingCollapsed();
|
|
930
935
|
}
|
|
931
936
|
let unifiedLineIndex = hunk.unifiedLineStart;
|
|
932
937
|
let splitLineIndex = hunk.splitLineStart;
|
|
@@ -940,37 +945,45 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
940
945
|
const isLastContent = content === lastContent;
|
|
941
946
|
if (content.type === "context") {
|
|
942
947
|
if (!state.shouldSkip(content.lines, content.lines)) {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
948
|
+
const [startIndex, endIndex] = getEqualLineIterationRange(state, content.lines, diffStyle);
|
|
949
|
+
if (startIndex > 0) state.incrementCounts(startIndex, startIndex);
|
|
950
|
+
let index = startIndex;
|
|
951
|
+
while (index < content.lines) {
|
|
952
|
+
if (index >= endIndex) {
|
|
953
|
+
state.incrementCounts(content.lines - index, content.lines - index);
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
if (state.isInWindow(0, 0)) {
|
|
957
|
+
const isLastLine = isLastContent && index === content.lines - 1;
|
|
958
|
+
const unifiedRowIndex = unifiedLineIndex + index;
|
|
959
|
+
const splitRowIndex = splitLineIndex + index;
|
|
960
|
+
if (state.emit({
|
|
961
|
+
hunkIndex,
|
|
962
|
+
hunk,
|
|
963
|
+
collapsedBefore: getPendingCollapsed(),
|
|
964
|
+
collapsedAfter: getTrailingCollapsedAfter(unifiedRowIndex, splitRowIndex),
|
|
965
|
+
type: "context",
|
|
966
|
+
deletionLine: {
|
|
967
|
+
lineNumber: deletionLineNumber + index,
|
|
968
|
+
lineIndex: deletionLineIndex + index,
|
|
969
|
+
noEOFCR: isLastLine && hunk.noEOFCRDeletions,
|
|
970
|
+
unifiedLineIndex: unifiedRowIndex,
|
|
971
|
+
splitLineIndex: splitRowIndex
|
|
972
|
+
},
|
|
973
|
+
additionLine: {
|
|
974
|
+
unifiedLineIndex: unifiedRowIndex,
|
|
975
|
+
splitLineIndex: splitRowIndex,
|
|
976
|
+
lineIndex: additionLineIndex + index,
|
|
977
|
+
lineNumber: additionLineNumber + index,
|
|
978
|
+
noEOFCR: isLastLine && hunk.noEOFCRAdditions
|
|
979
|
+
}
|
|
980
|
+
})) break hunkIterator;
|
|
981
|
+
} else state.incrementCounts(1, 1);
|
|
982
|
+
index++;
|
|
983
|
+
}
|
|
971
984
|
} else {
|
|
972
985
|
state.incrementCounts(content.lines, content.lines);
|
|
973
|
-
|
|
986
|
+
getPendingCollapsed();
|
|
974
987
|
}
|
|
975
988
|
unifiedLineIndex += content.lines;
|
|
976
989
|
splitLineIndex += content.lines;
|
|
@@ -983,13 +996,12 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
983
996
|
const unifiedCount = content.deletions + content.additions;
|
|
984
997
|
if (!state.shouldSkip(unifiedCount, splitCount)) {
|
|
985
998
|
const iterationRanges = getChangeIterationRanges(state, content, diffStyle);
|
|
986
|
-
if ((iterationRanges[0]?.[0] ?? 0) > 0) consumePendingCollapsed();
|
|
987
999
|
for (const [rangeStart, rangeEnd] of iterationRanges) for (let index = rangeStart; index < rangeEnd; index++) {
|
|
988
1000
|
const collapsedAfter = getTrailingCollapsedAfter(unifiedLineIndex + index, diffStyle === "unified" ? splitLineIndex + (index < content.deletions ? index : index - content.deletions) : splitLineIndex + index);
|
|
989
1001
|
if (state.emit(getChangeLineData({
|
|
990
1002
|
hunkIndex,
|
|
991
1003
|
hunk,
|
|
992
|
-
collapsedBefore:
|
|
1004
|
+
collapsedBefore: getPendingCollapsed(),
|
|
993
1005
|
collapsedAfter,
|
|
994
1006
|
diffStyle,
|
|
995
1007
|
index,
|
|
@@ -1006,7 +1018,7 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
1006
1018
|
}), true)) break hunkIterator;
|
|
1007
1019
|
}
|
|
1008
1020
|
}
|
|
1009
|
-
|
|
1021
|
+
getPendingCollapsed();
|
|
1010
1022
|
state.incrementCounts(unifiedCount, splitCount);
|
|
1011
1023
|
unifiedLineIndex += unifiedCount;
|
|
1012
1024
|
splitLineIndex += splitCount;
|
|
@@ -1019,30 +1031,41 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
|
|
|
1019
1031
|
if (trailingRegion != null) {
|
|
1020
1032
|
const { collapsedLines, fromStart, fromEnd } = trailingRegion;
|
|
1021
1033
|
const len = fromStart + fromEnd;
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1034
|
+
const [startIndex, endIndex] = getEqualLineIterationRange(state, len, diffStyle);
|
|
1035
|
+
if (startIndex > 0) state.incrementCounts(startIndex, startIndex);
|
|
1036
|
+
let index = startIndex;
|
|
1037
|
+
while (index < len) {
|
|
1038
|
+
if (state.shouldBreak()) break hunkIterator;
|
|
1039
|
+
if (index >= endIndex) {
|
|
1040
|
+
state.incrementCounts(len - index, len - index);
|
|
1041
|
+
break;
|
|
1042
|
+
}
|
|
1043
|
+
if (state.isInWindow(0, 0)) {
|
|
1044
|
+
const isLastLine = index === len - 1;
|
|
1045
|
+
if (state.emit({
|
|
1046
|
+
hunkIndex: diff.hunks.length,
|
|
1047
|
+
hunk: void 0,
|
|
1048
|
+
collapsedBefore: 0,
|
|
1049
|
+
collapsedAfter: isLastLine ? collapsedLines : 0,
|
|
1050
|
+
type: "context-expanded",
|
|
1051
|
+
deletionLine: {
|
|
1052
|
+
lineNumber: deletionLineNumber + index,
|
|
1053
|
+
lineIndex: deletionLineIndex + index,
|
|
1054
|
+
noEOFCR: false,
|
|
1055
|
+
unifiedLineIndex: unifiedLineIndex + index,
|
|
1056
|
+
splitLineIndex: splitLineIndex + index
|
|
1057
|
+
},
|
|
1058
|
+
additionLine: {
|
|
1059
|
+
unifiedLineIndex: unifiedLineIndex + index,
|
|
1060
|
+
splitLineIndex: splitLineIndex + index,
|
|
1061
|
+
lineIndex: additionLineIndex + index,
|
|
1062
|
+
lineNumber: additionLineNumber + index,
|
|
1063
|
+
noEOFCR: false
|
|
1064
|
+
}
|
|
1065
|
+
})) break hunkIterator;
|
|
1066
|
+
} else state.incrementCounts(1, 1);
|
|
1067
|
+
index++;
|
|
1068
|
+
}
|
|
1046
1069
|
}
|
|
1047
1070
|
}
|
|
1048
1071
|
}
|
|
@@ -1107,14 +1130,15 @@ function getHunkPrefixCounts({ diff, expandedHunks, collapsedContextThreshold })
|
|
|
1107
1130
|
const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;
|
|
1108
1131
|
splitCount += leadingCount + hunk.splitLineCount;
|
|
1109
1132
|
unifiedCount += leadingCount + hunk.unifiedLineCount;
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1133
|
+
if (index === finalHunkIndex && hasFinalCollapsedHunk(diff)) {
|
|
1134
|
+
const trailingRangeSize = getTrailingRangeSize(diff, hunk);
|
|
1135
|
+
const trailingRegion = getExpandedRegion({
|
|
1136
|
+
isPartial: diff.isPartial,
|
|
1137
|
+
rangeSize: trailingRangeSize,
|
|
1138
|
+
expandedHunks,
|
|
1139
|
+
hunkIndex: diff.hunks.length,
|
|
1140
|
+
collapsedContextThreshold
|
|
1141
|
+
});
|
|
1118
1142
|
const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;
|
|
1119
1143
|
splitCount += trailingCount;
|
|
1120
1144
|
unifiedCount += trailingCount;
|
|
@@ -1126,7 +1150,7 @@ function getHunkPrefixCounts({ diff, expandedHunks, collapsedContextThreshold })
|
|
|
1126
1150
|
}
|
|
1127
1151
|
return prefixCounts;
|
|
1128
1152
|
}
|
|
1129
|
-
function
|
|
1153
|
+
function getEqualLineIterationRange(state, count, diffStyle) {
|
|
1130
1154
|
if (!state.isWindowedHighlight || count <= 0) return [0, count];
|
|
1131
1155
|
const ranges = [];
|
|
1132
1156
|
function pushRange(currentCount) {
|
|
@@ -1146,25 +1170,16 @@ function getContextLineIterationBounds(state, count, diffStyle) {
|
|
|
1146
1170
|
}
|
|
1147
1171
|
return [start, end];
|
|
1148
1172
|
}
|
|
1149
|
-
function
|
|
1150
|
-
const
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
state.incrementCounts(count - index, count - index);
|
|
1160
|
-
break;
|
|
1161
|
-
}
|
|
1162
|
-
if (state.isInWindow(0, 0)) {
|
|
1163
|
-
if (callback(index) === true) return true;
|
|
1164
|
-
} else state.incrementCounts(1, 1);
|
|
1165
|
-
index++;
|
|
1166
|
-
}
|
|
1167
|
-
return false;
|
|
1173
|
+
function getTrailingRangeSize(diff, hunk) {
|
|
1174
|
+
const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
|
|
1175
|
+
const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
|
|
1176
|
+
if (additionRemaining !== deletionRemaining) throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
|
|
1177
|
+
return Math.min(additionRemaining, deletionRemaining);
|
|
1178
|
+
}
|
|
1179
|
+
function hasFinalCollapsedHunk(diff) {
|
|
1180
|
+
const lastHunk = diff.hunks.at(-1);
|
|
1181
|
+
if (lastHunk == null || diff.isPartial || diff.additionLines.length === 0 || diff.deletionLines.length === 0) return false;
|
|
1182
|
+
return lastHunk.additionLineIndex + lastHunk.additionCount < diff.additionLines.length || lastHunk.deletionLineIndex + lastHunk.deletionCount < diff.deletionLines.length;
|
|
1168
1183
|
}
|
|
1169
1184
|
function getChangeIterationRanges(state, content, diffStyle) {
|
|
1170
1185
|
if (!state.isWindowedHighlight) return [[0, diffStyle === "unified" ? content.deletions + content.additions : Math.max(content.deletions, content.additions)]];
|
|
@@ -1540,63 +1555,34 @@ function renderTwoFiles({ deletionFile, additionFile, deletionInfo, additionInfo
|
|
|
1540
1555
|
}
|
|
1541
1556
|
|
|
1542
1557
|
//#endregion
|
|
1543
|
-
//#region src/utils/
|
|
1558
|
+
//#region src/utils/computeFileOffsets.ts
|
|
1559
|
+
const LINE_FEED = 10;
|
|
1560
|
+
const CARRIAGE_RETURN = 13;
|
|
1544
1561
|
/**
|
|
1545
|
-
*
|
|
1546
|
-
*
|
|
1547
|
-
* Similar to `iterateOverDiff` but simplified for linear file content.
|
|
1548
|
-
* Supports viewport windowing for virtualization scenarios.
|
|
1549
|
-
*
|
|
1550
|
-
* @param props - Configuration for iteration
|
|
1551
|
-
* @param props.lines - Pre-split array of lines (use splitFileContents() to create from string)
|
|
1552
|
-
* @param props.startingLine - Optional starting line index (0-based, default: 0)
|
|
1553
|
-
* @param props.totalLines - Optional max lines to iterate (default: Infinity)
|
|
1554
|
-
* @param props.callback - Callback invoked for each line in the window.
|
|
1555
|
-
* Return `true` to stop iteration early.
|
|
1556
|
-
*
|
|
1557
|
-
* @example
|
|
1558
|
-
* ```typescript
|
|
1559
|
-
* const lines = splitFileContents('line1\nline2\nline3');
|
|
1560
|
-
* iterateOverFile({
|
|
1561
|
-
* lines,
|
|
1562
|
-
* startingLine: 0,
|
|
1563
|
-
* totalLines: 10,
|
|
1564
|
-
* callback: ({ lineIndex, lineNumber, content, isLastLine }) => {
|
|
1565
|
-
* console.log(`Line ${lineNumber}: ${content}`);
|
|
1566
|
-
* if (content.includes('stop')) return true; // Stop iteration
|
|
1567
|
-
* }
|
|
1568
|
-
* });
|
|
1569
|
-
* ```
|
|
1562
|
+
* Computes line start offsets for a string.
|
|
1570
1563
|
*/
|
|
1571
|
-
function
|
|
1572
|
-
const
|
|
1573
|
-
|
|
1574
|
-
const
|
|
1575
|
-
if (
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
const isLastLine = lineIndex === lastLineIndex;
|
|
1580
|
-
if (callback({
|
|
1581
|
-
lineIndex,
|
|
1582
|
-
lineNumber: lineIndex + 1,
|
|
1583
|
-
content: lines[lineIndex],
|
|
1584
|
-
isLastLine
|
|
1585
|
-
}) === true || isLastLine) break;
|
|
1564
|
+
function computeLineOffsets(contents) {
|
|
1565
|
+
const offsets = [0];
|
|
1566
|
+
for (let i = 0; i < contents.length; i++) {
|
|
1567
|
+
const char = contents.charCodeAt(i);
|
|
1568
|
+
if (char === LINE_FEED || char === CARRIAGE_RETURN) {
|
|
1569
|
+
if (char === CARRIAGE_RETURN && i + 1 < contents.length && contents.charCodeAt(i + 1) === LINE_FEED) i++;
|
|
1570
|
+
offsets.push(i + 1);
|
|
1571
|
+
}
|
|
1586
1572
|
}
|
|
1573
|
+
return offsets;
|
|
1587
1574
|
}
|
|
1588
|
-
|
|
1589
|
-
//#endregion
|
|
1590
|
-
//#region src/utils/splitFileContents.ts
|
|
1591
1575
|
/**
|
|
1592
|
-
* Splits file contents into lines
|
|
1593
|
-
*
|
|
1594
|
-
*
|
|
1595
|
-
* @param contents - The raw file contents string
|
|
1596
|
-
* @returns Array of lines with newlines preserved
|
|
1576
|
+
* Splits file contents into lines aligned with {@link computeLineOffsets}.
|
|
1577
|
+
* Unlike splitFileContents, a trailing newline produces a final empty line.
|
|
1597
1578
|
*/
|
|
1598
|
-
function
|
|
1599
|
-
|
|
1579
|
+
function linesFromFileContents(contents) {
|
|
1580
|
+
const offsets = computeLineOffsets(contents);
|
|
1581
|
+
return Array.from({ length: offsets.length }, (_, i) => {
|
|
1582
|
+
const start = offsets[i];
|
|
1583
|
+
const end = offsets[i + 1] ?? contents.length;
|
|
1584
|
+
return contents.slice(start, end);
|
|
1585
|
+
});
|
|
1600
1586
|
}
|
|
1601
1587
|
|
|
1602
1588
|
//#endregion
|
|
@@ -1641,7 +1627,7 @@ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES
|
|
|
1641
1627
|
tokenizeMaxLineLength
|
|
1642
1628
|
};
|
|
1643
1629
|
})();
|
|
1644
|
-
const highlightedLines = getLineNodes(highlighter$1.codeToHast(isWindowedHighlight ? extractWindowedFileContent(lines ??
|
|
1630
|
+
const highlightedLines = getLineNodes(highlighter$1.codeToHast(isWindowedHighlight ? extractWindowedFileContent(lines ?? linesFromFileContents(file.contents), startingLine, totalLines) : file.contents, hastConfig));
|
|
1645
1631
|
const code = isWindowedHighlight ? new Array(startingLine) : highlightedLines;
|
|
1646
1632
|
if (isWindowedHighlight) code.push(...highlightedLines);
|
|
1647
1633
|
return {
|
|
@@ -1651,16 +1637,9 @@ function renderFileWithHighlighter(file, highlighter$1, { theme = DEFAULT_THEMES
|
|
|
1651
1637
|
};
|
|
1652
1638
|
}
|
|
1653
1639
|
function extractWindowedFileContent(lines, startingLine, totalLines) {
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
startingLine,
|
|
1658
|
-
totalLines,
|
|
1659
|
-
callback({ content }) {
|
|
1660
|
-
windowContent += content;
|
|
1661
|
-
}
|
|
1662
|
-
});
|
|
1663
|
-
return windowContent;
|
|
1640
|
+
if (lines.length === 0) return "";
|
|
1641
|
+
const endLine = Math.min(startingLine + totalLines, lines.length);
|
|
1642
|
+
return lines.slice(startingLine, endLine).join("");
|
|
1664
1643
|
}
|
|
1665
1644
|
|
|
1666
1645
|
//#endregion
|