| 219 | } |
| 220 | |
| 221 | function whitespaceNormalizedSpans(content: string, find: string): string[] { |
| 222 | const out: string[] = []; |
| 223 | const normalize = (text: string) => text.replace(/\s+/g, ' ').trim(); |
| 224 | const normalizedFind = normalize(find); |
| 225 | if (normalizedFind === '') return out; |
| 226 | const lines = content.split('\n'); |
| 227 | const findLines = find.split('\n'); |
| 228 | if (findLines.length === 1) { |
| 229 | // Single-line old_string: match individual lines only. A multi-line |
| 230 | // old_string must never collapse onto one physical line — normalize() |
| 231 | // turns newlines into spaces, so an unguarded single-line scan would let |
| 232 | // `a\nb` match the line `a b`, which is a wrong-location edit. |
| 233 | for (let i = 0; i < lines.length; i++) { |
| 234 | if (normalize(lines[i]) === normalizedFind) out.push(lines[i]); |
| 235 | } |
| 236 | } else { |
| 237 | for (let i = 0; i <= lines.length - findLines.length; i++) { |
| 238 | const block = lines.slice(i, i + findLines.length).join('\n'); |
| 239 | if (normalize(block) === normalizedFind) out.push(block); |
| 240 | } |
| 241 | } |
| 242 | return out; |
| 243 | } |
| 244 | |
| 245 | function escapeNormalizedSpans(content: string, find: string): string[] { |
| 246 | const out: string[] = []; |