use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class XmlTagTreeHighlightingPass method clearLineMarkers.
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);
}
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class XLineBreakpointImpl method updateUI.
public void updateUI() {
if (isDisposed() || ApplicationManager.getApplication().isUnitTestMode()) {
return;
}
Document document = getDocument();
if (document == null) {
return;
}
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
TextAttributes attributes = scheme.getAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES);
RangeHighlighter highlighter = myHighlighter;
if (highlighter != null && (!highlighter.isValid() || !DocumentUtil.isValidOffset(highlighter.getStartOffset(), document) || !Comparing.equal(highlighter.getTextAttributes(), attributes))) {
removeHighlighter();
highlighter = null;
}
MarkupModelEx markupModel;
if (highlighter == null) {
markupModel = (MarkupModelEx) DocumentMarkupModel.forDocument(document, getProject(), true);
TextRange range = myType.getHighlightRange(this);
if (range != null && !range.isEmpty()) {
range = range.intersection(DocumentUtil.getLineTextRange(document, getLine()));
if (range != null && !range.isEmpty()) {
highlighter = markupModel.addRangeHighlighter(range.getStartOffset(), range.getEndOffset(), DebuggerColors.BREAKPOINT_HIGHLIGHTER_LAYER, attributes, HighlighterTargetArea.EXACT_RANGE);
}
}
if (highlighter == null) {
highlighter = markupModel.addPersistentLineHighlighter(getLine(), DebuggerColors.BREAKPOINT_HIGHLIGHTER_LAYER, attributes);
}
if (highlighter == null) {
return;
}
highlighter.setGutterIconRenderer(createGutterIconRenderer());
highlighter.putUserData(DebuggerColors.BREAKPOINT_HIGHLIGHTER_KEY, Boolean.TRUE);
highlighter.setEditorFilter(MarkupEditorFilterFactory.createIsNotDiffFilter());
myHighlighter = highlighter;
} else {
markupModel = null;
}
updateIcon();
if (markupModel == null) {
markupModel = (MarkupModelEx) DocumentMarkupModel.forDocument(document, getProject(), false);
if (markupModel != null) {
// renderersChanged false - we don't change gutter size
markupModel.fireAttributesChanged((RangeHighlighterEx) highlighter, false, false);
}
}
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class UpdateHighlightersUtil method assertMarkupConsistent.
private static void assertMarkupConsistent(@NotNull final MarkupModel markup, @NotNull Project project) {
if (!RedBlackTree.VERIFY) {
return;
}
Document document = markup.getDocument();
DaemonCodeAnalyzerEx.processHighlights(document, project, null, 0, document.getTextLength(), info -> {
assert ((MarkupModelEx) markup).containsHighlighter(info.getHighlighter());
return true;
});
RangeHighlighter[] allHighlighters = markup.getAllHighlighters();
for (RangeHighlighter highlighter : allHighlighters) {
if (!highlighter.isValid())
continue;
Object tooltip = highlighter.getErrorStripeTooltip();
if (!(tooltip instanceof HighlightInfo)) {
continue;
}
final HighlightInfo info = (HighlightInfo) tooltip;
boolean contains = !DaemonCodeAnalyzerEx.processHighlights(document, project, null, info.getActualStartOffset(), info.getActualEndOffset(), highlightInfo -> BY_START_OFFSET_NODUPS.compare(highlightInfo, info) != 0);
assert contains : info;
}
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class UpdateHighlightersUtil method setHighlightersOutsideRange.
// set highlights inside startOffset,endOffset but outside priorityRange
static void setHighlightersOutsideRange(@NotNull final Project project, @NotNull final Document document, @NotNull final PsiFile psiFile, @NotNull final List<HighlightInfo> infos, @Nullable final EditorColorsScheme colorsScheme, // if null global scheme will be used
final int startOffset, final int endOffset, @NotNull final ProperTextRange priorityRange, final int group) {
ApplicationManager.getApplication().assertIsDispatchThread();
final DaemonCodeAnalyzerEx codeAnalyzer = DaemonCodeAnalyzerEx.getInstanceEx(project);
if (startOffset == 0 && endOffset == document.getTextLength()) {
codeAnalyzer.cleanFileLevelHighlights(project, group, psiFile);
}
final MarkupModel markup = DocumentMarkupModel.forDocument(document, project, true);
assertMarkupConsistent(markup, project);
final SeverityRegistrar severityRegistrar = SeverityRegistrar.getSeverityRegistrar(project);
final HighlightersRecycler infosToRemove = new HighlightersRecycler();
ContainerUtil.quickSort(infos, BY_START_OFFSET_NODUPS);
Set<HighlightInfo> infoSet = new THashSet<>(infos);
Processor<HighlightInfo> processor = info -> {
if (info.getGroup() == group) {
RangeHighlighter highlighter = info.getHighlighter();
int hiStart = highlighter.getStartOffset();
int hiEnd = highlighter.getEndOffset();
if (!info.isFromInjection() && hiEnd < document.getTextLength() && (hiEnd <= startOffset || hiStart >= endOffset)) {
return true;
}
boolean toRemove = infoSet.contains(info) || !priorityRange.containsRange(hiStart, hiEnd) && (hiEnd != document.getTextLength() || priorityRange.getEndOffset() != document.getTextLength());
if (toRemove) {
infosToRemove.recycleHighlighter(highlighter);
info.setHighlighter(null);
}
}
return true;
};
DaemonCodeAnalyzerEx.processHighlightsOverlappingOutside(document, project, null, priorityRange.getStartOffset(), priorityRange.getEndOffset(), processor);
final Map<TextRange, RangeMarker> ranges2markersCache = new THashMap<>(10);
final boolean[] changed = { false };
RangeMarkerTree.sweep((RangeMarkerTree.Generator<HighlightInfo>) processor1 -> ContainerUtil.process(infos, processor1), (offset, info, atStart, overlappingIntervals) -> {
if (!atStart)
return true;
// injections are oblivious to restricting range
if (!info.isFromInjection() && info.getEndOffset() < document.getTextLength() && (info.getEndOffset() <= startOffset || info.getStartOffset() >= endOffset))
return true;
if (info.isFileLevelAnnotation()) {
codeAnalyzer.addFileLevelHighlight(project, group, info, psiFile);
changed[0] = true;
return true;
}
if (isWarningCoveredByError(info, overlappingIntervals, severityRegistrar)) {
return true;
}
if (info.getStartOffset() < priorityRange.getStartOffset() || info.getEndOffset() > priorityRange.getEndOffset()) {
createOrReuseHighlighterFor(info, colorsScheme, document, group, psiFile, (MarkupModelEx) markup, infosToRemove, ranges2markersCache, severityRegistrar);
changed[0] = true;
}
return true;
});
for (RangeHighlighter highlighter : infosToRemove.forAllInGarbageBin()) {
highlighter.dispose();
changed[0] = true;
}
if (changed[0]) {
clearWhiteSpaceOptimizationFlag(document);
}
assertMarkupConsistent(markup, project);
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class UpdateHighlightersUtil method createOrReuseHighlighterFor.
private static void createOrReuseHighlighterFor(@NotNull final HighlightInfo info, // if null global scheme will be used
@Nullable final EditorColorsScheme colorsScheme, @NotNull final Document document, final int group, @NotNull final PsiFile psiFile, @NotNull MarkupModelEx markup, @Nullable HighlightersRecycler infosToRemove, @NotNull final Map<TextRange, RangeMarker> ranges2markersCache, @NotNull SeverityRegistrar severityRegistrar) {
int infoStartOffset = info.startOffset;
int infoEndOffset = info.endOffset;
final int docLength = document.getTextLength();
if (infoEndOffset > docLength) {
infoEndOffset = docLength;
infoStartOffset = Math.min(infoStartOffset, infoEndOffset);
}
if (infoEndOffset == infoStartOffset && !info.isAfterEndOfLine()) {
// empty highlighter beyond file boundaries
if (infoEndOffset == docLength)
return;
//show something in case of empty highlightinfo
infoEndOffset++;
}
info.setGroup(group);
int layer = getLayer(info, severityRegistrar);
RangeHighlighterEx highlighter = infosToRemove == null ? null : (RangeHighlighterEx) infosToRemove.pickupHighlighterFromGarbageBin(info.startOffset, info.endOffset, layer);
final TextRange finalInfoRange = new TextRange(infoStartOffset, infoEndOffset);
final TextAttributes infoAttributes = info.getTextAttributes(psiFile, colorsScheme);
Consumer<RangeHighlighterEx> changeAttributes = finalHighlighter -> {
if (infoAttributes != null) {
finalHighlighter.setTextAttributes(infoAttributes);
}
info.setHighlighter(finalHighlighter);
finalHighlighter.setAfterEndOfLine(info.isAfterEndOfLine());
Color color = info.getErrorStripeMarkColor(psiFile, colorsScheme);
finalHighlighter.setErrorStripeMarkColor(color);
if (info != finalHighlighter.getErrorStripeTooltip()) {
finalHighlighter.setErrorStripeTooltip(info);
}
GutterMark renderer = info.getGutterIconRenderer();
finalHighlighter.setGutterIconRenderer((GutterIconRenderer) renderer);
ranges2markersCache.put(finalInfoRange, info.getHighlighter());
if (info.quickFixActionRanges != null) {
List<Pair<HighlightInfo.IntentionActionDescriptor, RangeMarker>> list = new ArrayList<>(info.quickFixActionRanges.size());
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
TextRange textRange = pair.second;
RangeMarker marker = getOrCreate(document, ranges2markersCache, textRange);
list.add(Pair.create(pair.first, marker));
}
info.quickFixActionMarkers = ContainerUtil.createLockFreeCopyOnWriteList(list);
}
ProperTextRange fixRange = info.getFixTextRange();
if (finalInfoRange.equals(fixRange)) {
info.fixMarker = null;
} else {
info.fixMarker = getOrCreate(document, ranges2markersCache, fixRange);
}
};
if (highlighter == null) {
highlighter = markup.addRangeHighlighterAndChangeAttributes(infoStartOffset, infoEndOffset, layer, null, HighlighterTargetArea.EXACT_RANGE, false, changeAttributes);
} else {
markup.changeAttributesInBatch(highlighter, changeAttributes);
}
boolean attributesSet = Comparing.equal(infoAttributes, highlighter.getTextAttributes());
assert attributesSet : "Info: " + infoAttributes + "; colorsScheme: " + (colorsScheme == null ? "[global]" : colorsScheme.getName()) + "; highlighter:" + highlighter.getTextAttributes();
}
Aggregations