refactor(hashline-edit): enforce three-op edit model

Unify internal hashline edit handling around replace/append/prepend to remove legacy operation shapes. This keeps normalization, ordering, deduplication, execution, and tests aligned with the new op/pos/end/lines contract.
This commit is contained in:
minpeter
2026-02-24 05:06:41 +09:00
parent 6ec0ff732b
commit 08b663df86
10 changed files with 86 additions and 261 deletions
+12 -48
View File
@@ -5,9 +5,7 @@ import {
applyAppend,
applyInsertAfter,
applyInsertBefore,
applyInsertBetween,
applyPrepend,
applyReplace,
applyReplaceLines,
applySetLine,
} from "./edit-operation-primitives"
@@ -33,42 +31,17 @@ export function applyHashlineEditsWithReport(content: string, edits: HashlineEdi
let noopEdits = 0
let result = content
let lines = result.length === 0 ? [] : result.split("\n")
let lines = content.length === 0 ? [] : content.split("\n")
const refs = collectLineRefs(sortedEdits)
validateLineRefs(lines, refs)
for (const edit of sortedEdits) {
switch (edit.type) {
case "set_line": {
lines = applySetLine(lines, edit.line, edit.text, { skipValidation: true })
break
}
case "replace_lines": {
lines = applyReplaceLines(lines, edit.start_line, edit.end_line, edit.text, { skipValidation: true })
break
}
case "insert_after": {
const next = applyInsertAfter(lines, edit.line, edit.text, { skipValidation: true })
if (next.join("\n") === lines.join("\n")) {
noopEdits += 1
break
}
lines = next
break
}
case "insert_before": {
const next = applyInsertBefore(lines, edit.line, edit.text, { skipValidation: true })
if (next.join("\n") === lines.join("\n")) {
noopEdits += 1
break
}
lines = next
break
}
case "insert_between": {
const next = applyInsertBetween(lines, edit.after_line, edit.before_line, edit.text, { skipValidation: true })
switch (edit.op) {
case "replace": {
const next = edit.end
? applyReplaceLines(lines, edit.pos, edit.end, edit.lines, { skipValidation: true })
: applySetLine(lines, edit.pos, edit.lines, { skipValidation: true })
if (next.join("\n") === lines.join("\n")) {
noopEdits += 1
break
@@ -77,7 +50,9 @@ export function applyHashlineEditsWithReport(content: string, edits: HashlineEdi
break
}
case "append": {
const next = applyAppend(lines, edit.text)
const next = edit.pos
? applyInsertAfter(lines, edit.pos, edit.lines, { skipValidation: true })
: applyAppend(lines, edit.lines)
if (next.join("\n") === lines.join("\n")) {
noopEdits += 1
break
@@ -86,7 +61,9 @@ export function applyHashlineEditsWithReport(content: string, edits: HashlineEdi
break
}
case "prepend": {
const next = applyPrepend(lines, edit.text)
const next = edit.pos
? applyInsertBefore(lines, edit.pos, edit.lines, { skipValidation: true })
: applyPrepend(lines, edit.lines)
if (next.join("\n") === lines.join("\n")) {
noopEdits += 1
break
@@ -94,17 +71,6 @@ export function applyHashlineEditsWithReport(content: string, edits: HashlineEdi
lines = next
break
}
case "replace": {
result = lines.join("\n")
const replaced = applyReplace(result, edit.old_text, edit.new_text)
if (replaced === result) {
noopEdits += 1
break
}
result = replaced
lines = result.split("\n")
break
}
}
}
@@ -124,6 +90,4 @@ export {
applyReplaceLines,
applyInsertAfter,
applyInsertBefore,
applyInsertBetween,
applyReplace,
} from "./edit-operation-primitives"