1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.fusesource.jansi;
20  
21  import java.util.ArrayList;
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  @Deprecated
32  @SuppressWarnings("unused")
33  public class Ansi implements Appendable {
34  
35      private static final char FIRST_ESC_CHAR = 27;
36      private static final char SECOND_ESC_CHAR = '[';
37  
38      
39  
40  
41      public enum Color {
42          BLACK(0, "BLACK"),
43          RED(1, "RED"),
44          GREEN(2, "GREEN"),
45          YELLOW(3, "YELLOW"),
46          BLUE(4, "BLUE"),
47          MAGENTA(5, "MAGENTA"),
48          CYAN(6, "CYAN"),
49          WHITE(7, "WHITE"),
50          DEFAULT(9, "DEFAULT");
51  
52          private final int value;
53          private final String name;
54  
55          Color(int index, String name) {
56              this.value = index;
57              this.name = name;
58          }
59  
60          @Override
61          public String toString() {
62              return name;
63          }
64  
65          public int value() {
66              return value;
67          }
68  
69          public int fg() {
70              return value + 30;
71          }
72  
73          public int bg() {
74              return value + 40;
75          }
76  
77          public int fgBright() {
78              return value + 90;
79          }
80  
81          public int bgBright() {
82              return value + 100;
83          }
84      }
85  
86      
87  
88  
89  
90  
91      public enum Attribute {
92          RESET(0, "RESET"),
93          INTENSITY_BOLD(1, "INTENSITY_BOLD"),
94          INTENSITY_FAINT(2, "INTENSITY_FAINT"),
95          ITALIC(3, "ITALIC_ON"),
96          UNDERLINE(4, "UNDERLINE_ON"),
97          BLINK_SLOW(5, "BLINK_SLOW"),
98          BLINK_FAST(6, "BLINK_FAST"),
99          NEGATIVE_ON(7, "NEGATIVE_ON"),
100         CONCEAL_ON(8, "CONCEAL_ON"),
101         STRIKETHROUGH_ON(9, "STRIKETHROUGH_ON"),
102         UNDERLINE_DOUBLE(21, "UNDERLINE_DOUBLE"),
103         INTENSITY_BOLD_OFF(22, "INTENSITY_BOLD_OFF"),
104         ITALIC_OFF(23, "ITALIC_OFF"),
105         UNDERLINE_OFF(24, "UNDERLINE_OFF"),
106         BLINK_OFF(25, "BLINK_OFF"),
107         NEGATIVE_OFF(27, "NEGATIVE_OFF"),
108         CONCEAL_OFF(28, "CONCEAL_OFF"),
109         STRIKETHROUGH_OFF(29, "STRIKETHROUGH_OFF");
110 
111         private final int value;
112         private final String name;
113 
114         Attribute(int index, String name) {
115             this.value = index;
116             this.name = name;
117         }
118 
119         @Override
120         public String toString() {
121             return name;
122         }
123 
124         public int value() {
125             return value;
126         }
127     }
128 
129     
130 
131 
132 
133 
134 
135     public enum Erase {
136         FORWARD(0, "FORWARD"),
137         BACKWARD(1, "BACKWARD"),
138         ALL(2, "ALL");
139 
140         private final int value;
141         private final String name;
142 
143         Erase(int index, String name) {
144             this.value = index;
145             this.name = name;
146         }
147 
148         @Override
149         public String toString() {
150             return name;
151         }
152 
153         public int value() {
154             return value;
155         }
156     }
157 
158     @FunctionalInterface
159     public interface Consumer {
160         void apply(Ansi ansi);
161     }
162 
163     public static boolean isEnabled() {
164         return org.apache.maven.jline.MessageUtils.isColorEnabled() && org.jline.jansi.Ansi.isEnabled();
165     }
166 
167     public static void setEnabled(final boolean flag) {
168         org.jline.jansi.Ansi.setEnabled(flag);
169     }
170 
171     public static Ansi ansi() {
172         if (isEnabled()) {
173             return new Ansi();
174         } else {
175             return new NoAnsi();
176         }
177     }
178 
179     public static Ansi ansi(StringBuilder builder) {
180         if (isEnabled()) {
181             return new Ansi(builder);
182         } else {
183             return new NoAnsi(builder);
184         }
185     }
186 
187     public static Ansi ansi(int size) {
188         if (isEnabled()) {
189             return new Ansi(size);
190         } else {
191             return new NoAnsi(size);
192         }
193     }
194 
195     private static class NoAnsi extends Ansi {
196         NoAnsi() {
197             super();
198         }
199 
200         NoAnsi(int size) {
201             super(size);
202         }
203 
204         NoAnsi(StringBuilder builder) {
205             super(builder);
206         }
207 
208         @Override
209         public Ansi fg(Color color) {
210             return this;
211         }
212 
213         @Override
214         public Ansi bg(Color color) {
215             return this;
216         }
217 
218         @Override
219         public Ansi fgBright(Color color) {
220             return this;
221         }
222 
223         @Override
224         public Ansi bgBright(Color color) {
225             return this;
226         }
227 
228         @Override
229         public Ansi fg(int color) {
230             return this;
231         }
232 
233         @Override
234         public Ansi fgRgb(int r, int g, int b) {
235             return this;
236         }
237 
238         @Override
239         public Ansi bg(int color) {
240             return this;
241         }
242 
243         @Override
244         public Ansi bgRgb(int r, int g, int b) {
245             return this;
246         }
247 
248         @Override
249         public Ansi a(Attribute attribute) {
250             return this;
251         }
252 
253         @Override
254         public Ansi cursor(int row, int column) {
255             return this;
256         }
257 
258         @Override
259         public Ansi cursorToColumn(int x) {
260             return this;
261         }
262 
263         @Override
264         public Ansi cursorUp(int y) {
265             return this;
266         }
267 
268         @Override
269         public Ansi cursorRight(int x) {
270             return this;
271         }
272 
273         @Override
274         public Ansi cursorDown(int y) {
275             return this;
276         }
277 
278         @Override
279         public Ansi cursorLeft(int x) {
280             return this;
281         }
282 
283         @Override
284         public Ansi cursorDownLine() {
285             return this;
286         }
287 
288         @Override
289         public Ansi cursorDownLine(final int n) {
290             return this;
291         }
292 
293         @Override
294         public Ansi cursorUpLine() {
295             return this;
296         }
297 
298         @Override
299         public Ansi cursorUpLine(final int n) {
300             return this;
301         }
302 
303         @Override
304         public Ansi eraseScreen() {
305             return this;
306         }
307 
308         @Override
309         public Ansi eraseScreen(Erase kind) {
310             return this;
311         }
312 
313         @Override
314         public Ansi eraseLine() {
315             return this;
316         }
317 
318         @Override
319         public Ansi eraseLine(Erase kind) {
320             return this;
321         }
322 
323         @Override
324         public Ansi scrollUp(int rows) {
325             return this;
326         }
327 
328         @Override
329         public Ansi scrollDown(int rows) {
330             return this;
331         }
332 
333         @Override
334         public Ansi saveCursorPosition() {
335             return this;
336         }
337 
338         @Override
339         @Deprecated
340         public Ansi restorCursorPosition() {
341             return this;
342         }
343 
344         @Override
345         public Ansi restoreCursorPosition() {
346             return this;
347         }
348 
349         @Override
350         public Ansi reset() {
351             return this;
352         }
353     }
354 
355     private final StringBuilder builder;
356     private final ArrayList<Integer> attributeOptions = new ArrayList<>(5);
357 
358     public Ansi() {
359         this(new StringBuilder(80));
360     }
361 
362     public Ansi(Ansi parent) {
363         this(new StringBuilder(parent.builder));
364         attributeOptions.addAll(parent.attributeOptions);
365     }
366 
367     public Ansi(int size) {
368         this(new StringBuilder(size));
369     }
370 
371     public Ansi(StringBuilder builder) {
372         this.builder = builder;
373     }
374 
375     public Ansi fg(Color color) {
376         attributeOptions.add(color.fg());
377         return this;
378     }
379 
380     public Ansi fg(int color) {
381         attributeOptions.add(38);
382         attributeOptions.add(5);
383         attributeOptions.add(color & 0xff);
384         return this;
385     }
386 
387     public Ansi fgRgb(int color) {
388         return fgRgb(color >> 16, color >> 8, color);
389     }
390 
391     public Ansi fgRgb(int r, int g, int b) {
392         attributeOptions.add(38);
393         attributeOptions.add(2);
394         attributeOptions.add(r & 0xff);
395         attributeOptions.add(g & 0xff);
396         attributeOptions.add(b & 0xff);
397         return this;
398     }
399 
400     public Ansi fgBlack() {
401         return this.fg(Color.BLACK);
402     }
403 
404     public Ansi fgBlue() {
405         return this.fg(Color.BLUE);
406     }
407 
408     public Ansi fgCyan() {
409         return this.fg(Color.CYAN);
410     }
411 
412     public Ansi fgDefault() {
413         return this.fg(Color.DEFAULT);
414     }
415 
416     public Ansi fgGreen() {
417         return this.fg(Color.GREEN);
418     }
419 
420     public Ansi fgMagenta() {
421         return this.fg(Color.MAGENTA);
422     }
423 
424     public Ansi fgRed() {
425         return this.fg(Color.RED);
426     }
427 
428     public Ansi fgYellow() {
429         return this.fg(Color.YELLOW);
430     }
431 
432     public Ansi bg(Color color) {
433         attributeOptions.add(color.bg());
434         return this;
435     }
436 
437     public Ansi bg(int color) {
438         attributeOptions.add(48);
439         attributeOptions.add(5);
440         attributeOptions.add(color & 0xff);
441         return this;
442     }
443 
444     public Ansi bgRgb(int color) {
445         return bgRgb(color >> 16, color >> 8, color);
446     }
447 
448     public Ansi bgRgb(int r, int g, int b) {
449         attributeOptions.add(48);
450         attributeOptions.add(2);
451         attributeOptions.add(r & 0xff);
452         attributeOptions.add(g & 0xff);
453         attributeOptions.add(b & 0xff);
454         return this;
455     }
456 
457     public Ansi bgCyan() {
458         return this.bg(Color.CYAN);
459     }
460 
461     public Ansi bgDefault() {
462         return this.bg(Color.DEFAULT);
463     }
464 
465     public Ansi bgGreen() {
466         return this.bg(Color.GREEN);
467     }
468 
469     public Ansi bgMagenta() {
470         return this.bg(Color.MAGENTA);
471     }
472 
473     public Ansi bgRed() {
474         return this.bg(Color.RED);
475     }
476 
477     public Ansi bgYellow() {
478         return this.bg(Color.YELLOW);
479     }
480 
481     public Ansi fgBright(Color color) {
482         attributeOptions.add(color.fgBright());
483         return this;
484     }
485 
486     public Ansi fgBrightBlack() {
487         return this.fgBright(Color.BLACK);
488     }
489 
490     public Ansi fgBrightBlue() {
491         return this.fgBright(Color.BLUE);
492     }
493 
494     public Ansi fgBrightCyan() {
495         return this.fgBright(Color.CYAN);
496     }
497 
498     public Ansi fgBrightDefault() {
499         return this.fgBright(Color.DEFAULT);
500     }
501 
502     public Ansi fgBrightGreen() {
503         return this.fgBright(Color.GREEN);
504     }
505 
506     public Ansi fgBrightMagenta() {
507         return this.fgBright(Color.MAGENTA);
508     }
509 
510     public Ansi fgBrightRed() {
511         return this.fgBright(Color.RED);
512     }
513 
514     public Ansi fgBrightYellow() {
515         return this.fgBright(Color.YELLOW);
516     }
517 
518     public Ansi bgBright(Color color) {
519         attributeOptions.add(color.bgBright());
520         return this;
521     }
522 
523     public Ansi bgBrightCyan() {
524         return this.bgBright(Color.CYAN);
525     }
526 
527     public Ansi bgBrightDefault() {
528         return this.bgBright(Color.DEFAULT);
529     }
530 
531     public Ansi bgBrightGreen() {
532         return this.bgBright(Color.GREEN);
533     }
534 
535     public Ansi bgBrightMagenta() {
536         return this.bgBright(Color.MAGENTA);
537     }
538 
539     public Ansi bgBrightRed() {
540         return this.bgBright(Color.RED);
541     }
542 
543     public Ansi bgBrightYellow() {
544         return this.bgBright(Color.YELLOW);
545     }
546 
547     public Ansi a(Attribute attribute) {
548         attributeOptions.add(attribute.value());
549         return this;
550     }
551 
552     
553 
554 
555 
556 
557 
558 
559 
560     public Ansi cursor(final int row, final int column) {
561         return appendEscapeSequence('H', Math.max(1, row), Math.max(1, column));
562     }
563 
564     
565 
566 
567 
568 
569 
570 
571     public Ansi cursorToColumn(final int x) {
572         return appendEscapeSequence('G', Math.max(1, x));
573     }
574 
575     
576 
577 
578 
579 
580 
581     public Ansi cursorUp(final int y) {
582         return y > 0 ? appendEscapeSequence('A', y) : y < 0 ? cursorDown(-y) : this;
583     }
584 
585     
586 
587 
588 
589 
590 
591     public Ansi cursorDown(final int y) {
592         return y > 0 ? appendEscapeSequence('B', y) : y < 0 ? cursorUp(-y) : this;
593     }
594 
595     
596 
597 
598 
599 
600 
601     public Ansi cursorRight(final int x) {
602         return x > 0 ? appendEscapeSequence('C', x) : x < 0 ? cursorLeft(-x) : this;
603     }
604 
605     
606 
607 
608 
609 
610 
611     public Ansi cursorLeft(final int x) {
612         return x > 0 ? appendEscapeSequence('D', x) : x < 0 ? cursorRight(-x) : this;
613     }
614 
615     
616 
617 
618 
619 
620 
621 
622 
623 
624     public Ansi cursorMove(final int x, final int y) {
625         return cursorRight(x).cursorDown(y);
626     }
627 
628     
629 
630 
631 
632 
633     public Ansi cursorDownLine() {
634         return appendEscapeSequence('E');
635     }
636 
637     
638 
639 
640 
641 
642 
643 
644     public Ansi cursorDownLine(final int n) {
645         return n < 0 ? cursorUpLine(-n) : appendEscapeSequence('E', n);
646     }
647 
648     
649 
650 
651 
652 
653     public Ansi cursorUpLine() {
654         return appendEscapeSequence('F');
655     }
656 
657     
658 
659 
660 
661 
662 
663 
664     public Ansi cursorUpLine(final int n) {
665         return n < 0 ? cursorDownLine(-n) : appendEscapeSequence('F', n);
666     }
667 
668     public Ansi eraseScreen() {
669         return appendEscapeSequence('J', Erase.ALL.value());
670     }
671 
672     public Ansi eraseScreen(final Erase kind) {
673         return appendEscapeSequence('J', kind.value());
674     }
675 
676     public Ansi eraseLine() {
677         return appendEscapeSequence('K');
678     }
679 
680     public Ansi eraseLine(final Erase kind) {
681         return appendEscapeSequence('K', kind.value());
682     }
683 
684     public Ansi scrollUp(final int rows) {
685         if (rows == Integer.MIN_VALUE) {
686             return scrollDown(Integer.MAX_VALUE);
687         }
688         return rows > 0 ? appendEscapeSequence('S', rows) : rows < 0 ? scrollDown(-rows) : this;
689     }
690 
691     public Ansi scrollDown(final int rows) {
692         if (rows == Integer.MIN_VALUE) {
693             return scrollUp(Integer.MAX_VALUE);
694         }
695         return rows > 0 ? appendEscapeSequence('T', rows) : rows < 0 ? scrollUp(-rows) : this;
696     }
697 
698     @Deprecated
699     public Ansi restorCursorPosition() {
700         return restoreCursorPosition();
701     }
702 
703     public Ansi saveCursorPosition() {
704         saveCursorPositionSCO();
705         return saveCursorPositionDEC();
706     }
707 
708     
709     public Ansi saveCursorPositionSCO() {
710         return appendEscapeSequence('s');
711     }
712 
713     
714     public Ansi saveCursorPositionDEC() {
715         builder.append(FIRST_ESC_CHAR);
716         builder.append('7');
717         return this;
718     }
719 
720     public Ansi restoreCursorPosition() {
721         restoreCursorPositionSCO();
722         return restoreCursorPositionDEC();
723     }
724 
725     
726     public Ansi restoreCursorPositionSCO() {
727         return appendEscapeSequence('u');
728     }
729 
730     
731     public Ansi restoreCursorPositionDEC() {
732         builder.append(FIRST_ESC_CHAR);
733         builder.append('8');
734         return this;
735     }
736 
737     public Ansi reset() {
738         return a(Attribute.RESET);
739     }
740 
741     public Ansi bold() {
742         return a(Attribute.INTENSITY_BOLD);
743     }
744 
745     public Ansi boldOff() {
746         return a(Attribute.INTENSITY_BOLD_OFF);
747     }
748 
749     public Ansi a(String value) {
750         flushAttributes();
751         builder.append(value);
752         return this;
753     }
754 
755     public Ansi a(boolean value) {
756         flushAttributes();
757         builder.append(value);
758         return this;
759     }
760 
761     public Ansi a(char value) {
762         flushAttributes();
763         builder.append(value);
764         return this;
765     }
766 
767     public Ansi a(char[] value, int offset, int len) {
768         flushAttributes();
769         builder.append(value, offset, len);
770         return this;
771     }
772 
773     public Ansi a(char[] value) {
774         flushAttributes();
775         builder.append(value);
776         return this;
777     }
778 
779     public Ansi a(CharSequence value, int start, int end) {
780         flushAttributes();
781         builder.append(value, start, end);
782         return this;
783     }
784 
785     public Ansi a(CharSequence value) {
786         flushAttributes();
787         builder.append(value);
788         return this;
789     }
790 
791     public Ansi a(double value) {
792         flushAttributes();
793         builder.append(value);
794         return this;
795     }
796 
797     public Ansi a(float value) {
798         flushAttributes();
799         builder.append(value);
800         return this;
801     }
802 
803     public Ansi a(int value) {
804         flushAttributes();
805         builder.append(value);
806         return this;
807     }
808 
809     public Ansi a(long value) {
810         flushAttributes();
811         builder.append(value);
812         return this;
813     }
814 
815     public Ansi a(Object value) {
816         flushAttributes();
817         builder.append(value);
818         return this;
819     }
820 
821     public Ansi a(StringBuffer value) {
822         flushAttributes();
823         builder.append(value);
824         return this;
825     }
826 
827     public Ansi newline() {
828         flushAttributes();
829         builder.append(System.lineSeparator());
830         return this;
831     }
832 
833     public Ansi format(String pattern, Object... args) {
834         flushAttributes();
835         builder.append(String.format(pattern, args));
836         return this;
837     }
838 
839     
840 
841 
842 
843 
844 
845 
846     public Ansi apply(Consumer fun) {
847         fun.apply(this);
848         return this;
849     }
850 
851     
852 
853 
854 
855 
856 
857 
858 
859     public Ansi render(final String text) {
860         a(new org.jline.jansi.Ansi().render(text).toString());
861         return this;
862     }
863 
864     
865 
866 
867 
868 
869 
870 
871 
872 
873     public Ansi render(final String text, Object... args) {
874         a(String.format(new org.jline.jansi.Ansi().render(text).toString(), args));
875         return this;
876     }
877 
878     @Override
879     public String toString() {
880         flushAttributes();
881         return builder.toString();
882     }
883 
884     
885     
886     
887 
888     private Ansi appendEscapeSequence(char command) {
889         flushAttributes();
890         builder.append(FIRST_ESC_CHAR);
891         builder.append(SECOND_ESC_CHAR);
892         builder.append(command);
893         return this;
894     }
895 
896     private Ansi appendEscapeSequence(char command, int option) {
897         flushAttributes();
898         builder.append(FIRST_ESC_CHAR);
899         builder.append(SECOND_ESC_CHAR);
900         builder.append(option);
901         builder.append(command);
902         return this;
903     }
904 
905     private Ansi appendEscapeSequence(char command, Object... options) {
906         flushAttributes();
907         return doAppendEscapeSequence(command, options);
908     }
909 
910     private void flushAttributes() {
911         if (attributeOptions.isEmpty()) {
912             return;
913         }
914         if (attributeOptions.size() == 1 && attributeOptions.get(0) == 0) {
915             builder.append(FIRST_ESC_CHAR);
916             builder.append(SECOND_ESC_CHAR);
917             builder.append('m');
918         } else {
919             doAppendEscapeSequence('m', attributeOptions.toArray());
920         }
921         attributeOptions.clear();
922     }
923 
924     private Ansi doAppendEscapeSequence(char command, Object... options) {
925         builder.append(FIRST_ESC_CHAR);
926         builder.append(SECOND_ESC_CHAR);
927         int size = options.length;
928         for (int i = 0; i < size; i++) {
929             if (i != 0) {
930                 builder.append(';');
931             }
932             if (options[i] != null) {
933                 builder.append(options[i]);
934             }
935         }
936         builder.append(command);
937         return this;
938     }
939 
940     @Override
941     public Ansi append(CharSequence csq) {
942         builder.append(csq);
943         return this;
944     }
945 
946     @Override
947     public Ansi append(CharSequence csq, int start, int end) {
948         builder.append(csq, start, end);
949         return this;
950     }
951 
952     @Override
953     public Ansi append(char c) {
954         builder.append(c);
955         return this;
956     }
957 }