| 151 | |
| 152 | // Group adjacent add/remove lines for word-level diffing |
| 153 | export function processAdjacentLines(lineObjects: LineObject[]): LineObject[] { |
| 154 | const processedLines: LineObject[] = []; |
| 155 | let i = 0; |
| 156 | while (i < lineObjects.length) { |
| 157 | const current = lineObjects[i]; |
| 158 | if (!current) { |
| 159 | i++; |
| 160 | continue; |
| 161 | } |
| 162 | |
| 163 | // Find a sequence of remove followed by add (possible word-level diff candidates) |
| 164 | if (current.type === 'remove') { |
| 165 | const removeLines: LineObject[] = [current]; |
| 166 | let j = i + 1; |
| 167 | |
| 168 | // Collect consecutive remove lines |
| 169 | while (j < lineObjects.length && lineObjects[j]?.type === 'remove') { |
| 170 | const line = lineObjects[j]; |
| 171 | if (line) { |
| 172 | removeLines.push(line); |
| 173 | } |
| 174 | j++; |
| 175 | } |
| 176 | |
| 177 | // Check if there are add lines following the remove lines |
| 178 | const addLines: LineObject[] = []; |
| 179 | while (j < lineObjects.length && lineObjects[j]?.type === 'add') { |
| 180 | const line = lineObjects[j]; |
| 181 | if (line) { |
| 182 | addLines.push(line); |
| 183 | } |
| 184 | j++; |
| 185 | } |
| 186 | |
| 187 | // If we have both remove and add lines, perform word-level diffing |
| 188 | if (removeLines.length > 0 && addLines.length > 0) { |
| 189 | // For word diffing, we'll compare each pair of lines or the closest available match |
| 190 | const pairCount = Math.min(removeLines.length, addLines.length); |
| 191 | |
| 192 | // Add paired lines with word diff info |
| 193 | for (let k = 0; k < pairCount; k++) { |
| 194 | const removeLine = removeLines[k]; |
| 195 | const addLine = addLines[k]; |
| 196 | if (removeLine && addLine) { |
| 197 | removeLine.wordDiff = true; |
| 198 | addLine.wordDiff = true; |
| 199 | |
| 200 | // Store the matched pair for later word diffing |
| 201 | removeLine.matchedLine = addLine; |
| 202 | addLine.matchedLine = removeLine; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | // Add all remove lines (both paired and unpaired) |
| 207 | processedLines.push(...removeLines.filter(Boolean)); |
| 208 | |
| 209 | // Then add all add lines (both paired and unpaired) |
| 210 | processedLines.push(...addLines.filter(Boolean)); |