void ( @NotNull Editor editor, @NotNull VisualPosition lineStartPosition, @NotNull VisualPosition lineEndPosition, int startOffset, int endOffset, @NotNull Document doc, @NotNull Graphics g ) { int indentColumn = lineStartPosition.column; if (indentColumn <= 0) return; FoldingModel foldingModel = editor.getFoldingModel(); if (foldingModel.isOffsetCollapsed(startOffset)) return; FoldRegion headerRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(startOffset))); FoldRegion tailRegion = foldingModel.getCollapsedRegionAtOffset(doc.getLineStartOffset(doc.getLineNumber(endOffset))); if (tailRegion != null && tailRegion == headerRegion) return; int vfmtRightShift = 0; if (VisualFormattingLayerService.isEnabledForEditor(editor)) { vfmtRightShift = VisualFormattingLayerService .getVisualFormattingInlineInlays(editor, doc.getLineStartOffset(doc.getLineNumber(startOffset)), startOffset) .stream() .map(inlay -> inlay.getWidthInPixels()) .reduce(0, Integer::sum); } boolean selected = isSelected(editor, endOffset, startOffset, lineStartPosition.column); Color color = getIndentColor(editor, startOffset, selected); int lineHeight = editor.getLineHeight(); Point start = editor.visualPositionToXY(lineStartPosition); start.x += vfmtRightShift; start.y += lineHeight; Point end = editor.visualPositionToXY(lineEndPosition); int maxY = end.y; if (lineEndPosition.line == editor.offsetToVisualPosition(doc.getTextLength()).line) { maxY += lineHeight; } Rectangle clip = g.getClipBounds(); if (clip != null) { if (clip.y >= maxY || clip.y + clip.height <= start.y) { return; } maxY = Math.min(maxY, clip.y + clip.height); } if (start.y >= maxY) return; int targetX = Math.max(0, start.x + EditorPainter.getIndentGuideShift(editor)); g.setColor(color); // There is a possible case that indent line intersects soft wrap-introduced text. Example: // this is a long line <soft-wrap> // that| is soft-wrapped // | // | <- vertical indent // // Also it's possible that no additional intersections are added because of soft wrap: // this is a long line <soft-wrap> // | that is soft-wrapped // | // | <- vertical indent // We want to use the following approach then: // 1. Show only active indent if it crosses soft wrap-introduced text; // 2. Show indent as is if it doesn't intersect with soft wrap-introduced text; List<? extends SoftWrap> softWraps = ((EditorEx)editor).getSoftWrapModel().getRegisteredSoftWraps(); if (selected || softWraps.isEmpty()) { LinePainter2D.paint((Graphics2D)g, targetX, start.y, targetX, maxY - 1); } else { int startY = start.y; int startVisualLine = lineStartPosition.line + 1; if (clip != null && startY < clip.y) { startY = clip.y; startVisualLine = editor.yToVisualLine(clip.y); } VisualLinesIterator it = new VisualLinesIterator((EditorImpl)editor, startVisualLine); while (!it.atEnd()) { int currY = it.getY(); if (currY >= startY) { if (currY >= maxY) break; if (it.startsWithSoftWrap()) { SoftWrap softWrap = softWraps.get(it.getStartOrPrevWrapIndex()); if (softWrap.getIndentInColumns() < indentColumn) { if (startY < currY) { LinePainter2D.paint((Graphics2D)g, targetX, startY, targetX, currY - 1); } startY = currY + lineHeight; } } } it.advance(); } if (startY < maxY) { LinePainter2D.paint((Graphics2D)g, targetX, startY, targetX, maxY - 1); } } }