Home | History | Annotate | Download | only in jline
      1 /*
      2  * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
      3  *
      4  * This software is distributable under the BSD license. See the terms of the
      5  * BSD license in the documentation provided with this software.
      6  */
      7 package jline;
      8 
      9 import java.io.*;
     10 
     11 /**
     12  *  A buffer that can contain ANSI text.
     13  *
     14  *  @author  <a href="mailto:mwp1 (at) cornell.edu">Marc Prud'hommeaux</a>
     15  */
     16 public class ANSIBuffer {
     17     private boolean ansiEnabled = true;
     18     private final StringBuffer ansiBuffer = new StringBuffer();
     19     private final StringBuffer plainBuffer = new StringBuffer();
     20 
     21     public ANSIBuffer() {
     22     }
     23 
     24     public ANSIBuffer(final String str) {
     25         append(str);
     26     }
     27 
     28     public void setAnsiEnabled(final boolean ansi) {
     29         this.ansiEnabled = ansi;
     30     }
     31 
     32     public boolean getAnsiEnabled() {
     33         return this.ansiEnabled;
     34     }
     35 
     36     public String getAnsiBuffer() {
     37         return ansiBuffer.toString();
     38     }
     39 
     40     public String getPlainBuffer() {
     41         return plainBuffer.toString();
     42     }
     43 
     44     public String toString(final boolean ansi) {
     45         return ansi ? getAnsiBuffer() : getPlainBuffer();
     46     }
     47 
     48     public String toString() {
     49         return toString(ansiEnabled);
     50     }
     51 
     52     public ANSIBuffer append(final String str) {
     53         ansiBuffer.append(str);
     54         plainBuffer.append(str);
     55 
     56         return this;
     57     }
     58 
     59     public ANSIBuffer attrib(final String str, final int code) {
     60         ansiBuffer.append(ANSICodes.attrib(code)).append(str)
     61                   .append(ANSICodes.attrib(ANSICodes.OFF));
     62         plainBuffer.append(str);
     63 
     64         return this;
     65     }
     66 
     67     public ANSIBuffer red(final String str) {
     68         return attrib(str, ANSICodes.FG_RED);
     69     }
     70 
     71     public ANSIBuffer blue(final String str) {
     72         return attrib(str, ANSICodes.FG_BLUE);
     73     }
     74 
     75     public ANSIBuffer green(final String str) {
     76         return attrib(str, ANSICodes.FG_GREEN);
     77     }
     78 
     79     public ANSIBuffer black(final String str) {
     80         return attrib(str, ANSICodes.FG_BLACK);
     81     }
     82 
     83     public ANSIBuffer yellow(final String str) {
     84         return attrib(str, ANSICodes.FG_YELLOW);
     85     }
     86 
     87     public ANSIBuffer magenta(final String str) {
     88         return attrib(str, ANSICodes.FG_MAGENTA);
     89     }
     90 
     91     public ANSIBuffer cyan(final String str) {
     92         return attrib(str, ANSICodes.FG_CYAN);
     93     }
     94 
     95     public ANSIBuffer bold(final String str) {
     96         return attrib(str, ANSICodes.BOLD);
     97     }
     98 
     99     public ANSIBuffer underscore(final String str) {
    100         return attrib(str, ANSICodes.UNDERSCORE);
    101     }
    102 
    103     public ANSIBuffer blink(final String str) {
    104         return attrib(str, ANSICodes.BLINK);
    105     }
    106 
    107     public ANSIBuffer reverse(final String str) {
    108         return attrib(str, ANSICodes.REVERSE);
    109     }
    110 
    111     public static class ANSICodes {
    112         static final int OFF = 0;
    113         static final int BOLD = 1;
    114         static final int UNDERSCORE = 4;
    115         static final int BLINK = 5;
    116         static final int REVERSE = 7;
    117         static final int CONCEALED = 8;
    118         static final int FG_BLACK = 30;
    119         static final int FG_RED = 31;
    120         static final int FG_GREEN = 32;
    121         static final int FG_YELLOW = 33;
    122         static final int FG_BLUE = 34;
    123         static final int FG_MAGENTA = 35;
    124         static final int FG_CYAN = 36;
    125         static final int FG_WHITE = 37;
    126         static final char ESC = 27;
    127 
    128         /**
    129          *  Constructor is private since this is a utility class.
    130          */
    131         private ANSICodes() {
    132         }
    133 
    134         /**
    135           * Sets the screen mode. The mode will be one of the following values:
    136           * <pre>
    137           * mode     description
    138           * ----------------------------------------
    139           *   0      40 x 148 x 25 monochrome (text)
    140           *   1      40 x 148 x 25 color (text)
    141           *   2      80 x 148 x 25 monochrome (text)
    142           *   3      80 x 148 x 25 color (text)
    143           *   4      320 x 148 x 200 4-color (graphics)
    144           *   5      320 x 148 x 200 monochrome (graphics)
    145           *   6      640 x 148 x 200 monochrome (graphics)
    146           *   7      Enables line wrapping
    147           *  13      320 x 148 x 200 color (graphics)
    148           *  14      640 x 148 x 200 color (16-color graphics)
    149           *  15      640 x 148 x 350 monochrome (2-color graphics)
    150           *  16      640 x 148 x 350 color (16-color graphics)
    151           *  17      640 x 148 x 480 monochrome (2-color graphics)
    152           *  18      640 x 148 x 480 color (16-color graphics)
    153           *  19      320 x 148 x 200 color (256-color graphics)
    154           * </pre>
    155           */
    156         public static String setmode(final int mode) {
    157             return ESC + "[=" + mode + "h";
    158         }
    159 
    160         /**
    161           * Same as setmode () except for mode = 7, which disables line
    162           * wrapping (useful for writing the right-most column without
    163           * scrolling to the next line).
    164           */
    165         public static String resetmode(final int mode) {
    166             return ESC + "[=" + mode + "l";
    167         }
    168 
    169         /**
    170           * Clears the screen and moves the cursor to the home postition.
    171           */
    172         public static String clrscr() {
    173             return ESC + "[2J";
    174         }
    175 
    176         /**
    177           * Removes all characters from the current cursor position until
    178           * the end of the line.
    179           */
    180         public static String clreol() {
    181             return ESC + "[K";
    182         }
    183 
    184         /**
    185           * Moves the cursor n positions to the left. If n is greater or
    186           * equal to the current cursor column, the cursor is moved to the
    187           * first column.
    188           */
    189         public static String left(final int n) {
    190             return ESC + "[" + n + "D";
    191         }
    192 
    193         /**
    194           * Moves the cursor n positions to the right. If n plus the current
    195           * cursor column is greater than the rightmost column, the cursor
    196           * is moved to the rightmost column.
    197           */
    198         public static String right(final int n) {
    199             return ESC + "[" + n + "C";
    200         }
    201 
    202         /**
    203           * Moves the cursor n rows up without changing the current column.
    204           * If n is greater than or equal to the current row, the cursor is
    205           * placed in the first row.
    206           */
    207         public static String up(final int n) {
    208             return ESC + "[" + n + "A";
    209         }
    210 
    211         /**
    212           * Moves the cursor n rows down. If n plus the current row is greater
    213           * than the bottom row, the cursor is moved to the bottom row.
    214           */
    215         public static String down(final int n) {
    216             return ESC + "[" + n + "B";
    217         }
    218 
    219         /*
    220           * Moves the cursor to the given row and column. (1,1) represents
    221           * the upper left corner. The lower right corner of a usual DOS
    222           * screen is (25, 80).
    223           */
    224         public static String gotoxy(final int row, final int column) {
    225             return ESC + "[" + row + ";" + column + "H";
    226         }
    227 
    228         /**
    229           * Saves the current cursor position.
    230           */
    231         public static String save() {
    232             return ESC + "[s";
    233         }
    234 
    235         /**
    236           * Restores the saved cursor position.
    237           */
    238         public static String restore() {
    239             return ESC + "[u";
    240         }
    241 
    242         /**
    243           * Sets the character attribute. It will be
    244          * one of the following character attributes:
    245           *
    246           * <pre>
    247           * Text attributes
    248           *    0    All attributes off
    249           *    1    Bold on
    250           *    4    Underscore (on monochrome display adapter only)
    251           *    5    Blink on
    252           *    7    Reverse video on
    253           *    8    Concealed on
    254           *
    255           *   Foreground colors
    256           *    30    Black
    257           *    31    Red
    258           *    32    Green
    259           *    33    Yellow
    260           *    34    Blue
    261           *    35    Magenta
    262           *    36    Cyan
    263           *    37    White
    264           *
    265           *   Background colors
    266           *    40    Black
    267           *    41    Red
    268           *    42    Green
    269           *    43    Yellow
    270           *    44    Blue
    271           *    45    Magenta
    272           *    46    Cyan
    273           *    47    White
    274           * </pre>
    275           *
    276           * The attributes remain in effect until the next attribute command
    277           * is sent.
    278           */
    279         public static String attrib(final int attr) {
    280             return ESC + "[" + attr + "m";
    281         }
    282 
    283         /**
    284           * Sets the key with the given code to the given value. code must be
    285           * derived from the following table, value must
    286          * be any semicolon-separated
    287           * combination of String (enclosed in double quotes) and numeric values.
    288           * For example, to set F1 to the String "Hello F1", followed by a CRLF
    289           * sequence, one can use: ANSI.setkey ("0;59", "\"Hello F1\";13;10").
    290           * Heres's the table of key values:
    291           * <pre>
    292           * Key                       Code      SHIFT+code  CTRL+code  ALT+code
    293           * ---------------------------------------------------------------
    294           * F1                        0;59      0;84        0;94       0;104
    295           * F2                        0;60      0;85        0;95       0;105
    296           * F3                        0;61      0;86        0;96       0;106
    297           * F4                        0;62      0;87        0;97       0;107
    298           * F5                        0;63      0;88        0;98       0;108
    299           * F6                        0;64      0;89        0;99       0;109
    300           * F7                        0;65      0;90        0;100      0;110
    301           * F8                        0;66      0;91        0;101      0;111
    302           * F9                        0;67      0;92        0;102      0;112
    303           * F10                       0;68      0;93        0;103      0;113
    304           * F11                       0;133     0;135       0;137      0;139
    305           * F12                       0;134     0;136       0;138      0;140
    306           * HOME (num keypad)         0;71      55          0;119      --
    307           * UP ARROW (num keypad)     0;72      56          (0;141)    --
    308           * PAGE UP (num keypad)      0;73      57          0;132      --
    309           * LEFT ARROW (num keypad)   0;75      52          0;115      --
    310           * RIGHT ARROW (num keypad)  0;77      54          0;116      --
    311           * END (num keypad)          0;79      49          0;117      --
    312           * DOWN ARROW (num keypad)   0;80      50          (0;145)    --
    313           * PAGE DOWN (num keypad)    0;81      51          0;118      --
    314           * INSERT (num keypad)       0;82      48          (0;146)    --
    315           * DELETE  (num keypad)      0;83      46          (0;147)    --
    316           * HOME                      (224;71)  (224;71)    (224;119)  (224;151)
    317           * UP ARROW                  (224;72)  (224;72)    (224;141)  (224;152)
    318           * PAGE UP                   (224;73)  (224;73)    (224;132)  (224;153)
    319           * LEFT ARROW                (224;75)  (224;75)    (224;115)  (224;155)
    320           * RIGHT ARROW               (224;77)  (224;77)    (224;116)  (224;157)
    321           * END                       (224;79)  (224;79)    (224;117)  (224;159)
    322           * DOWN ARROW                (224;80)  (224;80)    (224;145)  (224;154)
    323           * PAGE DOWN                 (224;81)  (224;81)    (224;118)  (224;161)
    324           * INSERT                    (224;82)  (224;82)    (224;146)  (224;162)
    325           * DELETE                    (224;83)  (224;83)    (224;147)  (224;163)
    326           * PRINT SCREEN              --        --          0;114      --
    327           * PAUSE/BREAK               --        --          0;0        --
    328           * BACKSPACE                 8         8           127        (0)
    329           * ENTER                     13        --          10         (0
    330           * TAB                       9         0;15        (0;148)    (0;165)
    331           * NULL                      0;3       --          --         --
    332           * A                         97        65          1          0;30
    333           * B                         98        66          2          0;48
    334           * C                         99        66          3          0;46
    335           * D                         100       68          4          0;32
    336           * E                         101       69          5          0;18
    337           * F                         102       70          6          0;33
    338           * G                         103       71          7          0;34
    339           * H                         104       72          8          0;35
    340           * I                         105       73          9          0;23
    341           * J                         106       74          10         0;36
    342           * K                         107       75          11         0;37
    343           * L                         108       76          12         0;38
    344           * M                         109       77          13         0;50
    345           * N                         110       78          14         0;49
    346           * O                         111       79          15         0;24
    347           * P                         112       80          16         0;25
    348           * Q                         113       81          17         0;16
    349           * R                         114       82          18         0;19
    350           * S                         115       83          19         0;31
    351           * T                         116       84          20         0;20
    352           * U                         117       85          21         0;22
    353           * V                         118       86          22         0;47
    354           * W                         119       87          23         0;17
    355           * X                         120       88          24         0;45
    356           * Y                         121       89          25         0;21
    357           * Z                         122       90          26         0;44
    358           * 1                         49        33          --         0;120
    359           * 2                         50        64          0          0;121
    360           * 3                         51        35          --         0;122
    361           * 4                         52        36          --         0;123
    362           * 5                         53        37          --         0;124
    363           * 6                         54        94          30         0;125
    364           * 7                         55        38          --         0;126
    365           * 8                         56        42          --         0;126
    366           * 9                         57        40          --         0;127
    367           * 0                         48        41          --         0;129
    368           * -                         45        95          31         0;130
    369           * =                         61        43          ---        0;131
    370           * [                         91        123         27         0;26
    371           * ]                         93        125         29         0;27
    372           *                           92        124         28         0;43
    373           * ;                         59        58          --         0;39
    374           * '                         39        34          --         0;40
    375           * ,                         44        60          --         0;51
    376           * .                         46        62          --         0;52
    377           * /                         47        63          --         0;53
    378           * `                         96        126         --         (0;41)
    379           * ENTER (keypad)            13        --          10         (0;166)
    380           * / (keypad)                47        47          (0;142)    (0;74)
    381           * * (keypad)                42        (0;144)     (0;78)     --
    382           * - (keypad)                45        45          (0;149)    (0;164)
    383           * + (keypad)                43        43          (0;150)    (0;55)
    384           * 5 (keypad)                (0;76)    53          (0;143)    --
    385           */
    386         public static String setkey(final String code, final String value) {
    387             return ESC + "[" + code + ";" + value + "p";
    388         }
    389     }
    390 
    391     public static void main(final String[] args) throws Exception {
    392         // sequence, one can use: ANSI.setkey ("0;59", "\"Hello F1\";13;10").
    393         BufferedReader reader =
    394             new BufferedReader(new InputStreamReader(System.in));
    395         System.out.print(ANSICodes.setkey("97", "97;98;99;13")
    396                          + ANSICodes.attrib(ANSICodes.OFF));
    397         System.out.flush();
    398 
    399         String line;
    400 
    401         while ((line = reader.readLine()) != null) {
    402             System.out.println("GOT: " + line);
    403         }
    404     }
    405 }
    406