void () { ThreadingAssertions.assertEventDispatchThread(); if (isDisposed()) return; EditorEx editor = (EditorEx)getEditor(); boolean shouldStickToEnd = !myCancelStickToEnd && isStickingToEnd(editor); myCancelStickToEnd = false; // Cancel only needs to last for one update. Next time, isStickingToEnd() will be false. List<TokenBuffer.TokenInfo> deferredTokens; Document document = editor.getDocument(); synchronized (LOCK) { if (myOutputPaused) return; deferredTokens = myDeferredBuffer.drain(); if (deferredTokens.isEmpty()) return; cancelHeavyAlarm(); } RangeMarker lastProcessedOutput = document.createRangeMarker(document.getTextLength(), document.getTextLength()); if (!shouldStickToEnd) { editor.getScrollingModel().accumulateViewportChanges(); } Collection<ConsoleViewContentType> contentTypes = new HashSet<>(); List<Pair<String, ConsoleViewContentType>> contents = new ArrayList<>(); CharSequence addedText; try { // the text can contain one "\r" at the start meaning we should delete the last line boolean startsWithCR = deferredTokens.get(0) == TokenBuffer.CR_TOKEN; if (startsWithCR) { // remove last line if any if (document.getLineCount() != 0) { int lineStartOffset = document.getLineStartOffset(document.getLineCount() - 1); document.deleteString(lineStartOffset, document.getTextLength()); } } int startIndex = startsWithCR ? 1 : 0; List<TokenBuffer.TokenInfo> refinedTokens = new ArrayList<>(deferredTokens.size() - startIndex); int backspacePrefixLength = ConsoleTokenUtil.evaluateBackspacesInTokens(deferredTokens, startIndex, refinedTokens); if (backspacePrefixLength > 0) { int lineCount = document.getLineCount(); if (lineCount != 0) { int lineStartOffset = document.getLineStartOffset(lineCount - 1); document.deleteString(Math.max(lineStartOffset, document.getTextLength() - backspacePrefixLength), document.getTextLength()); } } addedText = TokenBuffer.getRawText(refinedTokens); document.insertString(document.getTextLength(), addedText); ConsoleTokenUtil.highlightTokenTextAttributes(getEditor(), getProject(), refinedTokens, getHyperlinks(), contentTypes, contents); } finally { if (!shouldStickToEnd) { editor.getScrollingModel().flushViewportChanges(); } } if (!contentTypes.isEmpty()) { for (ChangeListener each : myListeners) { each.contentAdded(contentTypes); } } if (!contents.isEmpty()) { for (ChangeListener each : myListeners) { for (int i = contents.size() - 1; i >= 0; i--) { each.textAdded(contents.get(i).first, contents.get(i).second); } } } myPsiDisposedCheck.performCheck(); int startLine = lastProcessedOutput.isValid() ? editor.getDocument().getLineNumber(lastProcessedOutput.getEndOffset()) : 0; lastProcessedOutput.dispose(); highlightHyperlinksAndFoldings(startLine, myPredefinedFiltersUpdateExpirableTokenProvider.createExpirable()); if (shouldStickToEnd) { scrollToEnd(); } sendUserInput(addedText); }