From ac962d62ab9cef6a75623721362a29d1f4db27a6 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 24 Feb 2026 18:21:05 +0900 Subject: [PATCH] fix(hashline-edit): add same-line operation precedence ordering --- src/tools/hashline-edit/edit-operations.test.ts | 16 ++++++++++++++++ src/tools/hashline-edit/edit-operations.ts | 9 +++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/tools/hashline-edit/edit-operations.test.ts b/src/tools/hashline-edit/edit-operations.test.ts index 1940b9e4..5d8ad08b 100644 --- a/src/tools/hashline-edit/edit-operations.test.ts +++ b/src/tools/hashline-edit/edit-operations.test.ts @@ -92,6 +92,22 @@ describe("hashline edit operations", () => { expect(result).toEqual("line 1\ninserted\nline 2\nmodified") }) + it("applies replace before prepend when both target same line", () => { + //#given + const content = "line 1\nline 2\nline 3" + const lines = content.split("\n") + const edits: HashlineEdit[] = [ + { op: "prepend", pos: anchorFor(lines, 2), lines: "before line 2" }, + { op: "replace", pos: anchorFor(lines, 2), lines: "modified line 2" }, + ] + + //#when + const result = applyHashlineEdits(content, edits) + + //#then + expect(result).toEqual("line 1\nbefore line 2\nmodified line 2\nline 3") + }) + it("deduplicates identical insert edits in one pass", () => { //#given const content = "line 1\nline 2" diff --git a/src/tools/hashline-edit/edit-operations.ts b/src/tools/hashline-edit/edit-operations.ts index fae662d1..caec2307 100644 --- a/src/tools/hashline-edit/edit-operations.ts +++ b/src/tools/hashline-edit/edit-operations.ts @@ -27,7 +27,13 @@ export function applyHashlineEditsWithReport(content: string, edits: HashlineEdi } const dedupeResult = dedupeEdits(edits) - const sortedEdits = [...dedupeResult.edits].sort((a, b) => getEditLineNumber(b) - getEditLineNumber(a)) + const EDIT_PRECEDENCE: Record = { replace: 0, append: 1, prepend: 2 } + const sortedEdits = [...dedupeResult.edits].sort((a, b) => { + const lineA = getEditLineNumber(a) + const lineB = getEditLineNumber(b) + if (lineB !== lineA) return lineB - lineA + return (EDIT_PRECEDENCE[a.op] ?? 3) - (EDIT_PRECEDENCE[b.op] ?? 3) + }) let noopEdits = 0 @@ -87,4 +93,3 @@ export function applyHashlineEditsWithReport(content: string, edits: HashlineEdi export function applyHashlineEdits(content: string, edits: HashlineEdit[]): string { return applyHashlineEditsWithReport(content, edits).content } -