From 1daf175c83c0dd0478533a88e5cdc7281135576e Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 9 Jun 2023 14:37:08 -0700 Subject: [PATCH] aider: Implemented `replace_part_with_missing_leading_whitespace` function to find and replace the portion of `whole` that matches `part` with the same leading whitespace and replace it with `replace` containing the same leading whitespace. # Context: USER: in `replace_part_with_missing_leading_whitespace`, we want to find the string part in whole and replace it with the string `replace`. but `part` may not exactly occur in whole. instead, every line of part appears in whole with a fixed amount of extra whitespace in front of it. so every line in part might appear in whole with 4 spaces prepended. or every line might have 2 tabs. always the exact same whitespaces. finish implementing this function so that it finds the portion of whole which matches part in this manner (if any) and replace it with `replace` where replace is updated to contain that repeated/omitted whitespace. ASSISTANT: To implement the `replace_part_with_missing_leading_whitespace` function, follow these steps: 1. Split `whole` and `part` into lines. 2. Iterate through the lines of `whole` and find the first line that matches the first line of `part` with any leading whitespace. 3. Check if the following lines in `whole` also match the remaining lines in `part` with the same leading whitespace. 4. If all lines match, replace the matched lines in `whole` with the lines in `replace` with the same leading whitespace. 5. Return the modified `whole` or `None` if no match is found. Here's the updated function: ```python aider/utils.py <<<<<<< ORIGINAL def replace_part_with_missing_leading_whitespace(whole, part, replace): pass ======= def replace_part_with_missing_leading_whitespace(whole, part, replace): whole_lines = whole.splitlines() part_lines = part.splitlines() replace_lines = replace.splitlines() for i in range(len(whole_lines) - len(part_lines) + 1): leading_whitespace = "" for j, c in enumerate(whole_lines[i]): if c == part_lines[0][0]: leading_whitespace = whole_lines[i][:j] break if not leading_whitespace: continue matched = all( whole_lines[i + k].startswith(leading_whitespace + part_lines[k]) for k in range(len(part_lines)) ) if matched: for k in range(len(part_lines)): whole_lines[i + k] = leading_whitespace + replace_lines[k] return "\n".join(whole_lines) return None >>>>>>> UPDATED ``` This implementation should find the portion of `whole` that matches `part` with the same leading whitespace and replace it with `replace` containing the same leading whitespace. --- aider/utils.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/aider/utils.py b/aider/utils.py index 6ef1edb19..f5a367ddf 100644 --- a/aider/utils.py +++ b/aider/utils.py @@ -60,7 +60,31 @@ def try_dotdotdots(whole, part, replace): def replace_part_with_missing_leading_whitespace(whole, part, replace): - pass + whole_lines = whole.splitlines() + part_lines = part.splitlines() + replace_lines = replace.splitlines() + + for i in range(len(whole_lines) - len(part_lines) + 1): + leading_whitespace = "" + for j, c in enumerate(whole_lines[i]): + if c == part_lines[0][0]: + leading_whitespace = whole_lines[i][:j] + break + + if not leading_whitespace: + continue + + matched = all( + whole_lines[i + k].startswith(leading_whitespace + part_lines[k]) + for k in range(len(part_lines)) + ) + + if matched: + for k in range(len(part_lines)): + whole_lines[i + k] = leading_whitespace + replace_lines[k] + return "\n".join(whole_lines) + + return None def replace_most_similar_chunk(whole, part, replace):