blob: 38c7fdce56de19a95bc85b788eed6525e659e02b [file] [log] [blame]
// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.util.io;
import java.io.IOException;
import java.io.OutputStream;
/**
* A class which encapsulates the fancy curses-type stuff that you can do using
* standard ANSI terminal control sequences.
*/
public class AnsiTerminal {
private static final byte[] ESC = {27, (byte) '['};
private static final byte BEL = 7;
private static final byte UP = (byte) 'A';
private static final byte ERASE_LINE = (byte) 'K';
private static final byte SET_GRAPHICS = (byte) 'm';
private static final byte TEXT_BOLD = (byte) '1';
private static final byte[] SET_TERM_TITLE = {27, (byte) ']', (byte) '0', (byte) ';'};
public static final String FG_BLACK = "30";
public static final String FG_RED = "31";
public static final String FG_GREEN = "32";
public static final String FG_YELLOW = "33";
public static final String FG_BLUE = "34";
public static final String FG_MAGENTA = "35";
public static final String FG_CYAN = "36";
public static final String FG_GRAY = "37";
public static final String BG_BLACK = "40";
public static final String BG_RED = "41";
public static final String BG_GREEN = "42";
public static final String BG_YELLOW = "43";
public static final String BG_BLUE = "44";
public static final String BG_MAGENTA = "45";
public static final String BG_CYAN = "46";
public static final String BG_GRAY = "47";
public static byte[] CR = { 13 };
private final OutputStream out;
/**
* Creates an AnsiTerminal object wrapping an output stream which is going to
* be displayed in an ANSI compatible terminal or shell window.
*
* @param out the output stream
*/
public AnsiTerminal(OutputStream out) {
this.out = out;
}
/**
* Moves the cursor upwards by a specified number of lines. This will not
* cause any scrolling if it tries to move above the top of the terminal
* window.
*/
public void cursorUp(int numLines) throws IOException {
writeBytes(ESC, ("" + numLines).getBytes(), new byte[] { UP });
}
/**
* Clear the current terminal line from the cursor position to the end.
*/
public void clearLine() throws IOException {
writeEscapeSequence(ERASE_LINE);
}
/**
* Makes any text output to the terminal appear in bold.
*/
public void textBold() throws IOException {
writeEscapeSequence(TEXT_BOLD, SET_GRAPHICS);
}
/**
* Set the color of the foreground or background of the terminal.
*
* @param color one of the foreground or background color
* constants
*/
public void setTextColor(String color) throws IOException {
writeBytes(ESC, color.getBytes(), new byte[] { SET_GRAPHICS });
}
/**
* Resets the terminal colors and fonts to defaults.
*/
public void resetTerminal() throws IOException {
writeEscapeSequence((byte)'0', (byte)'m');
}
/**
* Makes text print on the terminal in red.
*/
public void textRed() throws IOException {
setTextColor(FG_RED);
}
/**
* Makes text print on the terminal in blue.
*/
public void textBlue() throws IOException {
setTextColor(FG_BLUE);
}
/**
* Makes text print on the terminal in red.
*/
public void textGreen() throws IOException {
setTextColor(FG_GREEN);
}
/**
* Makes text print on the terminal in red.
*/
public void textMagenta() throws IOException {
setTextColor(FG_MAGENTA);
}
/**
* Set the terminal title.
*/
public void setTitle(String title) throws IOException {
writeBytes(SET_TERM_TITLE, title.getBytes(), new byte[] { BEL });
}
/**
* Writes a string to the terminal using the current font, color and cursor
* position settings.
*
* @param text the text to write
*/
public void writeString(String text) throws IOException {
out.write(text.getBytes());
}
/**
* Writes a byte sequence to the terminal using the current font, color and
* cursor position settings.
*
* @param bytes the bytes to write
*/
public void writeBytes(byte[] bytes) throws IOException {
out.write(bytes);
}
/**
* Utility method which makes it easier to generate the control sequences for
* the terminal.
*
* @param bytes bytes which should be prefixed with the terminal escape
* sequence to produce a valid control sequence
*/
private void writeEscapeSequence(byte... bytes) throws IOException {
writeBytes(ESC, bytes);
}
/**
* Utility method for generating control sequences. Takes a collection of byte
* arrays, which contain the components of a control sequence, concatenates
* them, and prints them to the terminal.
*
* @param stuff the byte arrays that make up the sequence to be sent to the
* terminal
*/
private void writeBytes(byte[]... stuff) throws IOException {
for (byte[] bytes : stuff) {
out.write(bytes);
}
}
/**
* Sends a carriage return to the terminal.
*/
public void cr() throws IOException {
writeBytes(CR);
}
/**
* Flushes the underlying stream.
* This class does not do any buffering of its own, but the underlying
* OutputStream may.
*/
public void flush() throws IOException {
out.flush();
}
}