Home | History | Annotate | Download | only in util
      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 
     30     public MarkResetConsole(PrintStream out) {
     31         this.out = out;
     32     }
     33 
     34     public void println(String text) {
     35         print(text + "\n");
     36     }
     37 
     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 
     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 
     60         private Mark() {}
     61 
     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