b6e9db8024e69b41e89710107ea7c56c20953774
[idea/community.git] / platform / platform-api / src / com / intellij / execution / process / ColoredOutputTypeRegistry.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.execution.process;
17
18 import com.intellij.execution.ui.ConsoleViewContentType;
19 import com.intellij.openapi.components.ServiceManager;
20 import com.intellij.openapi.editor.colors.EditorColorsManager;
21 import com.intellij.openapi.editor.colors.EditorColorsScheme;
22 import com.intellij.openapi.editor.colors.TextAttributesKey;
23 import com.intellij.openapi.editor.markup.EffectType;
24 import com.intellij.openapi.editor.markup.TextAttributes;
25 import com.intellij.openapi.util.Key;
26 import com.intellij.openapi.util.text.StringUtil;
27 import org.jetbrains.annotations.NonNls;
28 import org.jetbrains.annotations.NotNull;
29
30 import java.awt.*;
31
32 /**
33  * @author yole
34  */
35 public class ColoredOutputTypeRegistry {
36   public static ColoredOutputTypeRegistry getInstance() {
37     return ServiceManager.getService(ColoredOutputTypeRegistry.class);
38   }
39
40   private static final TextAttributesKey[] myAnsiColorKeys = new TextAttributesKey[]{
41     ConsoleHighlighter.BLACK,
42     ConsoleHighlighter.RED,
43     ConsoleHighlighter.GREEN,
44     ConsoleHighlighter.YELLOW,
45     ConsoleHighlighter.BLUE,
46     ConsoleHighlighter.MAGENTA,
47     ConsoleHighlighter.CYAN,
48     ConsoleHighlighter.GRAY,
49
50     ConsoleHighlighter.DARKGRAY,
51     ConsoleHighlighter.RED_BRIGHT,
52     ConsoleHighlighter.GREEN_BRIGHT,
53     ConsoleHighlighter.YELLOW_BRIGHT,
54     ConsoleHighlighter.BLUE_BRIGHT,
55     ConsoleHighlighter.MAGENTA_BRIGHT,
56     ConsoleHighlighter.CYAN_BRIGHT,
57     ConsoleHighlighter.WHITE,
58   };
59
60   /*
61     Description
62      0  Cancel all attributes except foreground/background color
63      1  Bright (bold)
64      2  Normal (not bold)
65      4  Underline
66      5  Blink
67      7  Reverse video
68      8  Concealed (don't display characters)
69      30 Make foreground (the characters) black
70      31 Make foreground red
71      32 Make foreground green
72      33 Make foreground yellow
73      34 Make foreground blue
74      35 Make foreground magenta
75      36 Make foreground cyan
76      37 Make foreground white
77
78      40 Make background (around the characters) black
79      41 Make background red
80      42 Make background green
81      43 Make background yellow
82      44 Make background blue
83      45 Make background magenta
84      46 Make background cyan
85      47 Make background white (you may need 0 instead, or in addition)
86
87      see full doc at http://en.wikipedia.org/wiki/ANSI_escape_code
88   */
89
90   @NotNull
91   public Key getOutputKey(@NonNls String attribute) {
92     final String completeAttribute = attribute;
93     if (attribute.startsWith("\u001B[")) {
94       attribute = attribute.substring(2);
95     }
96     else {
97       attribute = StringUtil.trimStart(attribute, "[");
98     }
99     attribute = StringUtil.trimEnd(attribute, "m");
100     if (attribute.equals("0")) {
101       return ProcessOutputTypes.STDOUT;
102     }
103     boolean inverse = false;
104     TextAttributes attrs = new TextAttributes();
105     final String[] strings = attribute.split(";");
106     for (String string : strings) {
107       int value;
108       try {
109         value = Integer.parseInt(string);
110       }
111       catch (NumberFormatException e) {
112         continue;
113       }
114       if (value == 1) {
115         attrs.setFontType(Font.BOLD);
116       }
117       else if (value == 4) {
118         attrs.setEffectType(EffectType.LINE_UNDERSCORE);
119       }
120       else if (value == 7) {
121         inverse = true;
122       }
123       else if (value == 22) {
124         attrs.setFontType(Font.PLAIN);
125       }
126       else if (value == 24) {  //not underlined
127         attrs.setEffectType(null);
128       }
129       else if (value >= 30 && value <= 37) {
130         attrs.setForegroundColor(getAnsiColor(value - 30));
131       }
132       else if (value == 38) {
133         //TODO: 256 colors foreground
134       }
135       else if (value == 39) {
136         attrs.setForegroundColor(getDefaultForegroundColor());
137       }
138       else if (value >= 40 && value <= 47) {
139         attrs.setBackgroundColor(getAnsiColor(value - 40));
140       }
141       else if (value == 48) {
142         //TODO: 256 colors background
143       }
144       else if (value == 49) {
145         attrs.setBackgroundColor(getDefaultBackgroundColor());
146       }
147       else if (value >= 90 && value <= 97) {
148         attrs.setForegroundColor(
149           getAnsiColor(value - 82));
150       }
151       else if (value >= 100 && value <= 107) {
152         attrs.setBackgroundColor(
153           getAnsiColor(value - 92));
154       }
155     }
156     if (attrs.getEffectType() == EffectType.LINE_UNDERSCORE) {
157       Color foregroundColor = attrs.getForegroundColor();
158       if (foregroundColor == null) {
159         foregroundColor = getDefaultForegroundColor();
160       }
161       attrs.setEffectColor(foregroundColor);
162     }
163     if (inverse) {
164       Color foregroundColor = attrs.getForegroundColor();
165       if (foregroundColor == null) {
166         foregroundColor = getDefaultForegroundColor();
167       }
168       Color backgroundColor = attrs.getBackgroundColor();
169       if (backgroundColor == null) {
170         backgroundColor = getDefaultBackgroundColor();
171       }
172       attrs.setForegroundColor(backgroundColor);
173       attrs.setEffectColor(backgroundColor);
174       attrs.setBackgroundColor(foregroundColor);
175     }
176     Key newKey = new Key(completeAttribute);
177     ConsoleViewContentType contentType = new ConsoleViewContentType(completeAttribute, attrs);
178     ConsoleViewContentType.registerNewConsoleViewType(newKey, contentType);
179     return newKey;
180   }
181
182   private static Color getAnsiColor(final int value) {
183     return getColorByKey(getAnsiColorKey(value));
184   }
185
186   private static Color getColorByKey(TextAttributesKey colorKey) {
187     return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(colorKey).getForegroundColor();
188   }
189
190   @NotNull
191   private static Color getDefaultForegroundColor() {
192     EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
193     TextAttributes attr = scheme.getAttributes(ConsoleViewContentType.NORMAL_OUTPUT_KEY);
194     Color color = attr != null ? attr.getForegroundColor() : null;
195     if (color == null) {
196       color = scheme.getDefaultForeground();
197     }
198     return color;
199   }
200
201   @NotNull
202   private static Color getDefaultBackgroundColor() {
203     EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
204     Color color = scheme.getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY);
205     if (color == null) {
206       color = scheme.getDefaultBackground();
207     }
208     return color;
209   }
210
211   public static TextAttributesKey getAnsiColorKey(int value) {
212     if (value >= 16) {
213       return ConsoleViewContentType.NORMAL_OUTPUT_KEY;
214     }
215     return myAnsiColorKeys[value];
216   }
217 }