Skip to content

Commit b71e1e5

Browse files
committed
Checkpoint
1 parent e0bef89 commit b71e1e5

File tree

3 files changed

+74
-11
lines changed

3 files changed

+74
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ A fork of Cline, an autonomous coding agent, with some added experimental config
44
- Auto-approval capabilities for commands, write, and browser operations
55
- Support for .clinerules per-project custom instructions
66
- Ability to run side-by-side with Cline
7-
- Code is unit-tested
7+
- Unit test coverage (written almost entirely by Roo Cline!)
88
- Support for playing sound effects
99
- Support for OpenRouter compression
1010
- Support for editing through diffs (very experimental)

src/core/diff/strategies/__tests__/search-replace.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,29 @@ function example() {
8080
return 43;
8181
}
8282
83+
`)
84+
})
85+
86+
it('should match content with different indentation in search block', () => {
87+
const originalContent = ` function test() {
88+
return true;
89+
}
90+
`
91+
const diffContent = `test.ts
92+
<<<<<<< SEARCH
93+
function test() {
94+
return true;
95+
}
96+
=======
97+
function test() {
98+
return false;
99+
}
100+
>>>>>>> REPLACE`
101+
102+
const result = strategy.applyDiff(originalContent, diffContent)
103+
expect(result).toBe(` function test() {
104+
return false;
105+
}
83106
`)
84107
})
85108

src/core/diff/strategies/search-replace.ts

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,59 @@ Your search/replace content here
7070

7171
const [_, searchContent, replaceContent] = match;
7272

73-
// Trim both search and replace content
74-
const trimmedSearch = searchContent.trim();
75-
const trimmedReplace = replaceContent.trim();
73+
// Split content into lines
74+
const searchLines = searchContent.trim().split('\n');
75+
const replaceLines = replaceContent.trim().split('\n');
76+
const originalLines = originalContent.split('\n');
7677

77-
// Trim the original content for comparison
78-
const trimmedOriginal = originalContent.trim();
78+
// Find the search content in the original
79+
let matchIndex = -1;
7980

80-
// Verify the search content exists in the trimmed original
81-
if (!trimmedOriginal.includes(trimmedSearch)) {
81+
for (let i = 0; i <= originalLines.length - searchLines.length; i++) {
82+
let found = true;
83+
84+
for (let j = 0; j < searchLines.length; j++) {
85+
const originalLine = originalLines[i + j];
86+
const searchLine = searchLines[j];
87+
88+
// Compare lines after removing leading/trailing whitespace
89+
if (originalLine.trim() !== searchLine.trim()) {
90+
found = false;
91+
break;
92+
}
93+
}
94+
95+
if (found) {
96+
matchIndex = i;
97+
break;
98+
}
99+
}
100+
101+
if (matchIndex === -1) {
82102
return false;
83103
}
84-
85-
// Replace the content, maintaining original whitespace
86-
return originalContent.replace(trimmedSearch, trimmedReplace);
104+
105+
// Get the matched lines from the original content
106+
const matchedLines = originalLines.slice(matchIndex, matchIndex + searchLines.length);
107+
108+
// For each line in the match, get its indentation
109+
const indentations = matchedLines.map(line => {
110+
const match = line.match(/^(\s*)/);
111+
return match ? match[1] : '';
112+
});
113+
114+
// Apply the replacement while preserving indentation
115+
const indentedReplace = replaceLines.map((line, i) => {
116+
// Use the indentation from the corresponding line in the matched block
117+
// If we have more lines than the original, use the last indentation
118+
const indent = indentations[Math.min(i, indentations.length - 1)];
119+
return indent + line.trim();
120+
});
121+
122+
// Construct the final content
123+
const beforeMatch = originalLines.slice(0, matchIndex);
124+
const afterMatch = originalLines.slice(matchIndex + searchLines.length);
125+
126+
return [...beforeMatch, ...indentedReplace, ...afterMatch].join('\n');
87127
}
88128
}

0 commit comments

Comments
 (0)