@@ -4183,7 +4183,61 @@ class _CodeFieldRenderer extends RenderBox implements MouseTrackerAnnotation {
41834183 void _onControllerChange () {
41844184 if (controller.lspFoldRanges != _lastLspFoldRanges) {
41854185 _lastLspFoldRanges = controller.lspFoldRanges;
4186- _foldRangesNeedsClear = true ;
4186+
4187+ if (controller.lspFoldRanges != null ) {
4188+ final newLspRanges = controller.lspFoldRanges! ;
4189+ final preservedFoldRanges = < int , FoldRange > {};
4190+
4191+ for (final entry in newLspRanges.entries) {
4192+ final lineIndex = entry.key;
4193+ final newFold = entry.value;
4194+
4195+ FoldRange ? existingFold = _foldRanges[lineIndex];
4196+
4197+ if (existingFold != null ) {
4198+ newFold.isFolded = existingFold.isFolded;
4199+ newFold.originallyFoldedChildren =
4200+ existingFold.originallyFoldedChildren;
4201+ } else {
4202+ for (
4203+ int offset = 1 ;
4204+ offset <= 3 && existingFold == null ;
4205+ offset++
4206+ ) {
4207+ existingFold =
4208+ _foldRanges[lineIndex - offset] ??
4209+ _foldRanges[lineIndex + offset];
4210+ if (existingFold != null ) {
4211+ final oldRange =
4212+ existingFold.endIndex - existingFold.startIndex;
4213+ final newRange = newFold.endIndex - newFold.startIndex;
4214+ final diff = (oldRange - newRange).abs ();
4215+ if (diff <= (oldRange * 0.2 )) {
4216+ newFold.isFolded = existingFold.isFolded;
4217+ newFold.originallyFoldedChildren =
4218+ existingFold.originallyFoldedChildren;
4219+ } else {
4220+ existingFold = null ;
4221+ }
4222+ }
4223+ }
4224+ }
4225+
4226+ preservedFoldRanges[lineIndex] = newFold;
4227+ }
4228+
4229+ _foldRanges.clear ();
4230+ _foldRanges.addAll (preservedFoldRanges);
4231+
4232+ controller.foldings = {
4233+ for (var f in _foldRanges.values.where (
4234+ (f) => f != null && f.isFolded,
4235+ ))
4236+ f! .startIndex: f,
4237+ };
4238+ } else if (! controller.lspFoldRangesWereAdjusted) {
4239+ _foldRangesNeedsClear = true ;
4240+ }
41874241 }
41884242
41894243 if (controller.searchHighlightsChanged) {
@@ -4358,6 +4412,17 @@ class _CodeFieldRenderer extends RenderBox implements MouseTrackerAnnotation {
43584412 if (fold.isFolded) {
43594413 adjustedControllerFoldings[oldStartIndex] = fold;
43604414 }
4415+ } else if (fold.startIndex <= editLine && fold.endIndex >= editLine) {
4416+ final newEndIndex = fold.endIndex + lineDelta;
4417+ if (newEndIndex >= oldStartIndex) {
4418+ final newFold = FoldRange (oldStartIndex, newEndIndex);
4419+ newFold.isFolded = fold.isFolded;
4420+ newFold.originallyFoldedChildren = fold.originallyFoldedChildren;
4421+ adjustedFoldRanges[oldStartIndex] = newFold;
4422+ if (newFold.isFolded) {
4423+ adjustedControllerFoldings[oldStartIndex] = newFold;
4424+ }
4425+ }
43614426 } else if (fold.startIndex > editLine) {
43624427 final newStartIndex = fold.startIndex + lineDelta;
43634428 final newEndIndex = fold.endIndex + lineDelta;
@@ -4377,6 +4442,7 @@ class _CodeFieldRenderer extends RenderBox implements MouseTrackerAnnotation {
43774442 _foldRanges.addAll (adjustedFoldRanges);
43784443 _foldRangesNeedsClear = false ;
43794444 controller.foldings = adjustedControllerFoldings;
4445+ controller.adjustLspFoldRangesForLineChange (editLine, lineDelta);
43804446 }
43814447
43824448 _deferLayout ();
@@ -7114,7 +7180,9 @@ class _CodeFieldRenderer extends RenderBox implements MouseTrackerAnnotation {
71147180 ..color = highlightColor
71157181 ..style = PaintingStyle .fill;
71167182
7117- for (final foldRange in _foldRanges.values.where ((f) => f != null )) {
7183+ for (final foldRange in controller.foldings.values.where (
7184+ (f) => f != null ,
7185+ )) {
71187186 if (! foldRange! .isFolded) continue ;
71197187
71207188 final foldStartLine = foldRange.startIndex;
0 commit comments