private static void duplicateHighlighters(
     MarkupModel to, MarkupModel from, int offset, TextRange textRange) {
   for (RangeHighlighter rangeHighlighter : from.getAllHighlighters()) {
     if (!rangeHighlighter.isValid()) continue;
     Object tooltip = rangeHighlighter.getErrorStripeTooltip();
     HighlightInfo highlightInfo =
         tooltip instanceof HighlightInfo ? (HighlightInfo) tooltip : null;
     if (highlightInfo != null) {
       if (highlightInfo.getSeverity() != HighlightSeverity.INFORMATION) continue;
       if (highlightInfo.type.getAttributesKey() == EditorColors.IDENTIFIER_UNDER_CARET_ATTRIBUTES)
         continue;
     }
     final int localOffset = textRange.getStartOffset();
     final int start = Math.max(rangeHighlighter.getStartOffset(), localOffset) - localOffset;
     final int end =
         Math.min(rangeHighlighter.getEndOffset(), textRange.getEndOffset()) - localOffset;
     if (start > end) continue;
     final RangeHighlighter h =
         to.addRangeHighlighter(
             start + offset,
             end + offset,
             rangeHighlighter.getLayer(),
             rangeHighlighter.getTextAttributes(),
             rangeHighlighter.getTargetArea());
     ((RangeHighlighterEx) h)
         .setAfterEndOfLine(((RangeHighlighterEx) rangeHighlighter).isAfterEndOfLine());
   }
 }
  private void highlightNotification(
      final Notification notification, String message, final int line1, final int line2) {

    final MarkupModel markupModel = myLogEditor.getValue().getMarkupModel();
    TextAttributes bold = new TextAttributes(null, null, null, null, Font.BOLD);
    final List<RangeHighlighter> lineColors = new ArrayList<RangeHighlighter>();
    for (int line = line1; line < line2; line++) {
      final RangeHighlighter lineHighlighter =
          markupModel.addLineHighlighter(line, HighlighterLayer.CARET_ROW + 1, bold);
      Color color =
          notification.getType() == NotificationType.ERROR
              ? JBColor.RED
              : notification.getType() == NotificationType.WARNING ? JBColor.YELLOW : JBColor.GREEN;
      lineHighlighter.setErrorStripeMarkColor(color);
      lineHighlighter.setErrorStripeTooltip(message);
      lineColors.add(lineHighlighter);
    }

    final Runnable removeHandler =
        new Runnable() {
          @Override
          public void run() {
            for (RangeHighlighter color : lineColors) {
              markupModel.removeHighlighter(color);
            }

            TextAttributes attributes =
                EditorColorsManager.getInstance()
                    .getGlobalScheme()
                    .getAttributes(ConsoleViewContentType.LOG_EXPIRED_ENTRY);
            for (int line = line1; line < line2; line++) {
              markupModel.addLineHighlighter(line, HighlighterLayer.CARET_ROW + 1, attributes);
            }

            TextAttributes italic = new TextAttributes(null, null, null, null, Font.ITALIC);
            for (int line = line1; line < line2; line++) {
              for (RangeHighlighter highlighter :
                  myHyperlinkSupport.getValue().findAllHyperlinksOnLine(line)) {
                markupModel.addRangeHighlighter(
                    highlighter.getStartOffset(),
                    highlighter.getEndOffset(),
                    HighlighterLayer.CARET_ROW + 2,
                    italic,
                    HighlighterTargetArea.EXACT_RANGE);
                myHyperlinkSupport.getValue().removeHyperlink(highlighter);
              }
            }
          }
        };
    if (!notification.isExpired()) {
      myProjectModel.removeHandlers.put(notification, removeHandler);
    } else {
      removeHandler.run();
    }
  }
 public void printToHistory(String text, final TextAttributes attributes) {
   ApplicationManager.getApplication().assertIsDispatchThread();
   text = StringUtil.convertLineSeparators(text);
   final boolean scrollToEnd = shouldScrollHistoryToEnd();
   final Document history = myHistoryViewer.getDocument();
   final MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
   final int offset = history.getTextLength();
   appendToHistoryDocument(history, text);
   markupModel.addRangeHighlighter(
       offset,
       history.getTextLength(),
       HighlighterLayer.SYNTAX,
       attributes,
       HighlighterTargetArea.EXACT_RANGE);
   if (scrollToEnd) {
     scrollHistoryToEnd();
   }
   queueUiUpdate(scrollToEnd);
 }
 public void printToHistory(@NotNull final List<Pair<String, TextAttributes>> attributedText) {
   ApplicationManager.getApplication().assertIsDispatchThread();
   if (LOG.isDebugEnabled()) {
     LOG.debug("printToHistory(): " + attributedText.size());
   }
   final boolean scrollToEnd = shouldScrollHistoryToEnd();
   final int[] offsets = new int[attributedText.size() + 1];
   int i = 0;
   offsets[i] = 0;
   final StringBuilder sb = new StringBuilder();
   for (final Pair<String, TextAttributes> pair : attributedText) {
     sb.append(StringUtil.convertLineSeparators(pair.getFirst()));
     offsets[++i] = sb.length();
   }
   final DocumentEx history = myHistoryViewer.getDocument();
   final int oldHistoryLength = history.getTextLength();
   appendToHistoryDocument(history, sb.toString());
   assert oldHistoryLength + offsets[i] == history.getTextLength()
       : "unexpected history length "
           + oldHistoryLength
           + " "
           + offsets[i]
           + " "
           + history.getTextLength();
   LOG.debug("printToHistory(): text processed");
   final MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
   i = 0;
   for (final Pair<String, TextAttributes> pair : attributedText) {
     markupModel.addRangeHighlighter(
         oldHistoryLength + offsets[i],
         oldHistoryLength + offsets[i + 1],
         HighlighterLayer.SYNTAX,
         pair.getSecond(),
         HighlighterTargetArea.EXACT_RANGE);
     ++i;
   }
   LOG.debug("printToHistory(): markup added");
   if (scrollToEnd) {
     scrollHistoryToEnd();
   }
   queueUiUpdate(scrollToEnd);
   LOG.debug("printToHistory(): completed");
 }
  protected String addTextRangeToHistory(
      TextRange textRange, final EditorEx consoleEditor, boolean preserveMarkup) {
    final Document history = myHistoryViewer.getDocument();
    final MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
    if (myPrompt != null) {
      appendToHistoryDocument(history, myPrompt);
    }
    markupModel.addRangeHighlighter(
        history.getTextLength() - StringUtil.length(myPrompt),
        history.getTextLength(),
        HighlighterLayer.SYNTAX,
        ConsoleViewContentType.USER_INPUT.getAttributes(),
        HighlighterTargetArea.EXACT_RANGE);
    final int localStartOffset = textRange.getStartOffset();
    String text;
    EditorHighlighter highlighter;
    if (consoleEditor instanceof EditorWindow) {
      EditorWindow editorWindow = (EditorWindow) consoleEditor;
      EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
      PsiFile file = editorWindow.getInjectedFile();
      final VirtualFile virtualFile = file.getVirtualFile();
      assert virtualFile != null;
      highlighter = HighlighterFactory.createHighlighter(virtualFile, scheme, getProject());
      String fullText = InjectedLanguageUtil.getUnescapedText(file, null, null);
      highlighter.setText(fullText);
      text = textRange.substring(fullText);
    } else {
      text = consoleEditor.getDocument().getText(textRange);
      highlighter = consoleEditor.getHighlighter();
    }
    // offset can be changed after text trimming after insert due to buffer constraints
    appendToHistoryDocument(history, text);
    int offset = history.getTextLength() - text.length();

    final HighlighterIterator iterator = highlighter.createIterator(localStartOffset);
    final int localEndOffset = textRange.getEndOffset();
    while (!iterator.atEnd()) {
      final int itStart = iterator.getStart();
      if (itStart > localEndOffset) break;
      final int itEnd = iterator.getEnd();
      if (itEnd >= localStartOffset) {
        final int start = Math.max(itStart, localStartOffset) - localStartOffset + offset;
        final int end = Math.min(itEnd, localEndOffset) - localStartOffset + offset;
        markupModel.addRangeHighlighter(
            start,
            end,
            HighlighterLayer.SYNTAX,
            iterator.getTextAttributes(),
            HighlighterTargetArea.EXACT_RANGE);
      }
      iterator.advance();
    }
    if (preserveMarkup) {
      duplicateHighlighters(
          markupModel,
          DocumentMarkupModel.forDocument(consoleEditor.getDocument(), myProject, true),
          offset,
          textRange);
      duplicateHighlighters(markupModel, consoleEditor.getMarkupModel(), offset, textRange);
    }
    if (!text.endsWith("\n")) {
      appendToHistoryDocument(history, "\n");
    }
    return text;
  }