mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Merge pull request #90 from RooVetGit/fix_diff_bug
Fix indentation bug with diff replacing a single search line
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Roo Cline Changelog
|
# Roo Cline Changelog
|
||||||
|
|
||||||
|
## [2.2.1]
|
||||||
|
|
||||||
|
- Fix another diff editing indentation bug
|
||||||
|
|
||||||
## [2.2.0]
|
## [2.2.0]
|
||||||
|
|
||||||
- Incorporate MCP changes from Cline 2.2.0
|
- Incorporate MCP changes from Cline 2.2.0
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "roo-cline",
|
"name": "roo-cline",
|
||||||
"version": "2.2.0",
|
"version": "2.2.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "roo-cline",
|
"name": "roo-cline",
|
||||||
"version": "2.2.0",
|
"version": "2.2.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/bedrock-sdk": "^0.10.2",
|
"@anthropic-ai/bedrock-sdk": "^0.10.2",
|
||||||
"@anthropic-ai/sdk": "^0.26.0",
|
"@anthropic-ai/sdk": "^0.26.0",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"displayName": "Roo Cline",
|
"displayName": "Roo Cline",
|
||||||
"description": "A fork of Cline, an autonomous coding agent, with some added experimental configuration and automation features.",
|
"description": "A fork of Cline, an autonomous coding agent, with some added experimental configuration and automation features.",
|
||||||
"publisher": "RooVeterinaryInc",
|
"publisher": "RooVeterinaryInc",
|
||||||
"version": "2.2.0",
|
"version": "2.2.1",
|
||||||
"icon": "assets/icons/rocket.png",
|
"icon": "assets/icons/rocket.png",
|
||||||
"galleryBanner": {
|
"galleryBanner": {
|
||||||
"color": "#617A91",
|
"color": "#617A91",
|
||||||
|
|||||||
@@ -31,31 +31,6 @@ function hello() {
|
|||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle extra whitespace in search/replace blocks', () => {
|
|
||||||
const originalContent = `function test() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
const diffContent = `test.ts
|
|
||||||
<<<<<<< SEARCH
|
|
||||||
|
|
||||||
function test() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
=======
|
|
||||||
function test() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
>>>>>>> REPLACE`
|
|
||||||
|
|
||||||
const result = strategy.applyDiff(originalContent, diffContent)
|
|
||||||
expect(result).toBe(`function test() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should match content with different surrounding whitespace', () => {
|
it('should match content with different surrounding whitespace', () => {
|
||||||
const originalContent = `
|
const originalContent = `
|
||||||
function example() {
|
function example() {
|
||||||
@@ -286,6 +261,27 @@ Invalid diff format`
|
|||||||
expect(result).toBe(" modified\n still indented\n end\n")
|
expect(result).toBe(" modified\n still indented\n end\n")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should preserve indentation when adding new lines after existing content', () => {
|
||||||
|
const originalContent = ` onScroll={() => updateHighlights()}`
|
||||||
|
const diffContent = `test.ts
|
||||||
|
<<<<<<< SEARCH
|
||||||
|
onScroll={() => updateHighlights()}
|
||||||
|
=======
|
||||||
|
onScroll={() => updateHighlights()}
|
||||||
|
onDragOver={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
>>>>>>> REPLACE`
|
||||||
|
|
||||||
|
const result = strategy.applyDiff(originalContent, diffContent)
|
||||||
|
expect(result).toBe(` onScroll={() => updateHighlights()}
|
||||||
|
onDragOver={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}`)
|
||||||
|
})
|
||||||
|
|
||||||
it('should handle complex refactoring with multiple functions', () => {
|
it('should handle complex refactoring with multiple functions', () => {
|
||||||
const originalContent = `export async function extractTextFromFile(filePath: string): Promise<string> {
|
const originalContent = `export async function extractTextFromFile(filePath: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
@@ -519,3 +515,4 @@ export function addLineNumbers(content: string, startLine: number = 1): string {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ Your search/replace content here
|
|||||||
const lineEnding = originalContent.includes('\r\n') ? '\r\n' : '\n';
|
const lineEnding = originalContent.includes('\r\n') ? '\r\n' : '\n';
|
||||||
|
|
||||||
// Split content into lines, handling both \n and \r\n
|
// Split content into lines, handling both \n and \r\n
|
||||||
const searchLines = searchContent.trim().split(/\r?\n/);
|
const searchLines = searchContent.split(/\r?\n/);
|
||||||
const replaceLines = replaceContent.trim().split(/\r?\n/);
|
const replaceLines = replaceContent.split(/\r?\n/);
|
||||||
const originalLines = originalContent.split(/\r?\n/);
|
const originalLines = originalContent.split(/\r?\n/);
|
||||||
|
|
||||||
// Find the search content in the original
|
// Find the search content in the original
|
||||||
@@ -130,39 +130,32 @@ Your search/replace content here
|
|||||||
const currentIndentMatch = line.match(/^[\t ]*/);
|
const currentIndentMatch = line.match(/^[\t ]*/);
|
||||||
const currentIndent = currentIndentMatch ? currentIndentMatch[0] : '';
|
const currentIndent = currentIndentMatch ? currentIndentMatch[0] : '';
|
||||||
|
|
||||||
// If this line has the same indentation level as the search block,
|
// Get the corresponding search line's indentation
|
||||||
// use the original indentation. Otherwise, calculate the difference
|
const searchLineIndex = Math.min(i, searchLines.length - 1);
|
||||||
// and preserve the exact type of whitespace characters
|
const searchLineIndent = searchIndents[searchLineIndex];
|
||||||
if (currentIndent.length === searchIndent.length) {
|
|
||||||
return originalIndent + line.trim();
|
|
||||||
} else {
|
|
||||||
// Get the corresponding search line's indentation
|
|
||||||
const searchLineIndex = Math.min(i, searchLines.length - 1);
|
|
||||||
const searchLineIndent = searchIndents[searchLineIndex];
|
|
||||||
|
|
||||||
// Get the corresponding original line's indentation
|
// Get the corresponding original line's indentation
|
||||||
const originalLineIndex = Math.min(i, originalIndents.length - 1);
|
const originalLineIndex = Math.min(i, originalIndents.length - 1);
|
||||||
const originalLineIndent = originalIndents[originalLineIndex];
|
const originalLineIndent = originalIndents[originalLineIndex];
|
||||||
|
|
||||||
// If this line has the same indentation as its corresponding search line,
|
// If this line has the same indentation as its corresponding search line,
|
||||||
// use the original indentation
|
// use the original indentation
|
||||||
if (currentIndent === searchLineIndent) {
|
if (currentIndent === searchLineIndent) {
|
||||||
return originalLineIndent + line.trim();
|
return originalLineIndent + line.trim();
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, preserve the original indentation structure
|
|
||||||
const indentChar = originalLineIndent.charAt(0) || '\t';
|
|
||||||
const indentLevel = Math.floor(originalLineIndent.length / indentChar.length);
|
|
||||||
|
|
||||||
// Calculate the relative indentation from the search line
|
|
||||||
const searchLevel = Math.floor(searchLineIndent.length / indentChar.length);
|
|
||||||
const currentLevel = Math.floor(currentIndent.length / indentChar.length);
|
|
||||||
const relativeLevel = currentLevel - searchLevel;
|
|
||||||
|
|
||||||
// Apply the relative indentation to the original level
|
|
||||||
const targetLevel = Math.max(0, indentLevel + relativeLevel);
|
|
||||||
return indentChar.repeat(targetLevel) + line.trim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Otherwise, preserve the original indentation structure
|
||||||
|
const indentChar = originalLineIndent.charAt(0) || '\t';
|
||||||
|
const indentLevel = Math.floor(originalLineIndent.length / indentChar.length);
|
||||||
|
|
||||||
|
// Calculate the relative indentation from the search line
|
||||||
|
const searchLevel = Math.floor(searchLineIndent.length / indentChar.length);
|
||||||
|
const currentLevel = Math.floor(currentIndent.length / indentChar.length);
|
||||||
|
const relativeLevel = currentLevel - searchLevel;
|
||||||
|
|
||||||
|
// Apply the relative indentation to the original level
|
||||||
|
const targetLevel = Math.max(0, indentLevel + relativeLevel);
|
||||||
|
return indentChar.repeat(targetLevel) + line.trim();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Construct the final content
|
// Construct the final content
|
||||||
|
|||||||
Reference in New Issue
Block a user