1 /**
2 * jline - Java console input library
3 * Copyright (c) 2002, 2003, 2004, 2005, Marc Prud'hommeaux mwp1@cornell.edu
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer
15 * in the documentation and/or other materials provided with
16 * the distribution.
17 *
18 * Neither the name of JLine nor the names of its contributors
19 * may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
26 * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 * OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36 package jline;
37
38 import java.io.*;
39
40 /**
41 * A buffer that can contain ANSI text.
42 *
43 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
44 */
45 public class ANSIBuffer
46 {
47 private boolean ansiEnabled = true;
48 private final StringBuffer ansiBuffer = new StringBuffer ();
49 private final StringBuffer plainBuffer = new StringBuffer ();
50
51
52 public ANSIBuffer ()
53 {
54 }
55
56
57 public ANSIBuffer (final String str)
58 {
59 append (str);
60 }
61
62
63 public void setAnsiEnabled (final boolean ansi)
64 {
65 this.ansiEnabled = ansi;
66 }
67
68
69 public boolean getAnsiEnabled ()
70 {
71 return this.ansiEnabled;
72 }
73
74
75 public String getAnsiBuffer ()
76 {
77 return ansiBuffer.toString ();
78 }
79
80
81 public String getPlainBuffer ()
82 {
83 return plainBuffer.toString ();
84 }
85
86
87 public String toString (final boolean ansi)
88 {
89 return ansi ? getAnsiBuffer () : getPlainBuffer ();
90 }
91
92
93 public String toString ()
94 {
95 return toString (ansiEnabled);
96 }
97
98
99 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
309
310
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
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