BidiRun (@NotNull EditorView view, int line, int targetStartOffset, int targetEndOffset, @Nullable Runnable quickEvaluationListener) { assert targetStartOffset < endOffset; assert targetEndOffset > startOffset; int start = Math.max(startOffset, targetStartOffset); int end = Math.min(endOffset, targetEndOffset); BidiRun subRun = new BidiRun(level, start, end); List<Chunk> subChunks = new SmartList<>(); Document document = view.getEditor().getDocument(); List<Chunk> chunks = getChunks(document.getImmutableCharSequence(), document.getLineStartOffset(line)); for (int i = (start - startOffset) / CHUNK_CHARACTERS; i < chunks.size(); i++) { Chunk chunk = chunks.get(i); if (chunk.endOffset <= start) continue; if (chunk.startOffset >= end) break; subChunks.add(chunk.subChunk(view, this, line, start, end, quickEvaluationListener)); } subRun.chunks = subChunks; subRun.visualStartLogicalColumn = (subRun.isRtl() ? end == endOffset : start == startOffset) ? visualStartLogicalColumn : view.getLogicalPositionCache().offsetToLogicalColumn(line, subRun.isRtl() ? end : start); return subRun; }