private void highlightLine(int index, NamedTextAttr namedTextAttr) { UIUtil.invokeAndWaitIfNeeded((Runnable) () -> { try { MarkupModelEx markupModel = myEditor.getMarkupModel(); final Document doc = markupModel.getDocument(); final int lineStartOffset = doc.getLineStartOffset(index); final int lineEndOffset = doc.getLineEndOffset(index); // IDEA-53203: add ERASE_MARKER for manually defined attributes markupModel.addRangeHighlighter(lineStartOffset, lineEndOffset, HighlighterLayer.SELECTION - 1, TextAttributes.ERASE_MARKER, HighlighterTargetArea.EXACT_RANGE); RangeHighlighter rangeHighlight = markupModel.addRangeHighlighter(lineStartOffset, lineEndOffset, HighlighterLayer.SELECTION - 1, namedTextAttr, HighlighterTargetArea.EXACT_RANGE); rangeHighlight.setErrorStripeMarkColor(namedTextAttr.getErrorStripeColor()); rangeHighlight.setErrorStripeTooltip(namedTextAttr.getName()); } catch (Exception e) { throw new RuntimeException(e); } }); }
public UnifiedEditorRangeHighlighter(@Nullable Project project, @NotNull Document document) { ApplicationManager.getApplication().assertReadAccessAllowed(); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, false); if (model == null) return; model.processRangeHighlightersOverlappingWith(0, document.getTextLength(), new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx marker) { int newStart = marker.getStartOffset(); int newEnd = marker.getEndOffset(); myPieces.add(new Element(marker, newStart, newEnd)); return true; } }); }
private void processRange(@NotNull MarkupModelEx model, @NotNull HighlightRange range) { final TextRange base = range.getBase(); final TextRange changed = range.getChanged(); final int changedLength = changed.getEndOffset() - changed.getStartOffset(); model.processRangeHighlightersOverlappingWith(changed.getStartOffset(), changed.getEndOffset(), new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx marker) { int relativeStart = Math.max(marker.getStartOffset() - changed.getStartOffset(), 0); int relativeEnd = Math.min(marker.getEndOffset() - changed.getStartOffset(), changedLength); int newStart = base.getStartOffset() + relativeStart; int newEnd = base.getStartOffset() + relativeEnd; if (newEnd - newStart <= 0) return true; myPieces.add(new Element(marker, newStart, newEnd)); return true; } }); }
public static void setHighlightersToEditor(@NotNull Project project, @NotNull Document document, int startOffset, int endOffset, @NotNull Collection<HighlightInfo> highlights, @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used int group) { TextRange range = new TextRange(startOffset, endOffset); ApplicationManager.getApplication().assertIsDispatchThread(); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); final DaemonCodeAnalyzerEx codeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(project); codeAnalyzer.cleanFileLevelHighlights(project, group, psiFile); MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true); assertMarkupConsistent(markup, project); setHighlightersInRange(project, document, range, colorsScheme, new ArrayList<HighlightInfo>(highlights), (MarkupModelEx)markup, group); }
public static boolean processHighlights(@NotNull Document document, @NotNull Project project, @Nullable("null means all") final HighlightSeverity minSeverity, final int startOffset, final int endOffset, @NotNull final Processor<HighlightInfo> processor) { LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); return model.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx marker) { Object tt = marker.getErrorStripeTooltip(); if (!(tt instanceof HighlightInfo)) return true; HighlightInfo info = (HighlightInfo)tt; return minSeverity != null && severityRegistrar.compare(info.getSeverity(), minSeverity) < 0 || info.highlighter == null || processor.process(info); } }); }
static boolean processHighlightsOverlappingOutside(@NotNull Document document, @NotNull Project project, @Nullable("null means all") final HighlightSeverity minSeverity, final int startOffset, final int endOffset, @NotNull final Processor<HighlightInfo> processor) { LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); return model.processRangeHighlightersOutside(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx marker) { Object tt = marker.getErrorStripeTooltip(); if (!(tt instanceof HighlightInfo)) return true; HighlightInfo info = (HighlightInfo)tt; return minSeverity != null && severityRegistrar.compare(info.getSeverity(), minSeverity) < 0 || info.highlighter == null || processor.process(info); } }); }
private void paintBorderEffect(final Graphics2D g, final ClipDetector clipDetector, MarkupModelEx markupModel, int clipStartOffset, int clipEndOffset) { markupModel.processRangeHighlightersOverlappingWith(clipStartOffset, clipEndOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx rangeHighlighter) { if (rangeHighlighter.getEditorFilter().avaliableIn(myEditor)) { TextAttributes attributes = rangeHighlighter.getTextAttributes(); if (isBorder(attributes)) { paintBorderEffect(g, clipDetector, rangeHighlighter.getAffectedAreaStartOffset(), rangeHighlighter.getAffectedAreaEndOffset(), attributes); } } return true; } }); }
public static List<RangeHighlighter> getHyperlinks(int startOffset, int endOffset, final Editor editor) { final MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel(); final CommonProcessors.CollectProcessor<RangeHighlighterEx> processor = new CommonProcessors.CollectProcessor<RangeHighlighterEx>(); markupModel.processRangeHighlightersOverlappingWith(startOffset, endOffset, new FilteringProcessor<RangeHighlighterEx>(new Condition<RangeHighlighterEx>() { @Override public boolean value(RangeHighlighterEx rangeHighlighterEx) { return rangeHighlighterEx.getEditorFilter().avaliableIn(editor) && HYPERLINK_LAYER == rangeHighlighterEx.getLayer() && rangeHighlighterEx.isValid() && getHyperlinkInfo(rangeHighlighterEx) != null; } }, processor) ); return new ArrayList<RangeHighlighter>(processor.getResults()); }
private static void linkFollowed(Editor editor, Collection<RangeHighlighter> ranges, final RangeHighlighter link) { MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel(); for (RangeHighlighter range : ranges) { TextAttributes oldAttr = range.getUserData(OLD_HYPERLINK_TEXT_ATTRIBUTES); if (oldAttr != null) { markupModel.setRangeHighlighterAttributes(range, oldAttr); range.putUserData(OLD_HYPERLINK_TEXT_ATTRIBUTES, null); } if (range == link) { range.putUserData(OLD_HYPERLINK_TEXT_ATTRIBUTES, range.getTextAttributes()); markupModel.setRangeHighlighterAttributes(range, getFollowedHyperlinkAttributes(range)); } } //refresh highlighter text attributes markupModel.addRangeHighlighter(0, 0, HYPERLINK_LAYER, getHyperlinkAttributes(), HighlighterTargetArea.EXACT_RANGE).dispose(); }
public void testRangeHighlighterLinesInRangeForLongLinePerformance() throws Exception { final int N = 50000; Document document = EditorFactory.getInstance().createDocument(StringUtil.repeatSymbol('x', 2 * N)); final MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, ourProject, true); for (int i=0; i<N-1;i++) { markupModel.addRangeHighlighter(2*i, 2*i+1, 0, null, HighlighterTargetArea.EXACT_RANGE); } markupModel.addRangeHighlighter(N / 2, N / 2 + 1, 0, null, HighlighterTargetArea.LINES_IN_RANGE); PlatformTestUtil.startPerformanceTest("slow highlighters lookup", (int)(N*Math.log(N)/1000), new ThrowableRunnable() { @Override public void run() { List<RangeHighlighterEx> list = new ArrayList<RangeHighlighterEx>(); CommonProcessors.CollectProcessor<RangeHighlighterEx> coll = new CommonProcessors.CollectProcessor<RangeHighlighterEx>(list); for (int i=0; i<N-1;i++) { list.clear(); markupModel.processRangeHighlightersOverlappingWith(2*i, 2*i+1, coll); assertEquals(2, list.size()); // 1 line plus one exact range marker } } }).assertTiming(); }
@Nullable protected static RangeHighlighter createHighlighter(@NotNull Project project, @NotNull Document document, int lineIndex) { if (lineIndex < 0 || lineIndex >= document.getLineCount()) { return null; } EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); TextAttributes attributes = scheme.getAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES); RangeHighlighter highlighter = ((MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true)) .addPersistentLineHighlighter(lineIndex, DebuggerColors.BREAKPOINT_HIGHLIGHTER_LAYER, attributes); if (!highlighter.isValid()) { return null; } highlighter.putUserData(DebuggerColors.BREAKPOINT_HIGHLIGHTER_KEY, Boolean.TRUE); highlighter.setErrorStripeTooltip(DebuggerBundle.message("breakpoint.tooltip.text", lineIndex + 1)); return highlighter; }
public void updateUI() { if (myDisposed) return; if (ApplicationManager.getApplication().isUnitTestMode()) return; Document document = getDocument(); if (document == null) return; EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); TextAttributes attributes = scheme.getAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES); removeHighlighter(); MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), true); RangeHighlighter highlighter = markupModel.addPersistentLineHighlighter(getLine(), DebuggerColors.BREAKPOINT_HIGHLIGHTER_LAYER, attributes); if (highlighter != null) { updateIcon(); highlighter.setGutterIconRenderer(createGutterIconRenderer()); highlighter.putUserData(DebuggerColors.BREAKPOINT_HIGHLIGHTER_KEY, Boolean.TRUE); } myHighlighter = highlighter; }
public static boolean processHighlights(@NotNull Document document, @NotNull Project project, @Nullable("null means all") final HighlightSeverity minSeverity, final int startOffset, final int endOffset, @NotNull final Processor<HighlightInfo> processor) { LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); final SeverityRegistrar severityRegistrar = SeverityUtil.getSeverityRegistrar(project); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); return model.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx marker) { Object tt = marker.getErrorStripeTooltip(); if (!(tt instanceof HighlightInfo)) return true; HighlightInfo info = (HighlightInfo)tt; return minSeverity != null && severityRegistrar.compare(info.getSeverity(), minSeverity) < 0 || info.highlighter == null || processor.process(info); } }); }
static boolean processHighlightsOverlappingOutside(@NotNull Document document, @NotNull Project project, @Nullable("null means all") final HighlightSeverity minSeverity, final int startOffset, final int endOffset, @NotNull final Processor<HighlightInfo> processor) { LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); final SeverityRegistrar severityRegistrar = SeverityUtil.getSeverityRegistrar(project); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); return model.processRangeHighlightersOutside(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(@NotNull RangeHighlighterEx marker) { Object tt = marker.getErrorStripeTooltip(); if (!(tt instanceof HighlightInfo)) return true; HighlightInfo info = (HighlightInfo)tt; return minSeverity != null && severityRegistrar.compare(info.getSeverity(), minSeverity) < 0 || info.highlighter == null || processor.process(info); } }); }
public static void setHighlightersToEditor(@NotNull Project project, @NotNull Document document, int startOffset, int endOffset, @NotNull Collection<HighlightInfo> highlights, @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used int group) { TextRange range = new TextRange(startOffset, endOffset); ApplicationManager.getApplication().assertIsDispatchThread(); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); cleanFileLevelHighlights(project, group, psiFile); MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true); assertMarkupConsistent(markup, project); setHighlightersInRange(project, document, range, colorsScheme, new ArrayList<HighlightInfo>(highlights), (MarkupModelEx)markup, group); }
public RangeHighlighter createHighlighter(@NotNull MarkupModelEx markup) { final RangeHighlighter myHighlighter; int line = getLine(); if (line >= 0) { myHighlighter = markup.addPersistentLineHighlighter(line, HighlighterLayer.ERROR + 1, null); if (myHighlighter != null) { myHighlighter.setGutterIconRenderer(new MyGutterIconRenderer(this)); myHighlighter.setErrorStripeMarkColor(Color.black); myHighlighter.setErrorStripeTooltip(getBookmarkTooltip()); } } else { myHighlighter = null; } return myHighlighter; }
public UnifiedEditorRangeHighlighter(@Nullable Project project, @Nonnull Document document) { ApplicationManager.getApplication().assertReadAccessAllowed(); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, false); if (model == null) return; model.processRangeHighlightersOverlappingWith(0, document.getTextLength(), new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx marker) { int newStart = marker.getStartOffset(); int newEnd = marker.getEndOffset(); myPieces.add(new Element(marker, newStart, newEnd)); return true; } }); }
private void processRange(@Nonnull MarkupModelEx model, @Nonnull HighlightRange range) { final TextRange base = range.getBase(); final TextRange changed = range.getChanged(); final int changedLength = changed.getEndOffset() - changed.getStartOffset(); model.processRangeHighlightersOverlappingWith(changed.getStartOffset(), changed.getEndOffset(), new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx marker) { int relativeStart = Math.max(marker.getStartOffset() - changed.getStartOffset(), 0); int relativeEnd = Math.min(marker.getEndOffset() - changed.getStartOffset(), changedLength); int newStart = base.getStartOffset() + relativeStart; int newEnd = base.getStartOffset() + relativeEnd; if (newEnd - newStart <= 0) return true; myPieces.add(new Element(marker, newStart, newEnd)); return true; } }); }
public static void setHighlightersToEditor(@Nonnull Project project, @Nonnull Document document, int startOffset, int endOffset, @Nonnull Collection<HighlightInfo> highlights, @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used int group) { TextRange range = new TextRange(startOffset, endOffset); ApplicationManager.getApplication().assertIsDispatchThread(); PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); final DaemonCodeAnalyzerEx codeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(project); codeAnalyzer.cleanFileLevelHighlights(project, group, psiFile); MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true); assertMarkupConsistent(markup, project); setHighlightersInRange(project, document, range, colorsScheme, new ArrayList<>(highlights), (MarkupModelEx)markup, group); }
public static boolean processHighlights(@Nonnull Document document, @Nonnull Project project, @Nullable final HighlightSeverity minSeverity, final int startOffset, final int endOffset, @Nonnull final Processor<HighlightInfo> processor) { LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); return model.processRangeHighlightersOverlappingWith(startOffset, endOffset, marker -> { Object tt = marker.getErrorStripeTooltip(); if (!(tt instanceof HighlightInfo)) return true; HighlightInfo info = (HighlightInfo)tt; return minSeverity != null && severityRegistrar.compare(info.getSeverity(), minSeverity) < 0 || info.highlighter == null || processor.process(info); }); }
static boolean processHighlightsOverlappingOutside(@Nonnull Document document, @Nonnull Project project, @Nullable final HighlightSeverity minSeverity, final int startOffset, final int endOffset, @Nonnull final Processor<HighlightInfo> processor) { LOG.assertTrue(ApplicationManager.getApplication().isReadAccessAllowed()); final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project); MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); return model.processRangeHighlightersOutside(startOffset, endOffset, marker -> { Object tt = marker.getErrorStripeTooltip(); if (!(tt instanceof HighlightInfo)) return true; HighlightInfo info = (HighlightInfo)tt; return minSeverity != null && severityRegistrar.compare(info.getSeverity(), minSeverity) < 0 || info.highlighter == null || processor.process(info); }); }
private void createStatusHighlighter() { int line1 = myPatchDeletionRange.start; int line2 = myPatchInsertionRange.end; Color color = getStatusColor(); if (isResolved()) { color = ColorUtil.mix(color, myViewer.getPatchEditor().getGutterComponentEx().getBackground(), 0.6f); } String tooltip = getStatusText(); EditorEx patchEditor = myViewer.getPatchEditor(); Document document = patchEditor.getDocument(); MarkupModelEx markupModel = patchEditor.getMarkupModel(); TextRange textRange = DiffUtil.getLinesRange(document, line1, line2); RangeHighlighter highlighter = markupModel.addRangeHighlighter(textRange.getStartOffset(), textRange.getEndOffset(), HighlighterLayer.LAST, null, HighlighterTargetArea.LINES_IN_RANGE); PairConsumer<Editor, MouseEvent> clickHandler = getResultRange() != null ? (e, event) -> myViewer.scrollToChange(this, Side.RIGHT, false) : null; highlighter.setLineMarkerRenderer(LineStatusMarkerRenderer.createRenderer(line1, line2, color, tooltip, clickHandler)); myHighlighters.add(highlighter); }
/** * Patches attributes to be visible under debugger active line */ @SuppressWarnings("UseJBColor") public static TextAttributes patchAttributesColor(TextAttributes attributes, @Nonnull TextRange range, @Nonnull Editor editor) { if (attributes.getForegroundColor() == null && attributes.getEffectColor() == null) return attributes; MarkupModel model = DocumentMarkupModel.forDocument(editor.getDocument(), editor.getProject(), false); if (model != null) { if (!((MarkupModelEx)model).processRangeHighlightersOverlappingWith(range.getStartOffset(), range.getEndOffset(), highlighter -> { if (highlighter.isValid() && highlighter.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) { TextAttributes textAttributes = highlighter.getTextAttributes(); if (textAttributes != null) { Color color = textAttributes.getBackgroundColor(); return !(color != null && color.getBlue() > 128 && color.getRed() < 128 && color.getGreen() < 128); } } return true; })) { TextAttributes clone = attributes.clone(); clone.setForegroundColor(Color.orange); clone.setEffectColor(Color.orange); return clone; } } return attributes; }
static void addLineMarkerToEditorIncrementally(@Nonnull Project project, @Nonnull Document document, @Nonnull LineMarkerInfo marker) { ApplicationManager.getApplication().assertIsDispatchThread(); MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, project, true); LineMarkerInfo[] markerInTheWay = {null}; boolean allIsClear = markupModel.processRangeHighlightersOverlappingWith(marker.startOffset, marker.endOffset, highlighter -> (markerInTheWay[0] = getLineMarkerInfo(highlighter)) == null); if (allIsClear) { createOrReuseLineMarker(marker, markupModel, null); } if (LOG.isDebugEnabled()) { LOG.debug("LineMarkersUtil.addLineMarkerToEditorIncrementally: "+marker+" "+(allIsClear ? "created" : " (was not added because "+markerInTheWay[0] +" was in the way)")); } }
private static void clearLineMarkers(Editor editor) { final List<RangeHighlighter> oldHighlighters = editor.getUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY); if(oldHighlighters != null) { final MarkupModelEx markupModel = (MarkupModelEx) editor.getMarkupModel(); for(RangeHighlighter highlighter : oldHighlighters) { if(markupModel.containsHighlighter(highlighter)) { highlighter.dispose(); } } editor.putUserData(TAG_TREE_HIGHLIGHTERS_IN_EDITOR_KEY, null); } }
public UnifiedEditorRangeHighlighter(@Nullable Project project, @NotNull Document document1, @NotNull Document document2, @NotNull List<HighlightRange> ranges) { ApplicationManager.getApplication().assertReadAccessAllowed(); MarkupModelEx model1 = (MarkupModelEx)DocumentMarkupModel.forDocument(document1, project, false); MarkupModelEx model2 = (MarkupModelEx)DocumentMarkupModel.forDocument(document2, project, false); init(model1, model2, ranges); }
private void init(@Nullable MarkupModelEx model1, @Nullable MarkupModelEx model2, @NotNull List<HighlightRange> ranges) { for (HighlightRange range : ranges) { if (range.getSide().isLeft()) { if (model1 != null) processRange(model1, range); } else { if (model2 != null) processRange(model2, range); } } }
private void fireChanged(boolean renderersChanged) { if (myModel instanceof MarkupModelEx) { if (isFlagSet(IN_BATCH_CHANGE_MASK)) { setFlag(CHANGED_MASK, true); if (renderersChanged) { setFlag(RENDERERS_CHANGED_MASK, true); } } else { ((MarkupModelEx)myModel).fireAttributesChanged(this, renderersChanged); } } }
static void addHighlighterToEditorIncrementally(@NotNull Project project, @NotNull Document document, @NotNull PsiFile file, int startOffset, int endOffset, @NotNull final HighlightInfo info, @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used final int group, @NotNull Map<TextRange, RangeMarker> ranges2markersCache) { ApplicationManager.getApplication().assertIsDispatchThread(); if (isFileLevelOrGutterAnnotation(info)) return; if (info.getStartOffset() < startOffset || info.getEndOffset() > endOffset) return; MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true); final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project); final boolean myInfoIsError = isSevere(info, severityRegistrar); Processor<HighlightInfo> otherHighlightInTheWayProcessor = new Processor<HighlightInfo>() { @Override public boolean process(HighlightInfo oldInfo) { if (!myInfoIsError && isCovered(info, severityRegistrar, oldInfo)) { return false; } return oldInfo.getGroup() != group || !oldInfo.equalsByActualOffset(info); } }; boolean allIsClear = DaemonCodeAnalyzerEx.processHighlights(document, project, null, info.getActualStartOffset(), info.getActualEndOffset(), otherHighlightInTheWayProcessor); if (allIsClear) { createOrReuseHighlighterFor(info, colorsScheme, document, group, file, (MarkupModelEx)markup, null, ranges2markersCache, severityRegistrar); clearWhiteSpaceOptimizationFlag(document); assertMarkupConsistent(markup, project); } }
void paint(Graphics2D g) { Rectangle clip = g.getClipBounds(); if (myEditor.getContentComponent().isOpaque()) { g.setColor(myEditor.getBackgroundColor()); g.fillRect(clip.x, clip.y, clip.width, clip.height); } if (paintPlaceholderText(g)) { paintCaret(g); return; } int startLine = myView.yToVisualLine(Math.max(clip.y, 0)); int endLine = myView.yToVisualLine(Math.max(clip.y + clip.height, 0)); int startOffset = myView.visualPositionToOffset(new VisualPosition(startLine, 0)); int endOffset = myView.visualPositionToOffset(new VisualPosition(endLine + 1, 0, true)); ClipDetector clipDetector = new ClipDetector(myEditor, clip); paintBackground(g, clip, startLine, endLine); paintRightMargin(g, clip); paintCustomRenderers(g, startOffset, endOffset); MarkupModelEx docMarkup = (MarkupModelEx)DocumentMarkupModel.forDocument(myDocument, myEditor.getProject(), true); paintLineMarkersSeparators(g, clip, docMarkup, startOffset, endOffset); paintLineMarkersSeparators(g, clip, myEditor.getMarkupModel(), startOffset, endOffset); paintTextWithEffects(g, clip, startLine, endLine); paintHighlightersAfterEndOfLine(g, docMarkup, startOffset, endOffset); paintHighlightersAfterEndOfLine(g, myEditor.getMarkupModel(), startOffset, endOffset); paintBorderEffect(g, clipDetector, myEditor.getHighlighter(), startOffset, endOffset); paintBorderEffect(g, clipDetector, docMarkup, startOffset, endOffset); paintBorderEffect(g, clipDetector, myEditor.getMarkupModel(), startOffset, endOffset); paintCaret(g); paintComposedTextDecoration(g); }
private void paintLineMarkersSeparators(final Graphics g, final Rectangle clip, MarkupModelEx markupModel, int startOffset, int endOffset) { markupModel.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx highlighter) { if (highlighter.getEditorFilter().avaliableIn(myEditor)) { paintLineMarkerSeparator(highlighter, clip, g); } return true; } }); }
private void paintHighlightersAfterEndOfLine(final Graphics2D g, MarkupModelEx markupModel, final int startOffset, int endOffset) { markupModel.processRangeHighlightersOverlappingWith(startOffset, endOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx highlighter) { if (highlighter.getEditorFilter().avaliableIn(myEditor) && highlighter.getStartOffset() >= startOffset) { paintHighlighterAfterEndOfLine(g, highlighter); } return true; } }); }
public void paintHighlighters(MarkupModelEx markupModel) { markupModel.processRangeHighlightersOverlappingWith(myStartOffset, myEndOffset, new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx rangeHighlighter) { if (!rangeHighlighter.getEditorFilter().avaliableIn(myEditor)) return true; TextAttributes textAttributes = rangeHighlighter.getTextAttributes(); if (isBorder(textAttributes) && intersectsRange(rangeHighlighter)) { paintBorder(rangeHighlighter, textAttributes); } return true; } }); }
public void testRangeHighlighterIteratorOrder() throws Exception { Document document = EditorFactory.getInstance().createDocument("1234567890"); final MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, ourProject, true); RangeHighlighter exact = markupModel.addRangeHighlighter(3, 6, 0, null, HighlighterTargetArea.EXACT_RANGE); RangeHighlighter line = markupModel.addRangeHighlighter(4, 5, 0, null, HighlighterTargetArea.LINES_IN_RANGE); List<RangeHighlighter> list = new ArrayList<RangeHighlighter>(); markupModel.processRangeHighlightersOverlappingWith(2, 9, new CommonProcessors.CollectProcessor<RangeHighlighter>(list)); assertEquals(Arrays.asList(line, exact), list); }
private void removeLineMarkers() { ApplicationManager.getApplication().assertIsDispatchThread(); RangeHighlighter marker = myEditor.getUserData(LINE_MARKER_IN_EDITOR_KEY); if (marker != null && ((MarkupModelEx)myEditor.getMarkupModel()).containsHighlighter(marker)) { marker.dispose(); } myEditor.putUserData(LINE_MARKER_IN_EDITOR_KEY, null); }
@Override public boolean removeSegmentHighlighter(@NotNull Editor editor, @NotNull RangeHighlighter highlighter) { Map<RangeHighlighter, HighlightInfo> map = getHighlightInfoMap(editor, false); if (map == null) return false; HighlightInfo info = map.get(highlighter); if (info == null) return false; MarkupModel markupModel = info.editor.getMarkupModel(); if (((MarkupModelEx)markupModel).containsHighlighter(highlighter)) { highlighter.dispose(); } map.remove(highlighter); return true; }
/** * Patches attributes to be visible under debugger active line */ @SuppressWarnings("UseJBColor") public static TextAttributes patchAttributesColor(TextAttributes attributes, @NotNull TextRange range, @NotNull Editor editor) { MarkupModel model = DocumentMarkupModel.forDocument(editor.getDocument(), editor.getProject(), false); if (model != null) { if (!((MarkupModelEx)model).processRangeHighlightersOverlappingWith(range.getStartOffset(), range.getEndOffset(), new Processor<RangeHighlighterEx>() { @Override public boolean process(RangeHighlighterEx highlighter) { if (highlighter.isValid() && highlighter.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) { TextAttributes textAttributes = highlighter.getTextAttributes(); if (textAttributes != null) { Color color = textAttributes.getBackgroundColor(); return !(color != null && color.getBlue() > 128 && color.getRed() < 128 && color.getGreen() < 128); } } return true; } })) { TextAttributes clone = attributes.clone(); clone.setForegroundColor(Color.orange); clone.setEffectColor(Color.orange); return clone; } } return attributes; }
@Override public void highlightsInsideVisiblePartAreProduced(@NotNull final HighlightingSession session, @NotNull final List<HighlightInfo> infos, @NotNull TextRange priorityRange, @NotNull TextRange restrictRange, final int groupId) { final PsiFile psiFile = session.getPsiFile(); final Project project = psiFile.getProject(); final Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile); if (document == null) return; final long modificationStamp = document.getModificationStamp(); final TextRange priorityIntersection = priorityRange.intersection(restrictRange); final Editor editor = session.getEditor(); UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { if (project.isDisposed() || modificationStamp != document.getModificationStamp()) return; if (priorityIntersection != null) { MarkupModel markupModel = DocumentMarkupModel.forDocument(document, project, true); EditorColorsScheme scheme = session.getColorsScheme(); UpdateHighlightersUtil.setHighlightersInRange(project, document, priorityIntersection, scheme, infos, (MarkupModelEx)markupModel, groupId); } if (editor != null && !editor.isDisposed()) { // usability: show auto import popup as soon as possible new ShowAutoImportPass(project, psiFile, editor).applyInformationToEditor(); DaemonListeners.repaintErrorStripeRenderer(editor, project); } } }); }