diff --git a/src/filesystem/index.ts b/src/filesystem/index.ts index 8ebae2fa..44aa9480 100644 --- a/src/filesystem/index.ts +++ b/src/filesystem/index.ts @@ -223,13 +223,34 @@ async function searchFiles( return results; } -// Line ending detection and normalization utilities -// These functions ensure consistent behavior across different platforms and Git configurations. -// They handle the following scenarios: -// - Windows CRLF (\r\n) vs Unix LF (\n) line endings -// - Git's core.autocrlf setting converting line endings -// - Mixed line endings within the same file -// This makes the edit functionality reliable regardless of the development environment. +// Content normalization utilities +// These functions handle: +// - Line ending normalization (CRLF vs LF) +// - Indentation preservation and normalization +// - Git's core.autocrlf setting +// - Mixed line endings +// This makes the edit functionality reliable across different environments and formatting styles + +function normalizeForComparison(content: string): string { + // First normalize line endings + let normalized = content.replace(/\r\n/g, '\n'); + // Remove leading/trailing whitespace from each line while preserving empty lines + normalized = normalized.split('\n') + .map(line => line.trim()) + .join('\n'); + return normalized; +} + +function preserveIndentation(newContent: string, originalContent: string): string { + const originalLines = originalContent.split(/\r?\n/); + const indentMatch = originalLines.find(line => line.trim())?.match(/^\s*/); + const baseIndent = indentMatch ? indentMatch[0] : ''; + + return newContent.split(/\r?\n/) + .map(line => line.trim() ? baseIndent + line : line) + .join(originalContent.includes('\r\n') ? '\r\n' : '\n'); +} + function detectLineEnding(content: string): string { // Check if the content contains CRLF if (content.includes('\r\n')) { @@ -263,14 +284,10 @@ interface EditPreview { // File editing utilities async function applyFileEdits(filePath: string, edits: z.infer[]): Promise { - // Read the file and detect its line endings + // Read the file content let currentContent = await fs.readFile(filePath, 'utf-8'); - const originalLineEnding = detectLineEnding(currentContent); - - // Normalize content for processing - currentContent = normalizeLineEndings(currentContent); const previews: EditPreview[] = []; - let lines = currentContent.split('\n'); + let lines = currentContent.split(/\r?\n/); // Sort edits by line number in descending order const sortedEdits = [...edits].sort((a, b) => { @@ -281,73 +298,76 @@ async function applyFileEdits(filePath: string, edits: z.infer