• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
ANSIBuffer()21     public ANSIBuffer() {
22     }
23 
ANSIBuffer(final String str)24     public ANSIBuffer(final String str) {
25         append(str);
26     }
27 
setAnsiEnabled(final boolean ansi)28     public void setAnsiEnabled(final boolean ansi) {
29         this.ansiEnabled = ansi;
30     }
31 
getAnsiEnabled()32     public boolean getAnsiEnabled() {
33         return this.ansiEnabled;
34     }
35 
getAnsiBuffer()36     public String getAnsiBuffer() {
37         return ansiBuffer.toString();
38     }
39 
getPlainBuffer()40     public String getPlainBuffer() {
41         return plainBuffer.toString();
42     }
43 
toString(final boolean ansi)44     public String toString(final boolean ansi) {
45         return ansi ? getAnsiBuffer() : getPlainBuffer();
46     }
47 
toString()48     public String toString() {
49         return toString(ansiEnabled);
50     }
51 
append(final String str)52     public ANSIBuffer append(final String str) {
53         ansiBuffer.append(str);
54         plainBuffer.append(str);
55 
56         return this;
57     }
58 
attrib(final String str, final int code)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 
red(final String str)67     public ANSIBuffer red(final String str) {
68         return attrib(str, ANSICodes.FG_RED);
69     }
70 
blue(final String str)71     public ANSIBuffer blue(final String str) {
72         return attrib(str, ANSICodes.FG_BLUE);
73     }
74 
green(final String str)75     public ANSIBuffer green(final String str) {
76         return attrib(str, ANSICodes.FG_GREEN);
77     }
78 
black(final String str)79     public ANSIBuffer black(final String str) {
80         return attrib(str, ANSICodes.FG_BLACK);
81     }
82 
yellow(final String str)83     public ANSIBuffer yellow(final String str) {
84         return attrib(str, ANSICodes.FG_YELLOW);
85     }
86 
magenta(final String str)87     public ANSIBuffer magenta(final String str) {
88         return attrib(str, ANSICodes.FG_MAGENTA);
89     }
90 
cyan(final String str)91     public ANSIBuffer cyan(final String str) {
92         return attrib(str, ANSICodes.FG_CYAN);
93     }
94 
bold(final String str)95     public ANSIBuffer bold(final String str) {
96         return attrib(str, ANSICodes.BOLD);
97     }
98 
underscore(final String str)99     public ANSIBuffer underscore(final String str) {
100         return attrib(str, ANSICodes.UNDERSCORE);
101     }
102 
blink(final String str)103     public ANSIBuffer blink(final String str) {
104         return attrib(str, ANSICodes.BLINK);
105     }
106 
reverse(final String str)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          */
ANSICodes()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           */
setmode(final int mode)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           */
resetmode(final int mode)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           */
clrscr()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           */
clreol()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           */
left(final int n)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           */
right(final int n)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           */
up(final int n)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           */
down(final int n)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           */
gotoxy(final int row, final int column)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           */
save()231         public static String save() {
232             return ESC + "[s";
233         }
234 
235         /**
236           * Restores the saved cursor position.
237           */
restore()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           */
attrib(final int attr)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           */
setkey(final String code, final String value)386         public static String setkey(final String code, final String value) {
387             return ESC + "[" + code + ";" + value + "p";
388         }
389     }
390 
main(final String[] args)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