use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class LineMarkersUtil method createOrReuseLineMarker.
@NotNull
private static RangeHighlighter createOrReuseLineMarker(@NotNull LineMarkerInfo info, @NotNull MarkupModel markupModel, @Nullable HighlightersRecycler toReuse) {
RangeHighlighter highlighter = toReuse == null ? null : toReuse.pickupHighlighterFromGarbageBin(info.startOffset, info.endOffset, HighlighterLayer.ADDITIONAL_SYNTAX);
if (highlighter == null) {
highlighter = markupModel.addRangeHighlighter(info.startOffset, info.endOffset, HighlighterLayer.ADDITIONAL_SYNTAX, null, HighlighterTargetArea.LINES_IN_RANGE);
}
highlighter.putUserData(LINE_MARKER_INFO, info);
LineMarkerInfo.LineMarkerGutterIconRenderer newRenderer = (LineMarkerInfo.LineMarkerGutterIconRenderer) info.createGutterRenderer();
LineMarkerInfo.LineMarkerGutterIconRenderer oldRenderer = highlighter.getGutterIconRenderer() instanceof LineMarkerInfo.LineMarkerGutterIconRenderer ? (LineMarkerInfo.LineMarkerGutterIconRenderer) highlighter.getGutterIconRenderer() : null;
boolean rendererChanged = oldRenderer == null || newRenderer == null || !newRenderer.equals(oldRenderer);
boolean lineSeparatorColorChanged = !Comparing.equal(highlighter.getLineSeparatorColor(), info.separatorColor);
boolean lineSeparatorPlacementChanged = !Comparing.equal(highlighter.getLineSeparatorPlacement(), info.separatorPlacement);
if (rendererChanged || lineSeparatorColorChanged || lineSeparatorPlacementChanged) {
((MarkupModelEx) markupModel).changeAttributesInBatch((RangeHighlighterEx) highlighter, markerEx -> {
if (rendererChanged) {
markerEx.setGutterIconRenderer(newRenderer);
}
if (lineSeparatorColorChanged) {
markerEx.setLineSeparatorColor(info.separatorColor);
}
if (lineSeparatorPlacementChanged) {
markerEx.setLineSeparatorPlacement(info.separatorPlacement);
}
});
}
info.highlighter = highlighter;
return highlighter;
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class LivePreview method doHightlightRange.
private RangeHighlighter doHightlightRange(final TextRange textRange, final TextAttributes attributes, Set<RangeHighlighter> highlighters) {
HighlightManager highlightManager = HighlightManager.getInstance(mySearchResults.getProject());
MarkupModelEx markupModel = (MarkupModelEx) mySearchResults.getEditor().getMarkupModel();
final RangeHighlighter[] candidate = new RangeHighlighter[1];
boolean notFound = markupModel.processRangeHighlightersOverlappingWith(textRange.getStartOffset(), textRange.getEndOffset(), highlighter -> {
TextAttributes textAttributes = highlighter.getTextAttributes();
if (highlighter.getUserData(SEARCH_MARKER) != null && textAttributes != null && textAttributes.equals(attributes) && highlighter.getStartOffset() == textRange.getStartOffset() && highlighter.getEndOffset() == textRange.getEndOffset()) {
candidate[0] = highlighter;
return false;
}
return true;
});
if (!notFound && highlighters.contains(candidate[0])) {
return candidate[0];
}
final ArrayList<RangeHighlighter> dummy = new ArrayList<>();
highlightManager.addRangeHighlight(mySearchResults.getEditor(), textRange.getStartOffset(), textRange.getEndOffset(), attributes, false, dummy);
final RangeHighlighter h = dummy.get(0);
highlighters.add(h);
h.putUserData(SEARCH_MARKER, YES);
return h;
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class JumpToColorsAndFontsAction method actionPerformed.
@Override
public void actionPerformed(AnActionEvent e) {
// todo handle ColorKey's as well
Project project = e.getData(CommonDataKeys.PROJECT);
Editor editor = e.getData(CommonDataKeys.EDITOR);
if (project == null || editor == null)
return;
Map<TextAttributesKey, Pair<ColorSettingsPage, AttributesDescriptor>> keyMap = ContainerUtil.newHashMap();
Processor<RangeHighlighterEx> processor = r -> {
Object tt = r.getErrorStripeTooltip();
TextAttributesKey key = tt instanceof HighlightInfo ? ObjectUtils.chooseNotNull(((HighlightInfo) tt).forcedTextAttributesKey, ((HighlightInfo) tt).type.getAttributesKey()) : null;
Pair<ColorSettingsPage, AttributesDescriptor> p = key == null ? null : ColorSettingsPages.getInstance().getAttributeDescriptor(key);
if (p != null)
keyMap.put(key, p);
return true;
};
JBIterable<Editor> editors = editor instanceof EditorWindow ? JBIterable.of(editor, ((EditorWindow) editor).getDelegate()) : JBIterable.of(editor);
for (Editor ed : editors) {
TextRange selection = EditorUtil.getSelectionInAnyMode(ed);
MarkupModel forDocument = DocumentMarkupModel.forDocument(ed.getDocument(), project, false);
if (forDocument != null) {
((MarkupModelEx) forDocument).processRangeHighlightersOverlappingWith(selection.getStartOffset(), selection.getEndOffset(), processor);
}
((MarkupModelEx) ed.getMarkupModel()).processRangeHighlightersOverlappingWith(selection.getStartOffset(), selection.getEndOffset(), processor);
EditorHighlighter highlighter = ed instanceof EditorEx ? ((EditorEx) ed).getHighlighter() : null;
SyntaxHighlighter syntaxHighlighter = highlighter instanceof LexerEditorHighlighter ? ((LexerEditorHighlighter) highlighter).getSyntaxHighlighter() : null;
if (syntaxHighlighter != null) {
HighlighterIterator iterator = highlighter.createIterator(selection.getStartOffset());
while (!iterator.atEnd()) {
for (TextAttributesKey key : syntaxHighlighter.getTokenHighlights(iterator.getTokenType())) {
Pair<ColorSettingsPage, AttributesDescriptor> p = key == null ? null : ColorSettingsPages.getInstance().getAttributeDescriptor(key);
if (p != null)
keyMap.put(key, p);
}
if (iterator.getEnd() >= selection.getEndOffset())
break;
iterator.advance();
}
}
}
if (keyMap.isEmpty()) {
HintManager.getInstance().showErrorHint(editor, "No text attributes found");
} else if (keyMap.size() == 1) {
Pair<ColorSettingsPage, AttributesDescriptor> p = keyMap.values().iterator().next();
if (!openSettingsAndSelectKey(project, p.first, p.second)) {
HintManager.getInstance().showErrorHint(editor, "No appropriate settings page found");
}
} else {
ArrayList<Pair<ColorSettingsPage, AttributesDescriptor>> attrs = ContainerUtil.newArrayList(keyMap.values());
Collections.sort(attrs, (o1, o2) -> StringUtil.naturalCompare(o1.first.getDisplayName() + o1.second.getDisplayName(), o2.first.getDisplayName() + o2.second.getDisplayName()));
EditorColorsScheme colorsScheme = editor.getColorsScheme();
JBList<Pair<ColorSettingsPage, AttributesDescriptor>> list = new JBList<>(attrs);
list.setCellRenderer(new ColoredListCellRenderer<Pair<ColorSettingsPage, AttributesDescriptor>>() {
@Override
protected void customizeCellRenderer(@NotNull JList<? extends Pair<ColorSettingsPage, AttributesDescriptor>> list, Pair<ColorSettingsPage, AttributesDescriptor> value, int index, boolean selected, boolean hasFocus) {
TextAttributes ta = colorsScheme.getAttributes(value.second.getKey());
Color fg = ObjectUtils.chooseNotNull(ta.getForegroundColor(), colorsScheme.getDefaultForeground());
Color bg = ObjectUtils.chooseNotNull(ta.getBackgroundColor(), colorsScheme.getDefaultBackground());
SimpleTextAttributes sa = fromTextAttributes(ta);
SimpleTextAttributes saOpaque = sa.derive(STYLE_OPAQUE | sa.getStyle(), fg, bg, null);
SimpleTextAttributes saSelected = REGULAR_ATTRIBUTES.derive(sa.getStyle(), null, null, null);
SimpleTextAttributes saCur = REGULAR_ATTRIBUTES;
List<String> split = StringUtil.split(value.first.getDisplayName() + "//" + value.second.getDisplayName(), "//");
for (int i = 0, len = split.size(); i < len; i++) {
boolean last = i == len - 1;
saCur = !last ? REGULAR_ATTRIBUTES : selected ? saSelected : saOpaque;
if (last)
append(" ", saCur);
append(split.get(i), saCur);
if (last)
append(" ", saCur);
else
append(" > ", GRAYED_ATTRIBUTES);
}
Color stripeColor = ta.getErrorStripeColor();
boolean addStripe = stripeColor != null && stripeColor != saCur.getBgColor();
boolean addBoxed = ta.getEffectType() == EffectType.BOXED && ta.getEffectColor() != null;
if (addBoxed) {
append("▢" + (addStripe ? "" : " "), saCur.derive(-1, ta.getEffectColor(), null, null));
}
if (addStripe) {
append(" ", saCur.derive(STYLE_OPAQUE, null, stripeColor, null));
}
}
});
JBPopupFactory.getInstance().createListPopupBuilder(list).setTitle(StringUtil.notNullize(e.getPresentation().getText())).setMovable(false).setResizable(false).setRequestFocus(true).setItemChoosenCallback(() -> {
Pair<ColorSettingsPage, AttributesDescriptor> p = list.getSelectedValue();
if (p != null && !openSettingsAndSelectKey(project, p.first, p.second)) {
HintManager.getInstance().showErrorHint(editor, "No appropriate settings page found");
}
}).createPopup().showInBestPositionFor(editor);
}
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class ShowIntentionsPass method getActionsToShow.
public static void getActionsToShow(@NotNull final Editor hostEditor, @NotNull final PsiFile hostFile, @NotNull final IntentionsInfo intentions, int passIdToShowIntentionsFor) {
final PsiElement psiElement = hostFile.findElementAt(hostEditor.getCaretModel().getOffset());
LOG.assertTrue(psiElement == null || psiElement.isValid(), psiElement);
int offset = hostEditor.getCaretModel().getOffset();
final Project project = hostFile.getProject();
List<HighlightInfo.IntentionActionDescriptor> fixes = getAvailableFixes(hostEditor, hostFile, passIdToShowIntentionsFor);
final DaemonCodeAnalyzer codeAnalyzer = DaemonCodeAnalyzer.getInstance(project);
final Document hostDocument = hostEditor.getDocument();
HighlightInfo infoAtCursor = ((DaemonCodeAnalyzerImpl) codeAnalyzer).findHighlightByOffset(hostDocument, offset, true);
if (infoAtCursor == null) {
intentions.errorFixesToShow.addAll(fixes);
} else {
final boolean isError = infoAtCursor.getSeverity() == HighlightSeverity.ERROR;
for (HighlightInfo.IntentionActionDescriptor fix : fixes) {
if (fix.isError() && isError) {
intentions.errorFixesToShow.add(fix);
} else {
intentions.inspectionFixesToShow.add(fix);
}
}
}
for (final IntentionAction action : IntentionManager.getInstance().getAvailableIntentionActions()) {
Pair<PsiFile, Editor> place = ShowIntentionActionsHandler.chooseBetweenHostAndInjected(hostFile, hostEditor, (psiFile, editor) -> ShowIntentionActionsHandler.availableFor(psiFile, editor, action));
if (place != null) {
List<IntentionAction> enableDisableIntentionAction = new ArrayList<>();
enableDisableIntentionAction.add(new IntentionHintComponent.EnableDisableIntentionAction(action));
enableDisableIntentionAction.add(new IntentionHintComponent.EditIntentionSettingsAction(action));
HighlightInfo.IntentionActionDescriptor descriptor = new HighlightInfo.IntentionActionDescriptor(action, enableDisableIntentionAction, null);
if (!fixes.contains(descriptor)) {
intentions.intentionsToShow.add(descriptor);
}
}
}
if (HighlightingLevelManager.getInstance(project).shouldInspect(hostFile)) {
PsiElement intentionElement = psiElement;
int intentionOffset = offset;
if (psiElement instanceof PsiWhiteSpace && offset == psiElement.getTextRange().getStartOffset() && offset > 0) {
final PsiElement prev = hostFile.findElementAt(offset - 1);
if (prev != null && prev.isValid()) {
intentionElement = prev;
intentionOffset = offset - 1;
}
}
if (intentionElement != null && intentionElement.getManager().isInProject(intentionElement)) {
collectIntentionsFromDoNotShowLeveledInspections(project, hostFile, intentionElement, intentionOffset, intentions);
}
}
final int line = hostDocument.getLineNumber(offset);
MarkupModelEx model = (MarkupModelEx) DocumentMarkupModel.forDocument(hostDocument, project, true);
List<RangeHighlighterEx> result = new ArrayList<>();
Processor<RangeHighlighterEx> processor = Processors.cancelableCollectProcessor(result);
model.processRangeHighlightersOverlappingWith(hostDocument.getLineStartOffset(line), hostDocument.getLineEndOffset(line), processor);
GutterIntentionAction.addActions(hostEditor, intentions, project, result);
boolean cleanup = appendCleanupCode(intentions.inspectionFixesToShow, hostFile);
if (!cleanup) {
appendCleanupCode(intentions.errorFixesToShow, hostFile);
}
EditorNotificationActions.collectDescriptorsForEditor(hostEditor, intentions.notificationActionsToShow);
intentions.filterActions(hostFile);
}
use of com.intellij.openapi.editor.ex.MarkupModelEx in project intellij-community by JetBrains.
the class DaemonRespondToChangesTest method testLineMarkersDoNotBlinkOnBackSpaceRightBeforeMethodIdentifier.
public void testLineMarkersDoNotBlinkOnBackSpaceRightBeforeMethodIdentifier() throws Throwable {
configureByText(JavaFileType.INSTANCE, "package x; \n" + "class <caret>ToRun{\n" + " public static void main(String[] args) {\n" + " }\n" + "}");
List<HighlightInfo> errors = highlightErrors();
assertEmpty(errors);
List<LineMarkerInfo> lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
assertSize(2, lineMarkers);
backspace();
final Collection<String> changed = new ArrayList<>();
MarkupModelEx modelEx = (MarkupModelEx) DocumentMarkupModel.forDocument(getDocument(getFile()), getProject(), true);
modelEx.addMarkupModelListener(getTestRootDisposable(), new MarkupModelListener() {
@Override
public void afterAdded(@NotNull RangeHighlighterEx highlighter) {
changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("after added")));
}
@Override
public void beforeRemoved(@NotNull RangeHighlighterEx highlighter) {
changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("before removed")));
}
@Override
public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("changed")));
}
private void changed(@NotNull RangeHighlighterEx highlighter, String reason) {
// not line marker
if (highlighter.getTargetArea() != HighlighterTargetArea.LINES_IN_RANGE)
return;
List<LineMarkerInfo> lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject());
// not line marker
if (ContainerUtil.find(lineMarkers, lm -> lm.highlighter == highlighter) == null)
return;
changed.add(highlighter + ": \n" + reason);
}
});
assertEmpty(highlightErrors());
assertSize(2, DaemonCodeAnalyzerImpl.getLineMarkers(myEditor.getDocument(), getProject()));
assertEmpty(changed);
}
Aggregations