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());
   }
 }
示例#2
0
 /** Patches attributes to be visible under debugger active line */
 @SuppressWarnings("UseJBColor")
 private static TextAttributes patchAttributesColor(
     TextAttributes attributes, TextRange range, Editor editor) {
   int line = editor.offsetToLogicalPosition(range.getStartOffset()).line;
   for (RangeHighlighter highlighter : editor.getMarkupModel().getAllHighlighters()) {
     if (!highlighter.isValid()) continue;
     if (highlighter.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE
         && editor.offsetToLogicalPosition(highlighter.getStartOffset()).line == line) {
       TextAttributes textAttributes = highlighter.getTextAttributes();
       if (textAttributes != null) {
         Color color = textAttributes.getBackgroundColor();
         if (color != null
             && color.getBlue() > 128
             && color.getRed() < 128
             && color.getGreen() < 128) {
           TextAttributes clone = attributes.clone();
           clone.setForegroundColor(Color.orange);
           clone.setEffectColor(Color.orange);
           return clone;
         }
       }
     }
   }
   return attributes;
 }
  private List<HighlightInfo> getHighlights() {
    if (myReadAccessRanges.isEmpty() && myWriteAccessRanges.isEmpty()) {
      return Collections.emptyList();
    }
    Set<Pair<Object, TextRange>> existingMarkupTooltips = new HashSet<Pair<Object, TextRange>>();
    for (RangeHighlighter highlighter : myEditor.getMarkupModel().getAllHighlighters()) {
      existingMarkupTooltips.add(
          Pair.create(
              highlighter.getErrorStripeTooltip(),
              new TextRange(highlighter.getStartOffset(), highlighter.getEndOffset())));
    }

    List<HighlightInfo> result =
        new ArrayList<HighlightInfo>(myReadAccessRanges.size() + myWriteAccessRanges.size());
    for (TextRange range : myReadAccessRanges) {
      ContainerUtil.addIfNotNull(
          createHighlightInfo(
              range, HighlightInfoType.ELEMENT_UNDER_CARET_READ, existingMarkupTooltips),
          result);
    }
    for (TextRange range : myWriteAccessRanges) {
      ContainerUtil.addIfNotNull(
          createHighlightInfo(
              range, HighlightInfoType.ELEMENT_UNDER_CARET_WRITE, existingMarkupTooltips),
          result);
    }
    return result;
  }
  private void updateInSelectionHighlighters() {
    if (mySearchResults.getEditor() == null) return;
    final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel();
    int[] starts = selectionModel.getBlockSelectionStarts();
    int[] ends = selectionModel.getBlockSelectionEnds();

    final HashSet<RangeHighlighter> toRemove = new HashSet<RangeHighlighter>();
    Set<RangeHighlighter> toAdd = new HashSet<RangeHighlighter>();
    for (RangeHighlighter highlighter : myHighlighters) {
      boolean intersectsWithSelection = false;
      for (int i = 0; i < starts.length; ++i) {
        TextRange selectionRange = new TextRange(starts[i], ends[i]);
        intersectsWithSelection =
            selectionRange.intersects(highlighter.getStartOffset(), highlighter.getEndOffset())
                && selectionRange.getEndOffset() != highlighter.getStartOffset()
                && highlighter.getEndOffset() != selectionRange.getStartOffset();
        if (intersectsWithSelection) break;
      }

      final Object userData = highlighter.getUserData(IN_SELECTION_KEY);
      if (userData != null) {
        if (!intersectsWithSelection) {
          if (userData == IN_SELECTION2) {
            HighlightManager.getInstance(mySearchResults.getProject())
                .removeSegmentHighlighter(mySearchResults.getEditor(), highlighter);
            toRemove.add(highlighter);
          } else {
            highlighter.putUserData(IN_SELECTION_KEY, null);
          }
        }
      } else if (intersectsWithSelection) {
        TextRange cursor = mySearchResults.getCursor();
        if (cursor != null
            && highlighter.getStartOffset() == cursor.getStartOffset()
            && highlighter.getEndOffset() == cursor.getEndOffset()) continue;
        final RangeHighlighter toAnnotate =
            highlightRange(
                new TextRange(highlighter.getStartOffset(), highlighter.getEndOffset()),
                new TextAttributes(null, null, Color.WHITE, EffectType.ROUNDED_BOX, 0),
                toAdd);
        highlighter.putUserData(IN_SELECTION_KEY, IN_SELECTION1);
        toAnnotate.putUserData(IN_SELECTION_KEY, IN_SELECTION2);
      }
    }
    myHighlighters.removeAll(toRemove);
    myHighlighters.addAll(toAdd);
  }
  private String getDisplayInfoInternal(boolean showPackageInfo, int totalTextLength) {
    final RangeHighlighter highlighter = getHighlighter();
    if (highlighter.isValid() && isValid()) {
      final int lineNumber =
          (highlighter.getDocument().getLineNumber(highlighter.getStartOffset()) + 1);
      String className = getClassName();
      final boolean hasClassInfo = className != null && className.length() > 0;
      final boolean hasMethodInfo = myMethodName != null && myMethodName.length() > 0;
      if (hasClassInfo || hasMethodInfo) {
        final StringBuilder info = StringBuilderSpinAllocator.alloc();
        try {
          boolean isFile = getSourcePosition().getFile().getName().equals(className);
          String packageName = null;
          if (hasClassInfo) {
            final int dotIndex = className.lastIndexOf(".");
            if (dotIndex >= 0 && !isFile) {
              packageName = className.substring(0, dotIndex);
              className = className.substring(dotIndex + 1);
            }

            if (totalTextLength != -1) {
              if (className.length() + (hasMethodInfo ? myMethodName.length() : 0)
                  > totalTextLength + 3) {
                int offset = totalTextLength - (hasMethodInfo ? myMethodName.length() : 0);
                if (offset > 0 && offset < className.length()) {
                  className = className.substring(className.length() - offset);
                  info.append("...");
                }
              }
            }

            info.append(className);
          }
          if (hasMethodInfo) {
            if (isFile) {
              info.append(":");
            } else if (hasClassInfo) {
              info.append(".");
            }
            info.append(myMethodName);
          }
          if (showPackageInfo && packageName != null) {
            info.append(" (").append(packageName).append(")");
          }
          return DebuggerBundle.message(
              "line.breakpoint.display.name.with.class.or.method", lineNumber, info.toString());
        } finally {
          StringBuilderSpinAllocator.dispose(info);
        }
      }
      return DebuggerBundle.message("line.breakpoint.display.name", lineNumber);
    }
    return DebuggerBundle.message("status.breakpoint.invalid");
  }
 @Nullable
 public RelativePoint getHyperlinkLocation(HyperlinkInfo info) {
   Editor editor = myLogEditor.getValue();
   Project project = editor.getProject();
   RangeHighlighter range = myHyperlinkSupport.getValue().findHyperlinkRange(info);
   Window window = NotificationsManagerImpl.findWindowForBalloon(project);
   if (range != null && window != null) {
     Point point =
         editor.visualPositionToXY(editor.offsetToVisualPosition(range.getStartOffset()));
     return new RelativePoint(
         window, SwingUtilities.convertPoint(editor.getContentComponent(), point, window));
   }
   return null;
 }
  private boolean showToolTipByMouseMove(final MouseEvent e, final double width) {
    MouseEvent me = e;

    Set<RangeHighlighter> highlighters = new THashSet<RangeHighlighter>();

    getNearestHighlighters(this, me, width, highlighters);
    getNearestHighlighters(
        (MarkupModelEx) myEditor.getDocument().getMarkupModel(getEditor().getProject()),
        me,
        width,
        highlighters);

    if (highlighters.isEmpty()) return false;

    int minDelta = Integer.MAX_VALUE;
    int y = e.getY();

    for (RangeHighlighter each : highlighters) {
      ProperTextRange range = offsetToYPosition(each.getStartOffset(), each.getEndOffset());
      int eachStartY = range.getStartOffset();
      int eachEndY = range.getEndOffset();
      int eachY = eachStartY + (eachEndY - eachStartY) / 2;
      if (Math.abs(e.getY() - eachY) < minDelta) {
        y = eachY;
      }
    }

    me =
        new MouseEvent(
            (Component) e.getSource(),
            e.getID(),
            e.getWhen(),
            e.getModifiers(),
            e.getX(),
            y + 1,
            e.getClickCount(),
            e.isPopupTrigger());

    TooltipRenderer bigRenderer = myTooltipRendererProvider.calcTooltipRenderer(highlighters);
    if (bigRenderer != null) {
      showTooltip(
          me,
          bigRenderer,
          new HintHint(me).setAwtTooltip(true).setPreferredPosition(Balloon.Position.atLeft));
      return true;
    }
    return false;
  }
示例#8
0
    public void documentChanged(@NotNull DocumentEvent event) {
      if (!VimPlugin.isEnabled()) {
        return;
      }

      Project[] projs = ProjectManager.getInstance().getOpenProjects();
      for (Project proj : projs) {
        Editor[] editors = EditorFactory.getInstance().getEditors(event.getDocument(), proj);
        for (Editor editor : editors) {
          Collection hls = EditorData.getLastHighlights(editor);
          if (hls == null) {
            continue;
          }

          int soff = event.getOffset();
          int eoff = soff + event.getNewLength();

          if (logger.isDebugEnabled()) {
            logger.debug("hls=" + hls);
            logger.debug("event=" + event);
          }
          Iterator iter = hls.iterator();
          while (iter.hasNext()) {
            RangeHighlighter rh = (RangeHighlighter) iter.next();
            if (!rh.isValid() || (eoff >= rh.getStartOffset() && soff <= rh.getEndOffset())) {
              iter.remove();
              editor.getMarkupModel().removeHighlighter(rh);
            }
          }

          int sl = editor.offsetToLogicalPosition(soff).line;
          int el = editor.offsetToLogicalPosition(eoff).line;
          VimPlugin.getSearch().highlightSearchLines(editor, false, sl, el);
          hls = EditorData.getLastHighlights(editor);
          if (logger.isDebugEnabled()) {
            logger.debug("sl=" + sl + ", el=" + el);
            logger.debug("hls=" + hls);
          }
        }
      }
    }
  public void doClick(final MouseEvent e, final int width) {
    RangeHighlighter marker = getNearestRangeHighlighter(e, width);
    if (marker == null) return;
    int offset = marker.getStartOffset();

    final Document doc = myEditor.getDocument();
    if (doc.getLineCount() > 0) {
      // Necessary to expand folded block even if navigating just before one
      // Very useful when navigating to first unused import statement.
      int lineEnd = doc.getLineEndOffset(doc.getLineNumber(offset));
      myEditor.getCaretModel().moveToOffset(lineEnd);
    }

    myEditor.getCaretModel().moveToOffset(offset);
    myEditor.getSelectionModel().removeSelection();
    ScrollingModel scrollingModel = myEditor.getScrollingModel();
    scrollingModel.disableAnimation();
    scrollingModel.scrollToCaret(ScrollType.CENTER);
    scrollingModel.enableAnimation();
    fireErrorMarkerClicked(marker, e);
  }
  private RangeHighlighter getNearestRangeHighlighter(final MouseEvent e, final int width) {
    List<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>();
    getNearestHighlighters(this, e, width, highlighters);
    getNearestHighlighters(
        (MarkupModelEx) myEditor.getDocument().getMarkupModel(myEditor.getProject()),
        e,
        width,
        highlighters);
    RangeHighlighter nearestMarker = null;
    int yPos = 0;
    for (RangeHighlighter highlighter : highlighters) {
      final int newYPos =
          offsetToYPosition(highlighter.getStartOffset(), highlighter.getEndOffset())
              .getStartOffset();

      if (nearestMarker == null || Math.abs(yPos - e.getY()) > Math.abs(newYPos - e.getY())) {
        nearestMarker = highlighter;
        yPos = newYPos;
      }
    }
    return nearestMarker;
  }
  private void paintLineMarkerSeparator(RangeHighlighter marker, Rectangle clip, Graphics g) {
    Color separatorColor = marker.getLineSeparatorColor();
    LineSeparatorRenderer lineSeparatorRenderer = marker.getLineSeparatorRenderer();
    if (separatorColor == null && lineSeparatorRenderer == null) {
      return;
    }
    int line =
        myDocument.getLineNumber(
            marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP
                ? marker.getStartOffset()
                : marker.getEndOffset());
    int visualLine =
        myView.logicalToVisualPosition(
                new LogicalPosition(
                    line + (marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP ? 0 : 1),
                    0),
                false)
            .line;
    int y = myView.visualLineToY(visualLine) - 1;
    int endShift = clip.x + clip.width;
    EditorSettings settings = myEditor.getSettings();
    if (settings.isRightMarginShown()
        && myEditor.getColorsScheme().getColor(EditorColors.RIGHT_MARGIN_COLOR) != null) {
      endShift =
          Math.min(
              endShift,
              settings.getRightMargin(myEditor.getProject()) * myView.getPlainSpaceWidth());
    }

    g.setColor(separatorColor);
    if (lineSeparatorRenderer != null) {
      lineSeparatorRenderer.drawLine(g, 0, endShift, y);
    } else {
      UIUtil.drawLine(g, 0, y, endShift, y);
    }
  }
示例#12
0
 @NotNull
 private RangeHighlighter highlightRange(
     TextRange textRange, TextAttributes attributes, Set<RangeHighlighter> highlighters) {
   if (myInSmartUpdate) {
     for (RangeHighlighter highlighter : myHighlighters) {
       if (highlighter.isValid()
           && highlighter.getStartOffset() == textRange.getStartOffset()
           && highlighter.getEndOffset() == textRange.getEndOffset()) {
         if (attributes.equals(highlighter.getTextAttributes())) {
           highlighter.putUserData(MARKER_USED, YES);
           if (highlighters != myHighlighters) {
             highlighters.add(highlighter);
           }
           return highlighter;
         }
       }
     }
   }
   final RangeHighlighter highlighter = doHightlightRange(textRange, attributes, highlighters);
   if (myInSmartUpdate) {
     highlighter.putUserData(MARKER_USED, YES);
   }
   return highlighter;
 }
示例#13
0
        @Override
        @SuppressWarnings({"AssignmentToForLoopParameter"})
        public void paint(
            @NotNull Editor editor, @NotNull RangeHighlighter highlighter, @NotNull Graphics g) {
          int startOffset = highlighter.getStartOffset();
          final Document doc = highlighter.getDocument();
          if (startOffset >= doc.getTextLength()) return;

          final int endOffset = highlighter.getEndOffset();
          final int endLine = doc.getLineNumber(endOffset);

          int off;
          int startLine = doc.getLineNumber(startOffset);
          IndentGuideDescriptor descriptor =
              editor.getIndentsModel().getDescriptor(startLine, endLine);

          final CharSequence chars = doc.getCharsSequence();
          do {
            int start = doc.getLineStartOffset(startLine);
            int end = doc.getLineEndOffset(startLine);
            off = CharArrayUtil.shiftForward(chars, start, end, " \t");
            startLine--;
          } while (startLine > 1 && off < doc.getTextLength() && chars.charAt(off) == '\n');

          final VisualPosition startPosition = editor.offsetToVisualPosition(off);
          int indentColumn = startPosition.column;

          // It's considered that indent guide can cross not only white space but comments, javadocs
          // etc. Hence, there is a possible
          // case that the first indent guide line is, say, single-line comment where comment
          // symbols ('//') are located at the first
          // visual column. We need to calculate correct indent guide column then.
          int lineShift = 1;
          if (indentColumn <= 0 && descriptor != null) {
            indentColumn = descriptor.indentLevel;
            lineShift = 0;
          }
          if (indentColumn <= 0) return;

          final FoldingModel foldingModel = editor.getFoldingModel();
          if (foldingModel.isOffsetCollapsed(off)) return;

          final FoldRegion headerRegion =
              foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(doc.getLineNumber(off)));
          final FoldRegion tailRegion =
              foldingModel.getCollapsedRegionAtOffset(
                  doc.getLineStartOffset(doc.getLineNumber(endOffset)));

          if (tailRegion != null && tailRegion == headerRegion) return;

          final boolean selected;
          final IndentGuideDescriptor guide = editor.getIndentsModel().getCaretIndentGuide();
          if (guide != null) {
            final CaretModel caretModel = editor.getCaretModel();
            final int caretOffset = caretModel.getOffset();
            selected =
                caretOffset >= off
                    && caretOffset < endOffset
                    && caretModel.getLogicalPosition().column == indentColumn;
          } else {
            selected = false;
          }

          Point start =
              editor.visualPositionToXY(
                  new VisualPosition(startPosition.line + lineShift, indentColumn));
          final VisualPosition endPosition = editor.offsetToVisualPosition(endOffset);
          Point end =
              editor.visualPositionToXY(new VisualPosition(endPosition.line, endPosition.column));
          int maxY = end.y;
          if (endPosition.line == editor.offsetToVisualPosition(doc.getTextLength()).line) {
            maxY += editor.getLineHeight();
          }

          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);
          }

          final EditorColorsScheme scheme = editor.getColorsScheme();
          g.setColor(
              selected
                  ? scheme.getColor(EditorColors.SELECTED_INDENT_GUIDE_COLOR)
                  : scheme.getColor(EditorColors.INDENT_GUIDE_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;
          if (selected) {
            g.drawLine(start.x + 2, start.y, start.x + 2, maxY);
          } else {
            int y = start.y;
            int newY = start.y;
            SoftWrapModel softWrapModel = editor.getSoftWrapModel();
            int lineHeight = editor.getLineHeight();
            for (int i = Math.max(0, startLine + lineShift); i < endLine && newY < maxY; i++) {
              List<? extends SoftWrap> softWraps = softWrapModel.getSoftWrapsForLine(i);
              int logicalLineHeight = softWraps.size() * lineHeight;
              if (i > startLine + lineShift) {
                logicalLineHeight +=
                    lineHeight; // We assume that initial 'y' value points just below the target
                // line.
              }
              if (!softWraps.isEmpty() && softWraps.get(0).getIndentInColumns() < indentColumn) {
                if (y < newY
                    || i
                        > startLine
                            + lineShift) { // There is a possible case that soft wrap is located on
                  // indent start line.
                  g.drawLine(start.x + 2, y, start.x + 2, newY + lineHeight);
                }
                newY += logicalLineHeight;
                y = newY;
              } else {
                newY += logicalLineHeight;
              }

              FoldRegion foldRegion =
                  foldingModel.getCollapsedRegionAtOffset(doc.getLineEndOffset(i));
              if (foldRegion != null && foldRegion.getEndOffset() < doc.getTextLength()) {
                i = doc.getLineNumber(foldRegion.getEndOffset());
              }
            }

            if (y < maxY) {
              g.drawLine(start.x + 2, y, start.x + 2, maxY);
            }
          }
        }
示例#14
0
 private static int compare(@NotNull TextRange r, @NotNull RangeHighlighter h) {
   int answer = r.getStartOffset() - h.getStartOffset();
   return answer != 0 ? answer : r.getEndOffset() - h.getEndOffset();
 }
示例#15
0
  private void dumpEditorMarkupAndSelection(PrintStream dumpStream) {
    dumpStream.println(mySearchResults.getFindModel());
    if (myReplacementPreviewText != null) {
      dumpStream.println("--");
      dumpStream.println("Replacement Preview: " + myReplacementPreviewText);
    }
    dumpStream.println("--");

    Editor editor = mySearchResults.getEditor();

    RangeHighlighter[] highlighters = editor.getMarkupModel().getAllHighlighters();
    List<Pair<Integer, Character>> ranges = new ArrayList<Pair<Integer, Character>>();
    for (RangeHighlighter highlighter : highlighters) {
      ranges.add(new Pair<Integer, Character>(highlighter.getStartOffset(), '['));
      ranges.add(new Pair<Integer, Character>(highlighter.getEndOffset(), ']'));
    }

    SelectionModel selectionModel = editor.getSelectionModel();

    if (selectionModel.getSelectionStart() != selectionModel.getSelectionEnd()) {
      ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionStart(), '<'));
      ranges.add(new Pair<Integer, Character>(selectionModel.getSelectionEnd(), '>'));
    }
    ranges.add(new Pair<Integer, Character>(-1, '\n'));
    ranges.add(new Pair<Integer, Character>(editor.getDocument().getTextLength() + 1, '\n'));
    ContainerUtil.sort(
        ranges,
        new Comparator<Pair<Integer, Character>>() {
          @Override
          public int compare(Pair<Integer, Character> pair, Pair<Integer, Character> pair2) {
            int res = pair.first - pair2.first;
            if (res == 0) {

              Character c1 = pair.second;
              Character c2 = pair2.second;
              if (c1 == '<' && c2 == '[') {
                return 1;
              } else if (c1 == '[' && c2 == '<') {
                return -1;
              }
              return c1.compareTo(c2);
            }
            return res;
          }
        });

    Document document = editor.getDocument();
    for (int i = 0; i < ranges.size() - 1; ++i) {
      Pair<Integer, Character> pair = ranges.get(i);
      Pair<Integer, Character> pair1 = ranges.get(i + 1);
      dumpStream.print(
          pair.second
              + document.getText(
                  TextRange.create(
                      Math.max(pair.first, 0), Math.min(pair1.first, document.getTextLength()))));
    }
    dumpStream.println("\n--");

    if (NotFound) {
      dumpStream.println("Not Found");
      dumpStream.println("--");
      NotFound = false;
    }

    for (RangeHighlighter highlighter : highlighters) {
      dumpStream.println(highlighter + " : " + highlighter.getTextAttributes());
    }
    dumpStream.println("------------");
  }