Keep body folds through edits !58

merged merged by cmc on 2026-10-06 00:13 UTC · krz/orgstar:fix-body-folds into main

2 files changed, +18 −2

Layout: unified · split

Sources/OrgEditorAppKit/OrgEditor.swift +1 −2
@@ -727,8 +727,7 @@ public final class OrgEditor: NSObject {
727727 }
728728 let oldHidden = hidden.all
729729 view = view.mapped(through: [edit]).pruned(to: document.tree)
730 folded.set(view.folds)
731 hidden.set(Presentation.hiddenRanges(document.tree, folds: view.folds))
730 updateHidden()
732731 let newAffected = Self.affectedRange(document.tree, newText, edit.range.lowerBound, newEnd, touchedHeadings: touchedHeadings)
733732 let delta = edit.replacement.utf16.count - edit.range.count
734733 let oldMapped = oldAffected.lowerBound..<(oldAffected.upperBound >= edit.range.upperBound ? oldAffected.upperBound + delta : newEnd)
Tests/OrgEditorAppKitTests/FindTests.swift +17
@@ -24,3 +24,20 @@ struct FindTests {
2424 #expect(h.textView.selectedRange() == needle)
2525 }
2626}
27
28@MainActor
29struct BodyFoldTests {
30 /// CONTENTS view hides bodies (body folds); an edit elsewhere keeps them hidden.
31 @Test func bodyFoldsSurviveEdits() {
32 let h = Harness("* A\nbody a\n** B\nbody b\n* C\nbody c\n")
33 h.editor.cycleGlobal()
34 h.editor.cycleGlobal()
35 #expect(!h.editor.foldState.bodyFolds.isEmpty)
36 let hiddenBefore = h.editor.hidden.all
37 #expect(!hiddenBefore.isEmpty)
38 h.caret(at: 3)
39 h.textView.insertText("x", replacementRange: NSRange(location: 3, length: 0))
40 #expect(h.editor.hidden.all.count == hiddenBefore.count)
41 #expect(h.editor.hidden.all.map { $0.count } == hiddenBefore.map { $0.count })
42 }
43}