@Override public void doCollectInformation(@NotNull ProgressIndicator progress) { assert myDocument != null; final Long stamp = myEditor.getUserData(LAST_TIME_INDENTS_BUILT); if (stamp != null && stamp.longValue() == nowStamp()) return; myDescriptors = buildDescriptors(); ArrayList<TextRange> ranges = new ArrayList<TextRange>(); for (IndentGuideDescriptor descriptor : myDescriptors) { ProgressManager.checkCanceled(); int endOffset = descriptor.endLine < myDocument.getLineCount() ? myDocument.getLineStartOffset(descriptor.endLine) : myDocument.getTextLength(); ranges.add(new TextRange(myDocument.getLineStartOffset(descriptor.startLine), endOffset)); } Collections.sort(ranges, RANGE_COMPARATOR); myRanges = ranges; }
private List<IndentGuideDescriptor> buildDescriptors() { if (!myEditor.getSettings().isIndentGuidesShown()) return Collections.emptyList(); IndentsCalculator calculator = new IndentsCalculator(); calculator.calculate(); int[] lineIndents = calculator.lineIndents; TIntIntHashMap effectiveCommentColumns = calculator.indentAfterUncomment; List<IndentGuideDescriptor> descriptors = new ArrayList<IndentGuideDescriptor>(); IntStack lines = new IntStack(); IntStack indents = new IntStack(); lines.push(0); indents.push(0); assert myDocument != null; final CharSequence chars = myDocument.getCharsSequence(); for (int line = 1; line < lineIndents.length; line++) { ProgressManager.checkCanceled(); int curIndent = lineIndents[line]; while (!indents.empty() && curIndent <= indents.peek()) { ProgressManager.checkCanceled(); final int level = indents.pop(); int startLine = lines.pop(); if (level > 0) { boolean addDescriptor = effectiveCommentColumns.contains(startLine); // Indent started at comment if (!addDescriptor) { for (int i = startLine; i < line; i++) { if (level != lineIndents[i] && level != effectiveCommentColumns.get(i)) { addDescriptor = true; break; } } } if (addDescriptor) { descriptors.add(createDescriptor(level, startLine, line, chars)); } } } int prevLine = line - 1; int prevIndent = lineIndents[prevLine]; if (curIndent - prevIndent > 1) { lines.push(prevLine); indents.push(prevIndent); } } while (!indents.empty()) { ProgressManager.checkCanceled(); final int level = indents.pop(); int startLine = lines.pop(); if (level > 0) { descriptors.add(createDescriptor(level, startLine, myDocument.getLineCount(), chars)); } } return descriptors; }