applyEditsToFile function
Apply a list of edits to file content and return the updated content. Throws if any edit fails or produces overlapping changes.
Implementation
String applyEditsToFile(String fileContents, List<FileEdit> edits) {
var updatedFile = fileContents;
final appliedNewStrings = <String>[];
// Special case for empty files
if (fileContents.isEmpty &&
edits.length == 1 &&
edits[0].oldString.isEmpty &&
edits[0].newString.isEmpty) {
return '';
}
for (final edit in edits) {
// Strip trailing newlines from old_string before checking
final oldStringToCheck = edit.oldString.replaceAll(RegExp(r'\n+$'), '');
// Check if old_string is a substring of any previously applied new_string
for (final previousNewString in appliedNewStrings) {
if (oldStringToCheck.isNotEmpty &&
previousNewString.contains(oldStringToCheck)) {
throw StateError(
'Cannot edit file: old_string is a substring of a new_string '
'from a previous edit.',
);
}
}
final previousContent = updatedFile;
updatedFile = edit.oldString.isEmpty
? edit.newString
: applyEditToFile(
updatedFile,
edit.oldString,
edit.newString,
replaceAll: edit.replaceAll,
);
// If this edit did not change anything, throw
if (updatedFile == previousContent) {
throw StateError('String not found in file. Failed to apply edit.');
}
appliedNewStrings.add(edit.newString);
}
if (updatedFile == fileContents) {
throw StateError(
'Original and edited file match exactly. Failed to apply edit.',
);
}
return updatedFile;
}