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