@@ -1652,8 +1652,16 @@ impl Editor {
16521652 /// Only parse/snapshot/diff work — no IO.
16531653 pub fn apply_reload ( & mut self , content : String , base_text : Option < String > ) {
16541654 if !self . state . buffer . content_eq ( & content) {
1655+ // Persist folds across the reload: remap their offsets from the actual
1656+ // splice (external edits are usually a localized change), the same way a
1657+ // local edit does. `set_text` leaves `folded_headings` untouched, so without
1658+ // this the old offsets would land on the wrong lines in the new content.
1659+ let before = ( !self . folded_headings . is_empty ( ) ) . then ( || self . state . buffer . text ( ) ) ;
16551660 let cursor_line = self . state . buffer . byte_to_line ( self . state . selection . head ) ;
16561661 self . set_text ( & content) ;
1662+ if let Some ( before) = before {
1663+ self . remap_folds ( & before, & content) ;
1664+ }
16571665 let line = cursor_line. min ( self . state . buffer . line_count ( ) . saturating_sub ( 1 ) ) ;
16581666 let offset = self . state . buffer . line_to_byte ( line) ;
16591667 self . state . selection = Selection :: new ( offset, offset) ;
@@ -2533,6 +2541,24 @@ let code = target(); // fenced block line
25332541 ) ;
25342542 }
25352543
2544+ #[ test]
2545+ fn folds_persist_and_remap_across_reload ( ) {
2546+ let mut e = Editor :: new ( "# One\n body\n ## Two\n more\n " ) ;
2547+ let two = e. text ( ) . find ( "## Two" ) . unwrap ( ) ;
2548+ e. toggle_fold ( two) ;
2549+ assert ! ( e. folded_headings. contains( & two) ) ;
2550+ // An external edit prepends a line; the reload should shift the fold offset so it
2551+ // still lands on the (moved) heading rather than pointing at stale bytes.
2552+ let prefix = "intro line\n " ;
2553+ e. apply_reload ( format ! ( "{prefix}# One\n body\n ## Two\n more\n " ) , None ) ;
2554+ let two_after = e. text ( ) . find ( "## Two" ) . unwrap ( ) ;
2555+ assert_eq ! ( two_after, two + prefix. len( ) ) ;
2556+ assert ! (
2557+ e. folded_headings. contains( & two_after) ,
2558+ "fold should remap to the heading's new offset after reload"
2559+ ) ;
2560+ }
2561+
25362562 #[ test]
25372563 fn find_replace_current_is_single_undo_step ( ) {
25382564 let mut e = Editor :: new ( "a a a\n " ) ;
0 commit comments