diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml index 500cd29bf..aee25446c 100644 --- a/.github/workflows/close-stale.yml +++ b/.github/workflows/close-stale.yml @@ -13,8 +13,8 @@ jobs: steps: - uses: actions/stale@v9 with: - stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Remove stale label or add a comment to keep this issue open. Otherwise, it will be closed in 7 days.' - close-issue-message: 'This issue was closed because it has been stalled for 21 days with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue any time.' + stale-issue-message: 'This issue has been labelled stale because it has been open for 2 weeks with no activity. Remove stale label or add a comment to keep this issue open. Otherwise, it will be closed in 7 days.' + close-issue-message: 'This issue was closed because it has been stalled for 3 weeks with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue any time.' days-before-stale: 14 days-before-close: 7 stale-issue-label: 'stale' diff --git a/aider/coders/editblock_prompts.py b/aider/coders/editblock_prompts.py index 488afdca4..05d2a3de3 100644 --- a/aider/coders/editblock_prompts.py +++ b/aider/coders/editblock_prompts.py @@ -159,8 +159,9 @@ Use the *FULL* file path, as shown to you by the user. Every *SEARCH* section must *EXACTLY MATCH* the existing file content, character for character, including all comments, docstrings, etc. If the file contains code or other data wrapped/escaped in json/xml/quotes or other containers, you need to propose edits to the literal contents of the file, including the container markup. -*SEARCH/REPLACE* blocks will replace *all* matching occurrences. -Include enough lines to make the SEARCH blocks uniquely match the lines to change. +*SEARCH/REPLACE* blocks will *only* replace the first match occurrence. +Including multiple unique *SEARCH/REPLACE* blocks if needed. +Include enough lines in each SEARCH section to uniquely match each set of lines that need to change. Keep *SEARCH/REPLACE* blocks concise. Break large *SEARCH/REPLACE* blocks into a series of smaller blocks that each change a small portion of the file. diff --git a/tests/basic/test_editblock.py b/tests/basic/test_editblock.py index 395c59d90..4b3817b1c 100644 --- a/tests/basic/test_editblock.py +++ b/tests/basic/test_editblock.py @@ -296,6 +296,28 @@ These changes replace the `subprocess.run` patches with `subprocess.check_output result = eb.replace_most_similar_chunk(whole, part, replace) self.assertEqual(result, expected_output) + def test_replace_multiple_matches(self): + "only replace first occurrence" + + whole = "line1\nline2\nline1\nline3\n" + part = "line1\n" + replace = "new_line\n" + expected_output = "new_line\nline2\nline1\nline3\n" + + result = eb.replace_most_similar_chunk(whole, part, replace) + self.assertEqual(result, expected_output) + + def test_replace_multiple_matches_missing_whitespace(self): + "only replace first occurrence" + + whole = " line1\n line2\n line1\n line3\n" + part = "line1\n" + replace = "new_line\n" + expected_output = " new_line\n line2\n line1\n line3\n" + + result = eb.replace_most_similar_chunk(whole, part, replace) + self.assertEqual(result, expected_output) + def test_replace_part_with_just_some_missing_leading_whitespace(self): whole = " line1\n line2\n line3\n" part = " line1\n line2\n" @@ -482,9 +504,7 @@ two Hope you like it! """ - edits = list( - eb.find_original_update_blocks(edit, valid_fnames=["path/to/a/file1.txt"]) - ) + edits = list(eb.find_original_update_blocks(edit, valid_fnames=["path/to/a/file1.txt"])) self.assertEqual( edits, [