From 5ec441dd2c84d8abad5ed0706a4536e0c67200a8 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Sat, 11 May 2024 10:25:16 -0700 Subject: [PATCH] More clear feedback when SEARCH/REPLACE blocks fail to match --- aider/coders/editblock_coder.py | 45 +++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/aider/coders/editblock_coder.py b/aider/coders/editblock_coder.py index 0c96cc559..8f6582d3b 100644 --- a/aider/coders/editblock_coder.py +++ b/aider/coders/editblock_coder.py @@ -24,24 +24,47 @@ class EditBlockCoder(Coder): return edits def apply_edits(self, edits): - for path, original, updated in edits: + failed = [] + passed = [] + for edit in edits: + path, original, updated = edit full_path = self.abs_root_path(path) content = self.io.read_text(full_path) content = do_replace(full_path, content, original, updated, self.fence) if content: self.io.write_text(full_path, content) - continue - raise ValueError(f"""InvalidEditBlock: edit failed! + passed.append(edit) + else: + failed.append(edit) -{path} does not contain the *exact chunk* of SEARCH lines you specified. -Try again. -DO NOT skip blank lines, comments, docstrings, etc! -The SEARCH block needs to be EXACTLY the same as the lines in {path} with nothing missing! + if not failed: + return -{path} does not contain these {len(original.splitlines())} exact lines in a row: -``` -{original}``` -""") + blocks = "block" if len(failed) == 1 else "blocks" + + res = f"# {len(failed)} SEARCH/REPLACE {blocks} failed to match!\n" + for edit in failed: + path, original, updated = edit + res += f""" +## SearchReplaceNoExactMatch: This SEARCH block failed to exactly match lines in {path} +<<<<<<< SEARCH +{original} +======= +{updated} +>>>>>>> REPLACE +""" + res += ( + "\nThe SEARCH section must exactly match an existing block of lines including all white" + " space, comments, indentation, docstrings, etc\n" + ) + if passed: + pblocks = "block" if len(passed) == 1 else "blocks" + res += f""" +# The other {len(passed)} SEARCH/REPLACE {pblocks} were applied successfully. +Don't re-send them. +Just reply with fixed versions of the {blocks} above that failed to match. +""" + raise ValueError(res) def prep(content):