@pierre/diffs 1.0.7 → 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 (128) 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 +220 -79
  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 +8 -4
  12. package/dist/components/FileStream.js.map +1 -1
  13. package/dist/constants.d.ts +8 -2
  14. package/dist/constants.d.ts.map +1 -1
  15. package/dist/constants.js +10 -1
  16. package/dist/constants.js.map +1 -1
  17. package/dist/index.d.ts +19 -10
  18. package/dist/index.js +14 -5
  19. package/dist/managers/LineSelectionManager.d.ts.map +1 -1
  20. package/dist/managers/LineSelectionManager.js +8 -9
  21. package/dist/managers/LineSelectionManager.js.map +1 -1
  22. package/dist/react/MultiFileDiff.js +2 -2
  23. package/dist/react/MultiFileDiff.js.map +1 -1
  24. package/dist/react/index.d.ts +2 -2
  25. package/dist/react/utils/renderDiffChildren.d.ts +4 -4
  26. package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
  27. package/dist/react/utils/renderDiffChildren.js +3 -3
  28. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  29. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  30. package/dist/renderers/DiffHunksRenderer.d.ts +7 -6
  31. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  32. package/dist/renderers/DiffHunksRenderer.js +263 -337
  33. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  34. package/dist/renderers/FileRenderer.d.ts +1 -0
  35. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  36. package/dist/renderers/FileRenderer.js +11 -4
  37. package/dist/renderers/FileRenderer.js.map +1 -1
  38. package/dist/ssr/index.d.ts +2 -2
  39. package/dist/style.js +1 -1
  40. package/dist/style.js.map +1 -1
  41. package/dist/types.d.ts +246 -42
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/utils/areDiffLineAnnotationsEqual.d.ts +7 -0
  44. package/dist/utils/areDiffLineAnnotationsEqual.d.ts.map +1 -0
  45. package/dist/utils/areDiffLineAnnotationsEqual.js +8 -0
  46. package/dist/utils/areDiffLineAnnotationsEqual.js.map +1 -0
  47. package/dist/utils/areHunkDataEqual.d.ts +7 -0
  48. package/dist/utils/areHunkDataEqual.d.ts.map +1 -0
  49. package/dist/utils/areHunkDataEqual.js +8 -0
  50. package/dist/utils/areHunkDataEqual.js.map +1 -0
  51. package/dist/utils/areLineAnnotationsEqual.d.ts +7 -0
  52. package/dist/utils/areLineAnnotationsEqual.d.ts.map +1 -0
  53. package/dist/utils/areLineAnnotationsEqual.js +8 -0
  54. package/dist/utils/areLineAnnotationsEqual.js.map +1 -0
  55. package/dist/utils/arePrePropertiesEqual.d.ts +7 -0
  56. package/dist/utils/arePrePropertiesEqual.d.ts.map +1 -0
  57. package/dist/utils/arePrePropertiesEqual.js +9 -0
  58. package/dist/utils/arePrePropertiesEqual.js.map +1 -0
  59. package/dist/utils/areRenderRangesEqual.d.ts +7 -0
  60. package/dist/utils/areRenderRangesEqual.d.ts.map +1 -0
  61. package/dist/utils/areRenderRangesEqual.js +9 -0
  62. package/dist/utils/areRenderRangesEqual.js.map +1 -0
  63. package/dist/utils/areVirtualWindowSpecsEqual.d.ts +7 -0
  64. package/dist/utils/areVirtualWindowSpecsEqual.d.ts.map +1 -0
  65. package/dist/utils/areVirtualWindowSpecsEqual.js +9 -0
  66. package/dist/utils/areVirtualWindowSpecsEqual.js.map +1 -0
  67. package/dist/utils/areWorkerStatsEqual.d.ts +8 -0
  68. package/dist/utils/areWorkerStatsEqual.d.ts.map +1 -0
  69. package/dist/utils/areWorkerStatsEqual.js +9 -0
  70. package/dist/utils/areWorkerStatsEqual.js.map +1 -0
  71. package/dist/utils/createTransformerWithState.js +1 -1
  72. package/dist/utils/createTransformerWithState.js.map +1 -1
  73. package/dist/utils/createWindowFromScrollPosition.d.ts +22 -0
  74. package/dist/utils/createWindowFromScrollPosition.d.ts.map +1 -0
  75. package/dist/utils/createWindowFromScrollPosition.js +26 -0
  76. package/dist/utils/createWindowFromScrollPosition.js.map +1 -0
  77. package/dist/utils/diffAcceptRejectHunk.js +36 -21
  78. package/dist/utils/diffAcceptRejectHunk.js.map +1 -1
  79. package/dist/utils/getOrCreateCodeNode.d.ts +14 -0
  80. package/dist/utils/getOrCreateCodeNode.d.ts.map +1 -0
  81. package/dist/utils/getOrCreateCodeNode.js +13 -0
  82. package/dist/utils/getOrCreateCodeNode.js.map +1 -0
  83. package/dist/utils/getTotalLineCountFromHunks.js +1 -1
  84. package/dist/utils/getTotalLineCountFromHunks.js.map +1 -1
  85. package/dist/utils/hast_utils.d.ts +2 -1
  86. package/dist/utils/hast_utils.d.ts.map +1 -1
  87. package/dist/utils/hast_utils.js +10 -1
  88. package/dist/utils/hast_utils.js.map +1 -1
  89. package/dist/utils/isDefaultRenderRange.d.ts +7 -0
  90. package/dist/utils/isDefaultRenderRange.d.ts.map +1 -0
  91. package/dist/utils/isDefaultRenderRange.js +8 -0
  92. package/dist/utils/isDefaultRenderRange.js.map +1 -0
  93. package/dist/utils/iterateOverDiff.d.ts +39 -0
  94. package/dist/utils/iterateOverDiff.d.ts.map +1 -0
  95. package/dist/utils/iterateOverDiff.js +356 -0
  96. package/dist/utils/iterateOverDiff.js.map +1 -0
  97. package/dist/utils/parseDiffFromFile.d.ts.map +1 -1
  98. package/dist/utils/parseDiffFromFile.js +8 -6
  99. package/dist/utils/parseDiffFromFile.js.map +1 -1
  100. package/dist/utils/parsePatchFiles.d.ts +15 -3
  101. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  102. package/dist/utils/parsePatchFiles.js +207 -158
  103. package/dist/utils/parsePatchFiles.js.map +1 -1
  104. package/dist/utils/processLine.js +4 -3
  105. package/dist/utils/processLine.js.map +1 -1
  106. package/dist/utils/renderDiffWithHighlighter.d.ts +7 -2
  107. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  108. package/dist/utils/renderDiffWithHighlighter.js +149 -227
  109. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  110. package/dist/utils/setWrapperNodeProps.d.ts +3 -7
  111. package/dist/utils/setWrapperNodeProps.d.ts.map +1 -1
  112. package/dist/utils/setWrapperNodeProps.js +1 -1
  113. package/dist/utils/setWrapperNodeProps.js.map +1 -1
  114. package/dist/worker/WorkerPoolManager.d.ts +9 -2
  115. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  116. package/dist/worker/WorkerPoolManager.js +124 -45
  117. package/dist/worker/WorkerPoolManager.js.map +1 -1
  118. package/dist/worker/types.d.ts +7 -0
  119. package/dist/worker/types.d.ts.map +1 -1
  120. package/dist/worker/worker-portable.js +634 -242
  121. package/dist/worker/worker-portable.js.map +1 -1
  122. package/dist/worker/worker.js +511 -231
  123. package/dist/worker/worker.js.map +1 -1
  124. package/package.json +20 -1
  125. package/dist/utils/createCodeNode.d.ts +0 -12
  126. package/dist/utils/createCodeNode.d.ts.map +0 -1
  127. package/dist/utils/createCodeNode.js +0 -12
  128. package/dist/utils/createCodeNode.js.map +0 -1
@@ -1,29 +1,36 @@
1
- import { DEFAULT_THEMES } from "../constants.js";
1
+ import { DEFAULT_EXPANDED_REGION, DEFAULT_THEMES } from "../constants.js";
2
2
  import { areLanguagesAttached } from "../highlighter/languages/areLanguagesAttached.js";
3
3
  import { getHighlighterIfLoaded, getSharedHighlighter } from "../highlighter/shared_highlighter.js";
4
4
  import { areThemesAttached } from "../highlighter/themes/areThemesAttached.js";
5
5
  import { areThemesEqual } from "../utils/areThemesEqual.js";
6
- import { createHastElement } from "../utils/hast_utils.js";
6
+ import { createBufferElement, createHastElement } from "../utils/hast_utils.js";
7
7
  import { createAnnotationElement } from "../utils/createAnnotationElement.js";
8
8
  import { createFileHeaderElement } from "../utils/createFileHeaderElement.js";
9
9
  import { createPreElement } from "../utils/createPreElement.js";
10
10
  import { getFiletypeFromFileName } from "../utils/getFiletypeFromFileName.js";
11
11
  import { getHighlighterOptions } from "../utils/getHighlighterOptions.js";
12
12
  import { getLineAnnotationName } from "../utils/getLineAnnotationName.js";
13
+ import { areRenderRangesEqual } from "../utils/areRenderRangesEqual.js";
13
14
  import { createEmptyRowBuffer } from "../utils/createEmptyRowBuffer.js";
14
15
  import { createNoNewlineElement } from "../utils/createNoNewlineElement.js";
15
16
  import { createSeparator } from "../utils/createSeparator.js";
16
17
  import { getHunkSeparatorSlotName } from "../utils/getHunkSeparatorSlotName.js";
17
18
  import { getTotalLineCountFromHunks } from "../utils/getTotalLineCountFromHunks.js";
19
+ import { isDefaultRenderRange } from "../utils/isDefaultRenderRange.js";
20
+ import { iterateOverDiff } from "../utils/iterateOverDiff.js";
18
21
  import { renderDiffWithHighlighter } from "../utils/renderDiffWithHighlighter.js";
19
22
  import { toHtml } from "hast-util-to-html";
20
23
 
21
24
  //#region src/renderers/DiffHunksRenderer.ts
22
- const EXPANDED_REGION = {
23
- fromStart: 0,
24
- fromEnd: 0
25
+ const DEFAULT_RENDER_RANGE = {
26
+ startingLine: 0,
27
+ totalLines: Infinity,
28
+ bufferBefore: 0,
29
+ bufferAfter: 0
25
30
  };
31
+ let instanceId = -1;
26
32
  var DiffHunksRenderer = class {
33
+ __id = `diff-hunks-renderer:${++instanceId}`;
27
34
  highlighter;
28
35
  diff;
29
36
  expandedHunks = /* @__PURE__ */ new Map();
@@ -41,9 +48,16 @@ var DiffHunksRenderer = class {
41
48
  this.highlighter = void 0;
42
49
  this.diff = void 0;
43
50
  this.renderCache = void 0;
51
+ this.workerManager?.cleanUpPendingTasks(this);
44
52
  this.workerManager = void 0;
45
53
  this.onRenderUpdate = void 0;
46
54
  }
55
+ recycle() {
56
+ this.highlighter = void 0;
57
+ this.diff = void 0;
58
+ this.renderCache = void 0;
59
+ this.workerManager?.cleanUpPendingTasks(this);
60
+ }
47
61
  setOptions(options) {
48
62
  this.options = options;
49
63
  }
@@ -59,14 +73,20 @@ var DiffHunksRenderer = class {
59
73
  }
60
74
  expandHunk(index, direction) {
61
75
  const { expansionLineCount } = this.getOptionsWithDefaults();
62
- const region = this.expandedHunks.get(index) ?? {
76
+ const region = { ...this.expandedHunks.get(index) ?? {
63
77
  fromStart: 0,
64
78
  fromEnd: 0
65
- };
79
+ } };
66
80
  if (direction === "up" || direction === "both") region.fromStart += expansionLineCount;
67
81
  if (direction === "down" || direction === "both") region.fromEnd += expansionLineCount;
68
82
  this.expandedHunks.set(index, region);
69
83
  }
84
+ getExpandedHunk(hunkIndex) {
85
+ return this.expandedHunks.get(hunkIndex) ?? DEFAULT_EXPANDED_REGION;
86
+ }
87
+ getExpandedHunksMap() {
88
+ return this.expandedHunks;
89
+ }
70
90
  setLineAnnotations(lineAnnotations) {
71
91
  this.additionAnnotations = {};
72
92
  this.deletionAnnotations = {};
@@ -83,13 +103,14 @@ var DiffHunksRenderer = class {
83
103
  }
84
104
  }
85
105
  getOptionsWithDefaults() {
86
- const { diffIndicators = "bars", diffStyle = "split", disableBackground = false, disableFileHeader = false, disableLineNumbers = false, expandUnchanged = false, expansionLineCount = 100, hunkSeparators = "line-info", lineDiffType = "word-alt", maxLineDiffLength = 1e3, overflow = "scroll", theme = DEFAULT_THEMES, themeType = "system", tokenizeMaxLineLength = 1e3, useCSSClasses = false } = this.options;
106
+ const { diffIndicators = "bars", diffStyle = "split", disableBackground = false, disableFileHeader = false, disableLineNumbers = false, disableVirtualizationBuffers = false, expandUnchanged = false, expansionLineCount = 100, hunkSeparators = "line-info", lineDiffType = "word-alt", maxLineDiffLength = 1e3, overflow = "scroll", theme = DEFAULT_THEMES, themeType = "system", tokenizeMaxLineLength = 1e3, useCSSClasses = false } = this.options;
87
107
  return {
88
108
  diffIndicators,
89
109
  diffStyle,
90
110
  disableBackground,
91
111
  disableFileHeader,
92
112
  disableLineNumbers,
113
+ disableVirtualizationBuffers,
93
114
  expandUnchanged,
94
115
  expansionLineCount,
95
116
  hunkSeparators,
@@ -116,7 +137,8 @@ var DiffHunksRenderer = class {
116
137
  diff,
117
138
  highlighted: true,
118
139
  options,
119
- result: cache?.result
140
+ result: cache?.result,
141
+ renderRange: void 0
120
142
  };
121
143
  if (this.workerManager?.isWorkingPool() === true && this.renderCache.result == null) this.workerManager.highlightDiffAST(this, this.diff);
122
144
  else this.asyncHighlight(diff).then(({ result, options: options$1 }) => {
@@ -148,12 +170,14 @@ var DiffHunksRenderer = class {
148
170
  forceRender: false
149
171
  };
150
172
  }
151
- renderDiff(diff = this.renderCache?.diff) {
173
+ renderDiff(diff = this.renderCache?.diff, renderRange = DEFAULT_RENDER_RANGE) {
152
174
  if (diff == null) return;
175
+ const { expandUnchanged = false } = this.options;
153
176
  const cache = this.workerManager?.getDiffResultCache(diff);
154
177
  if (cache != null && this.renderCache == null) this.renderCache = {
155
178
  diff,
156
179
  highlighted: true,
180
+ renderRange: void 0,
157
181
  ...cache
158
182
  };
159
183
  const { options, forceRender } = this.getRenderOptions(diff);
@@ -161,11 +185,15 @@ var DiffHunksRenderer = class {
161
185
  diff,
162
186
  highlighted: false,
163
187
  options,
164
- result: void 0
188
+ result: void 0,
189
+ renderRange: void 0
165
190
  };
166
191
  if (this.workerManager?.isWorkingPool() === true) {
167
- this.renderCache.result ??= this.workerManager.getPlainDiffAST(diff);
168
- if (!this.renderCache.highlighted || forceRender) this.workerManager.highlightDiffAST(this, diff);
192
+ if (this.renderCache.result == null || !this.renderCache.highlighted && !areRenderRangesEqual(this.renderCache.renderRange, renderRange)) {
193
+ this.renderCache.result = this.workerManager.getPlainDiffAST(diff, renderRange.startingLine, renderRange.totalLines, isDefaultRenderRange(renderRange) ? true : expandUnchanged ? true : this.expandedHunks);
194
+ this.renderCache.renderRange = renderRange;
195
+ }
196
+ if (renderRange.totalLines > 0 && (!this.renderCache.highlighted || forceRender)) this.workerManager.highlightDiffAST(this, diff);
169
197
  } else {
170
198
  this.computedLang = diff.lang ?? getFiletypeFromFileName(diff.name);
171
199
  const hasThemes = this.highlighter != null && areThemesAttached(options.theme);
@@ -176,18 +204,19 @@ var DiffHunksRenderer = class {
176
204
  diff,
177
205
  options: options$1,
178
206
  highlighted: hasLangs,
179
- result
207
+ result,
208
+ renderRange: void 0
180
209
  };
181
210
  }
182
211
  if (!hasThemes || !hasLangs) this.asyncHighlight(diff).then(({ result, options: options$1 }) => {
183
212
  this.onHighlightSuccess(diff, result, options$1);
184
213
  });
185
214
  }
186
- return this.renderCache.result != null ? this.processDiffResult(this.renderCache.diff, this.renderCache.result) : void 0;
215
+ return this.renderCache.result != null ? this.processDiffResult(this.renderCache.diff, renderRange, this.renderCache.result) : void 0;
187
216
  }
188
- async asyncRender(diff) {
217
+ async asyncRender(diff, renderRange = DEFAULT_RENDER_RANGE) {
189
218
  const { result } = await this.asyncHighlight(diff);
190
- return this.processDiffResult(diff, result);
219
+ return this.processDiffResult(diff, renderRange, result);
191
220
  }
192
221
  createPreElement(split, totalLines, themeStyles, baseThemeType) {
193
222
  const { diffIndicators, disableBackground, disableLineNumbers, overflow, themeType } = this.getOptionsWithDefaults();
@@ -209,10 +238,13 @@ var DiffHunksRenderer = class {
209
238
  if (this.highlighter == null || !hasThemes || !hasLangs) this.highlighter = await this.initializeHighlighter();
210
239
  return this.renderDiffWithHighlighter(diff, this.highlighter);
211
240
  }
212
- renderDiffWithHighlighter(diff, highlighter, plainText = false) {
241
+ renderDiffWithHighlighter(diff, highlighter, forcePlainText = false) {
213
242
  const { options } = this.getRenderOptions(diff);
214
243
  return {
215
- result: renderDiffWithHighlighter(diff, highlighter, options, plainText),
244
+ result: renderDiffWithHighlighter(diff, highlighter, options, {
245
+ forcePlainText,
246
+ expandedHunks: forcePlainText ? true : void 0
247
+ }),
216
248
  options
217
249
  };
218
250
  }
@@ -223,45 +255,172 @@ var DiffHunksRenderer = class {
223
255
  diff,
224
256
  options,
225
257
  highlighted: true,
226
- result
258
+ result,
259
+ renderRange: void 0
227
260
  };
228
261
  if (triggerRenderUpdate) this.onRenderUpdate?.();
229
262
  }
230
263
  onHighlightError(error) {
231
264
  console.error(error);
232
265
  }
233
- processDiffResult(fileDiff, { code, themeStyles, baseThemeType }) {
234
- const { diffStyle, disableFileHeader } = this.getOptionsWithDefaults();
266
+ processDiffResult(fileDiff, renderRange, { code, themeStyles, baseThemeType }) {
267
+ const { diffStyle, disableFileHeader, disableVirtualizationBuffers, expandUnchanged, expansionLineCount, hunkSeparators } = this.getOptionsWithDefaults();
235
268
  this.diff = fileDiff;
236
269
  const unified = diffStyle === "unified";
237
270
  let additionsAST = [];
238
271
  let deletionsAST = [];
239
272
  let unifiedAST = [];
240
- let hunkIndex = 0;
241
273
  const hunkData = [];
242
- let prevHunk;
243
- let lineIndex = 0;
244
- for (const hunk of fileDiff.hunks) {
245
- lineIndex += hunk.collapsedBefore;
246
- lineIndex = this.renderHunks({
247
- ast: code,
248
- hunk,
249
- prevHunk,
250
- hunkIndex,
251
- isLastHunk: hunkIndex === fileDiff.hunks.length - 1,
252
- additionsAST,
253
- deletionsAST,
254
- unifiedAST,
255
- hunkData,
256
- lineIndex
257
- });
258
- hunkIndex++;
259
- prevHunk = hunk;
274
+ const { additionLines, deletionLines } = code;
275
+ const separatorContext = {
276
+ hunkSeparators,
277
+ additionsAST,
278
+ deletionsAST,
279
+ unifiedAST,
280
+ expansionLineCount,
281
+ hunkData
282
+ };
283
+ const trailingRangeSize = (() => {
284
+ const lastHunk = fileDiff.hunks.at(-1);
285
+ if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) return 0;
286
+ const additionRemaining = fileDiff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount);
287
+ const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
288
+ if (additionRemaining !== deletionRemaining) throw new Error(`DiffHunksRenderer.processDiffResult: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`);
289
+ return Math.min(additionRemaining, deletionRemaining);
290
+ })();
291
+ let pendingSplitSpanSize = 0;
292
+ let pendingSplitMissing;
293
+ let lastHunkIndex;
294
+ function flushSplitSpan() {
295
+ if (pendingSplitSpanSize <= 0 || pendingSplitMissing == null) {
296
+ pendingSplitSpanSize = 0;
297
+ pendingSplitMissing = void 0;
298
+ return;
299
+ }
300
+ if (pendingSplitMissing === "additions") additionsAST?.push(createEmptyRowBuffer(pendingSplitSpanSize));
301
+ else deletionsAST?.push(createEmptyRowBuffer(pendingSplitSpanSize));
302
+ pendingSplitSpanSize = 0;
303
+ pendingSplitMissing = void 0;
304
+ }
305
+ function pushSeparators(props) {
306
+ flushSplitSpan();
307
+ if (diffStyle === "unified") pushSeparator("unified", props, separatorContext);
308
+ else {
309
+ pushSeparator("deletions", props, separatorContext);
310
+ pushSeparator("additions", props, separatorContext);
311
+ }
312
+ }
313
+ iterateOverDiff({
314
+ diff: fileDiff,
315
+ diffStyle,
316
+ startingLine: renderRange.startingLine,
317
+ totalLines: renderRange.totalLines,
318
+ expandedHunks: expandUnchanged ? true : this.expandedHunks,
319
+ callback: ({ hunkIndex, hunk, collapsedBefore, collapsedAfter, unifiedDeletionLineIndex, unifiedAdditionLineIndex, splitLineIndex, additionLineIndex, deletionLineIndex, additionLineNumber, deletionLineNumber, type, noEOFCRAddition, noEOFCRDeletion }) => {
320
+ if (diffStyle === "split") {
321
+ if (lastHunkIndex != null && lastHunkIndex !== hunkIndex) flushSplitSpan();
322
+ if (type !== "change") flushSplitSpan();
323
+ }
324
+ lastHunkIndex = hunkIndex;
325
+ if (collapsedBefore > 0) pushSeparators({
326
+ hunkIndex,
327
+ collapsedLines: collapsedBefore,
328
+ rangeSize: Math.max(hunk?.collapsedBefore ?? 0, 0),
329
+ hunkSpecs: hunk?.hunkSpecs,
330
+ isFirstHunk: hunkIndex === 0,
331
+ isLastHunk: false,
332
+ isExpandable: !fileDiff.isPartial
333
+ });
334
+ const lineIndex = diffStyle === "unified" ? unifiedDeletionLineIndex ?? unifiedAdditionLineIndex : splitLineIndex;
335
+ if (lineIndex == null) {
336
+ const errorMessage = "DiffHunksRenderer.processDiffResult: iterateOverDiff, no valid line index";
337
+ console.error(errorMessage, { file: fileDiff.name });
338
+ throw new Error(errorMessage);
339
+ }
340
+ if (diffStyle === "unified") {
341
+ const deletionLine = additionLineIndex != null ? void 0 : deletionLineIndex != null ? deletionLines[deletionLineIndex] : void 0;
342
+ const additionLine = additionLineIndex != null ? additionLines[additionLineIndex] : void 0;
343
+ if (deletionLine == null && additionLine == null) {
344
+ const errorMessage = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
345
+ console.error(errorMessage, { file: fileDiff.name });
346
+ throw new Error(errorMessage);
347
+ }
348
+ pushLineWithAnnotation({
349
+ deletionLine,
350
+ additionLine,
351
+ unifiedAST,
352
+ unifiedSpan: this.getAnnotations("unified", deletionLineNumber, additionLineNumber, hunkIndex, lineIndex)
353
+ });
354
+ } else {
355
+ const deletionLine = deletionLineIndex != null ? deletionLines[deletionLineIndex] : void 0;
356
+ const additionLine = additionLineIndex != null ? additionLines[additionLineIndex] : void 0;
357
+ if (deletionLine == null && additionLine == null) {
358
+ const errorMessage = "DiffHunksRenderer.processDiffResult: deletionLine and additionLine are null, something is wrong";
359
+ console.error(errorMessage, { file: fileDiff.name });
360
+ throw new Error(errorMessage);
361
+ }
362
+ const missingSide = deletionLine == null ? "deletions" : additionLine == null ? "additions" : void 0;
363
+ if (missingSide != null) {
364
+ if (pendingSplitMissing != null && pendingSplitMissing !== missingSide) throw new Error("DiffHunksRenderer.processDiffResult: iterateOverDiff, invalid pending splits");
365
+ pendingSplitMissing = missingSide;
366
+ pendingSplitSpanSize++;
367
+ }
368
+ const annotationSpans = this.getAnnotations("split", deletionLineNumber, additionLineNumber, hunkIndex, lineIndex);
369
+ if (annotationSpans != null && pendingSplitSpanSize > 0) flushSplitSpan();
370
+ pushLineWithAnnotation({
371
+ additionLine,
372
+ deletionLine,
373
+ deletionsAST,
374
+ additionsAST,
375
+ ...annotationSpans
376
+ });
377
+ }
378
+ if (noEOFCRDeletion || noEOFCRAddition) {
379
+ const noEOFType = type === "context" || type === "context-expanded" ? "context" : deletionLineIndex != null ? "change-deletion" : "change-addition";
380
+ if (noEOFCRDeletion) if (diffStyle === "unified") unifiedAST?.push(createNoNewlineElement(noEOFType));
381
+ else {
382
+ deletionsAST?.push(createNoNewlineElement("change-deletion"));
383
+ if (!noEOFCRAddition) additionsAST?.push(createEmptyRowBuffer(1));
384
+ }
385
+ if (noEOFCRAddition) if (diffStyle === "unified") unifiedAST?.push(createNoNewlineElement("change-addition"));
386
+ else {
387
+ additionsAST?.push(createNoNewlineElement("change-addition"));
388
+ if (!noEOFCRDeletion) deletionsAST?.push(createEmptyRowBuffer(1));
389
+ }
390
+ }
391
+ if (collapsedAfter > 0) pushSeparators({
392
+ hunkIndex: type === "context-expanded" ? hunkIndex : hunkIndex + 1,
393
+ collapsedLines: collapsedAfter,
394
+ rangeSize: trailingRangeSize,
395
+ hunkSpecs: void 0,
396
+ isFirstHunk: false,
397
+ isLastHunk: true,
398
+ isExpandable: !fileDiff.isPartial
399
+ });
400
+ }
401
+ });
402
+ if (diffStyle === "split") flushSplitSpan();
403
+ const totalLines = Math.max(getTotalLineCountFromHunks(fileDiff.hunks), fileDiff.additionLines.length ?? 0, fileDiff.deletionLines.length ?? 0);
404
+ additionsAST = !unified && fileDiff.type !== "deleted" ? additionsAST : void 0;
405
+ deletionsAST = !unified && fileDiff.type !== "new" ? deletionsAST : void 0;
406
+ unifiedAST = unified ? unifiedAST : void 0;
407
+ if (!disableVirtualizationBuffers) {
408
+ if (renderRange.bufferBefore > 0) {
409
+ const element = createBufferElement("before", renderRange.bufferBefore);
410
+ unifiedAST?.unshift(element);
411
+ deletionsAST?.unshift(element);
412
+ additionsAST?.unshift(element);
413
+ }
414
+ if (renderRange.bufferAfter > 0) {
415
+ const element = createBufferElement("after", renderRange.bufferAfter);
416
+ unifiedAST?.push(element);
417
+ deletionsAST?.push(element);
418
+ additionsAST?.push(element);
419
+ }
260
420
  }
261
- const totalLines = Math.max(getTotalLineCountFromHunks(fileDiff.hunks), fileDiff.newLines?.length ?? 0, fileDiff.oldLines?.length ?? 0);
262
- additionsAST = !unified && (code.hunks != null || code.newLines.length > 0) ? additionsAST : void 0;
263
- deletionsAST = !unified && (code.hunks != null || code.oldLines.length > 0) ? deletionsAST : void 0;
264
- unifiedAST = unifiedAST.length > 0 ? unifiedAST : void 0;
421
+ if (unifiedAST?.length === 0) unifiedAST = void 0;
422
+ if (deletionsAST?.length === 0) deletionsAST = void 0;
423
+ if (additionsAST?.length === 0) additionsAST = void 0;
265
424
  const preNode = this.createPreElement(deletionsAST != null && additionsAST != null, totalLines, themeStyles, baseThemeType);
266
425
  return {
267
426
  additionsAST,
@@ -320,310 +479,21 @@ var DiffHunksRenderer = class {
320
479
  }
321
480
  }));
322
481
  }
323
- renderCollapsedHunks({ ast, hunkData, hunkIndex, hunkSpecs, isFirstHunk, isLastHunk, rangeSize, lineIndex, additionLineNumber, deletionLineNumber, unifiedAST, deletionsAST, additionsAST }) {
324
- if (rangeSize <= 0) return;
325
- const { hunkSeparators, expandUnchanged, diffStyle, expansionLineCount } = this.getOptionsWithDefaults();
326
- const expandable = ast.hunks == null && ast.newLines.length > 0 && ast.oldLines.length > 0;
327
- const expandedRegion = this.expandedHunks.get(hunkIndex) ?? EXPANDED_REGION;
328
- const chunked = rangeSize > expansionLineCount;
329
- const collapsedLines = Math.max(!expandUnchanged ? rangeSize - (expandedRegion.fromEnd + expandedRegion.fromStart) : 0, 0);
330
- const pushHunkSeparator = ({ type, linesAST }) => {
331
- if (hunkSeparators === "line-info" || hunkSeparators === "custom") {
332
- const slotName = getHunkSeparatorSlotName(type, hunkIndex);
333
- linesAST.push(createSeparator({
334
- type: hunkSeparators,
335
- content: getModifiedLinesString(collapsedLines),
336
- expandIndex: expandable ? hunkIndex : void 0,
337
- chunked,
338
- slotName,
339
- isFirstHunk,
340
- isLastHunk
341
- }));
342
- hunkData.push({
343
- slotName,
344
- hunkIndex,
345
- lines: collapsedLines,
346
- type,
347
- expandable: expandable ? {
348
- up: expandable && !isFirstHunk,
349
- down: expandable,
350
- chunked
351
- } : void 0
352
- });
353
- } else if (hunkSeparators === "metadata" && hunkSpecs != null) linesAST.push(createSeparator({
354
- type: "metadata",
355
- content: hunkSpecs,
356
- isFirstHunk,
357
- isLastHunk
358
- }));
359
- else if (hunkSeparators === "simple" && hunkIndex > 0) linesAST.push(createSeparator({
360
- type: "simple",
361
- isFirstHunk,
362
- isLastHunk: false
363
- }));
364
- };
365
- const renderRange = ({ rangeLen, fromStart }) => {
366
- if (ast.newLines == null || ast.oldLines == null) return;
367
- const offset = isLastHunk ? 0 : fromStart ? rangeSize : rangeLen;
368
- let dLineNumber = deletionLineNumber - offset;
369
- let aLineNumber = additionLineNumber - offset;
370
- let lIndex = lineIndex - offset;
371
- for (let i = 0; i < rangeLen; i++) {
372
- const oldLine = ast.oldLines[dLineNumber];
373
- const newLine = ast.newLines[aLineNumber];
374
- if (oldLine == null || newLine == null) {
375
- console.error({
376
- aLineNumber,
377
- dLineNumber,
378
- ast
379
- });
380
- throw new Error("DiffHunksRenderer.renderHunks prefill context invalid. Must include data for old and new lines");
381
- }
382
- dLineNumber++;
383
- aLineNumber++;
384
- if (diffStyle === "unified") this.pushLineWithAnnotation({
385
- newLine,
386
- unifiedAST,
387
- unifiedSpan: this.getAnnotations("unified", dLineNumber, aLineNumber, hunkIndex, lIndex)
388
- });
389
- else this.pushLineWithAnnotation({
390
- newLine,
391
- oldLine,
392
- additionsAST,
393
- deletionsAST,
394
- ...this.getAnnotations("split", dLineNumber, aLineNumber, hunkIndex, lIndex)
395
- });
396
- lIndex++;
397
- }
398
- };
399
- if (expandable) renderRange({
400
- rangeLen: Math.min(collapsedLines === 0 || expandUnchanged ? rangeSize : expandedRegion.fromStart, rangeSize),
401
- fromStart: true
402
- });
403
- if (collapsedLines > 0) if (diffStyle === "unified") pushHunkSeparator({
404
- type: "unified",
405
- linesAST: unifiedAST
406
- });
407
- else {
408
- pushHunkSeparator({
409
- type: "deletions",
410
- linesAST: deletionsAST
411
- });
412
- pushHunkSeparator({
413
- type: "additions",
414
- linesAST: additionsAST
415
- });
416
- }
417
- if (collapsedLines > 0 && expandedRegion.fromEnd > 0 && !isLastHunk) renderRange({
418
- rangeLen: Math.min(expandedRegion.fromEnd, rangeSize),
419
- fromStart: false
420
- });
421
- }
422
- renderHunks({ hunk, hunkData, hunkIndex, lineIndex, isLastHunk, prevHunk, ast, deletionsAST, additionsAST, unifiedAST }) {
423
- const { diffStyle } = this.getOptionsWithDefaults();
424
- const unified = diffStyle === "unified";
425
- let additionLineNumber = hunk.additionStart - 1;
426
- let deletionLineNumber = hunk.deletionStart - 1;
427
- this.renderCollapsedHunks({
428
- additionLineNumber,
429
- additionsAST,
430
- ast,
431
- deletionLineNumber,
432
- deletionsAST,
433
- hunkData,
434
- hunkIndex,
435
- hunkSpecs: hunk.hunkSpecs,
436
- isFirstHunk: prevHunk == null,
437
- isLastHunk: false,
438
- lineIndex,
439
- rangeSize: Math.max(hunk.collapsedBefore, 0),
440
- unifiedAST
441
- });
442
- let { oldLines, newLines, oldIndex, newIndex } = (() => {
443
- if (ast.hunks != null) {
444
- const lineHunk = ast.hunks[hunkIndex];
445
- if (lineHunk == null) {
446
- console.error({
447
- ast,
448
- hunkIndex
449
- });
450
- throw new Error(`DiffHunksRenderer.renderHunks: lineHunk doesn't exist`);
451
- }
452
- return {
453
- oldLines: lineHunk.oldLines,
454
- newLines: lineHunk.newLines,
455
- oldIndex: 0,
456
- newIndex: 0
457
- };
458
- }
459
- return {
460
- oldLines: ast.oldLines,
461
- newLines: ast.newLines,
462
- oldIndex: deletionLineNumber,
463
- newIndex: additionLineNumber
464
- };
465
- })();
466
- for (const hunkContent of hunk.hunkContent) if (hunkContent.type === "context") {
467
- const { length: len } = hunkContent.lines;
468
- for (let i = 0; i < len; i++) {
469
- const oldLine = oldLines[oldIndex];
470
- const newLine = newLines[newIndex];
471
- oldIndex++;
472
- newIndex++;
473
- additionLineNumber++;
474
- deletionLineNumber++;
475
- if (unified) {
476
- if (newLine == null) throw new Error("DiffHunksRenderer.renderHunks: newLine doesnt exist for context...");
477
- this.pushLineWithAnnotation({
478
- newLine,
479
- unifiedAST,
480
- unifiedSpan: this.getAnnotations("unified", deletionLineNumber, additionLineNumber, hunkIndex, lineIndex)
481
- });
482
- } else {
483
- if (newLine == null || oldLine == null) throw new Error("DiffHunksRenderer.renderHunks: newLine or oldLine doesnt exist for context...");
484
- this.pushLineWithAnnotation({
485
- oldLine,
486
- newLine,
487
- deletionsAST,
488
- additionsAST,
489
- ...this.getAnnotations("split", deletionLineNumber, additionLineNumber, hunkIndex, lineIndex)
490
- });
491
- }
492
- lineIndex++;
493
- }
494
- if (hunkContent.noEOFCR) {
495
- const node = createNoNewlineElement("context");
496
- if (unified) unifiedAST.push(node);
497
- else {
498
- deletionsAST.push(node);
499
- additionsAST.push(node);
500
- }
501
- }
502
- } else {
503
- const { length: dLen } = hunkContent.deletions;
504
- const { length: aLen } = hunkContent.additions;
505
- const len = unified ? dLen + aLen : Math.max(dLen, aLen);
506
- let spanSize = 0;
507
- for (let i = 0; i < len; i++) {
508
- const { oldLine, newLine } = (() => {
509
- let oldLine$1 = oldLines[oldIndex];
510
- let newLine$1 = newLines[newIndex];
511
- if (unified) if (i < dLen) newLine$1 = void 0;
512
- else oldLine$1 = void 0;
513
- else {
514
- if (i >= dLen) oldLine$1 = void 0;
515
- if (i >= aLen) newLine$1 = void 0;
516
- }
517
- if (oldLine$1 == null && newLine$1 == null) {
518
- console.error({
519
- i,
520
- len,
521
- ast,
522
- hunkContent
523
- });
524
- throw new Error("renderHunks: oldLine and newLine are null, something is wrong");
525
- }
526
- return {
527
- oldLine: oldLine$1,
528
- newLine: newLine$1
529
- };
530
- })();
531
- if (oldLine != null) {
532
- oldIndex++;
533
- deletionLineNumber++;
534
- }
535
- if (newLine != null) {
536
- newIndex++;
537
- additionLineNumber++;
538
- }
539
- if (unified) {
540
- this.pushLineWithAnnotation({
541
- oldLine,
542
- newLine,
543
- unifiedAST,
544
- unifiedSpan: this.getAnnotations("unified", oldLine != null ? deletionLineNumber : void 0, newLine != null ? additionLineNumber : void 0, hunkIndex, lineIndex)
545
- });
546
- lineIndex++;
547
- } else {
548
- if (oldLine == null || newLine == null) spanSize++;
549
- const annotationSpans = this.getAnnotations("split", oldLine != null ? deletionLineNumber : void 0, newLine != null ? additionLineNumber : void 0, hunkIndex, lineIndex);
550
- if (annotationSpans != null) {
551
- if (spanSize > 0) {
552
- if (aLen > dLen) deletionsAST.push(createEmptyRowBuffer(spanSize));
553
- else additionsAST.push(createEmptyRowBuffer(spanSize));
554
- spanSize = 0;
555
- }
556
- }
557
- this.pushLineWithAnnotation({
558
- newLine,
559
- oldLine,
560
- deletionsAST,
561
- additionsAST,
562
- ...annotationSpans
563
- });
564
- lineIndex++;
565
- }
566
- }
567
- if (!unified) {
568
- if (spanSize > 0) {
569
- if (aLen > dLen) deletionsAST.push(createEmptyRowBuffer(spanSize));
570
- else additionsAST.push(createEmptyRowBuffer(spanSize));
571
- spanSize = 0;
572
- }
573
- if (hunkContent.noEOFCRDeletions) {
574
- deletionsAST.push(createNoNewlineElement("change-deletion"));
575
- if (!hunkContent.noEOFCRAdditions) additionsAST.push(createEmptyRowBuffer(1));
576
- }
577
- if (hunkContent.noEOFCRAdditions) {
578
- additionsAST.push(createNoNewlineElement("change-addition"));
579
- if (!hunkContent.noEOFCRDeletions) deletionsAST.push(createEmptyRowBuffer(1));
580
- }
581
- }
582
- }
583
- if (isLastHunk && ast.newLines != null && ast.newLines.length > 0) this.renderCollapsedHunks({
584
- additionLineNumber,
585
- additionsAST,
586
- ast,
587
- deletionLineNumber,
588
- deletionsAST,
589
- hunkData,
590
- hunkIndex: hunkIndex + 1,
591
- hunkSpecs: void 0,
592
- isFirstHunk: false,
593
- isLastHunk: true,
594
- lineIndex,
595
- rangeSize: Math.max(ast.newLines.length - Math.max(hunk.additionStart + hunk.additionCount - 1, 0), 0),
596
- unifiedAST
597
- });
598
- return lineIndex;
599
- }
600
- pushLineWithAnnotation({ newLine, oldLine, unifiedAST, additionsAST, deletionsAST, unifiedSpan, deletionSpan, additionSpan }) {
601
- if (unifiedAST != null) {
602
- if (oldLine != null) unifiedAST.push(oldLine);
603
- else if (newLine != null) unifiedAST.push(newLine);
604
- if (unifiedSpan != null) unifiedAST.push(createAnnotationElement(unifiedSpan));
605
- } else if (deletionsAST != null && additionsAST != null) {
606
- if (oldLine != null) deletionsAST.push(oldLine);
607
- if (newLine != null) additionsAST.push(newLine);
608
- if (deletionSpan != null) deletionsAST.push(createAnnotationElement(deletionSpan));
609
- if (additionSpan != null) additionsAST.push(createAnnotationElement(additionSpan));
610
- }
611
- }
612
- getAnnotations(type, oldLineNumber, newLineNumber, hunkIndex, lineIndex) {
482
+ getAnnotations(type, deletionLineNumber, additionLineNumber, hunkIndex, lineIndex) {
613
483
  const deletionSpan = {
614
484
  type: "annotation",
615
485
  hunkIndex,
616
486
  lineIndex,
617
487
  annotations: []
618
488
  };
619
- if (oldLineNumber != null) for (const anno of this.deletionAnnotations[oldLineNumber] ?? []) deletionSpan.annotations.push(getLineAnnotationName(anno));
489
+ if (deletionLineNumber != null) for (const anno of this.deletionAnnotations[deletionLineNumber] ?? []) deletionSpan.annotations.push(getLineAnnotationName(anno));
620
490
  const additionSpan = {
621
491
  type: "annotation",
622
492
  hunkIndex,
623
493
  lineIndex,
624
494
  annotations: []
625
495
  };
626
- if (newLineNumber != null) for (const anno of this.additionAnnotations[newLineNumber] ?? []) (type === "unified" ? deletionSpan : additionSpan).annotations.push(getLineAnnotationName(anno));
496
+ if (additionLineNumber != null) for (const anno of this.additionAnnotations[additionLineNumber] ?? []) (type === "unified" ? deletionSpan : additionSpan).annotations.push(getLineAnnotationName(anno));
627
497
  if (type === "unified") {
628
498
  if (deletionSpan.annotations.length > 0) return deletionSpan;
629
499
  return;
@@ -649,6 +519,62 @@ function areRenderOptionsEqual(optionsA, optionsB) {
649
519
  function getModifiedLinesString(lines) {
650
520
  return `${lines} unmodified line${lines > 1 ? "s" : ""}`;
651
521
  }
522
+ function pushLineWithAnnotation({ deletionLine, additionLine, unifiedAST, additionsAST, deletionsAST, unifiedSpan, deletionSpan, additionSpan }) {
523
+ if (unifiedAST != null) {
524
+ if (deletionLine != null) unifiedAST.push(deletionLine);
525
+ else if (additionLine != null) unifiedAST.push(additionLine);
526
+ if (unifiedSpan != null) unifiedAST.push(createAnnotationElement(unifiedSpan));
527
+ } else if (deletionsAST != null && additionsAST != null) {
528
+ if (deletionLine != null) deletionsAST.push(deletionLine);
529
+ if (additionLine != null) additionsAST.push(additionLine);
530
+ if (deletionSpan != null) deletionsAST.push(createAnnotationElement(deletionSpan));
531
+ if (additionSpan != null) additionsAST.push(createAnnotationElement(additionSpan));
532
+ }
533
+ }
534
+ function pushSeparator(type, { hunkIndex, collapsedLines, rangeSize, hunkSpecs, isFirstHunk, isLastHunk, isExpandable }, { expansionLineCount, hunkSeparators, unifiedAST, deletionsAST, additionsAST, hunkData }) {
535
+ if (collapsedLines <= 0) return;
536
+ const linesAST = type === "unified" ? unifiedAST : type === "deletions" ? deletionsAST : additionsAST;
537
+ if (hunkSeparators === "metadata") {
538
+ if (hunkSpecs != null) linesAST.push(createSeparator({
539
+ type: "metadata",
540
+ content: hunkSpecs,
541
+ isFirstHunk,
542
+ isLastHunk
543
+ }));
544
+ return;
545
+ }
546
+ if (hunkSeparators === "simple") {
547
+ if (hunkIndex > 0) linesAST.push(createSeparator({
548
+ type: "simple",
549
+ isFirstHunk,
550
+ isLastHunk: false
551
+ }));
552
+ return;
553
+ }
554
+ const slotName = getHunkSeparatorSlotName(type, hunkIndex);
555
+ const chunked = rangeSize > expansionLineCount;
556
+ const expandIndex = isExpandable ? hunkIndex : void 0;
557
+ linesAST.push(createSeparator({
558
+ type: hunkSeparators,
559
+ content: getModifiedLinesString(collapsedLines),
560
+ expandIndex,
561
+ chunked,
562
+ slotName,
563
+ isFirstHunk,
564
+ isLastHunk
565
+ }));
566
+ hunkData.push({
567
+ slotName,
568
+ hunkIndex,
569
+ lines: collapsedLines,
570
+ type,
571
+ expandable: isExpandable ? {
572
+ up: !isFirstHunk,
573
+ down: !isLastHunk,
574
+ chunked
575
+ } : void 0
576
+ });
577
+ }
652
578
 
653
579
  //#endregion
654
580
  export { DiffHunksRenderer };