diff --git a/pr_agent/tools/pr_code_suggestions.py b/pr_agent/tools/pr_code_suggestions.py index 0fdc8019fe..1b5ada89f3 100644 --- a/pr_agent/tools/pr_code_suggestions.py +++ b/pr_agent/tools/pr_code_suggestions.py @@ -609,10 +609,26 @@ def dedent_code(self, relevant_file, relevant_lines_start, new_code_snippet): original_initial_spaces = len(original_initial_line) - len(original_initial_line.lstrip()) # lstrip works both for spaces and tabs suggested_initial_spaces = len(suggested_initial_line) - len(suggested_initial_line.lstrip()) delta_spaces = original_initial_spaces - suggested_initial_spaces + # Detect indentation character from original line + indent_char = '\t' if original_initial_line.startswith('\t') else ' ' if delta_spaces > 0: - # Detect indentation character from original line - indent_char = '\t' if original_initial_line.startswith('\t') else ' ' new_code_snippet = textwrap.indent(new_code_snippet, delta_spaces * indent_char).rstrip('\n') + elif delta_spaces < 0: + new_code_snippet = textwrap.dedent(new_code_snippet).rstrip('\n') + # Normalize all lines in the suggestion to use the original's + # indentation character. This fixes the bug where /improve + # replaces tabs with spaces in Go, Makefile, and other + # tab-indented codebases (#1858). + if indent_char == '\t': + new_lines = [] + for line in new_code_snippet.split('\n'): + stripped = line.lstrip(' ') + leading_spaces = len(line) - len(stripped) + if leading_spaces > 0: + new_lines.append('\t' * (leading_spaces // 4) + stripped) + else: + new_lines.append(line) + new_code_snippet = '\n'.join(new_lines) except Exception as e: get_logger().error(f"Error when dedenting code snippet for file {relevant_file}, error: {e}")