(lines: string[], oldStart: number, newStart: number)
| 13 | * This provides more syntactic context to the highlighter |
| 14 | */ |
| 15 | export function groupDiffLines(lines: string[], oldStart: number, newStart: number): DiffChunk[] { |
| 16 | const chunks: DiffChunk[] = []; |
| 17 | let currentChunk: DiffChunk | null = null; |
| 18 | |
| 19 | let oldLineNum = oldStart; |
| 20 | let newLineNum = newStart; |
| 21 | |
| 22 | for (let i = 0; i < lines.length; i++) { |
| 23 | const line = lines[i]; |
| 24 | const firstChar = line[0]; |
| 25 | |
| 26 | // Skip headers (@@) - they reset line numbers |
| 27 | if (line.startsWith("@@")) { |
| 28 | // Flush current chunk |
| 29 | if (currentChunk && currentChunk.lines.length > 0) { |
| 30 | chunks.push(currentChunk); |
| 31 | currentChunk = null; |
| 32 | } |
| 33 | |
| 34 | // Parse header for line numbers |
| 35 | const regex = /^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/; |
| 36 | const match = regex.exec(line); |
| 37 | if (match) { |
| 38 | oldLineNum = parseInt(match[1], 10); |
| 39 | newLineNum = parseInt(match[2], 10); |
| 40 | } |
| 41 | continue; |
| 42 | } |
| 43 | |
| 44 | // Determine line type and line numbers. |
| 45 | let type: Exclude<DiffLineType, "header">; |
| 46 | let oldLineNumber: number | null; |
| 47 | let newLineNumber: number | null; |
| 48 | |
| 49 | if (firstChar === "+") { |
| 50 | type = "add"; |
| 51 | oldLineNumber = null; |
| 52 | newLineNumber = newLineNum++; |
| 53 | } else if (firstChar === "-") { |
| 54 | type = "remove"; |
| 55 | oldLineNumber = oldLineNum++; |
| 56 | newLineNumber = null; |
| 57 | } else { |
| 58 | type = "context"; |
| 59 | oldLineNumber = oldLineNum++; |
| 60 | newLineNumber = newLineNum++; |
| 61 | } |
| 62 | |
| 63 | // Start new chunk if type changed or no current chunk |
| 64 | // eslint-disable-next-line @typescript-eslint/prefer-optional-chain |
| 65 | if (!currentChunk || currentChunk.type !== type) { |
| 66 | // Flush previous chunk if it exists |
| 67 | if (currentChunk?.lines.length) { |
| 68 | chunks.push(currentChunk); |
| 69 | } |
| 70 | // Start new chunk |
| 71 | currentChunk = { |
| 72 | type, |
no test coverage detected