@pierre/diffs 1.3.0-beta.1 → 1.3.0-beta.3

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 (82) hide show
  1. package/dist/components/CodeView.d.ts +4 -0
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +38 -0
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts.map +1 -1
  6. package/dist/components/File.js +9 -9
  7. package/dist/components/File.js.map +1 -1
  8. package/dist/components/FileDiff.d.ts.map +1 -1
  9. package/dist/components/FileDiff.js +3 -2
  10. package/dist/components/FileDiff.js.map +1 -1
  11. package/dist/components/VirtualizedFile.js +6 -1
  12. package/dist/components/VirtualizedFile.js.map +1 -1
  13. package/dist/components/VirtualizedFileDiff.js +22 -42
  14. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  15. package/dist/components/Virtualizer.js +5 -3
  16. package/dist/components/Virtualizer.js.map +1 -1
  17. package/dist/editor/editor.d.ts +7 -1
  18. package/dist/editor/editor.d.ts.map +1 -1
  19. package/dist/editor/editor.js +550 -405
  20. package/dist/editor/editor.js.map +1 -1
  21. package/dist/editor/editor2.js +6 -0
  22. package/dist/editor/editor2.js.map +1 -0
  23. package/dist/editor/pieceTable.d.ts +1 -1
  24. package/dist/editor/pieceTable.d.ts.map +1 -1
  25. package/dist/editor/pieceTable.js +2 -22
  26. package/dist/editor/pieceTable.js.map +1 -1
  27. package/dist/editor/quickEdit.js +2 -4
  28. package/dist/editor/quickEdit.js.map +1 -1
  29. package/dist/editor/searchPanel.d.ts +6 -7
  30. package/dist/editor/searchPanel.d.ts.map +1 -1
  31. package/dist/editor/searchPanel.js +102 -137
  32. package/dist/editor/searchPanel.js.map +1 -1
  33. package/dist/editor/selection.js +8 -2
  34. package/dist/editor/selection.js.map +1 -1
  35. package/dist/editor/sprite.d.ts +7 -0
  36. package/dist/editor/sprite.d.ts.map +1 -0
  37. package/dist/editor/sprite.js +38 -0
  38. package/dist/editor/sprite.js.map +1 -0
  39. package/dist/editor/textDocument.d.ts +1 -1
  40. package/dist/editor/textDocument.d.ts.map +1 -1
  41. package/dist/editor/textDocument.js +2 -2
  42. package/dist/editor/textDocument.js.map +1 -1
  43. package/dist/editor/textMeasure.js +3 -3
  44. package/dist/editor/textMeasure.js.map +1 -1
  45. package/dist/editor/tokenzier.d.ts +6 -2
  46. package/dist/editor/tokenzier.d.ts.map +1 -1
  47. package/dist/editor/tokenzier.js +127 -85
  48. package/dist/editor/tokenzier.js.map +1 -1
  49. package/dist/index.d.ts +2 -2
  50. package/dist/react/index.d.ts +2 -2
  51. package/dist/react/jsx.d.ts +1 -0
  52. package/dist/react/jsx.d.ts.map +1 -1
  53. package/dist/react/types.js +1 -0
  54. package/dist/renderers/DiffHunksRenderer.js +5 -9
  55. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  56. package/dist/ssr/index.d.ts +2 -2
  57. package/dist/style.js +1 -1
  58. package/dist/style.js.map +1 -1
  59. package/dist/types.d.ts +13 -12
  60. package/dist/types.d.ts.map +1 -1
  61. package/dist/utils/computeEstimatedDiffHeights.js +9 -20
  62. package/dist/utils/computeEstimatedDiffHeights.js.map +1 -1
  63. package/dist/utils/iterateOverDiff.js +147 -182
  64. package/dist/utils/iterateOverDiff.js.map +1 -1
  65. package/dist/utils/virtualDiffLayout.d.ts +23 -2
  66. package/dist/utils/virtualDiffLayout.d.ts.map +1 -1
  67. package/dist/utils/virtualDiffLayout.js +41 -1
  68. package/dist/utils/virtualDiffLayout.js.map +1 -1
  69. package/dist/worker/WorkerPoolManager.js +1 -1
  70. package/dist/worker/WorkerPoolManager.js.map +1 -1
  71. package/dist/worker/{wasm-D4DU5jgR.js → wasm-BaDzIkIn.js} +2 -2
  72. package/dist/worker/wasm-BaDzIkIn.js.map +1 -0
  73. package/dist/worker/worker-portable.js +294 -292
  74. package/dist/worker/worker-portable.js.map +1 -1
  75. package/dist/worker/worker.js +179 -181
  76. package/dist/worker/worker.js.map +1 -1
  77. package/package.json +22 -21
  78. package/dist/editor/css.d.ts +0 -6
  79. package/dist/editor/css.d.ts.map +0 -1
  80. package/dist/editor/css.js +0 -218
  81. package/dist/editor/css.js.map +0 -1
  82. package/dist/worker/wasm-D4DU5jgR.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_COLLAPSED_CONTEXT_THRESHOLD } from "../constants.js";
2
- import { getExpandedRegion } from "./virtualDiffLayout.js";
2
+ import { getExpandedRegion, getTrailingExpandedRegion } from "./virtualDiffLayout.js";
3
3
 
4
4
  //#region src/utils/iterateOverDiff.ts
5
5
  function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infinity, expandedHunks, collapsedContextThreshold = DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, callback }) {
@@ -11,12 +11,12 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
11
11
  collapsedContextThreshold
12
12
  });
13
13
  const state = {
14
- finalHunk: diff.hunks.at(-1),
15
14
  viewportStart: startingLine,
16
15
  viewportEnd: startingLine + totalLines,
17
16
  isWindowedHighlight: startingLine > 0 || totalLines < Infinity,
18
17
  splitCount: iterationStart.splitCount,
19
18
  unifiedCount: iterationStart.unifiedCount,
19
+ finalHunkIndex: diff.hunks.length - 1,
20
20
  shouldBreak() {
21
21
  if (!state.isWindowedHighlight) return false;
22
22
  const breakUnified = state.unifiedCount >= startingLine + totalLines;
@@ -69,31 +69,24 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
69
69
  hunkIndex,
70
70
  collapsedContextThreshold
71
71
  });
72
- const trailingRegion = (() => {
73
- if (hunk !== state.finalHunk || !hasFinalCollapsedHunk(diff)) return;
74
- const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
75
- const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
76
- if (additionRemaining !== deletionRemaining) throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
77
- const trailingRangeSize = Math.min(additionRemaining, deletionRemaining);
78
- return getExpandedRegion({
79
- isPartial: diff.isPartial,
80
- rangeSize: trailingRangeSize,
81
- expandedHunks,
82
- hunkIndex: diff.hunks.length,
83
- collapsedContextThreshold
84
- });
85
- })();
72
+ const trailingRegion = hunkIndex === state.finalHunkIndex ? getTrailingExpandedRegion({
73
+ fileDiff: diff,
74
+ hunkIndex,
75
+ expandedHunks,
76
+ collapsedContextThreshold,
77
+ errorPrefix: "iterateOverDiff"
78
+ }) : void 0;
86
79
  const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;
87
80
  function getTrailingCollapsedAfter(unifiedLineIndex$1, splitLineIndex$1) {
88
81
  if (trailingRegion == null || trailingRegion.collapsedLines <= 0 || trailingRegion.fromStart + trailingRegion.fromEnd > 0) return 0;
89
82
  if (diffStyle === "unified") return unifiedLineIndex$1 === hunk.unifiedLineStart + hunk.unifiedLineCount - 1 ? trailingRegion.collapsedLines : 0;
90
83
  return splitLineIndex$1 === hunk.splitLineStart + hunk.splitLineCount - 1 ? trailingRegion.collapsedLines : 0;
91
84
  }
92
- function getPendingCollapsed() {
93
- if (leadingRegion.collapsedLines === 0) return 0;
94
- const value = leadingRegion.collapsedLines;
95
- leadingRegion.collapsedLines = 0;
96
- return value;
85
+ let consumedCollapsed = leadingRegion.collapsedLines === 0;
86
+ function consumePendingCollapsed() {
87
+ if (consumedCollapsed) return 0;
88
+ consumedCollapsed = true;
89
+ return leadingRegion.collapsedLines;
97
90
  }
98
91
  if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {
99
92
  let unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.rangeSize;
@@ -102,81 +95,63 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
102
95
  let additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.rangeSize;
103
96
  let deletionLineNumber$1 = hunk.deletionStart - leadingRegion.rangeSize;
104
97
  let additionLineNumber$1 = hunk.additionStart - leadingRegion.rangeSize;
105
- const [startIndex, endIndex] = getEqualLineIterationRange(state, leadingRegion.fromStart, diffStyle);
106
- if (startIndex > 0) state.incrementCounts(startIndex, startIndex);
107
- let index = startIndex;
108
- while (index < leadingRegion.fromStart) {
109
- if (index >= endIndex) {
110
- state.incrementCounts(leadingRegion.fromStart - index, leadingRegion.fromStart - index);
111
- break;
112
- }
113
- if (state.isInWindow(0, 0)) {
114
- if (state.emit({
115
- hunkIndex,
116
- hunk,
117
- collapsedBefore: 0,
118
- collapsedAfter: 0,
119
- type: "context-expanded",
120
- deletionLine: {
121
- lineNumber: deletionLineNumber$1 + index,
122
- lineIndex: deletionLineIndex$1 + index,
123
- noEOFCR: false,
124
- unifiedLineIndex: unifiedLineIndex$1 + index,
125
- splitLineIndex: splitLineIndex$1 + index
126
- },
127
- additionLine: {
128
- unifiedLineIndex: unifiedLineIndex$1 + index,
129
- splitLineIndex: splitLineIndex$1 + index,
130
- lineIndex: additionLineIndex$1 + index,
131
- lineNumber: additionLineNumber$1 + index,
132
- noEOFCR: false
133
- }
134
- })) break hunkIterator;
135
- } else state.incrementCounts(1, 1);
136
- index++;
137
- }
98
+ if (walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {
99
+ return state.emit({
100
+ hunkIndex,
101
+ hunk,
102
+ collapsedBefore: 0,
103
+ collapsedAfter: 0,
104
+ type: "context-expanded",
105
+ deletionLine: {
106
+ lineNumber: deletionLineNumber$1 + index,
107
+ lineIndex: deletionLineIndex$1 + index,
108
+ noEOFCR: false,
109
+ unifiedLineIndex: unifiedLineIndex$1 + index,
110
+ splitLineIndex: splitLineIndex$1 + index
111
+ },
112
+ additionLine: {
113
+ unifiedLineIndex: unifiedLineIndex$1 + index,
114
+ splitLineIndex: splitLineIndex$1 + index,
115
+ lineIndex: additionLineIndex$1 + index,
116
+ lineNumber: additionLineNumber$1 + index,
117
+ noEOFCR: false
118
+ }
119
+ });
120
+ })) break hunkIterator;
138
121
  unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.fromEnd;
139
122
  splitLineIndex$1 = hunk.splitLineStart - leadingRegion.fromEnd;
140
123
  deletionLineIndex$1 = hunk.deletionLineIndex - leadingRegion.fromEnd;
141
124
  additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.fromEnd;
142
125
  deletionLineNumber$1 = hunk.deletionStart - leadingRegion.fromEnd;
143
126
  additionLineNumber$1 = hunk.additionStart - leadingRegion.fromEnd;
144
- const [fromEndStartIndex, fromEndEndIndex] = getEqualLineIterationRange(state, leadingRegion.fromEnd, diffStyle);
145
- if (fromEndStartIndex > 0) state.incrementCounts(fromEndStartIndex, fromEndStartIndex);
146
- index = fromEndStartIndex;
147
- while (index < leadingRegion.fromEnd) {
148
- if (index >= fromEndEndIndex) {
149
- state.incrementCounts(leadingRegion.fromEnd - index, leadingRegion.fromEnd - index);
150
- break;
151
- }
152
- if (state.isInWindow(0, 0)) {
153
- if (state.emit({
154
- hunkIndex,
155
- hunk,
156
- collapsedBefore: getPendingCollapsed(),
157
- collapsedAfter: 0,
158
- type: "context-expanded",
159
- deletionLine: {
160
- lineNumber: deletionLineNumber$1 + index,
161
- lineIndex: deletionLineIndex$1 + index,
162
- noEOFCR: false,
163
- unifiedLineIndex: unifiedLineIndex$1 + index,
164
- splitLineIndex: splitLineIndex$1 + index
165
- },
166
- additionLine: {
167
- unifiedLineIndex: unifiedLineIndex$1 + index,
168
- splitLineIndex: splitLineIndex$1 + index,
169
- lineIndex: additionLineIndex$1 + index,
170
- lineNumber: additionLineNumber$1 + index,
171
- noEOFCR: false
172
- }
173
- })) break hunkIterator;
174
- } else state.incrementCounts(1, 1);
175
- index++;
176
- }
127
+ if (walkContextLines(state, leadingRegion.fromEnd, diffStyle, (index) => {
128
+ return state.emit({
129
+ hunkIndex,
130
+ hunk,
131
+ collapsedBefore: consumePendingCollapsed(),
132
+ collapsedAfter: 0,
133
+ type: "context-expanded",
134
+ deletionLine: {
135
+ lineNumber: deletionLineNumber$1 + index,
136
+ lineIndex: deletionLineIndex$1 + index,
137
+ noEOFCR: false,
138
+ unifiedLineIndex: unifiedLineIndex$1 + index,
139
+ splitLineIndex: splitLineIndex$1 + index
140
+ },
141
+ additionLine: {
142
+ unifiedLineIndex: unifiedLineIndex$1 + index,
143
+ splitLineIndex: splitLineIndex$1 + index,
144
+ lineIndex: additionLineIndex$1 + index,
145
+ lineNumber: additionLineNumber$1 + index,
146
+ noEOFCR: false
147
+ }
148
+ });
149
+ }, () => {
150
+ consumePendingCollapsed();
151
+ })) break hunkIterator;
177
152
  } else {
178
153
  state.incrementCounts(expandedLineCount, expandedLineCount);
179
- getPendingCollapsed();
154
+ consumePendingCollapsed();
180
155
  }
181
156
  let unifiedLineIndex = hunk.unifiedLineStart;
182
157
  let splitLineIndex = hunk.splitLineStart;
@@ -190,45 +165,37 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
190
165
  const isLastContent = content === lastContent;
191
166
  if (content.type === "context") {
192
167
  if (!state.shouldSkip(content.lines, content.lines)) {
193
- const [startIndex, endIndex] = getEqualLineIterationRange(state, content.lines, diffStyle);
194
- if (startIndex > 0) state.incrementCounts(startIndex, startIndex);
195
- let index = startIndex;
196
- while (index < content.lines) {
197
- if (index >= endIndex) {
198
- state.incrementCounts(content.lines - index, content.lines - index);
199
- break;
200
- }
201
- if (state.isInWindow(0, 0)) {
202
- const isLastLine = isLastContent && index === content.lines - 1;
203
- const unifiedRowIndex = unifiedLineIndex + index;
204
- const splitRowIndex = splitLineIndex + index;
205
- if (state.emit({
206
- hunkIndex,
207
- hunk,
208
- collapsedBefore: getPendingCollapsed(),
209
- collapsedAfter: getTrailingCollapsedAfter(unifiedRowIndex, splitRowIndex),
210
- type: "context",
211
- deletionLine: {
212
- lineNumber: deletionLineNumber + index,
213
- lineIndex: deletionLineIndex + index,
214
- noEOFCR: isLastLine && hunk.noEOFCRDeletions,
215
- unifiedLineIndex: unifiedRowIndex,
216
- splitLineIndex: splitRowIndex
217
- },
218
- additionLine: {
219
- unifiedLineIndex: unifiedRowIndex,
220
- splitLineIndex: splitRowIndex,
221
- lineIndex: additionLineIndex + index,
222
- lineNumber: additionLineNumber + index,
223
- noEOFCR: isLastLine && hunk.noEOFCRAdditions
224
- }
225
- })) break hunkIterator;
226
- } else state.incrementCounts(1, 1);
227
- index++;
228
- }
168
+ if (walkContextLines(state, content.lines, diffStyle, (index) => {
169
+ const isLastLine = isLastContent && index === content.lines - 1;
170
+ const unifiedRowIndex = unifiedLineIndex + index;
171
+ const splitRowIndex = splitLineIndex + index;
172
+ return state.emit({
173
+ hunkIndex,
174
+ hunk,
175
+ collapsedBefore: consumePendingCollapsed(),
176
+ collapsedAfter: getTrailingCollapsedAfter(unifiedRowIndex, splitRowIndex),
177
+ type: "context",
178
+ deletionLine: {
179
+ lineNumber: deletionLineNumber + index,
180
+ lineIndex: deletionLineIndex + index,
181
+ noEOFCR: isLastLine && hunk.noEOFCRDeletions,
182
+ unifiedLineIndex: unifiedRowIndex,
183
+ splitLineIndex: splitRowIndex
184
+ },
185
+ additionLine: {
186
+ unifiedLineIndex: unifiedRowIndex,
187
+ splitLineIndex: splitRowIndex,
188
+ lineIndex: additionLineIndex + index,
189
+ lineNumber: additionLineNumber + index,
190
+ noEOFCR: isLastLine && hunk.noEOFCRAdditions
191
+ }
192
+ });
193
+ }, () => {
194
+ consumePendingCollapsed();
195
+ })) break hunkIterator;
229
196
  } else {
230
197
  state.incrementCounts(content.lines, content.lines);
231
- getPendingCollapsed();
198
+ consumePendingCollapsed();
232
199
  }
233
200
  unifiedLineIndex += content.lines;
234
201
  splitLineIndex += content.lines;
@@ -241,12 +208,13 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
241
208
  const unifiedCount = content.deletions + content.additions;
242
209
  if (!state.shouldSkip(unifiedCount, splitCount)) {
243
210
  const iterationRanges = getChangeIterationRanges(state, content, diffStyle);
211
+ if ((iterationRanges[0]?.[0] ?? 0) > 0) consumePendingCollapsed();
244
212
  for (const [rangeStart, rangeEnd] of iterationRanges) for (let index = rangeStart; index < rangeEnd; index++) {
245
213
  const collapsedAfter = getTrailingCollapsedAfter(unifiedLineIndex + index, diffStyle === "unified" ? splitLineIndex + (index < content.deletions ? index : index - content.deletions) : splitLineIndex + index);
246
214
  if (state.emit(getChangeLineData({
247
215
  hunkIndex,
248
216
  hunk,
249
- collapsedBefore: getPendingCollapsed(),
217
+ collapsedBefore: consumePendingCollapsed(),
250
218
  collapsedAfter,
251
219
  diffStyle,
252
220
  index,
@@ -263,7 +231,7 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
263
231
  }), true)) break hunkIterator;
264
232
  }
265
233
  }
266
- getPendingCollapsed();
234
+ consumePendingCollapsed();
267
235
  state.incrementCounts(unifiedCount, splitCount);
268
236
  unifiedLineIndex += unifiedCount;
269
237
  splitLineIndex += splitCount;
@@ -276,41 +244,30 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
276
244
  if (trailingRegion != null) {
277
245
  const { collapsedLines, fromStart, fromEnd } = trailingRegion;
278
246
  const len = fromStart + fromEnd;
279
- const [startIndex, endIndex] = getEqualLineIterationRange(state, len, diffStyle);
280
- if (startIndex > 0) state.incrementCounts(startIndex, startIndex);
281
- let index = startIndex;
282
- while (index < len) {
283
- if (state.shouldBreak()) break hunkIterator;
284
- if (index >= endIndex) {
285
- state.incrementCounts(len - index, len - index);
286
- break;
287
- }
288
- if (state.isInWindow(0, 0)) {
289
- const isLastLine = index === len - 1;
290
- if (state.emit({
291
- hunkIndex: diff.hunks.length,
292
- hunk: void 0,
293
- collapsedBefore: 0,
294
- collapsedAfter: isLastLine ? collapsedLines : 0,
295
- type: "context-expanded",
296
- deletionLine: {
297
- lineNumber: deletionLineNumber + index,
298
- lineIndex: deletionLineIndex + index,
299
- noEOFCR: false,
300
- unifiedLineIndex: unifiedLineIndex + index,
301
- splitLineIndex: splitLineIndex + index
302
- },
303
- additionLine: {
304
- unifiedLineIndex: unifiedLineIndex + index,
305
- splitLineIndex: splitLineIndex + index,
306
- lineIndex: additionLineIndex + index,
307
- lineNumber: additionLineNumber + index,
308
- noEOFCR: false
309
- }
310
- })) break hunkIterator;
311
- } else state.incrementCounts(1, 1);
312
- index++;
313
- }
247
+ if (walkContextLines(state, len, diffStyle, (index) => {
248
+ const isLastLine = index === len - 1;
249
+ return state.emit({
250
+ hunkIndex: diff.hunks.length,
251
+ hunk: void 0,
252
+ collapsedBefore: 0,
253
+ collapsedAfter: isLastLine ? collapsedLines : 0,
254
+ type: "context-expanded",
255
+ deletionLine: {
256
+ lineNumber: deletionLineNumber + index,
257
+ lineIndex: deletionLineIndex + index,
258
+ noEOFCR: false,
259
+ unifiedLineIndex: unifiedLineIndex + index,
260
+ splitLineIndex: splitLineIndex + index
261
+ },
262
+ additionLine: {
263
+ unifiedLineIndex: unifiedLineIndex + index,
264
+ splitLineIndex: splitLineIndex + index,
265
+ lineIndex: additionLineIndex + index,
266
+ lineNumber: additionLineNumber + index,
267
+ noEOFCR: false
268
+ }
269
+ });
270
+ }, void 0, () => state.shouldBreak())) break hunkIterator;
314
271
  }
315
272
  }
316
273
  }
@@ -375,15 +332,14 @@ function getHunkPrefixCounts({ diff, expandedHunks, collapsedContextThreshold })
375
332
  const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;
376
333
  splitCount += leadingCount + hunk.splitLineCount;
377
334
  unifiedCount += leadingCount + hunk.unifiedLineCount;
378
- if (index === finalHunkIndex && hasFinalCollapsedHunk(diff)) {
379
- const trailingRangeSize = getTrailingRangeSize(diff, hunk);
380
- const trailingRegion = getExpandedRegion({
381
- isPartial: diff.isPartial,
382
- rangeSize: trailingRangeSize,
383
- expandedHunks,
384
- hunkIndex: diff.hunks.length,
385
- collapsedContextThreshold
386
- });
335
+ const trailingRegion = index === finalHunkIndex ? getTrailingExpandedRegion({
336
+ fileDiff: diff,
337
+ hunkIndex: index,
338
+ expandedHunks,
339
+ collapsedContextThreshold,
340
+ errorPrefix: "iterateOverDiff"
341
+ }) : void 0;
342
+ if (trailingRegion != null) {
387
343
  const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;
388
344
  splitCount += trailingCount;
389
345
  unifiedCount += trailingCount;
@@ -395,7 +351,7 @@ function getHunkPrefixCounts({ diff, expandedHunks, collapsedContextThreshold })
395
351
  }
396
352
  return prefixCounts;
397
353
  }
398
- function getEqualLineIterationRange(state, count, diffStyle) {
354
+ function getContextLineIterationBounds(state, count, diffStyle) {
399
355
  if (!state.isWindowedHighlight || count <= 0) return [0, count];
400
356
  const ranges = [];
401
357
  function pushRange(currentCount) {
@@ -415,16 +371,25 @@ function getEqualLineIterationRange(state, count, diffStyle) {
415
371
  }
416
372
  return [start, end];
417
373
  }
418
- function getTrailingRangeSize(diff, hunk) {
419
- const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
420
- const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
421
- if (additionRemaining !== deletionRemaining) throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
422
- return Math.min(additionRemaining, deletionRemaining);
423
- }
424
- function hasFinalCollapsedHunk(diff) {
425
- const lastHunk = diff.hunks.at(-1);
426
- if (lastHunk == null || diff.isPartial || diff.additionLines.length === 0 || diff.deletionLines.length === 0) return false;
427
- return lastHunk.additionLineIndex + lastHunk.additionCount < diff.additionLines.length || lastHunk.deletionLineIndex + lastHunk.deletionCount < diff.deletionLines.length;
374
+ function walkContextLines(state, count, diffStyle, callback, onSkippedStart, shouldBreak) {
375
+ const [startIndex, endIndex] = getContextLineIterationBounds(state, count, diffStyle);
376
+ if (startIndex > 0) {
377
+ state.incrementCounts(startIndex, startIndex);
378
+ onSkippedStart?.();
379
+ }
380
+ let index = startIndex;
381
+ while (index < count) {
382
+ if (shouldBreak?.() === true) return true;
383
+ if (index >= endIndex) {
384
+ state.incrementCounts(count - index, count - index);
385
+ break;
386
+ }
387
+ if (state.isInWindow(0, 0)) {
388
+ if (callback(index) === true) return true;
389
+ } else state.incrementCounts(1, 1);
390
+ index++;
391
+ }
392
+ return false;
428
393
  }
429
394
  function getChangeIterationRanges(state, content, diffStyle) {
430
395
  if (!state.isWindowedHighlight) return [[0, diffStyle === "unified" ? content.deletions + content.additions : Math.max(content.deletions, content.additions)]];