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

Function replace

packages/opencode/src/tool/edit.ts:682–729  ·  view source on GitHub ↗
(content: string, oldString: string, newString: string, replaceAll = false)

Source from the content-addressed store, hash-verified

680}
681
682export function replace(content: string, oldString: string, newString: string, replaceAll = false): string {
683 if (oldString === newString) {
684 throw new Error("No changes to apply: oldString and newString are identical.")
685 }
686 if (oldString === "") {
687 throw new Error(
688 "oldString cannot be empty when editing an existing file. Provide the exact text to replace, or use write for an intentional full-file replacement.",
689 )
690 }
691
692 let notFound = true
693
694 for (const replacer of [
695 SimpleReplacer,
696 LineTrimmedReplacer,
697 BlockAnchorReplacer,
698 WhitespaceNormalizedReplacer,
699 IndentationFlexibleReplacer,
700 EscapeNormalizedReplacer,
701 TrimmedBoundaryReplacer,
702 ContextAwareReplacer,
703 MultiOccurrenceReplacer,
704 ]) {
705 for (const search of replacer(content, oldString)) {
706 const index = content.indexOf(search)
707 if (index === -1) continue
708 notFound = false
709 if (isDisproportionateMatch(search, oldString)) {
710 throw new Error(
711 "Refusing replacement because the matched span is much larger than oldString. Re-read the file and provide the full exact oldString for the intended replacement.",
712 )
713 }
714 if (replaceAll) {
715 return content.replaceAll(search, newString)
716 }
717 const lastIndex = content.lastIndexOf(search)
718 if (index !== lastIndex) continue
719 return content.substring(0, index) + newString + content.substring(index + search.length)
720 }
721 }
722
723 if (notFound) {
724 throw new Error(
725 "Could not find oldString in the file. It must match exactly, including whitespace, indentation, and line endings.",
726 )
727 }
728 throw new Error("Found multiple matches for oldString. Provide more surrounding context to make the match unique.")
729}
730
731function isDisproportionateMatch(search: string, oldString: string) {
732 const oldLines = oldString.split("\n").length

Callers 1

edit.tsFile · 0.70

Calls 2

replacerFunction · 0.85
isDisproportionateMatchFunction · 0.85

Tested by

no test coverage detected