void (@NotNull 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<ColorAndFontDescriptorsProvider, AttributesDescriptor>> keyMap = new HashMap<>(); List<TextAttributesKey> keys = getTextAttributesKeys(project, editor); for (TextAttributesKey key : keys) { Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor> p = key == null ? null : ColorSettingsPages.getInstance().getAttributeDescriptor(key); if (p != null) keyMap.put(key, p); } if (keyMap.isEmpty()) { HintManager.getInstance().showErrorHint(editor, LangBundle.message("hint.text.no.text.attributes.found")); } else if (keyMap.size() == 1) { Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor> p = keyMap.values().iterator().next(); if (!openSettingsAndSelectKey(project, p.first, p.second)) { HintManager.getInstance().showErrorHint(editor, LangBundle.message("hint.text.no.appropriate.settings.page.found")); } } else { ArrayList<Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor>> attrs = new ArrayList<>(keyMap.values()); attrs.sort((o1, o2) -> StringUtil.naturalCompare( o1.first.getDisplayName() + o1.second.getDisplayName(), o2.first.getDisplayName() + o2.second.getDisplayName())); EditorColorsScheme colorsScheme = editor.getColorsScheme(); ColoredListCellRenderer<Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor>> renderer = new ColoredListCellRenderer<>() { @Override protected void customizeCellRenderer(@NotNull JList<? extends Pair<ColorAndFontDescriptorsProvider, AttributesDescriptor>> list, Pair<ColorAndFontDescriptorsProvider, 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("\u25A2" + (addStripe ? "" : " "), saCur.derive(-1, ta.getEffectColor(), null, null)); } if (addStripe) { append(" ", saCur.derive(STYLE_OPAQUE, null, stripeColor, null)); } } }; JBPopupFactory.getInstance() .createPopupChooserBuilder(attrs) .setRenderer(renderer) .setTitle(StringUtil.notNullize(e.getPresentation().getText())) .setMovable(false) .setResizable(false) .setRequestFocus(true) .setItemChosenCallback((p) -> { if (!openSettingsAndSelectKey(project, p.first, p.second)) { HintManager.getInstance().showErrorHint(editor, LangBundle.message("hint.text.no.appropriate.settings.page.found")); } }) .createPopup().showInBestPositionFor(editor); } }