diff --git a/src/core/Cline.ts b/src/core/Cline.ts
index 1781440adb..9451d1385f 100644
--- a/src/core/Cline.ts
+++ b/src/core/Cline.ts
@@ -1168,7 +1168,7 @@ export class Cline {
pushToolResult(
formatResponse.toolError(
`${(error as Error)?.message}\n\n` +
- `This is likely because the SEARCH block content doesn't match exactly with what's in the file.\n\n` +
+ `This is likely because the SEARCH block content doesn't match exactly with what's in the file, or if you used multiple SEARCH/REPLACE blocks they may not have been in the order they appear in the file.\n\n` +
`The file was reverted to its original state:\n\n` +
`\n${this.diffViewProvider.originalContent}\n\n\n` +
`Try again with a more precise SEARCH block.\n(If you keep running into this error, you may use the write_to_file tool as a workaround.)`,
@@ -1292,7 +1292,7 @@ export class Cline {
}
}
- const { newProblemsMessage, userEdits, finalContent } =
+ const { newProblemsMessage, userEdits, autoFormattingEdits, finalContent } =
await this.diffViewProvider.saveChanges()
this.didEditFile = true // used to determine if we should wait for busy terminal to update before sending api request
if (userEdits) {
@@ -1306,7 +1306,10 @@ export class Cline {
)
pushToolResult(
`The user made the following updates to your content:\n\n${userEdits}\n\n` +
- `The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file:\n\n` +
+ (autoFormattingEdits
+ ? `The user's editor also applied the following auto-formatting to your content:\n\n${autoFormattingEdits}\n\n(Note: Pay close attention to changes such as single quotes being converted to double quotes, semicolons being removed or added, long lines being broken into multiple lines, adjusting indentation style, adding/removing trailing commas, etc. This will help you ensure future SEARCH/REPLACE operations to this file are accurate.)\n\n`
+ : "") +
+ `The updated content, which includes both your original modifications and the additional edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file that was saved:\n\n` +
`\n${finalContent}\n\n\n` +
`Please note:\n` +
`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
@@ -1318,7 +1321,10 @@ export class Cline {
} else {
pushToolResult(
`The content was successfully saved to ${relPath.toPosix()}.\n\n` +
- `Here is the full, updated content of the file:\n\n` +
+ (autoFormattingEdits
+ ? `Along with your edits, the user's editor applied the following auto-formatting to your content:\n\n${autoFormattingEdits}\n\n(Note: Pay close attention to changes such as single quotes being converted to double quotes, semicolons being removed or added, long lines being broken into multiple lines, adjusting indentation style, adding/removing trailing commas, etc. This will help you ensure future SEARCH/REPLACE operations to this file are accurate.)\n\n`
+ : "") +
+ `Here is the full, updated content of the file that was saved:\n\n` +
`\n${finalContent}\n\n\n` +
`IMPORTANT: For any future changes to this file, use the final_file_content shown above as your reference. This content reflects the current state of the file, including any auto-formatting (e.g., if you used single quotes but the formatter converted them to double quotes). Always base your SEARCH/REPLACE operations on this final version to ensure accuracy.\n\n` +
`${newProblemsMessage}`,
diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts
index 8f23a50e33..1e39799303 100644
--- a/src/core/prompts/system.ts
+++ b/src/core/prompts/system.ts
@@ -795,9 +795,8 @@ You have access to two tools for working with files: **write_to_file** and **rep
- After using either write_to_file or replace_in_file, the user's editor may automatically format the file
- This auto-formatting may modify the file contents, for example:
- - Breaking single lines into multiple lines (e.g. long function declarations, object literals, array definitions)
+ - Breaking single lines into multiple lines
- Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs)
- - Standardizing spacing and line endings (e.g. removing extra whitespace, ensuring consistent newlines)
- Converting single quotes to double quotes (or vice versa based on project preferences)
- Organizing imports (e.g. sorting, grouping by type)
- Adding/removing trailing commas in objects and arrays
diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts
index 5eb6a56b8f..4cc9f4b9d0 100644
--- a/src/integrations/editor/DiffViewProvider.ts
+++ b/src/integrations/editor/DiffViewProvider.ts
@@ -141,10 +141,16 @@ export class DiffViewProvider {
async saveChanges(): Promise<{
newProblemsMessage: string | undefined
userEdits: string | undefined
+ autoFormattingEdits: string | undefined
finalContent: string | undefined
}> {
if (!this.relPath || !this.newContent || !this.activeDiffEditor) {
- return { newProblemsMessage: undefined, userEdits: undefined, finalContent: undefined }
+ return {
+ newProblemsMessage: undefined,
+ userEdits: undefined,
+ autoFormattingEdits: undefined,
+ finalContent: undefined,
+ }
}
const absolutePath = path.resolve(this.cwd, this.relPath)
const updatedDocument = this.activeDiffEditor.document
@@ -197,18 +203,32 @@ export class DiffViewProvider {
const normalizedPostSaveContent = postSaveContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL // this is the final content we return to the model to use as the new baseline for future edits
// just in case the new content has a mix of varying EOL characters
const normalizedNewContent = this.newContent.replace(/\r\n|\n/g, newContentEOL).trimEnd() + newContentEOL
+
+ let userEdits: string | undefined
if (normalizedPreSaveContent !== normalizedNewContent) {
// user made changes before approving edit. let the model know about user made changes (not including post-save auto-formatting changes)
- const userEdits = formatResponse.createPrettyPatch(
+ userEdits = formatResponse.createPrettyPatch(
this.relPath.toPosix(),
normalizedNewContent,
normalizedPreSaveContent,
)
- return { newProblemsMessage, userEdits, finalContent: normalizedPostSaveContent }
+ // return { newProblemsMessage, userEdits, finalContent: normalizedPostSaveContent }
} else {
// no changes to cline's edits
- return { newProblemsMessage, userEdits: undefined, finalContent: normalizedPostSaveContent }
+ // return { newProblemsMessage, userEdits: undefined, finalContent: normalizedPostSaveContent }
}
+
+ let autoFormattingEdits: string | undefined
+ if (normalizedPreSaveContent !== normalizedPostSaveContent) {
+ // auto-formatting was done by the editor
+ autoFormattingEdits = formatResponse.createPrettyPatch(
+ this.relPath.toPosix(),
+ normalizedPreSaveContent,
+ normalizedPostSaveContent,
+ )
+ }
+
+ return { newProblemsMessage, userEdits, autoFormattingEdits, finalContent: normalizedPostSaveContent }
}
async revertChanges(): Promise {