highlighting: do not read highlighter attributes before it's created

GitOrigin-RevId: 5b9cca65f27917000e8db918f44f548fb59996a3
This commit is contained in:
Alexey Kudravtsev
2024-12-20 18:50:16 +00:00
committed by intellij-monorepo-bot
parent c32067bfb3
commit ff42a38187
8 changed files with 66 additions and 65 deletions
@@ -293,8 +293,6 @@ public final class BackgroundUpdateHighlightersUtil {
TextAttributes infoAttributes = info.getTextAttributes(psiFile, colorsScheme);
Consumer<RangeHighlighterEx> changeAttributes = finalHighlighter -> {
changeAttributes(finalHighlighter, info, colorsScheme, psiFile, infoAttributes);
range2markerCache.put(finalInfoRange, finalHighlighter);
info.updateQuickFixFields(document, range2markerCache, finalInfoRange);
};
@@ -319,6 +317,8 @@ public final class BackgroundUpdateHighlightersUtil {
highlighter = salvagedHighlighter;
markup.changeAttributesInBatch(highlighter, changeAttributes);
}
info.setHighlighter(highlighter);
range2markerCache.put(finalInfoRange, highlighter);
if (LOG.isDebugEnabled()) {
LOG.debug("createOrReuseHighlighter " + highlighter + (salvagedHighlighter == null ? "" : " (recycled)"));
@@ -348,17 +348,14 @@ public final class BackgroundUpdateHighlightersUtil {
TextAttributesKey textAttributesKey = info.forcedTextAttributesKey == null ? info.type.getAttributesKey() : info.forcedTextAttributesKey;
highlighter.setTextAttributesKey(textAttributesKey);
TextAttributes highlighterTextAttributes = highlighter.getTextAttributes(colorsScheme);
if (infoAttributes == TextAttributes.ERASE_MARKER ||
infoAttributes != null && !infoAttributes.equals(highlighterTextAttributes)) {
if (infoAttributes != null) {
highlighter.setTextAttributes(infoAttributes);
}
info.setHighlighter(highlighter);
highlighter.setAfterEndOfLine(info.isAfterEndOfLine());
Color infoErrorStripeColor = info.getErrorStripeMarkColor(psiFile, colorsScheme);
Color attributesErrorStripeColor = highlighterTextAttributes != null ? highlighterTextAttributes.getErrorStripeColor() : null;
Color attributesErrorStripeColor = infoAttributes != null ? infoAttributes.getErrorStripeColor() : null;
if (infoErrorStripeColor != null && !infoErrorStripeColor.equals(attributesErrorStripeColor)) {
highlighter.setErrorStripeMarkColor(infoErrorStripeColor);
}
@@ -1225,22 +1225,21 @@ final class HighlightInfoUpdaterImpl extends HighlightInfoUpdater implements Dis
TextAttributes infoAttributes = newInfo.getTextAttributes(psiFile, session.getColorsScheme());
com.intellij.util.Consumer<RangeHighlighterEx> changeAttributes = finalHighlighter -> {
BackgroundUpdateHighlightersUtil.changeAttributes(finalHighlighter, newInfo, session.getColorsScheme(), psiFile, infoAttributes);
range2markerCache.put(finalInfoRange, finalHighlighter);
newInfo.updateQuickFixFields(session.getDocument(), range2markerCache, finalInfoRange);
};
if (LOG.isDebugEnabled()) {
LOG.debug("remap: create " + (recycled == null ? "(new RH)" : "(recycled)") + newInfo + currentProgressInfo());
}
RangeHighlighterEx highlighter;
if (recycled == null) {
// create new
if (isFileLevel) {
RangeHighlighterEx highlighter = createOrReuseFakeFileLevelHighlighter(MANAGED_HIGHLIGHT_INFO_GROUP, newInfo, null, markup);
highlighter = createOrReuseFakeFileLevelHighlighter(MANAGED_HIGHLIGHT_INFO_GROUP, newInfo, null, markup);
((HighlightingSessionImpl)session).addFileLevelHighlight(newInfo, highlighter);
}
else {
//assertNoInfoInMarkup(newInfo, markup, recycler, invalidElementRecycler);
markup.addRangeHighlighterAndChangeAttributes(null, infoStartOffset, infoEndOffset, layer,
highlighter = markup.addRangeHighlighterAndChangeAttributes(null, infoStartOffset, infoEndOffset, layer,
HighlighterTargetArea.EXACT_RANGE, false,
changeAttributes);
}
@@ -1248,17 +1247,18 @@ final class HighlightInfoUpdaterImpl extends HighlightInfoUpdater implements Dis
else {
// recycle
HighlightInfo info = recycled.info();
RangeHighlighterEx highlighter = info.getHighlighter();
highlighter = info.getHighlighter();
if (isFileLevel) {
RangeHighlighterEx highlighterToUse =
createOrReuseFakeFileLevelHighlighter(MANAGED_HIGHLIGHT_INFO_GROUP, newInfo, highlighter, markup);
((HighlightingSessionImpl)session).replaceFileLevelHighlight(info, newInfo, highlighterToUse);
highlighter = createOrReuseFakeFileLevelHighlighter(MANAGED_HIGHLIGHT_INFO_GROUP, newInfo, highlighter, markup);
((HighlightingSessionImpl)session).replaceFileLevelHighlight(info, newInfo, highlighter);
}
else {
markup.changeAttributesInBatch(highlighter, changeAttributes);
}
assert info.getGroup() == HighlightInfoUpdaterImpl.MANAGED_HIGHLIGHT_INFO_GROUP: info;
}
newInfo.setHighlighter(highlighter);
range2markerCache.put(finalInfoRange, highlighter);
}
@NotNull
@@ -1272,7 +1272,7 @@ final class HighlightInfoUpdaterImpl extends HighlightInfoUpdater implements Dis
// for the condition `existing.equalsByActualOffset(info)` above work correctly,
// create a fake whole-file highlighter which will track the document size changes
// and which will make possible to calculate correct `info.getActualEndOffset()`
info.setHighlighter(highlighter);
//info.setHighlighter(highlighter);
info.setGroup(group);
return highlighter;
}
@@ -298,12 +298,10 @@ public final class UpdateHighlightersUtil {
TextAttributesKey textAttributesKey = info.forcedTextAttributesKey == null ? info.type.getAttributesKey() : info.forcedTextAttributesKey;
finalHighlighter.setTextAttributesKey(textAttributesKey);
if (infoAttributes != null && !infoAttributes.equals(finalHighlighter.getTextAttributes(colorsScheme)) ||
infoAttributes == TextAttributes.ERASE_MARKER) {
if (infoAttributes != null) {
finalHighlighter.setTextAttributes(infoAttributes);
}
info.setHighlighter(finalHighlighter);
finalHighlighter.setAfterEndOfLine(info.isAfterEndOfLine());
Color infoErrorStripeColor = info.getErrorStripeMarkColor(psiFile, colorsScheme);
@@ -312,14 +310,10 @@ public final class UpdateHighlightersUtil {
if (infoErrorStripeColor != null && !infoErrorStripeColor.equals(attributesErrorStripeColor)) {
finalHighlighter.setErrorStripeMarkColor(infoErrorStripeColor);
}
if (info != finalHighlighter.getErrorStripeTooltip()) {
finalHighlighter.setErrorStripeTooltip(info);
}
finalHighlighter.setErrorStripeTooltip(info);
GutterMark renderer = info.getGutterIconRenderer();
finalHighlighter.setGutterIconRenderer((GutterIconRenderer)renderer);
range2markerCache.put(finalInfoRange, finalHighlighter);
info.updateQuickFixFields(document, range2markerCache, finalInfoRange);
};
@@ -334,6 +328,8 @@ public final class UpdateHighlightersUtil {
else {
markup.changeAttributesInBatch(highlighter, changeAttributes);
}
info.setHighlighter(highlighter);
range2markerCache.put(finalInfoRange, highlighter);
if (infoAttributes != null) {
boolean attributesSet = Comparing.equal(infoAttributes, highlighter.getTextAttributes(colorsScheme));
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHint;
import com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHintKt;
import com.intellij.openapi.editor.impl.ImaginaryEditor;
@@ -1136,25 +1137,29 @@ public final class TemplateState extends TemplateStateBase implements Disposable
int start = getSegments().getSegmentStart(segmentNumber);
int end = getSegments().getSegmentEnd(segmentNumber);
MarkupModelEx markupModel = (MarkupModelEx)getEditor().getMarkupModel();
return markupModel.addRangeHighlighterAndChangeAttributes(attributesKey, start, end, HighlighterLayer.ELEMENT_UNDER_CARET - 1,
HighlighterTargetArea.EXACT_RANGE, false, segmentHighlighter -> {
segmentHighlighter.setGreedyToLeft(true);
segmentHighlighter.setGreedyToRight(true);
RangeHighlighterEx highlighter =
markupModel.addRangeHighlighterAndChangeAttributes(attributesKey, start, end, HighlighterLayer.ELEMENT_UNDER_CARET - 1,
HighlighterTargetArea.EXACT_RANGE, false, segmentHighlighter -> {
segmentHighlighter.setGreedyToLeft(true);
segmentHighlighter.setGreedyToRight(true);
EditorColorsScheme scheme = getEditor().getColorsScheme();
TextAttributes attributes = segmentHighlighter.getTextAttributes(scheme);
if (attributes != null && attributes.getEffectType() == EffectType.BOXED && newStyle) {
TextAttributes clone = attributes.clone();
clone.setEffectType(EffectType.SLIGHTLY_WIDER_BOX);
clone.setBackgroundColor(scheme.getDefaultBackground());
segmentHighlighter.setTextAttributes(clone);
}
EditorActionAvailabilityHintKt.addActionAvailabilityHint(segmentHighlighter,
new EditorActionAvailabilityHint("NextTemplateVariable", EditorActionAvailabilityHint.AvailabilityCondition.CaretInside),
new EditorActionAvailabilityHint("PreviousTemplateVariable", EditorActionAvailabilityHint.AvailabilityCondition.CaretInside),
new EditorActionAvailabilityHint("EditorEscape", EditorActionAvailabilityHint.AvailabilityCondition.CaretInside));
segmentHighlighter.putUserData(TEMPLATE_RANGE_HIGHLIGHTER_KEY, mightStop);
});
EditorColorsScheme scheme = getEditor().getColorsScheme();
TextAttributes attributes = scheme.getAttributes(attributesKey);
if (attributes != null && attributes.getEffectType() == EffectType.BOXED && newStyle) {
TextAttributes clone = attributes.clone();
clone.setEffectType(EffectType.SLIGHTLY_WIDER_BOX);
clone.setBackgroundColor(scheme.getDefaultBackground());
segmentHighlighter.setTextAttributes(clone);
}
});
EditorActionAvailabilityHintKt.addActionAvailabilityHint(highlighter,
new EditorActionAvailabilityHint("NextTemplateVariable", EditorActionAvailabilityHint.AvailabilityCondition.CaretInside),
new EditorActionAvailabilityHint("PreviousTemplateVariable", EditorActionAvailabilityHint.AvailabilityCondition.CaretInside),
new EditorActionAvailabilityHint("EditorEscape", EditorActionAvailabilityHint.AvailabilityCondition.CaretInside));
highlighter.putUserData(TEMPLATE_RANGE_HIGHLIGHTER_KEY, mightStop);
return highlighter;
}
private boolean mightStopAtVariable(@Nullable Variable var, int segmentNumber) {
@@ -17,7 +17,7 @@
- s:values():com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHint$AvailabilityCondition[]
f:com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHintKt
- *sf:addActionAvailabilityHint(com.intellij.openapi.editor.Inlay,com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHint[]):V
- *sf:addActionAvailabilityHint(com.intellij.openapi.editor.RangeMarker,com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHint[]):V
- *sf:addActionAvailabilityHint(com.intellij.openapi.util.UserDataHolder,com.intellij.openapi.editor.ex.util.EditorActionAvailabilityHint[]):V
- *sf:clearAvailabilityHints(com.intellij.openapi.editor.Inlay):V
- *sf:clearAvailabilityHints(com.intellij.openapi.editor.markup.RangeHighlighter):V
f:com.intellij.openapi.editor.impl.DocumentMarkupModel
@@ -65,12 +65,12 @@ class EditorActionAvailabilityHint @JvmOverloads constructor(val actionId: Strin
* See the last parameter of [com.intellij.openapi.editor.ex.MarkupModelEx.addRangeHighlighterAndChangeAttributes]
*/
@Experimental
fun RangeMarker.addActionAvailabilityHint(vararg hints: EditorActionAvailabilityHint) {
this as UserDataHolderEx? ?: run {
fun UserDataHolder.addActionAvailabilityHint(vararg hints: EditorActionAvailabilityHint) {
this as UserDataHolder? ?: run {
logger.error("Attempt to register ${EditorActionAvailabilityHint::class.simpleName} on ${RangeMarker::class.simpleName} which is not ${UserDataHolderEx::class.simpleName} ")
return
}
this.addActionAvailabilityHintImpl(*hints)
addActionAvailabilityHintImpl(*hints)
}
/**
@@ -81,11 +81,11 @@ fun RangeMarker.addActionAvailabilityHint(vararg hints: EditorActionAvailability
*/
@Experimental
fun Inlay<*>.addActionAvailabilityHint(vararg hints: EditorActionAvailabilityHint) {
this as UserDataHolderEx? ?: run {
this as UserDataHolder? ?: run {
logger.error("Attempt to register ${EditorActionAvailabilityHint::class.simpleName} on ${Inlay::class.simpleName} which is not ${UserDataHolderEx::class.simpleName} ")
return
}
this.addActionAvailabilityHintImpl(*hints)
addActionAvailabilityHintImpl(*hints)
}
@Experimental
@@ -154,7 +154,7 @@ private fun MarkupModelEx.isActionAvailableByHint(offset: Int, actionId: String,
return null
}
private fun UserDataHolderEx.addActionAvailabilityHintImpl(vararg newHints: EditorActionAvailabilityHint) {
private fun UserDataHolder.addActionAvailabilityHintImpl(vararg newHints: EditorActionAvailabilityHint) {
var hints = ConcurrencyUtil.computeIfAbsent(this, hintsKey) { ContainerUtil.createConcurrentList() }
for (newHint in newHints) {
val existingHint = hints.find { it.actionId == newHint.actionId }
@@ -18,6 +18,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.impl.ImaginaryEditor;
import com.intellij.openapi.editor.markup.HighlighterLayer;
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
@@ -165,24 +166,24 @@ public final class HighlightManagerImpl extends HighlightManager {
@Nullable Collection<? super RangeHighlighter> outHighlighters,
@Nullable Color scrollMarkColor) {
MarkupModelEx markupModel = (MarkupModelEx)editor.getMarkupModel();
markupModel.addRangeHighlighterAndChangeAttributes(attributesKey, start, end, OCCURRENCE_LAYER,
HighlighterTargetArea.EXACT_RANGE, false, highlighter -> {
RangeHighlighterEx result = markupModel.addRangeHighlighterAndChangeAttributes(attributesKey, start, end, OCCURRENCE_LAYER, HighlighterTargetArea.EXACT_RANGE, false,
highlighter -> {
addEditorHighlighterWithHideFlags(editor, highlighter, flags);
addEditorHighlighterWithHideFlags(editor, highlighter, flags);
highlighter.setVisibleIfFolded(true);
if (outHighlighters != null) {
outHighlighters.add(highlighter);
}
highlighter.setVisibleIfFolded(true);
if (forcedAttributes != null) {
highlighter.setTextAttributes(forcedAttributes);
}
if (forcedAttributes != null) {
highlighter.setTextAttributes(forcedAttributes);
}
if (scrollMarkColor != null) {
highlighter.setErrorStripeMarkColor(scrollMarkColor);
}
});
if (scrollMarkColor != null) {
highlighter.setErrorStripeMarkColor(scrollMarkColor);
}
});
if (outHighlighters != null) {
outHighlighters.add(result);
}
}
@ApiStatus.Internal
@@ -5,6 +5,7 @@ import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.ex.MarkupModelEx;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
@@ -145,11 +146,12 @@ public final class ConsoleTokenUtil {
prevMarker.dispose();
}
}
TextAttributesKey key = contentType.getAttributesKey();
model.addRangeHighlighterAndChangeAttributes(
contentType.getAttributesKey(), startOffset, endOffset, layer, HighlighterTargetArea.EXACT_RANGE, false,
key, startOffset, endOffset, layer, HighlighterTargetArea.EXACT_RANGE, false,
rm -> {
// fallback for contentTypes that provides only attributes
if (rm.getTextAttributesKey() == null) {
if (key == null) {
rm.setTextAttributes(contentType.getAttributes());
}
saveTokenType(rm, contentType);