MCPcopy Index your code
hub / github.com/anomalyco/opencode / computeReplacements

Function computeReplacements

packages/opencode/src/patch/index.ts:342–396  ·  view source on GitHub ↗
(
  originalLines: string[],
  filePath: string,
  chunks: UpdateFileChunk[],
)

Source from the content-addressed store, hash-verified

340}
341
342function computeReplacements(
343 originalLines: string[],
344 filePath: string,
345 chunks: UpdateFileChunk[],
346): Array<[number, number, string[]]> {
347 const replacements: Array<[number, number, string[]]> = []
348 let lineIndex = 0
349
350 for (const chunk of chunks) {
351 // Handle context-based seeking
352 if (chunk.change_context) {
353 const contextIdx = seekSequence(originalLines, [chunk.change_context], lineIndex)
354 if (contextIdx === -1) {
355 throw new Error(`Failed to find context '${chunk.change_context}' in ${filePath}`)
356 }
357 lineIndex = contextIdx + 1
358 }
359
360 // Handle pure addition (no old lines)
361 if (chunk.old_lines.length === 0) {
362 const insertionIdx =
363 originalLines.length > 0 && originalLines[originalLines.length - 1] === ""
364 ? originalLines.length - 1
365 : originalLines.length
366 replacements.push([insertionIdx, 0, chunk.new_lines])
367 continue
368 }
369
370 // Try to match old lines in the file
371 let pattern = chunk.old_lines
372 let newSlice = chunk.new_lines
373 let found = seekSequence(originalLines, pattern, lineIndex, chunk.is_end_of_file)
374
375 // Retry without trailing empty line if not found
376 if (found === -1 && pattern.length > 0 && pattern[pattern.length - 1] === "") {
377 pattern = pattern.slice(0, -1)
378 if (newSlice.length > 0 && newSlice[newSlice.length - 1] === "") {
379 newSlice = newSlice.slice(0, -1)
380 }
381 found = seekSequence(originalLines, pattern, lineIndex, chunk.is_end_of_file)
382 }
383
384 if (found !== -1) {
385 replacements.push([found, pattern.length, newSlice])
386 lineIndex = found + pattern.length
387 } else {
388 throw new Error(`Failed to find expected lines in ${filePath}:\n${chunk.old_lines.join("\n")}`)
389 }
390 }
391
392 // Sort replacements by index to apply in order
393 replacements.sort((a, b) => a[0] - b[0])
394
395 return replacements
396}
397
398function applyReplacements(lines: string[], replacements: Array<[number, number, string[]]>): string[] {
399 // Apply replacements in reverse order to avoid index shifting

Callers 1

Calls 2

seekSequenceFunction · 0.85
pushMethod · 0.80

Tested by

no test coverage detected