Implement the str_replace command, which replaces old_str with new_str in the file content
(self, path: Path, old_str: str, new_str: str | None)
| 154 | ) |
| 155 | |
| 156 | def str_replace(self, path: Path, old_str: str, new_str: str | None): |
| 157 | """Implement the str_replace command, which replaces old_str with new_str in the file content""" |
| 158 | # Read the file content |
| 159 | file_content = self.read_file(path).expandtabs() |
| 160 | old_str = old_str.expandtabs() |
| 161 | new_str = new_str.expandtabs() if new_str is not None else "" |
| 162 | |
| 163 | # Check if old_str is unique in the file |
| 164 | occurrences = file_content.count(old_str) |
| 165 | if occurrences == 0: |
| 166 | raise ToolError( |
| 167 | f"No replacement was performed, old_str `{old_str}` did not appear verbatim in {path}." |
| 168 | ) |
| 169 | elif occurrences > 1: |
| 170 | file_content_lines = file_content.split("\n") |
| 171 | lines = [ |
| 172 | idx + 1 |
| 173 | for idx, line in enumerate(file_content_lines) |
| 174 | if old_str in line |
| 175 | ] |
| 176 | raise ToolError( |
| 177 | f"No replacement was performed. Multiple occurrences of old_str `{old_str}` in lines {lines}. Please ensure it is unique" |
| 178 | ) |
| 179 | |
| 180 | # Replace old_str with new_str |
| 181 | new_file_content = file_content.replace(old_str, new_str) |
| 182 | |
| 183 | # Write the new content to the file |
| 184 | self.write_file(path, new_file_content) |
| 185 | |
| 186 | # Save the content to history |
| 187 | self._file_history[path].append(file_content) |
| 188 | |
| 189 | # Create a snippet of the edited section |
| 190 | replacement_line = file_content.split(old_str)[0].count("\n") |
| 191 | start_line = max(0, replacement_line - SNIPPET_LINES) |
| 192 | end_line = replacement_line + SNIPPET_LINES + new_str.count("\n") |
| 193 | snippet = "\n".join(new_file_content.split("\n")[start_line : end_line + 1]) |
| 194 | |
| 195 | # Prepare the success message |
| 196 | success_msg = f"The file {path} has been edited. " |
| 197 | success_msg += self._make_output( |
| 198 | snippet, f"a snippet of {path}", start_line + 1 |
| 199 | ) |
| 200 | success_msg += "Review the changes and make sure they are as expected. Edit the file again if necessary." |
| 201 | |
| 202 | return CLIResult(output=success_msg) |
| 203 | |
| 204 | def insert(self, path: Path, insert_line: int, new_str: str): |
| 205 | """Implement the insert command, which inserts new_str at the specified line in the file content.""" |
no test coverage detected