@pierre/diffs 1.2.5 → 1.2.7

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.
@@ -9270,7 +9270,7 @@ function l(a$1) {
9270
9270
  }
9271
9271
 
9272
9272
  //#endregion
9273
- //#region ../../node_modules/.bun/regex@6.1.0/node_modules/regex/src/utils-internals.js
9273
+ //#region ../../node_modules/.bun/regex@6.0.1/node_modules/regex/src/utils-internals.js
9274
9274
  const noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
9275
9275
  /**
9276
9276
  Updates the array in place by incrementing each value greater than or equal to the threshold.
@@ -9458,16 +9458,13 @@ function getGroupContents(expression, contentsStartPos) {
9458
9458
  }
9459
9459
 
9460
9460
  //#endregion
9461
- //#region ../../node_modules/.bun/regex@6.1.0/node_modules/regex/src/atomic.js
9462
- /**
9463
- @import {PluginData, PluginResult} from './regex.js';
9464
- */
9461
+ //#region ../../node_modules/.bun/regex@6.0.1/node_modules/regex/src/atomic.js
9465
9462
  const atomicPluginToken = new RegExp(String.raw`(?<noncapturingStart>${noncapturingDelim})|(?<capturingStart>\((?:\?<[^>]+>)?)|\\?.`, "gsu");
9466
9463
  /**
9467
9464
  Apply transformations for atomic groups: `(?>…)`.
9468
9465
  @param {string} expression
9469
- @param {PluginData} [data]
9470
- @returns {Required<PluginResult>}
9466
+ @param {import('./regex.js').PluginData} [data]
9467
+ @returns {Required<import('./regex.js').PluginResult>}
9471
9468
  */
9472
9469
  function atomic(expression, data) {
9473
9470
  const hiddenCaptures = data?.hiddenCaptures ?? [];
@@ -9575,7 +9572,7 @@ Transform posessive quantifiers into atomic groups. The posessessive quantifiers
9575
9572
  This follows Java, PCRE, Perl, and Python.
9576
9573
  Possessive quantifiers in Oniguruma and Onigmo are only: `?+`, `*+`, `++`.
9577
9574
  @param {string} expression
9578
- @returns {PluginResult}
9575
+ @returns {import('./regex.js').PluginResult}
9579
9576
  */
9580
9577
  function possessive(expression) {
9581
9578
  if (!new RegExp(`${baseQuantifier}\\+`).test(expression)) {
@@ -9634,7 +9631,7 @@ function possessive(expression) {
9634
9631
  }
9635
9632
 
9636
9633
  //#endregion
9637
- //#region ../../node_modules/.bun/regex@6.1.0/node_modules/regex/src/subclass.js
9634
+ //#region ../../node_modules/.bun/regex@6.0.1/node_modules/regex/src/subclass.js
9638
9635
  /**
9639
9636
  Works the same as JavaScript's native `RegExp` constructor in all contexts, but automatically
9640
9637
  adjusts subpattern matches and indices (with flag `d`) to account for captures added as part of
@@ -15171,6 +15168,60 @@ function getExpandedRegion({ isPartial, rangeSize, expandedHunks, hunkIndex, col
15171
15168
  renderAll
15172
15169
  };
15173
15170
  }
15171
+ function hasTrailingContext(fileDiff) {
15172
+ const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
15173
+ if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) {
15174
+ return false;
15175
+ }
15176
+ const additionRemaining = fileDiff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount);
15177
+ const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
15178
+ return additionRemaining > 0 || deletionRemaining > 0;
15179
+ }
15180
+ function getTrailingContextRangeSize({ fileDiff, errorPrefix }) {
15181
+ const lastHunk = fileDiff.hunks[fileDiff.hunks.length - 1];
15182
+ if (lastHunk == null || fileDiff.isPartial || fileDiff.additionLines.length === 0 || fileDiff.deletionLines.length === 0) {
15183
+ return 0;
15184
+ }
15185
+ const additionRemaining = fileDiff.additionLines.length - (lastHunk.additionLineIndex + lastHunk.additionCount);
15186
+ const deletionRemaining = fileDiff.deletionLines.length - (lastHunk.deletionLineIndex + lastHunk.deletionCount);
15187
+ if (additionRemaining <= 0 && deletionRemaining <= 0) {
15188
+ return 0;
15189
+ }
15190
+ if (additionRemaining !== deletionRemaining) {
15191
+ throw new Error(`${errorPrefix}: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${fileDiff.name}`);
15192
+ }
15193
+ return Math.min(additionRemaining, deletionRemaining);
15194
+ }
15195
+ function getTrailingExpandedRegion({ fileDiff, hunkIndex, expandedHunks, collapsedContextThreshold, errorPrefix }) {
15196
+ if (hunkIndex !== fileDiff.hunks.length - 1) {
15197
+ return undefined;
15198
+ }
15199
+ const trailingRangeSize = getTrailingContextRangeSize({
15200
+ fileDiff,
15201
+ errorPrefix
15202
+ });
15203
+ if (trailingRangeSize <= 0) {
15204
+ return undefined;
15205
+ }
15206
+ if (expandedHunks === true || trailingRangeSize <= collapsedContextThreshold) {
15207
+ return {
15208
+ fromStart: trailingRangeSize,
15209
+ fromEnd: 0,
15210
+ rangeSize: trailingRangeSize,
15211
+ collapsedLines: 0,
15212
+ renderAll: true
15213
+ };
15214
+ }
15215
+ const region = expandedHunks?.get(fileDiff.hunks.length);
15216
+ const fromStart = Math.min(Math.max(region?.fromStart ?? 0, 0), trailingRangeSize);
15217
+ return {
15218
+ fromStart,
15219
+ fromEnd: 0,
15220
+ rangeSize: trailingRangeSize,
15221
+ collapsedLines: trailingRangeSize - fromStart,
15222
+ renderAll: fromStart >= trailingRangeSize
15223
+ };
15224
+ }
15174
15225
  function getHunkSeparatorHeight({ type, metrics }) {
15175
15226
  return metrics.hunkSeparatorHeight ?? getDefaultHunkSeparatorHeight(type);
15176
15227
  }
@@ -15245,12 +15296,12 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15245
15296
  collapsedContextThreshold
15246
15297
  });
15247
15298
  const state = {
15248
- finalHunk: diff.hunks.at(-1),
15249
15299
  viewportStart: startingLine,
15250
15300
  viewportEnd: startingLine + totalLines,
15251
15301
  isWindowedHighlight: startingLine > 0 || totalLines < Infinity,
15252
15302
  splitCount: iterationStart.splitCount,
15253
15303
  unifiedCount: iterationStart.unifiedCount,
15304
+ finalHunkIndex: diff.hunks.length - 1,
15254
15305
  shouldBreak() {
15255
15306
  if (!state.isWindowedHighlight) {
15256
15307
  return false;
@@ -15335,24 +15386,13 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15335
15386
  hunkIndex,
15336
15387
  collapsedContextThreshold
15337
15388
  });
15338
- const trailingRegion = (() => {
15339
- if (hunk !== state.finalHunk || !hasFinalCollapsedHunk(diff)) {
15340
- return undefined;
15341
- }
15342
- const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
15343
- const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
15344
- if (additionRemaining !== deletionRemaining) {
15345
- throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
15346
- }
15347
- const trailingRangeSize = Math.min(additionRemaining, deletionRemaining);
15348
- return getExpandedRegion({
15349
- isPartial: diff.isPartial,
15350
- rangeSize: trailingRangeSize,
15351
- expandedHunks,
15352
- hunkIndex: diff.hunks.length,
15353
- collapsedContextThreshold
15354
- });
15355
- })();
15389
+ const trailingRegion = hunkIndex === state.finalHunkIndex ? getTrailingExpandedRegion({
15390
+ fileDiff: diff,
15391
+ hunkIndex,
15392
+ expandedHunks,
15393
+ collapsedContextThreshold,
15394
+ errorPrefix: "iterateOverDiff"
15395
+ }) : undefined;
15356
15396
  const expandedLineCount = leadingRegion.fromStart + leadingRegion.fromEnd;
15357
15397
  function getTrailingCollapsedAfter(unifiedLineIndex$1, splitLineIndex$1) {
15358
15398
  if (trailingRegion == null || trailingRegion.collapsedLines <= 0 || trailingRegion.fromStart + trailingRegion.fromEnd > 0) {
@@ -15363,13 +15403,13 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15363
15403
  }
15364
15404
  return splitLineIndex$1 === hunk.splitLineStart + hunk.splitLineCount - 1 ? trailingRegion.collapsedLines : 0;
15365
15405
  }
15366
- function getPendingCollapsed() {
15367
- if (leadingRegion.collapsedLines === 0) {
15406
+ let consumedCollapsed = leadingRegion.collapsedLines === 0;
15407
+ function consumePendingCollapsed() {
15408
+ if (consumedCollapsed) {
15368
15409
  return 0;
15369
15410
  }
15370
- const value = leadingRegion.collapsedLines;
15371
- leadingRegion.collapsedLines = 0;
15372
- return value;
15411
+ consumedCollapsed = true;
15412
+ return leadingRegion.collapsedLines;
15373
15413
  }
15374
15414
  if (!state.shouldSkip(expandedLineCount, expandedLineCount)) {
15375
15415
  let unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.rangeSize;
@@ -15378,44 +15418,30 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15378
15418
  let additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.rangeSize;
15379
15419
  let deletionLineNumber$1 = hunk.deletionStart - leadingRegion.rangeSize;
15380
15420
  let additionLineNumber$1 = hunk.additionStart - leadingRegion.rangeSize;
15381
- const [startIndex, endIndex] = getEqualLineIterationRange(state, leadingRegion.fromStart, diffStyle);
15382
- if (startIndex > 0) {
15383
- state.incrementCounts(startIndex, startIndex);
15384
- }
15385
- let index = startIndex;
15386
- while (index < leadingRegion.fromStart) {
15387
- if (index >= endIndex) {
15388
- state.incrementCounts(leadingRegion.fromStart - index, leadingRegion.fromStart - index);
15389
- break;
15390
- }
15391
- if (state.isInWindow(0, 0)) {
15392
- if (state.emit({
15393
- hunkIndex,
15394
- hunk,
15395
- collapsedBefore: 0,
15396
- collapsedAfter: 0,
15397
- type: "context-expanded",
15398
- deletionLine: {
15399
- lineNumber: deletionLineNumber$1 + index,
15400
- lineIndex: deletionLineIndex$1 + index,
15401
- noEOFCR: false,
15402
- unifiedLineIndex: unifiedLineIndex$1 + index,
15403
- splitLineIndex: splitLineIndex$1 + index
15404
- },
15405
- additionLine: {
15406
- unifiedLineIndex: unifiedLineIndex$1 + index,
15407
- splitLineIndex: splitLineIndex$1 + index,
15408
- lineIndex: additionLineIndex$1 + index,
15409
- lineNumber: additionLineNumber$1 + index,
15410
- noEOFCR: false
15411
- }
15412
- })) {
15413
- break hunkIterator;
15421
+ if (walkContextLines(state, leadingRegion.fromStart, diffStyle, (index) => {
15422
+ return state.emit({
15423
+ hunkIndex,
15424
+ hunk,
15425
+ collapsedBefore: 0,
15426
+ collapsedAfter: 0,
15427
+ type: "context-expanded",
15428
+ deletionLine: {
15429
+ lineNumber: deletionLineNumber$1 + index,
15430
+ lineIndex: deletionLineIndex$1 + index,
15431
+ noEOFCR: false,
15432
+ unifiedLineIndex: unifiedLineIndex$1 + index,
15433
+ splitLineIndex: splitLineIndex$1 + index
15434
+ },
15435
+ additionLine: {
15436
+ unifiedLineIndex: unifiedLineIndex$1 + index,
15437
+ splitLineIndex: splitLineIndex$1 + index,
15438
+ lineIndex: additionLineIndex$1 + index,
15439
+ lineNumber: additionLineNumber$1 + index,
15440
+ noEOFCR: false
15414
15441
  }
15415
- } else {
15416
- state.incrementCounts(1, 1);
15417
- }
15418
- index++;
15442
+ });
15443
+ })) {
15444
+ break hunkIterator;
15419
15445
  }
15420
15446
  unifiedLineIndex$1 = hunk.unifiedLineStart - leadingRegion.fromEnd;
15421
15447
  splitLineIndex$1 = hunk.splitLineStart - leadingRegion.fromEnd;
@@ -15423,48 +15449,36 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15423
15449
  additionLineIndex$1 = hunk.additionLineIndex - leadingRegion.fromEnd;
15424
15450
  deletionLineNumber$1 = hunk.deletionStart - leadingRegion.fromEnd;
15425
15451
  additionLineNumber$1 = hunk.additionStart - leadingRegion.fromEnd;
15426
- const [fromEndStartIndex, fromEndEndIndex] = getEqualLineIterationRange(state, leadingRegion.fromEnd, diffStyle);
15427
- if (fromEndStartIndex > 0) {
15428
- state.incrementCounts(fromEndStartIndex, fromEndStartIndex);
15429
- }
15430
- index = fromEndStartIndex;
15431
- while (index < leadingRegion.fromEnd) {
15432
- if (index >= fromEndEndIndex) {
15433
- state.incrementCounts(leadingRegion.fromEnd - index, leadingRegion.fromEnd - index);
15434
- break;
15435
- }
15436
- if (state.isInWindow(0, 0)) {
15437
- if (state.emit({
15438
- hunkIndex,
15439
- hunk,
15440
- collapsedBefore: getPendingCollapsed(),
15441
- collapsedAfter: 0,
15442
- type: "context-expanded",
15443
- deletionLine: {
15444
- lineNumber: deletionLineNumber$1 + index,
15445
- lineIndex: deletionLineIndex$1 + index,
15446
- noEOFCR: false,
15447
- unifiedLineIndex: unifiedLineIndex$1 + index,
15448
- splitLineIndex: splitLineIndex$1 + index
15449
- },
15450
- additionLine: {
15451
- unifiedLineIndex: unifiedLineIndex$1 + index,
15452
- splitLineIndex: splitLineIndex$1 + index,
15453
- lineIndex: additionLineIndex$1 + index,
15454
- lineNumber: additionLineNumber$1 + index,
15455
- noEOFCR: false
15456
- }
15457
- })) {
15458
- break hunkIterator;
15452
+ if (walkContextLines(state, leadingRegion.fromEnd, diffStyle, (index) => {
15453
+ return state.emit({
15454
+ hunkIndex,
15455
+ hunk,
15456
+ collapsedBefore: consumePendingCollapsed(),
15457
+ collapsedAfter: 0,
15458
+ type: "context-expanded",
15459
+ deletionLine: {
15460
+ lineNumber: deletionLineNumber$1 + index,
15461
+ lineIndex: deletionLineIndex$1 + index,
15462
+ noEOFCR: false,
15463
+ unifiedLineIndex: unifiedLineIndex$1 + index,
15464
+ splitLineIndex: splitLineIndex$1 + index
15465
+ },
15466
+ additionLine: {
15467
+ unifiedLineIndex: unifiedLineIndex$1 + index,
15468
+ splitLineIndex: splitLineIndex$1 + index,
15469
+ lineIndex: additionLineIndex$1 + index,
15470
+ lineNumber: additionLineNumber$1 + index,
15471
+ noEOFCR: false
15459
15472
  }
15460
- } else {
15461
- state.incrementCounts(1, 1);
15462
- }
15463
- index++;
15473
+ });
15474
+ }, () => {
15475
+ consumePendingCollapsed();
15476
+ })) {
15477
+ break hunkIterator;
15464
15478
  }
15465
15479
  } else {
15466
15480
  state.incrementCounts(expandedLineCount, expandedLineCount);
15467
- getPendingCollapsed();
15481
+ consumePendingCollapsed();
15468
15482
  }
15469
15483
  let unifiedLineIndex = hunk.unifiedLineStart;
15470
15484
  let splitLineIndex = hunk.splitLineStart;
@@ -15480,51 +15494,39 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15480
15494
  const isLastContent = content === lastContent;
15481
15495
  if (content.type === "context") {
15482
15496
  if (!state.shouldSkip(content.lines, content.lines)) {
15483
- const [startIndex, endIndex] = getEqualLineIterationRange(state, content.lines, diffStyle);
15484
- if (startIndex > 0) {
15485
- state.incrementCounts(startIndex, startIndex);
15486
- }
15487
- let index = startIndex;
15488
- while (index < content.lines) {
15489
- if (index >= endIndex) {
15490
- state.incrementCounts(content.lines - index, content.lines - index);
15491
- break;
15492
- }
15493
- if (state.isInWindow(0, 0)) {
15494
- const isLastLine = isLastContent && index === content.lines - 1;
15495
- const unifiedRowIndex = unifiedLineIndex + index;
15496
- const splitRowIndex = splitLineIndex + index;
15497
- if (state.emit({
15498
- hunkIndex,
15499
- hunk,
15500
- collapsedBefore: getPendingCollapsed(),
15501
- collapsedAfter: getTrailingCollapsedAfter(unifiedRowIndex, splitRowIndex),
15502
- type: "context",
15503
- deletionLine: {
15504
- lineNumber: deletionLineNumber + index,
15505
- lineIndex: deletionLineIndex + index,
15506
- noEOFCR: isLastLine && hunk.noEOFCRDeletions,
15507
- unifiedLineIndex: unifiedRowIndex,
15508
- splitLineIndex: splitRowIndex
15509
- },
15510
- additionLine: {
15511
- unifiedLineIndex: unifiedRowIndex,
15512
- splitLineIndex: splitRowIndex,
15513
- lineIndex: additionLineIndex + index,
15514
- lineNumber: additionLineNumber + index,
15515
- noEOFCR: isLastLine && hunk.noEOFCRAdditions
15516
- }
15517
- })) {
15518
- break hunkIterator;
15497
+ if (walkContextLines(state, content.lines, diffStyle, (index) => {
15498
+ const isLastLine = isLastContent && index === content.lines - 1;
15499
+ const unifiedRowIndex = unifiedLineIndex + index;
15500
+ const splitRowIndex = splitLineIndex + index;
15501
+ return state.emit({
15502
+ hunkIndex,
15503
+ hunk,
15504
+ collapsedBefore: consumePendingCollapsed(),
15505
+ collapsedAfter: getTrailingCollapsedAfter(unifiedRowIndex, splitRowIndex),
15506
+ type: "context",
15507
+ deletionLine: {
15508
+ lineNumber: deletionLineNumber + index,
15509
+ lineIndex: deletionLineIndex + index,
15510
+ noEOFCR: isLastLine && hunk.noEOFCRDeletions,
15511
+ unifiedLineIndex: unifiedRowIndex,
15512
+ splitLineIndex: splitRowIndex
15513
+ },
15514
+ additionLine: {
15515
+ unifiedLineIndex: unifiedRowIndex,
15516
+ splitLineIndex: splitRowIndex,
15517
+ lineIndex: additionLineIndex + index,
15518
+ lineNumber: additionLineNumber + index,
15519
+ noEOFCR: isLastLine && hunk.noEOFCRAdditions
15519
15520
  }
15520
- } else {
15521
- state.incrementCounts(1, 1);
15522
- }
15523
- index++;
15521
+ });
15522
+ }, () => {
15523
+ consumePendingCollapsed();
15524
+ })) {
15525
+ break hunkIterator;
15524
15526
  }
15525
15527
  } else {
15526
15528
  state.incrementCounts(content.lines, content.lines);
15527
- getPendingCollapsed();
15529
+ consumePendingCollapsed();
15528
15530
  }
15529
15531
  unifiedLineIndex += content.lines;
15530
15532
  splitLineIndex += content.lines;
@@ -15538,6 +15540,10 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15538
15540
  const shouldSkipChange = state.shouldSkip(unifiedCount, splitCount);
15539
15541
  if (!shouldSkipChange) {
15540
15542
  const iterationRanges = getChangeIterationRanges(state, content, diffStyle);
15543
+ const firstRangeStart = iterationRanges[0]?.[0] ?? 0;
15544
+ if (firstRangeStart > 0) {
15545
+ consumePendingCollapsed();
15546
+ }
15541
15547
  for (const [rangeStart, rangeEnd] of iterationRanges) {
15542
15548
  for (let index = rangeStart; index < rangeEnd; index++) {
15543
15549
  const unifiedRowIndex = unifiedLineIndex + index;
@@ -15546,7 +15552,7 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15546
15552
  if (state.emit(getChangeLineData({
15547
15553
  hunkIndex,
15548
15554
  hunk,
15549
- collapsedBefore: getPendingCollapsed(),
15555
+ collapsedBefore: consumePendingCollapsed(),
15550
15556
  collapsedAfter,
15551
15557
  diffStyle,
15552
15558
  index,
@@ -15566,7 +15572,7 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15566
15572
  }
15567
15573
  }
15568
15574
  }
15569
- getPendingCollapsed();
15575
+ consumePendingCollapsed();
15570
15576
  state.incrementCounts(unifiedCount, splitCount);
15571
15577
  unifiedLineIndex += unifiedCount;
15572
15578
  splitLineIndex += splitCount;
@@ -15579,48 +15585,31 @@ function iterateOverDiff({ diff, diffStyle, startingLine = 0, totalLines = Infin
15579
15585
  if (trailingRegion != null) {
15580
15586
  const { collapsedLines, fromStart, fromEnd } = trailingRegion;
15581
15587
  const len = fromStart + fromEnd;
15582
- const [startIndex, endIndex] = getEqualLineIterationRange(state, len, diffStyle);
15583
- if (startIndex > 0) {
15584
- state.incrementCounts(startIndex, startIndex);
15585
- }
15586
- let index = startIndex;
15587
- while (index < len) {
15588
- if (state.shouldBreak()) {
15589
- break hunkIterator;
15590
- }
15591
- if (index >= endIndex) {
15592
- state.incrementCounts(len - index, len - index);
15593
- break;
15594
- }
15595
- if (state.isInWindow(0, 0)) {
15596
- const isLastLine = index === len - 1;
15597
- if (state.emit({
15598
- hunkIndex: diff.hunks.length,
15599
- hunk: undefined,
15600
- collapsedBefore: 0,
15601
- collapsedAfter: isLastLine ? collapsedLines : 0,
15602
- type: "context-expanded",
15603
- deletionLine: {
15604
- lineNumber: deletionLineNumber + index,
15605
- lineIndex: deletionLineIndex + index,
15606
- noEOFCR: false,
15607
- unifiedLineIndex: unifiedLineIndex + index,
15608
- splitLineIndex: splitLineIndex + index
15609
- },
15610
- additionLine: {
15611
- unifiedLineIndex: unifiedLineIndex + index,
15612
- splitLineIndex: splitLineIndex + index,
15613
- lineIndex: additionLineIndex + index,
15614
- lineNumber: additionLineNumber + index,
15615
- noEOFCR: false
15616
- }
15617
- })) {
15618
- break hunkIterator;
15588
+ if (walkContextLines(state, len, diffStyle, (index) => {
15589
+ const isLastLine = index === len - 1;
15590
+ return state.emit({
15591
+ hunkIndex: diff.hunks.length,
15592
+ hunk: undefined,
15593
+ collapsedBefore: 0,
15594
+ collapsedAfter: isLastLine ? collapsedLines : 0,
15595
+ type: "context-expanded",
15596
+ deletionLine: {
15597
+ lineNumber: deletionLineNumber + index,
15598
+ lineIndex: deletionLineIndex + index,
15599
+ noEOFCR: false,
15600
+ unifiedLineIndex: unifiedLineIndex + index,
15601
+ splitLineIndex: splitLineIndex + index
15602
+ },
15603
+ additionLine: {
15604
+ unifiedLineIndex: unifiedLineIndex + index,
15605
+ splitLineIndex: splitLineIndex + index,
15606
+ lineIndex: additionLineIndex + index,
15607
+ lineNumber: additionLineNumber + index,
15608
+ noEOFCR: false
15619
15609
  }
15620
- } else {
15621
- state.incrementCounts(1, 1);
15622
- }
15623
- index++;
15610
+ });
15611
+ }, undefined, () => state.shouldBreak())) {
15612
+ break hunkIterator;
15624
15613
  }
15625
15614
  }
15626
15615
  }
@@ -15699,15 +15688,14 @@ function getHunkPrefixCounts({ diff, expandedHunks, collapsedContextThreshold })
15699
15688
  const leadingCount = leadingRegion.fromStart + leadingRegion.fromEnd;
15700
15689
  splitCount += leadingCount + hunk.splitLineCount;
15701
15690
  unifiedCount += leadingCount + hunk.unifiedLineCount;
15702
- if (index === finalHunkIndex && hasFinalCollapsedHunk(diff)) {
15703
- const trailingRangeSize = getTrailingRangeSize(diff, hunk);
15704
- const trailingRegion = getExpandedRegion({
15705
- isPartial: diff.isPartial,
15706
- rangeSize: trailingRangeSize,
15707
- expandedHunks,
15708
- hunkIndex: diff.hunks.length,
15709
- collapsedContextThreshold
15710
- });
15691
+ const trailingRegion = index === finalHunkIndex ? getTrailingExpandedRegion({
15692
+ fileDiff: diff,
15693
+ hunkIndex: index,
15694
+ expandedHunks,
15695
+ collapsedContextThreshold,
15696
+ errorPrefix: "iterateOverDiff"
15697
+ }) : undefined;
15698
+ if (trailingRegion != null) {
15711
15699
  const trailingCount = trailingRegion.fromStart + trailingRegion.fromEnd;
15712
15700
  splitCount += trailingCount;
15713
15701
  unifiedCount += trailingCount;
@@ -15719,7 +15707,7 @@ function getHunkPrefixCounts({ diff, expandedHunks, collapsedContextThreshold })
15719
15707
  }
15720
15708
  return prefixCounts;
15721
15709
  }
15722
- function getEqualLineIterationRange(state, count, diffStyle) {
15710
+ function getContextLineIterationBounds(state, count, diffStyle) {
15723
15711
  if (!state.isWindowedHighlight || count <= 0) {
15724
15712
  return [0, count];
15725
15713
  }
@@ -15749,20 +15737,31 @@ function getEqualLineIterationRange(state, count, diffStyle) {
15749
15737
  }
15750
15738
  return [start, end];
15751
15739
  }
15752
- function getTrailingRangeSize(diff, hunk) {
15753
- const additionRemaining = diff.additionLines.length - (hunk.additionLineIndex + hunk.additionCount);
15754
- const deletionRemaining = diff.deletionLines.length - (hunk.deletionLineIndex + hunk.deletionCount);
15755
- if (additionRemaining !== deletionRemaining) {
15756
- throw new Error(`iterateOverDiff: trailing context mismatch (additions=${additionRemaining}, deletions=${deletionRemaining}) for ${diff.name}`);
15740
+ function walkContextLines(state, count, diffStyle, callback, onSkippedStart, shouldBreak) {
15741
+ const [startIndex, endIndex] = getContextLineIterationBounds(state, count, diffStyle);
15742
+ if (startIndex > 0) {
15743
+ state.incrementCounts(startIndex, startIndex);
15744
+ onSkippedStart?.();
15757
15745
  }
15758
- return Math.min(additionRemaining, deletionRemaining);
15759
- }
15760
- function hasFinalCollapsedHunk(diff) {
15761
- const lastHunk = diff.hunks.at(-1);
15762
- if (lastHunk == null || diff.isPartial || diff.additionLines.length === 0 || diff.deletionLines.length === 0) {
15763
- return false;
15746
+ let index = startIndex;
15747
+ while (index < count) {
15748
+ if (shouldBreak?.() === true) {
15749
+ return true;
15750
+ }
15751
+ if (index >= endIndex) {
15752
+ state.incrementCounts(count - index, count - index);
15753
+ break;
15754
+ }
15755
+ if (state.isInWindow(0, 0)) {
15756
+ if (callback(index) === true) {
15757
+ return true;
15758
+ }
15759
+ } else {
15760
+ state.incrementCounts(1, 1);
15761
+ }
15762
+ index++;
15764
15763
  }
15765
- return lastHunk.additionLineIndex + lastHunk.additionCount < diff.additionLines.length || lastHunk.deletionLineIndex + lastHunk.deletionCount < diff.deletionLines.length;
15764
+ return false;
15766
15765
  }
15767
15766
  function getChangeIterationRanges(state, content, diffStyle) {
15768
15767
  if (!state.isWindowedHighlight) {