From 9e548988666c5ce1bcc81e74197b5c2284e5bf86 Mon Sep 17 00:00:00 2001 From: zjy1412 Date: Thu, 17 Apr 2025 14:30:13 +0800 Subject: [PATCH 1/2] fix: correctly detect edit blocks in diff-fenced mode --- aider/coders/editblock_coder.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aider/coders/editblock_coder.py b/aider/coders/editblock_coder.py index 321a6a921..4d7776278 100644 --- a/aider/coders/editblock_coder.py +++ b/aider/coders/editblock_coder.py @@ -454,7 +454,10 @@ def find_original_update_blocks(content, fence=DEFAULT_FENCE, valid_fnames=None) "```csh", "```tcsh", ] - next_is_editblock = i + 1 < len(lines) and head_pattern.match(lines[i + 1].strip()) + + # Check if the next line or the one after that is an editblock + next_is_editblock = (i + 1 < len(lines) and head_pattern.match(lines[i + 1].strip()) + or i + 2 < len(lines) and head_pattern.match(lines[i + 2].strip())) if any(line.strip().startswith(start) for start in shell_starts) and not next_is_editblock: shell_content = [] From a564f94bf34ef9611f14fda40640ffc4aaf64423 Mon Sep 17 00:00:00 2001 From: zjy1412 Date: Thu, 17 Apr 2025 16:50:54 +0800 Subject: [PATCH 2/2] Added two test cases --- tests/basic/test_editblock.py | 63 +++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/basic/test_editblock.py b/tests/basic/test_editblock.py index 0a1f1bf5b..d80952bbe 100644 --- a/tests/basic/test_editblock.py +++ b/tests/basic/test_editblock.py @@ -575,6 +575,69 @@ Hope you like it! edits = list(eb.find_original_update_blocks(edit, fence=quad_backticks)) self.assertEqual(edits, [("foo.txt", "", "Tooooo\n")]) + #Test for shell script blocks with sh language identifier (issue #3785) + def test_find_original_update_blocks_with_sh_language_identifier(self): + # https://github.com/Aider-AI/aider/issues/3785 + edit = """ +Here's a shell script: + +```sh +test_hello.sh +<<<<<<< SEARCH +======= +#!/bin/bash +# Check if exactly one argument is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +# Echo the first argument +echo "$1" + +exit 0 +>>>>>>> REPLACE +``` +""" + + edits = list(eb.find_original_update_blocks(edit)) + # Instead of comparing exact strings, check that we got the right file and structure + self.assertEqual(len(edits), 1) + self.assertEqual(edits[0][0], "test_hello.sh") + self.assertEqual(edits[0][1], "") + + # Check that the content contains the expected shell script elements + result_content = edits[0][2] + self.assertIn("#!/bin/bash", result_content) + self.assertIn("if [ \"$#\" -ne 1 ];", result_content) + self.assertIn("echo \"Usage: $0 \"", result_content) + self.assertIn("exit 1", result_content) + self.assertIn("echo \"$1\"", result_content) + self.assertIn("exit 0", result_content) + + #Test for C# code blocks with csharp language identifier + def test_find_original_update_blocks_with_csharp_language_identifier(self): + edit = """ +Here's a C# code change: + +```csharp +Program.cs +<<<<<<< SEARCH +Console.WriteLine("Hello World!"); +======= +Console.WriteLine("Hello, C# World!"); +>>>>>>> REPLACE +``` +""" + + edits = list(eb.find_original_update_blocks(edit)) + search_text = "Console.WriteLine(\"Hello World!\");\n" + replace_text = "Console.WriteLine(\"Hello, C# World!\");\n" + self.assertEqual( + edits, + [("Program.cs", search_text, replace_text)] + ) + if __name__ == "__main__": unittest.main()