summaryrefslogtreecommitdiff
path: root/src/jline/src/main/java/jline/ANSIBuffer.java
blob: c2e33180bb85bd7648b53412e22be39b7265c384 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
/*
 * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
 *
 * This software is distributable under the BSD license. See the terms of the
 * BSD license in the documentation provided with this software.
 */
package jline;

import java.io.*;

/**
 *  A buffer that can contain ANSI text.
 *
 *  @author  <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
 */
public class ANSIBuffer {
    private boolean ansiEnabled = true;
    private final StringBuffer ansiBuffer = new StringBuffer();
    private final StringBuffer plainBuffer = new StringBuffer();

    public ANSIBuffer() {
    }

    public ANSIBuffer(final String str) {
        append(str);
    }

    public void setAnsiEnabled(final boolean ansi) {
        this.ansiEnabled = ansi;
    }

    public boolean getAnsiEnabled() {
        return this.ansiEnabled;
    }

    public String getAnsiBuffer() {
        return ansiBuffer.toString();
    }

    public String getPlainBuffer() {
        return plainBuffer.toString();
    }

    public String toString(final boolean ansi) {
        return ansi ? getAnsiBuffer() : getPlainBuffer();
    }

    public String toString() {
        return toString(ansiEnabled);
    }

    public ANSIBuffer append(final String str) {
        ansiBuffer.append(str);
        plainBuffer.append(str);

        return this;
    }

    public ANSIBuffer attrib(final String str, final int code) {
        ansiBuffer.append(ANSICodes.attrib(code)).append(str)
                  .append(ANSICodes.attrib(ANSICodes.OFF));
        plainBuffer.append(str);

        return this;
    }

    public ANSIBuffer red(final String str) {
        return attrib(str, ANSICodes.FG_RED);
    }

    public ANSIBuffer blue(final String str) {
        return attrib(str, ANSICodes.FG_BLUE);
    }

    public ANSIBuffer green(final String str) {
        return attrib(str, ANSICodes.FG_GREEN);
    }

    public ANSIBuffer black(final String str) {
        return attrib(str, ANSICodes.FG_BLACK);
    }

    public ANSIBuffer yellow(final String str) {
        return attrib(str, ANSICodes.FG_YELLOW);
    }

    public ANSIBuffer magenta(final String str) {
        return attrib(str, ANSICodes.FG_MAGENTA);
    }

    public ANSIBuffer cyan(final String str) {
        return attrib(str, ANSICodes.FG_CYAN);
    }

    public ANSIBuffer bold(final String str) {
        return attrib(str, ANSICodes.BOLD);
    }

    public ANSIBuffer underscore(final String str) {
        return attrib(str, ANSICodes.UNDERSCORE);
    }

    public ANSIBuffer blink(final String str) {
        return attrib(str, ANSICodes.BLINK);
    }

    public ANSIBuffer reverse(final String str) {
        return attrib(str, ANSICodes.REVERSE);
    }

    public static class ANSICodes {
        static final int OFF = 0;
        static final int BOLD = 1;
        static final int UNDERSCORE = 4;
        static final int BLINK = 5;
        static final int REVERSE = 7;
        static final int CONCEALED = 8;
        static final int FG_BLACK = 30;
        static final int FG_RED = 31;
        static final int FG_GREEN = 32;
        static final int FG_YELLOW = 33;
        static final int FG_BLUE = 34;
        static final int FG_MAGENTA = 35;
        static final int FG_CYAN = 36;
        static final int FG_WHITE = 37;
        static final char ESC = 27;

        /**
         *  Constructor is private since this is a utility class.
         */
        private ANSICodes() {
        }

        /**
          * Sets the screen mode. The mode will be one of the following values:
          * <pre>
          * mode     description
          * ----------------------------------------
          *   0      40 x 148 x 25 monochrome (text)
          *   1      40 x 148 x 25 color (text)
          *   2      80 x 148 x 25 monochrome (text)
          *   3      80 x 148 x 25 color (text)
          *   4      320 x 148 x 200 4-color (graphics)
          *   5      320 x 148 x 200 monochrome (graphics)
          *   6      640 x 148 x 200 monochrome (graphics)
          *   7      Enables line wrapping
          *  13      320 x 148 x 200 color (graphics)
          *  14      640 x 148 x 200 color (16-color graphics)
          *  15      640 x 148 x 350 monochrome (2-color graphics)
          *  16      640 x 148 x 350 color (16-color graphics)
          *  17      640 x 148 x 480 monochrome (2-color graphics)
          *  18      640 x 148 x 480 color (16-color graphics)
          *  19      320 x 148 x 200 color (256-color graphics)
          * </pre>
          */
        public static String setmode(final int mode) {
            return ESC + "[=" + mode + "h";
        }

        /**
          * Same as setmode () except for mode = 7, which disables line
          * wrapping (useful for writing the right-most column without
          * scrolling to the next line).
          */
        public static String resetmode(final int mode) {
            return ESC + "[=" + mode + "l";
        }

        /**
          * Clears the screen and moves the cursor to the home postition.
          */
        public static String clrscr() {
            return ESC + "[2J";
        }

        /**
          * Removes all characters from the current cursor position until
          * the end of the line.
          */
        public static String clreol() {
            return ESC + "[K";
        }

        /**
          * Moves the cursor n positions to the left. If n is greater or
          * equal to the current cursor column, the cursor is moved to the
          * first column.
          */
        public static String left(final int n) {
            return ESC + "[" + n + "D";
        }

        /**
          * Moves the cursor n positions to the right. If n plus the current
          * cursor column is greater than the rightmost column, the cursor
          * is moved to the rightmost column.
          */
        public static String right(final int n) {
            return ESC + "[" + n + "C";
        }

        /**
          * Moves the cursor n rows up without changing the current column.
          * If n is greater than or equal to the current row, the cursor is
          * placed in the first row.
          */
        public static String up(final int n) {
            return ESC + "[" + n + "A";
        }

        /**
          * Moves the cursor n rows down. If n plus the current row is greater
          * than the bottom row, the cursor is moved to the bottom row.
          */
        public static String down(final int n) {
            return ESC + "[" + n + "B";
        }

        /*
          * Moves the cursor to the given row and column. (1,1) represents
          * the upper left corner. The lower right corner of a usual DOS
          * screen is (25, 80).
          */
        public static String gotoxy(final int row, final int column) {
            return ESC + "[" + row + ";" + column + "H";
        }

        /**
          * Saves the current cursor position.
          */
        public static String save() {
            return ESC + "[s";
        }

        /**
          * Restores the saved cursor position.
          */
        public static String restore() {
            return ESC + "[u";
        }

        /**
          * Sets the character attribute. It will be
         * one of the following character attributes:
          *
          * <pre>
          * Text attributes
          *    0    All attributes off
          *    1    Bold on
          *    4    Underscore (on monochrome display adapter only)
          *    5    Blink on
          *    7    Reverse video on
          *    8    Concealed on
          *
          *   Foreground colors
          *    30    Black
          *    31    Red
          *    32    Green
          *    33    Yellow
          *    34    Blue
          *    35    Magenta
          *    36    Cyan
          *    37    White
          *
          *   Background colors
          *    40    Black
          *    41    Red
          *    42    Green
          *    43    Yellow
          *    44    Blue
          *    45    Magenta
          *    46    Cyan
          *    47    White
          * </pre>
          *
          * The attributes remain in effect until the next attribute command
          * is sent.
          */
        public static String attrib(final int attr) {
            return ESC + "[" + attr + "m";
        }

        /**
          * Sets the key with the given code to the given value. code must be
          * derived from the following table, value must
         * be any semicolon-separated
          * combination of String (enclosed in double quotes) and numeric values.
          * For example, to set F1 to the String "Hello F1", followed by a CRLF
          * sequence, one can use: ANSI.setkey ("0;59", "\"Hello F1\";13;10").
          * Heres's the table of key values:
          * <pre>
          * Key                       Code      SHIFT+code  CTRL+code  ALT+code
          * ---------------------------------------------------------------
          * F1                        0;59      0;84        0;94       0;104
          * F2                        0;60      0;85        0;95       0;105
          * F3                        0;61      0;86        0;96       0;106
          * F4                        0;62      0;87        0;97       0;107
          * F5                        0;63      0;88        0;98       0;108
          * F6                        0;64      0;89        0;99       0;109
          * F7                        0;65      0;90        0;100      0;110
          * F8                        0;66      0;91        0;101      0;111
          * F9                        0;67      0;92        0;102      0;112
          * F10                       0;68      0;93        0;103      0;113
          * F11                       0;133     0;135       0;137      0;139
          * F12                       0;134     0;136       0;138      0;140
          * HOME (num keypad)         0;71      55          0;119      --
          * UP ARROW (num keypad)     0;72      56          (0;141)    --
          * PAGE UP (num keypad)      0;73      57          0;132      --
          * LEFT ARROW (num keypad)   0;75      52          0;115      --
          * RIGHT ARROW (num keypad)  0;77      54          0;116      --
          * END (num keypad)          0;79      49          0;117      --
          * DOWN ARROW (num keypad)   0;80      50          (0;145)    --
          * PAGE DOWN (num keypad)    0;81      51          0;118      --
          * INSERT (num keypad)       0;82      48          (0;146)    --
          * DELETE  (num keypad)      0;83      46          (0;147)    --
          * HOME                      (224;71)  (224;71)    (224;119)  (224;151)
          * UP ARROW                  (224;72)  (224;72)    (224;141)  (224;152)
          * PAGE UP                   (224;73)  (224;73)    (224;132)  (224;153)
          * LEFT ARROW                (224;75)  (224;75)    (224;115)  (224;155)
          * RIGHT ARROW               (224;77)  (224;77)    (224;116)  (224;157)
          * END                       (224;79)  (224;79)    (224;117)  (224;159)
          * DOWN ARROW                (224;80)  (224;80)    (224;145)  (224;154)
          * PAGE DOWN                 (224;81)  (224;81)    (224;118)  (224;161)
          * INSERT                    (224;82)  (224;82)    (224;146)  (224;162)
          * DELETE                    (224;83)  (224;83)    (224;147)  (224;163)
          * PRINT SCREEN              --        --          0;114      --
          * PAUSE/BREAK               --        --          0;0        --
          * BACKSPACE                 8         8           127        (0)
          * ENTER                     13        --          10         (0
          * TAB                       9         0;15        (0;148)    (0;165)
          * NULL                      0;3       --          --         --
          * A                         97        65          1          0;30
          * B                         98        66          2          0;48
          * C                         99        66          3          0;46
          * D                         100       68          4          0;32
          * E                         101       69          5          0;18
          * F                         102       70          6          0;33
          * G                         103       71          7          0;34
          * H                         104       72          8          0;35
          * I                         105       73          9          0;23
          * J                         106       74          10         0;36
          * K                         107       75          11         0;37
          * L                         108       76          12         0;38
          * M                         109       77          13         0;50
          * N                         110       78          14         0;49
          * O                         111       79          15         0;24
          * P                         112       80          16         0;25
          * Q                         113       81          17         0;16
          * R                         114       82          18         0;19
          * S                         115       83          19         0;31
          * T                         116       84          20         0;20
          * U                         117       85          21         0;22
          * V                         118       86          22         0;47
          * W                         119       87          23         0;17
          * X                         120       88          24         0;45
          * Y                         121       89          25         0;21
          * Z                         122       90          26         0;44
          * 1                         49        33          --         0;120
          * 2                         50        64          0          0;121
          * 3                         51        35          --         0;122
          * 4                         52        36          --         0;123
          * 5                         53        37          --         0;124
          * 6                         54        94          30         0;125
          * 7                         55        38          --         0;126
          * 8                         56        42          --         0;126
          * 9                         57        40          --         0;127
          * 0                         48        41          --         0;129
          * -                         45        95          31         0;130
          * =                         61        43          ---        0;131
          * [                         91        123         27         0;26
          * ]                         93        125         29         0;27
          *                           92        124         28         0;43
          * ;                         59        58          --         0;39
          * '                         39        34          --         0;40
          * ,                         44        60          --         0;51
          * .                         46        62          --         0;52
          * /                         47        63          --         0;53
          * `                         96        126         --         (0;41)
          * ENTER (keypad)            13        --          10         (0;166)
          * / (keypad)                47        47          (0;142)    (0;74)
          * * (keypad)                42        (0;144)     (0;78)     --
          * - (keypad)                45        45          (0;149)    (0;164)
          * + (keypad)                43        43          (0;150)    (0;55)
          * 5 (keypad)                (0;76)    53          (0;143)    --
          */
        public static String setkey(final String code, final String value) {
            return ESC + "[" + code + ";" + value + "p";
        }
    }

    public static void main(final String[] args) throws Exception {
        // sequence, one can use: ANSI.setkey ("0;59", "\"Hello F1\";13;10").
        BufferedReader reader =
            new BufferedReader(new InputStreamReader(System.in));
        System.out.print(ANSICodes.setkey("97", "97;98;99;13")
                         + ANSICodes.attrib(ANSICodes.OFF));
        System.out.flush();

        String line;

        while ((line = reader.readLine()) != null) {
            System.out.println("GOT: " + line);
        }
    }
}