blob: 857587f166292152a6f768c2b754fa31d39136b0 [file] [log] [blame]
package org.eclipse.dltk.console.ui;
import java.util.StringTokenizer;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
/**
* @author ssanders
*/
public class AnsiColorHelper {
public static interface IAnsiColorHandler {
public void handleText(int start, String content, boolean isInput,
boolean isError) throws BadLocationException;
public void processingComplete(int start, int length);
}
public static final Color COLOR_BLACK = new Color(Display.getCurrent(), 0,
0, 0);
public static final Color COLOR_BLUE = new Color(Display.getCurrent(), 0,
0, 255);
public static final Color COLOR_CYAN = new Color(Display.getCurrent(), 0,
255, 255);
public static final Color COLOR_GREEN = new Color(Display.getCurrent(), 0,
255, 0);
public static final Color COLOR_MAGENTA = new Color(Display.getCurrent(),
255, 0, 255);
public static final Color COLOR_RED = new Color(Display.getCurrent(), 255,
0, 0);
public static final Color COLOR_WHITE = new Color(Display.getCurrent(),
255, 255, 255);
public static final Color COLOR_YELLOW = new Color(Display.getCurrent(),
255, 255, 0);
private static final StyleRange DEFAULT_ERROR = new StyleRange(-1, -1,
COLOR_RED, null, SWT.BOLD);
private static final StyleRange DEFAULT_OUTPUT = new StyleRange(-1, -1,
COLOR_BLUE, null);
private StyleRange defaultOutput;
private StyleRange defaultError;
private boolean enabled = true;
private boolean bright;
private boolean dim;
private boolean underscore;
private boolean blink;
private boolean reverse;
private boolean hidden;
private Color foreground;
private Color background;
public AnsiColorHelper(StyleRange defaultOutput, StyleRange defaultError) {
this.defaultOutput = ((defaultOutput != null) ? defaultOutput
: DEFAULT_OUTPUT);
this.defaultError = ((defaultError != null) ? defaultError
: DEFAULT_ERROR);
}
public AnsiColorHelper() {
this(DEFAULT_OUTPUT, DEFAULT_ERROR);
}
public void reset() {
bright = false;
dim = false;
underscore = false;
blink = false;
reverse = false;
hidden = false;
foreground = null;
background = null;
}
public StyleRange resolveStyleRange(int start, int length, boolean isError) {
StyleRange styleRange;
Color curForeground = foreground;
Color curBackground = background;
int curFontStyle = 0;
if (bright == true) {
curFontStyle = (curFontStyle | SWT.BOLD);
}
if (dim == true) {
curFontStyle = (curFontStyle | SWT.ITALIC);
}
if (curForeground == null) {
StyleRange curDefault = ((isError == true) ? defaultError
: defaultOutput);
curForeground = curDefault.foreground;
curBackground = curDefault.background;
if (curFontStyle == 0) {
curFontStyle = curDefault.fontStyle;
}
}
if (hidden == true) {
curForeground = curBackground;
} else if (reverse == true) {
Color oldForeground = curForeground;
curForeground = curBackground;
curBackground = oldForeground;
}
styleRange = new StyleRange(start, length, curForeground,
curBackground, curFontStyle);
styleRange.underline = underscore;
styleRange.strikeout = blink;
return styleRange;
}
private void decodeAnsi(String ansiCode) {
StringTokenizer tokenizer = new StringTokenizer(ansiCode, ";"); //$NON-NLS-1$
String token;
while (tokenizer.hasMoreTokens() == true) {
token = tokenizer.nextToken();
if ("0".equals(token) == true) { //$NON-NLS-1$
reset();
} else if ("1".equals(token) == true) { //$NON-NLS-1$
bright = true;
} else if ("2".equals(token) == true) { //$NON-NLS-1$
dim = true;
} else if ("4".equals(token) == true) { //$NON-NLS-1$
underscore = true;
} else if ("5".equals(token) == true) { //$NON-NLS-1$
blink = true;
} else if ("7".equals(token) == true) { //$NON-NLS-1$
reverse = true;
} else if ("8".equals(token) == true) { //$NON-NLS-1$
hidden = true;
} else if ("30".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_BLACK;
} else if ("31".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_RED;
} else if ("32".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_GREEN;
} else if ("33".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_YELLOW;
} else if ("34".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_BLUE;
} else if ("35".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_MAGENTA;
} else if ("36".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_CYAN;
} else if ("37".equals(token) == true) { //$NON-NLS-1$
foreground = COLOR_WHITE;
} else if ("40".equals(token) == true) { //$NON-NLS-1$
background = COLOR_BLACK;
} else if ("41".equals(token) == true) { //$NON-NLS-1$
background = COLOR_RED;
} else if ("42".equals(token) == true) { //$NON-NLS-1$
background = COLOR_GREEN;
} else if ("43".equals(token) == true) { //$NON-NLS-1$
background = COLOR_YELLOW;
} else if ("44".equals(token) == true) { //$NON-NLS-1$
background = COLOR_BLUE;
} else if ("45".equals(token) == true) { //$NON-NLS-1$
background = COLOR_MAGENTA;
} else if ("46".equals(token) == true) { //$NON-NLS-1$
background = COLOR_CYAN;
} else if ("47".equals(token) == true) { //$NON-NLS-1$
background = COLOR_WHITE;
}
}
}
public void processText(int originalOffset, String content,
boolean isInput, boolean isError, IAnsiColorHandler handler)
throws BadLocationException {
int start = 0;
int adjust = 0;
if (enabled == true) {
int ansiCnt;
boolean isAnsi;
char curChar;
String ansiCode;
String curContent;
for (int cnt = 0, max = content.length(); cnt < max; cnt++) {
if (content.charAt(cnt) == '[') {
ansiCnt = (cnt + 1);
isAnsi = false;
while (ansiCnt < max) {
curChar = content.charAt(ansiCnt);
if ((curChar == ';')
|| ((curChar >= '0') && (curChar <= '9'))) {
ansiCnt++;
} else if (curChar == 'm') {
isAnsi = true;
break;
} else {
isAnsi = false;
break;
}
}
if (isAnsi == true) {
curContent = content.substring(start, cnt);
handler.handleText((originalOffset + start - adjust),
curContent, isInput, isError);
ansiCode = content.substring((cnt + 1), ansiCnt);
decodeAnsi(ansiCode);
adjust += ((ansiCnt - cnt) + 1);
cnt = ansiCnt;
start = (ansiCnt + 1);
}
}
}
}
if (start < content.length()) {
String overflowContent = ((start == 0) ? content : content
.substring(start));
handler.handleText((originalOffset + start - adjust),
overflowContent, isInput, isError);
}
handler.processingComplete(originalOffset, (content.length() - adjust));
}
public void disableWhile(Runnable runnable) {
boolean oldEnabled = enabled;
enabled = false;
try {
runnable.run();
} finally {
enabled = oldEnabled;
}
}
}