mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-21 04:41:16 -05:00
Prioritize exact line matches in search/replace
This commit is contained in:
@@ -610,6 +610,95 @@ function two() {
|
|||||||
|
|
||||||
function three() {
|
function three() {
|
||||||
return 3;
|
return 3;
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should prioritize exact line match over expanded search', () => {
|
||||||
|
const originalContent = `
|
||||||
|
function one() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
return "old";
|
||||||
|
}
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
return "old";
|
||||||
|
}
|
||||||
|
|
||||||
|
function two() {
|
||||||
|
return 2;
|
||||||
|
}`
|
||||||
|
const diffContent = `test.ts
|
||||||
|
<<<<<<< SEARCH
|
||||||
|
function process() {
|
||||||
|
return "old";
|
||||||
|
}
|
||||||
|
=======
|
||||||
|
function process() {
|
||||||
|
return "new";
|
||||||
|
}
|
||||||
|
>>>>>>> REPLACE`
|
||||||
|
|
||||||
|
// Should match the second instance exactly at lines 10-12
|
||||||
|
// even though the first instance at 6-8 is within the expanded search range
|
||||||
|
const result = strategy.applyDiff(originalContent, diffContent, 10, 12)
|
||||||
|
expect(result).toBe(`
|
||||||
|
function one() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
return "old";
|
||||||
|
}
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
return "new";
|
||||||
|
}
|
||||||
|
|
||||||
|
function two() {
|
||||||
|
return 2;
|
||||||
|
}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fall back to expanded search only if exact match fails', () => {
|
||||||
|
const originalContent = `
|
||||||
|
function one() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
return "target";
|
||||||
|
}
|
||||||
|
|
||||||
|
function two() {
|
||||||
|
return 2;
|
||||||
|
}`.trim()
|
||||||
|
const diffContent = `test.ts
|
||||||
|
<<<<<<< SEARCH
|
||||||
|
function process() {
|
||||||
|
return "target";
|
||||||
|
}
|
||||||
|
=======
|
||||||
|
function process() {
|
||||||
|
return "updated";
|
||||||
|
}
|
||||||
|
>>>>>>> REPLACE`
|
||||||
|
|
||||||
|
// Specify wrong line numbers (3-5), but content exists at 6-8
|
||||||
|
// Should still find and replace it since it's within the expanded range
|
||||||
|
const result = strategy.applyDiff(originalContent, diffContent, 3, 5)
|
||||||
|
expect(result).toBe(`function one() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function process() {
|
||||||
|
return "updated";
|
||||||
|
}
|
||||||
|
|
||||||
|
function two() {
|
||||||
|
return 2;
|
||||||
}`)
|
}`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -132,33 +132,52 @@ Your search/replace content here
|
|||||||
const replaceLines = replaceContent.split(/\r?\n/);
|
const replaceLines = replaceContent.split(/\r?\n/);
|
||||||
const originalLines = originalContent.split(/\r?\n/);
|
const originalLines = originalContent.split(/\r?\n/);
|
||||||
|
|
||||||
// Determine search range based on provided line numbers
|
// First try exact line range if provided
|
||||||
let searchStartIndex = 0;
|
|
||||||
let searchEndIndex = originalLines.length;
|
|
||||||
|
|
||||||
if (startLine !== undefined || endLine !== undefined) {
|
|
||||||
// Convert to 0-based index and add buffer
|
|
||||||
if (startLine !== undefined) {
|
|
||||||
searchStartIndex = Math.max(0, startLine - 6);
|
|
||||||
}
|
|
||||||
if (endLine !== undefined) {
|
|
||||||
searchEndIndex = Math.min(originalLines.length, endLine + 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the search content in the original using fuzzy matching
|
|
||||||
let matchIndex = -1;
|
let matchIndex = -1;
|
||||||
let bestMatchScore = 0;
|
let bestMatchScore = 0;
|
||||||
|
|
||||||
for (let i = searchStartIndex; i <= searchEndIndex - searchLines.length; i++) {
|
if (startLine !== undefined && endLine !== undefined) {
|
||||||
// Join the lines and calculate overall similarity
|
// Convert to 0-based index
|
||||||
const originalChunk = originalLines.slice(i, i + searchLines.length).join('\n');
|
const exactStartIndex = startLine - 1;
|
||||||
|
const exactEndIndex = endLine - 1;
|
||||||
|
|
||||||
|
// Check exact range first
|
||||||
|
const originalChunk = originalLines.slice(exactStartIndex, exactEndIndex + 1).join('\n');
|
||||||
const searchChunk = searchLines.join('\n');
|
const searchChunk = searchLines.join('\n');
|
||||||
|
|
||||||
const similarity = getSimilarity(originalChunk, searchChunk);
|
const similarity = getSimilarity(originalChunk, searchChunk);
|
||||||
if (similarity > bestMatchScore) {
|
if (similarity >= this.fuzzyThreshold) {
|
||||||
|
matchIndex = exactStartIndex;
|
||||||
bestMatchScore = similarity;
|
bestMatchScore = similarity;
|
||||||
matchIndex = i;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no match found in exact range, try expanded range
|
||||||
|
if (matchIndex === -1) {
|
||||||
|
let searchStartIndex = 0;
|
||||||
|
let searchEndIndex = originalLines.length;
|
||||||
|
|
||||||
|
if (startLine !== undefined || endLine !== undefined) {
|
||||||
|
// Convert to 0-based index and add buffer
|
||||||
|
if (startLine !== undefined) {
|
||||||
|
searchStartIndex = Math.max(0, startLine - 6);
|
||||||
|
}
|
||||||
|
if (endLine !== undefined) {
|
||||||
|
searchEndIndex = Math.min(originalLines.length, endLine + 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the search content in the expanded range using fuzzy matching
|
||||||
|
for (let i = searchStartIndex; i <= searchEndIndex - searchLines.length; i++) {
|
||||||
|
// Join the lines and calculate overall similarity
|
||||||
|
const originalChunk = originalLines.slice(i, i + searchLines.length).join('\n');
|
||||||
|
const searchChunk = searchLines.join('\n');
|
||||||
|
|
||||||
|
const similarity = getSimilarity(originalChunk, searchChunk);
|
||||||
|
if (similarity > bestMatchScore) {
|
||||||
|
bestMatchScore = similarity;
|
||||||
|
matchIndex = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user