(diff: string)
| 37 | * structure — degrades to unnumbered meta rows. |
| 38 | */ |
| 39 | export function parseUnifiedDiffRows(diff: string): UnifiedDiffRow[] { |
| 40 | const lines = diff.split('\n'); |
| 41 | // A trailing newline terminates the diff rather than starting an empty row. |
| 42 | if (lines.length > 1 && lines[lines.length - 1] === '') lines.pop(); |
| 43 | |
| 44 | const rows: UnifiedDiffRow[] = []; |
| 45 | let oldLine = 0; |
| 46 | let newLine = 0; |
| 47 | let remainingOld = 0; |
| 48 | let remainingNew = 0; |
| 49 | let inHunk = false; |
| 50 | |
| 51 | for (const line of lines) { |
| 52 | if (inHunk && remainingOld + remainingNew > 0) { |
| 53 | const marker = line.charAt(0); |
| 54 | if (marker === '\\') { |
| 55 | // `\ No newline at end of file` annotates the previous row without |
| 56 | // consuming a line on either side. |
| 57 | rows.push({ kind: 'meta', text: line }); |
| 58 | continue; |
| 59 | } |
| 60 | if (marker === '-') { |
| 61 | rows.push({ kind: 'del', text: line, oldLine }); |
| 62 | oldLine += 1; |
| 63 | remainingOld -= 1; |
| 64 | continue; |
| 65 | } |
| 66 | if (marker === '+') { |
| 67 | rows.push({ kind: 'add', text: line, newLine }); |
| 68 | newLine += 1; |
| 69 | remainingNew -= 1; |
| 70 | continue; |
| 71 | } |
| 72 | // ' ' context, and the bare empty line some generators emit for one. |
| 73 | rows.push({ kind: 'ctx', text: line, oldLine, newLine }); |
| 74 | oldLine += 1; |
| 75 | newLine += 1; |
| 76 | remainingOld -= 1; |
| 77 | remainingNew -= 1; |
| 78 | continue; |
| 79 | } |
| 80 | inHunk = false; |
| 81 | |
| 82 | const hunk = HUNK_HEADER.exec(line); |
| 83 | if (hunk) { |
| 84 | oldLine = Number(hunk[1]); |
| 85 | newLine = Number(hunk[3]); |
| 86 | remainingOld = hunk[2] === undefined ? 1 : Number(hunk[2]); |
| 87 | remainingNew = hunk[4] === undefined ? 1 : Number(hunk[4]); |
| 88 | inHunk = true; |
| 89 | rows.push({ kind: 'hunk', text: line }); |
| 90 | continue; |
| 91 | } |
| 92 | if (line.startsWith('diff ')) { |
| 93 | rows.push({ kind: 'meta', text: line }); |
| 94 | continue; |
| 95 | } |
| 96 | if (line.startsWith('--- ') || line.startsWith('+++ ') || line.startsWith('index ')) { |
no test coverage detected