Better error messages for diffs

This commit is contained in:
Matt Rubens
2024-12-15 19:34:51 -05:00
parent 25da0b1907
commit c1dfdeda22
5 changed files with 226 additions and 56 deletions

View File

@@ -1,4 +1,4 @@
import { DiffStrategy } from "../types"
import { DiffStrategy, DiffResult } from "../types"
function levenshteinDistance(a: string, b: string): number {
const matrix: number[][] = [];
@@ -115,11 +115,20 @@ Your search/replace content here
</apply_diff>`
}
applyDiff(originalContent: string, diffContent: string, startLine?: number, endLine?: number): string | false {
applyDiff(originalContent: string, diffContent: string, startLine?: number, endLine?: number): DiffResult {
// Extract the search and replace blocks
const match = diffContent.match(/<<<<<<< SEARCH\n([\s\S]*?)\n=======\n([\s\S]*?)\n>>>>>>> REPLACE/);
if (!match) {
return false;
// Log detailed format information
console.log('Invalid Diff Format Debug:', {
expectedFormat: "<<<<<<< SEARCH\\n[search content]\\n=======\\n[replace content]\\n>>>>>>> REPLACE",
tip: "Make sure to include both SEARCH and REPLACE sections with correct markers"
});
return {
success: false,
error: "Invalid diff format - missing required SEARCH/REPLACE sections"
};
}
const [_, searchContent, replaceContent] = match;
@@ -135,12 +144,26 @@ Your search/replace content here
// First try exact line range if provided
let matchIndex = -1;
let bestMatchScore = 0;
let bestMatchContent = "";
if (startLine !== undefined && endLine !== undefined) {
// Convert to 0-based index
const exactStartIndex = startLine - 1;
const exactEndIndex = endLine - 1;
if (exactStartIndex < 0 || exactEndIndex >= originalLines.length) {
// Log detailed debug information
console.log('Invalid Line Range Debug:', {
requestedRange: { start: startLine, end: endLine },
fileBounds: { start: 1, end: originalLines.length }
});
return {
success: false,
error: `Line range ${startLine}-${endLine} is invalid (file has ${originalLines.length} lines)`,
};
}
// Check exact range first
const originalChunk = originalLines.slice(exactStartIndex, exactEndIndex + 1).join('\n');
const searchChunk = searchLines.join('\n');
@@ -149,6 +172,7 @@ Your search/replace content here
if (similarity >= this.fuzzyThreshold) {
matchIndex = exactStartIndex;
bestMatchScore = similarity;
bestMatchContent = originalChunk;
}
}
@@ -177,13 +201,26 @@ Your search/replace content here
if (similarity > bestMatchScore) {
bestMatchScore = similarity;
matchIndex = i;
bestMatchContent = originalChunk;
}
}
}
// Require similarity to meet threshold
if (matchIndex === -1 || bestMatchScore < this.fuzzyThreshold) {
return false;
const searchChunk = searchLines.join('\n');
// Log detailed debug information to console
console.log('Search/Replace Debug Info:', {
similarity: bestMatchScore,
threshold: this.fuzzyThreshold,
searchContent: searchChunk,
bestMatch: bestMatchContent || undefined
});
return {
success: false,
error: `No sufficiently similar match found${startLine !== undefined ? ` near lines ${startLine}-${endLine}` : ''} (${Math.round(bestMatchScore * 100)}% similar, needs ${Math.round(this.fuzzyThreshold * 100)}%)`
};
}
// Get the matched lines from the original content
@@ -229,6 +266,10 @@ Your search/replace content here
const beforeMatch = originalLines.slice(0, matchIndex);
const afterMatch = originalLines.slice(matchIndex + searchLines.length);
return [...beforeMatch, ...indentedReplaceLines, ...afterMatch].join(lineEnding);
const finalContent = [...beforeMatch, ...indentedReplaceLines, ...afterMatch].join(lineEnding);
return {
success: true,
content: finalContent
};
}
}
}