IJPL-251582 [editor] soft-wraps: make sure grid mode optimized algo does not place soft-wraps inside collapsed fold-regions

IJ-CR-217736

(cherry picked from commit ab280e5420511022b21fb24b2d336c0949040f8b)

GitOrigin-RevId: 5f93bbfd4cfa8358cc899870b6009487890fcc06
This commit is contained in:
Vojtech Balik
2026-08-10 17:09:24 +00:00
committed by intellij-monorepo-bot
parent 12e50374c4
commit 08a68de340
3 changed files with 28 additions and 1 deletions
@@ -79,7 +79,8 @@ public final class SoftWrapEngine {
var customWraps = myEditor.getCustomWrapModel().getWrapsInRange(startOffset, maxEndOffset);
var grid = myEditor.getCharacterGrid();
if (grid != null && inlineInlays.isEmpty() && afterLineEndInlays.isEmpty() && customWraps.isEmpty()) {
if (grid != null && inlineInlays.isEmpty() && afterLineEndInlays.isEmpty() && customWraps.isEmpty()
&& !SoftWrapHelper.hasCollapsedOffsetsIn(myEditor.getFoldingModel(), startOffset, maxEndOffset)) {
generateGridSoftWraps(grid, startOffset, minEndOffset, maxEndOffset);
return;
}
@@ -4,11 +4,13 @@ package com.intellij.openapi.editor.impl.softwrap;
import com.intellij.openapi.editor.CustomWrapModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.SoftWrap;
import com.intellij.openapi.editor.SoftWrapModel;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.CaretImpl;
import com.intellij.openapi.editor.impl.EditorImpl;
@@ -131,4 +133,18 @@ public final class SoftWrapHelper {
storage.removeCustomWrapsInRange(srcOffset, srcOffset + event.getNewLength() + /* end-inclusive */ 1);
}
}
/**
* Answers whether there are any offsets collapsed by fold regions inside {@code [startOffset; endOffset)}.
* <p>
* Since soft-wraps may be placed at either edge of a collapsed fold region,
* this method will not return {@code true} due to a collapsed fold region
* where {@code region.endOffset == startOffset} or where {@code region.startOffset == endOffset}.
*/
public static boolean hasCollapsedOffsetsIn(@NotNull FoldingModelEx foldingModel, int startOffset, int endOffset) {
FoldRegion[] topLevel = foldingModel.fetchTopLevel();
if (topLevel == null) return false;
int idx = foldingModel.getLastCollapsedRegionBefore(startOffset) + 1;
return idx < topLevel.length && topLevel[idx].getStartOffset() < endOffset;
}
}
@@ -37,4 +37,14 @@ public class EditorCharacterGridSizeTest extends AbstractEditorTest {
assertTrue("preferred=" + preferredWidth(), preferredWidth() < CONTENT_WIDTH);
}
// IJPL-251582: The grid mode optimized soft-wrapping must not place soft-wraps inside collapsed fold regions.
public void testGridEditorWithSoftWrapOptimizationsDoesNotWrapInsideCollapsedFoldRegion() {
initText(LONG_LINE.substring(0, 20));
configureSoftWraps(10, false);
addCollapsedFoldRegion(8, 14, "..."); // covers the grid column boundary at offset 11
enableGridMode();
verifySoftWrapPositions(8);
}
}