    001    /**
    002     *      jline - Java console input library
    003     *      Copyright (c) 2002, 2003, 2004, 2005, Marc Prud'hommeaux mwp1@cornell.edu
    004     *      All rights reserved.
    005     *
    006     *      Redistribution and use in source and binary forms, with or
    007     *      without modification, are permitted provided that the following
    008     *      conditions are met:
    009     *
    010     *      Redistributions of source code must retain the above copyright
    011     *      notice, this list of conditions and the following disclaimer.
    012     *
    013     *      Redistributions in binary form must reproduce the above copyright
    014     *      notice, this list of conditions and the following disclaimer
    015     *      in the documentation and/or other materials provided with
    016     *      the distribution.
    017     *
    018     *      Neither the name of JLine nor the names of its contributors
    019     *      may be used to endorse or promote products derived from this
    020     *      software without specific prior written permission.
    021     *
    022     *      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    023     *      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
    024     *      BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
    025     *      AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    026     *      EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
    027     *      FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
    028     *      OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    029     *      PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    030     *      DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    031     *      AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    032     *      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
    033     *      IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    034     *      OF THE POSSIBILITY OF SUCH DAMAGE.
    035     */
    036    package jline;
    037
    038    import java.io.*;
    039
    040    /**
    041     *  A buffer that can contain ANSI text.
    042     *
    043     *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
    044     */
    045    public class ANSIBuffer
    046    {
    047            private boolean ansiEnabled = true;
    048            private final StringBuffer ansiBuffer = new StringBuffer ();
    049            private final StringBuffer plainBuffer = new StringBuffer ();
    050
    051
    052            public ANSIBuffer ()
    053            {
    054            }
    055
    056
    057            public ANSIBuffer (final String str)
    058            {
    059                    append (str);
    060            }
    061
    062
    063            public void setAnsiEnabled (final boolean ansi)
    064            {
    065                    this.ansiEnabled = ansi;
    066            }
    067
    068
    069            public boolean getAnsiEnabled ()
    070            {
    071                    return this.ansiEnabled;
    072            }
    073
    074
    075            public String getAnsiBuffer ()
    076            {
    077                    return ansiBuffer.toString ();
    078            }
    079
    080
    081            public String getPlainBuffer ()
    082            {
    083                    return plainBuffer.toString ();
    084            }
    085
    086
    087            public String toString (final boolean ansi)
    088            {
    089                    return ansi ? getAnsiBuffer () : getPlainBuffer ();
    090            }
    091
    092
    093            public String toString ()
    094            {
    095                    return toString (ansiEnabled);
    096            }
    097
    098
    099            public ANSIBuffer append (final String str)
    100            {
    101                    ansiBuffer.append (str);
    102                    plainBuffer.append (str);
    103                    return this;
    104            }
    105
    106
    107            public ANSIBuffer attrib (final String str, final int code)
    108            {
    109                    ansiBuffer.append (ANSICodes.attrib (code))
    110                            .append (str)
    111                            .append (ANSICodes.attrib (ANSICodes.OFF));
    112                    plainBuffer.append (str);
    113
    114                    return this;
    115            }
    116
    117
    118            public ANSIBuffer red (final String str)
    119            {
    120                    return attrib (str, ANSICodes.FG_RED);
    121            }
    122
    123
    124            public ANSIBuffer blue (final String str)
    125            {
    126                    return attrib (str, ANSICodes.FG_BLUE);
    127            }
    128
    129
    130            public ANSIBuffer green (final String str)
    131            {
    132                    return attrib (str, ANSICodes.FG_GREEN);
    133            }
    134
    135
    136            public ANSIBuffer black (final String str)
    137            {
    138                    return attrib (str, ANSICodes.FG_BLACK);
    139            }
    140
    141
    142            public ANSIBuffer yellow (final String str)
    143            {
    144                    return attrib (str, ANSICodes.FG_YELLOW);
    145            }
    146
    147
    148            public ANSIBuffer magenta (final String str)
    149            {
    150                    return attrib (str, ANSICodes.FG_MAGENTA);
    151            }
    152
    153
    154            public ANSIBuffer cyan (final String str)
    155            {
    156                    return attrib (str, ANSICodes.FG_CYAN);
    157            }
    158
    159
    160            public ANSIBuffer bold (final String str)
    161            {
    162                    return attrib (str, ANSICodes.BOLD);
    163            }
    164
    165
    166            public ANSIBuffer underscore (final String str)
    167            {
    168                    return attrib (str, ANSICodes.UNDERSCORE);
    169            }
    170
    171
    172            public ANSIBuffer blink (final String str)
    173            {
    174                    return attrib (str, ANSICodes.BLINK);
    175            }
    176
    177
    178            public ANSIBuffer reverse (final String str)
    179            {
    180                    return attrib (str, ANSICodes.REVERSE);
    181            }
    182
    183
    184
    185            public static class ANSICodes
    186            {
    187                    static final int OFF = 0;
    188                    static final int BOLD = 1;
    189                    static final int UNDERSCORE = 4;
    190                    static final int BLINK = 5;
    191                    static final int REVERSE = 7;
    192                    static final int CONCEALED = 8;
    193
    194                    static final int FG_BLACK = 30;
    195                    static final int FG_RED = 31;
    196                    static final int FG_GREEN = 32;
    197                    static final int FG_YELLOW = 33;
    198                    static final int FG_BLUE = 34;
    199                    static final int FG_MAGENTA = 35;
    200                    static final int FG_CYAN = 36;
    201                    static final int FG_WHITE = 37;
    202                    static final char ESC = 27;
    203
    204
    205
    206                    /**
    207                     *  Constructor is private since this is a utility class.
    208                     */
    209                    private ANSICodes ()
    210                    {
    211                    }
    212
    213
    214                    /**
    215                     * Sets the screen mode. The mode will be one of the following values:
    216                     * <pre>
    217                     * mode     description
    218                     * ----------------------------------------
    219                     *   0      40 x 148 x 25 monochrome (text)
    220                     *   1      40 x 148 x 25 color (text)
    221                     *   2      80 x 148 x 25 monochrome (text)
    222                     *   3      80 x 148 x 25 color (text)
    223                     *   4      320 x 148 x 200 4-color (graphics)
    224                     *   5      320 x 148 x 200 monochrome (graphics)
    225                     *   6      640 x 148 x 200 monochrome (graphics)
    226                     *   7      Enables line wrapping
    227                     *  13      320 x 148 x 200 color (graphics)
    228                     *  14      640 x 148 x 200 color (16-color graphics)
    229                     *  15      640 x 148 x 350 monochrome (2-color graphics)
    230                     *  16      640 x 148 x 350 color (16-color graphics)
    231                     *  17      640 x 148 x 480 monochrome (2-color graphics)
    232                     *  18      640 x 148 x 480 color (16-color graphics)
    233                     *  19      320 x 148 x 200 color (256-color graphics)
    234                     * </pre>
    235                     */
    236                    public static String setmode (final int mode)
    237                    {
    238                            return ESC + "[=" + mode + "h";
    239                    }
    240
    241                    /**
    242                     * Same as setmode () except for mode = 7, which disables line
    243                     * wrapping (useful for writing the right-most column without
    244                     * scrolling to the next line).
    245                     */
    246                    public static String resetmode (final int mode)
    247                    {
    248                            return ESC + "[=" + mode + "l";
    249                    }
    250
    251                    /**
    252                     * Clears the screen and moves the cursor to the home postition.
    253                     */
    254                    public static String clrscr ()
    255                    {
    256                            return ESC + "[2J";
    257                    }
    258
    259                    /**
    260                     * Removes all characters from the current cursor position until
    261                     * the end of the line.
    262                     */
    263                    public static String clreol ()
    264                    {
    265                            return ESC + "[K";
    266                    }
    267
    268                    /**
    269                     * Moves the cursor n positions to the left. If n is greater or
    270                     * equal to the current cursor column, the cursor is moved to the
    271                     * first column.
    272                     */
    273                    public static String left (final int n)
    274                    {
    275                            return ESC + "[" + n + "D";
    276                    }
    277
    278                    /**
    279                     * Moves the cursor n positions to the right. If n plus the current
    280                     * cursor column is greater than the rightmost column, the cursor
    281                     * is moved to the rightmost column.
    282                     */
    283                    public static String right (final int n)
    284                    {
    285                            return ESC + "[" + n + "C";
    286                    }
    287
    288                    /**
    289                     * Moves the cursor n rows up without changing the current column.
    290                     * If n is greater than or equal to the current row, the cursor is
    291                     * placed in the first row.
    292                     */
    293                    public static String up (final int n)
    294                    {
    295                            return ESC + "[" + n + "A";
    296                    }
    297
    298                    /**
    299                     * Moves the cursor n rows down. If n plus the current row is greater
    300                     * than the bottom row, the cursor is moved to the bottom row.
    301                     */
    302                    public static String down (final int n)
    303                    {
    304                            return ESC + "[" + n + "B";
    305                    }
    306
    307                    /*
    308                     * Moves the cursor to the given row and column. (1,1) represents
    309                     * the upper left corner. The lower right corner of a usual DOS
    310                     * screen is (25, 80).
    311                     */
    312                    public static String gotoxy (final int row, final int column)
    313                    {
    314                            return ESC + "[" + row + ";" + column + "H";
    315                    }
    316
    317                    /**
    318                     * Saves the current cursor position.
    319                     */
    320                    public static String save ()
    321                    {
    322                            return ESC + "[s";
    323                    }
    324
    325                    /**
    326                     * Restores the saved cursor position.
    327                     */
    328                    public static String restore ()
    329                    {
    330                            return ESC + "[u";
    331                    }
    332
    333                    /**
    334                     * Sets the character attribute. It will be
    335                     * one of the following character attributes:
    336                     *
    337                     * <pre>
    338                     * Text attributes
    339                     *    0    All attributes off
    340                     *    1    Bold on
    341                     *    4    Underscore (on monochrome display adapter only)
    342                     *    5    Blink on
    343                     *    7    Reverse video on
    344                     *    8    Concealed on
    345                     *
    346                     *   Foreground colors
    347                     *    30    Black
    348                     *    31    Red
    349                     *    32    Green
    350                     *    33    Yellow
    351                     *    34    Blue
    352                     *    35    Magenta
    353                     *    36    Cyan
    354                     *    37    White
    355                     *
    356                     *   Background colors
    357                     *    40    Black
    358                     *    41    Red
    359                     *    42    Green
    360                     *    43    Yellow
    361                     *    44    Blue
    362                     *    45    Magenta
    363                     *    46    Cyan
    364                     *    47    White
    365                     * </pre>
    366                     *
    367                     * The attributes remain in effect until the next attribute command
    368                     * is sent.
    369                     */
    370                    public static String attrib (final int attr)
    371                    {
    372                            return ESC + "[" + attr + "m";
    373                    }
    374
    375                    /**
    376                     * Sets the key with the given code to the given value. code must be
    377                     * derived from the following table, value must
    378                     * be any semicolon-separated
    379                     * combination of String (enclosed in double quotes) and numeric values.
    380                     * For example, to set F1 to the String "Hello F1", followed by a CRLF
    381                     * sequence, one can use: ANSI.setkey ("0;59", "\"Hello F1\";13;10").
    382                     * Heres's the table of key values:
    383                     * <pre>
    384                     * Key                       Code      SHIFT+code  CTRL+code  ALT+code
    385                     * ---------------------------------------------------------------
    386                     * F1                        0;59      0;84        0;94       0;104
    387                     * F2                        0;60      0;85        0;95       0;105
    388                     * F3                        0;61      0;86        0;96       0;106
    389                     * F4                        0;62      0;87        0;97       0;107
    390                     * F5                        0;63      0;88        0;98       0;108
    391                     * F6                        0;64      0;89        0;99       0;109
    392                     * F7                        0;65      0;90        0;100      0;110
    393                     * F8                        0;66      0;91        0;101      0;111
    394                     * F9                        0;67      0;92        0;102      0;112
    395                     * F10                       0;68      0;93        0;103      0;113
    396                     * F11                       0;133     0;135       0;137      0;139
    397                     * F12                       0;134     0;136       0;138      0;140
    398                     * HOME (num keypad)         0;71      55          0;119      --
    399                     * UP ARROW (num keypad)     0;72      56          (0;141)    --
    400                     * PAGE UP (num keypad)      0;73      57          0;132      --
    401                     * LEFT ARROW (num keypad)   0;75      52          0;115      --
    402                     * RIGHT ARROW (num keypad)  0;77      54          0;116      --
    403                     * END (num keypad)          0;79      49          0;117      --
    404                     * DOWN ARROW (num keypad)   0;80      50          (0;145)    --
    405                     * PAGE DOWN (num keypad)    0;81      51          0;118      --
    406                     * INSERT (num keypad)       0;82      48          (0;146)    --
    407                     * DELETE  (num keypad)      0;83      46          (0;147)    --
    408                     * HOME                      (224;71)  (224;71)    (224;119)  (224;151)
    409                     * UP ARROW                  (224;72)  (224;72)    (224;141)  (224;152)
    410                     * PAGE UP                   (224;73)  (224;73)    (224;132)  (224;153)
    411                     * LEFT ARROW                (224;75)  (224;75)    (224;115)  (224;155)
    412                     * RIGHT ARROW               (224;77)  (224;77)    (224;116)  (224;157)
    413                     * END                       (224;79)  (224;79)    (224;117)  (224;159)
    414                     * DOWN ARROW                (224;80)  (224;80)    (224;145)  (224;154)
    415                     * PAGE DOWN                 (224;81)  (224;81)    (224;118)  (224;161)
    416                     * INSERT                    (224;82)  (224;82)    (224;146)  (224;162)
    417                     * DELETE                    (224;83)  (224;83)    (224;147)  (224;163)
    418                     * PRINT SCREEN              --        --          0;114      --
    419                     * PAUSE/BREAK               --        --          0;0        --
    420                     * BACKSPACE                 8         8           127        (0)
    421                     * ENTER                     13        --          10         (0
    422                     * TAB                       9         0;15        (0;148)    (0;165)
    423                     * NULL                      0;3       --          --         --
    424                     * A                         97        65          1          0;30
    425                     * B                         98        66          2          0;48
    426                     * C                         99        66          3          0;46
    427                     * D                         100       68          4          0;32
    428                     * E                         101       69          5          0;18
    429                     * F                         102       70          6          0;33
    430                     * G                         103       71          7          0;34
    431                     * H                         104       72          8          0;35
    432                     * I                         105       73          9          0;23
    433                     * J                         106       74          10         0;36
    434                     * K                         107       75          11         0;37
    435                     * L                         108       76          12         0;38
    436                     * M                         109       77          13         0;50
    437                     * N                         110       78          14         0;49
    438                     * O                         111       79          15         0;24
    439                     * P                         112       80          16         0;25
    440                     * Q                         113       81          17         0;16
    441                     * R                         114       82          18         0;19
    442                     * S                         115       83          19         0;31
    443                     * T                         116       84          20         0;20
    444                     * U                         117       85          21         0;22
    445                     * V                         118       86          22         0;47
    446                     * W                         119       87          23         0;17
    447                     * X                         120       88          24         0;45
    448                     * Y                         121       89          25         0;21
    449                     * Z                         122       90          26         0;44
    450                     * 1                         49        33          --         0;120
    451                     * 2                         50        64          0          0;121
    452                     * 3                         51        35          --         0;122
    453                     * 4                         52        36          --         0;123
    454                     * 5                         53        37          --         0;124
    455                     * 6                         54        94          30         0;125
    456                     * 7                         55        38          --         0;126
    457                     * 8                         56        42          --         0;126
    458                     * 9                         57        40          --         0;127
    459                     * 0                         48        41          --         0;129
    460                     * -                         45        95          31         0;130
    461                     * =                         61        43          ---        0;131
    462                     * [                         91        123         27         0;26
    463                     * ]                         93        125         29         0;27
    464                     *                           92        124         28         0;43
    465                     * ;                         59        58          --         0;39
    466                     * '                         39        34          --         0;40
    467                     * ,                         44        60          --         0;51
    468                     * .                         46        62          --         0;52
    469                     * /                         47        63          --         0;53
    470                     * `                         96        126         --         (0;41)
    471                     * ENTER (keypad)            13        --          10         (0;166)
    472                     * / (keypad)                47        47          (0;142)    (0;74)
    473                     * * (keypad)                42        (0;144)     (0;78)     --
    474                     * - (keypad)                45        45          (0;149)    (0;164)
    475                     * + (keypad)                43        43          (0;150)    (0;55)
    476                     * 5 (keypad)                (0;76)    53          (0;143)    --
    477                     */
    478                    public static String setkey (final String code, final String value)
    479                    {
    480                            return ESC + "[" + code + ";" + value + "p";
    481                    }
    482            }
    483
    484
    485            public static void main (final String [] args)
    486                    throws Exception
    487            {
    488                    // sequence, one can use: ANSI.setkey ("0;59", "\"Hello F1\";13;10").
    489                    BufferedReader reader = new BufferedReader (
    490                            new InputStreamReader (System.in));
    491                    System.out.print (ANSICodes.setkey ("97", "97;98;99;13")
    492                            + ANSICodes.attrib (ANSICodes.OFF));
    493                    System.out.flush ();
    494                    String line;
    495                    while ((line = reader.readLine ()) != null)
    496                    {
    497                            System.out.println ("GOT: " + line);
    498                    }
    499            }
    500    }
    501