diff --git a/src/core/diff/strategies/__tests__/multi-search-replace.test.ts b/src/core/diff/strategies/__tests__/multi-search-replace.test.ts index e4a52af6d4..60d9f0508b 100644 --- a/src/core/diff/strategies/__tests__/multi-search-replace.test.ts +++ b/src/core/diff/strategies/__tests__/multi-search-replace.test.ts @@ -1486,6 +1486,23 @@ function five() { }`) } }) + + it("should delete a line when search block has line number prefix and replace is empty", async () => { + const originalContent = "line 1\nline to delete\nline 3" + const diffContent = ` +<<<<<<< SEARCH +:start_line:2 +:end_line:2 +------- +2 | line to delete +======= +>>>>>>> REPLACE` + const result = await strategy.applyDiff(originalContent, diffContent) + expect(result.success).toBe(true) + if (result.success) { + expect(result.content).toBe("line 1\nline 3") + } + }) }) describe("insertion", () => { diff --git a/src/core/diff/strategies/multi-search-replace.ts b/src/core/diff/strategies/multi-search-replace.ts index bf80f09052..b4c0920843 100644 --- a/src/core/diff/strategies/multi-search-replace.ts +++ b/src/core/diff/strategies/multi-search-replace.ts @@ -301,7 +301,10 @@ Only use a single line of '=======' between search and replacement content, beca replaceContent = this.unescapeMarkers(replaceContent) // Strip line numbers from search and replace content if every line starts with a line number - if (everyLineHasLineNumbers(searchContent) && everyLineHasLineNumbers(replaceContent)) { + if ( + (everyLineHasLineNumbers(searchContent) && everyLineHasLineNumbers(replaceContent)) || + (everyLineHasLineNumbers(searchContent) && replaceContent.trim() === "") + ) { searchContent = stripLineNumbers(searchContent) replaceContent = stripLineNumbers(replaceContent) }