1 /* 2 * Copyright (C) 2010 The Android Open Source Project 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 17 package vogar.util; 18 19 import java.io.PrintStream; 20 21 /** 22 * A console that can erase output back to a previously marked position. 23 */ 24 public final class MarkResetConsole { 25 26 private final PrintStream out; 27 private int row; 28 private final StringBuilder rowContent = new StringBuilder(); 29 MarkResetConsole(PrintStream out)30 public MarkResetConsole(PrintStream out) { 31 this.out = out; 32 } 33 println(String text)34 public void println(String text) { 35 print(text + "\n"); 36 } 37 print(String text)38 public void print(String text) { 39 for (int i = 0; i < text.length(); i++) { 40 if (text.charAt(i) == '\n') { 41 row++; 42 rowContent.delete(0, rowContent.length()); 43 } else { 44 rowContent.append(text.charAt(i)); 45 } 46 } 47 48 out.print(text); 49 out.flush(); 50 } 51 mark()52 public Mark mark() { 53 return new Mark(); 54 } 55 56 public class Mark { 57 private final int markRow = row; 58 private final String markRowContent = rowContent.toString(); 59 Mark()60 private Mark() {} 61 reset()62 public void reset() { 63 /* 64 * ANSI escapes 65 * http://en.wikipedia.org/wiki/ANSI_escape_code 66 * 67 * \u001b[K clear the rest of the current line 68 * \u001b[nA move the cursor up n lines 69 * \u001b[nB move the cursor down n lines 70 * \u001b[nC move the cursor right n lines 71 * \u001b[nD move the cursor left n columns 72 */ 73 74 for (int r = row; r > markRow; r--) { 75 // clear the line, up a line 76 System.out.print("\u001b[0G\u001b[K\u001b[1A"); 77 } 78 79 // clear the line, reprint the line 80 out.print("\u001b[0G\u001b[K"); 81 out.print(markRowContent); 82 rowContent.delete(0, rowContent.length()); 83 rowContent.append(markRowContent); 84 row = markRow; 85 } 86 } 87 } 88