Walk the LCS DP table backwards to produce an ordered edit script.
(oldLines: string[], newLines: string[])
| 47 | |
| 48 | /** Walk the LCS DP table backwards to produce an ordered edit script. */ |
| 49 | function buildEditScript(oldLines: string[], newLines: string[]): EditOp[] { |
| 50 | const m = oldLines.length; |
| 51 | const n = newLines.length; |
| 52 | const stride = n + 1; |
| 53 | const dp = computeLcsTable(oldLines, newLines); |
| 54 | const ops: EditOp[] = []; |
| 55 | let i = m; |
| 56 | let j = n; |
| 57 | while (i > 0 && j > 0) { |
| 58 | if (oldLines[i - 1] === newLines[j - 1]) { |
| 59 | ops.push({ type: 'equal', oldLine: oldLines[i - 1], newLine: newLines[j - 1] }); |
| 60 | i--; |
| 61 | j--; |
| 62 | } else if (dp[(i - 1) * stride + j] >= dp[i * stride + (j - 1)]) { |
| 63 | ops.push({ type: 'delete', oldLine: oldLines[i - 1] }); |
| 64 | i--; |
| 65 | } else { |
| 66 | ops.push({ type: 'insert', newLine: newLines[j - 1] }); |
| 67 | j--; |
| 68 | } |
| 69 | } |
| 70 | while (i > 0) { |
| 71 | ops.push({ type: 'delete', oldLine: oldLines[i - 1] }); |
| 72 | i--; |
| 73 | } |
| 74 | while (j > 0) { |
| 75 | ops.push({ type: 'insert', newLine: newLines[j - 1] }); |
| 76 | j--; |
| 77 | } |
| 78 | ops.reverse(); |
| 79 | return ops; |
| 80 | } |
| 81 | |
| 82 | function countsFromOps(ops: EditOp[]): { added: number; removed: number; modified: number } { |
| 83 | // Pair adjacent delete+insert runs as "modified" — git's default semantics. |
no test coverage detected