2 * Copyright 2000-2016 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.codeHighlighting;
18 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
19 import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
20 import com.intellij.lang.annotation.HighlightSeverity;
21 import com.intellij.openapi.application.ApplicationManager;
22 import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
23 import com.intellij.openapi.editor.colors.EditorColorsManager;
24 import com.intellij.openapi.editor.colors.TextAttributesKey;
25 import com.intellij.openapi.editor.colors.TextAttributesScheme;
26 import com.intellij.openapi.editor.markup.TextAttributes;
27 import com.intellij.openapi.util.registry.Registry;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.psi.PsiElement;
30 import com.intellij.ui.ColorUtil;
31 import com.intellij.ui.JBColor;
32 import com.intellij.util.containers.ContainerUtil;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.annotations.Nullable;
37 import java.util.List;
39 public class RainbowHighlighter {
40 private static final JBColor[] RAINBOW_JB_COLORS_DEFAULT = {
41 new JBColor(0x9b3b6a, 0x529d52),
42 new JBColor(0x114d77, 0xbe7070),
43 new JBColor(0xbc8650, 0x3d7676),
44 new JBColor(0x005910, 0xbe9970),
45 new JBColor(0xbc5150, 0x9d527c),
47 private static final TextAttributesKey[] RAINBOW_COLOR_KEYS = new TextAttributesKey[RAINBOW_JB_COLORS_DEFAULT.length];
48 private static final int RAINBOW_COLORS_BETWEEN = 4;
49 private static final String UNIT_TEST_COLORS = "#000001,#000002,#000003,#000004"; // Do not modify!
51 for (int i = 0; i < RAINBOW_JB_COLORS_DEFAULT.length; ++i) {
52 JBColor jbColor = RAINBOW_JB_COLORS_DEFAULT[i];
53 TextAttributes textAttributes = new TextAttributes(jbColor, null, null, null, Font.PLAIN);
54 RAINBOW_COLOR_KEYS[i] = TextAttributesKey.createTextAttributesKey("RAINBOW_COLOR" + i, textAttributes);
58 @NotNull private final TextAttributesScheme myColorsScheme;
59 @NotNull private final Color[] myRainbowColors;
61 public RainbowHighlighter(@Nullable TextAttributesScheme colorsScheme) {
62 myColorsScheme = colorsScheme != null ? colorsScheme : EditorColorsManager.getInstance().getGlobalScheme();
63 myRainbowColors = generateColorSequence(myColorsScheme);
66 public static final HighlightInfoType RAINBOW_ELEMENT = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, DefaultLanguageHighlighterColors.CONSTANT);
68 public static boolean isRainbowEnabled() {
69 return Registry.is("editor.rainbow.identifiers", false);
72 public static void setRainbowEnabled(boolean enabled) {
73 Registry.get("editor.rainbow.identifiers").setValue(enabled);
77 private Color calculateForeground(int colorIndex) {
78 return myRainbowColors[colorIndex];
81 public int getColorsCount() {
82 return myRainbowColors.length;
86 private static Color[] generateColorSequence(@NotNull TextAttributesScheme colorsScheme) {
87 String colorDump = ApplicationManager.getApplication().isUnitTestMode()
89 : Registry.get("rainbow.highlighter.colors").asString();
91 final List<String> registryColors = StringUtil.split(colorDump, ",");
92 if (!registryColors.isEmpty()) {
93 return registryColors.stream().map(s -> ColorUtil.fromHex(s.trim())).toArray(Color[]::new);
96 List<Color> foregroundColors = ContainerUtil.map(RAINBOW_COLOR_KEYS, key -> colorsScheme.getAttributes(key).getForegroundColor());
97 List<Color> colors = ColorGenerator.generateLinearColorSequence(foregroundColors, RAINBOW_COLORS_BETWEEN);
98 return colors.toArray(new Color[colors.size()]);
101 public HighlightInfo getInfo(int colorIndex, @Nullable PsiElement id, @Nullable TextAttributesKey colorKey) {
102 return id == null ? null : getInfoBuilder(colorIndex, colorKey).range(id).create();
105 public HighlightInfo getInfo(int colorIndex, int start, int end, @Nullable TextAttributesKey colorKey) {
106 return getInfoBuilder(colorIndex, colorKey).range(start, end).create();
110 protected HighlightInfo.Builder getInfoBuilder(int colorIndex, @Nullable TextAttributesKey colorKey) {
111 if (colorKey == null) {
112 colorKey = DefaultLanguageHighlighterColors.LOCAL_VARIABLE;
115 .newHighlightInfo(RAINBOW_ELEMENT)
116 .textAttributes(TextAttributes
117 .fromFlyweight(myColorsScheme
118 .getAttributes(colorKey)
120 .withForeground(calculateForeground(colorIndex))));