001    /**
002     *      jline - Java console input library
003     *      Copyright (c) 2002-2006, 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