@@ -760,17 +760,6 @@ fn writeEscaped(out: anytype, input: []const u8) !void {
760760//#define VT_BOLD "\x1b[0;1m"
761761//#define VT_RESET "\x1b[0m"
762762
763- const TermState = enum {
764- Start ,
765- Escape ,
766- LBracket ,
767- Number ,
768- AfterNumber ,
769- Arg ,
770- ArgNumber ,
771- ExpectEnd ,
772- };
773-
774763test "term color" {
775764 const input_bytes = "A\x1b [32;1mgreen\x1b [0mB" ;
776765 const result = try termColor (std .testing .allocator , input_bytes );
@@ -787,61 +776,80 @@ fn termColor(allocator: Allocator, input: []const u8) ![]u8 {
787776 var first_number : usize = undefined ;
788777 var second_number : usize = undefined ;
789778 var i : usize = 0 ;
790- var state = TermState .Start ;
779+ var state : enum {
780+ start ,
781+ escape ,
782+ lbracket ,
783+ number ,
784+ after_number ,
785+ arg ,
786+ arg_number ,
787+ expect_end ,
788+ } = .start ;
789+ var last_new_line : usize = 0 ;
791790 var open_span_count : usize = 0 ;
792791 while (i < input .len ) : (i += 1 ) {
793792 const c = input [i ];
794793 switch (state ) {
795- TermState .Start = > switch (c ) {
796- '\x1b ' = > state = TermState .Escape ,
794+ .start = > switch (c ) {
795+ '\x1b ' = > state = .escape ,
796+ '\n ' = > {
797+ try out .writeByte (c );
798+ last_new_line = buf .items .len ;
799+ },
797800 else = > try out .writeByte (c ),
798801 },
799- TermState . Escape = > switch (c ) {
800- '[' = > state = TermState . LBracket ,
802+ .escape = > switch (c ) {
803+ '[' = > state = .lbracket ,
801804 else = > return error .UnsupportedEscape ,
802805 },
803- TermState . LBracket = > switch (c ) {
806+ .lbracket = > switch (c ) {
804807 '0' ... '9' = > {
805808 number_start_index = i ;
806- state = TermState . Number ;
809+ state = .number ;
807810 },
808811 else = > return error .UnsupportedEscape ,
809812 },
810- TermState . Number = > switch (c ) {
813+ .number = > switch (c ) {
811814 '0' ... '9' = > {},
812815 else = > {
813816 first_number = std .fmt .parseInt (usize , input [number_start_index .. i ], 10 ) catch unreachable ;
814817 second_number = 0 ;
815- state = TermState . AfterNumber ;
818+ state = .after_number ;
816819 i -= 1 ;
817820 },
818821 },
819822
820- TermState .AfterNumber = > switch (c ) {
821- ';' = > state = TermState .Arg ,
823+ .after_number = > switch (c ) {
824+ ';' = > state = .arg ,
825+ 'D' = > state = .start ,
826+ 'K' = > {
827+ buf .items .len = last_new_line ;
828+ state = .start ;
829+ },
822830 else = > {
823- state = TermState . ExpectEnd ;
831+ state = .expect_end ;
824832 i -= 1 ;
825833 },
826834 },
827- TermState . Arg = > switch (c ) {
835+ .arg = > switch (c ) {
828836 '0' ... '9' = > {
829837 number_start_index = i ;
830- state = TermState . ArgNumber ;
838+ state = .arg_number ;
831839 },
832840 else = > return error .UnsupportedEscape ,
833841 },
834- TermState . ArgNumber = > switch (c ) {
842+ .arg_number = > switch (c ) {
835843 '0' ... '9' = > {},
836844 else = > {
837845 second_number = std .fmt .parseInt (usize , input [number_start_index .. i ], 10 ) catch unreachable ;
838- state = TermState . ExpectEnd ;
846+ state = .expect_end ;
839847 i -= 1 ;
840848 },
841849 },
842- TermState . ExpectEnd = > switch (c ) {
850+ .expect_end = > switch (c ) {
843851 'm' = > {
844- state = TermState . Start ;
852+ state = .start ;
845853 while (open_span_count != 0 ) : (open_span_count -= 1 ) {
846854 try out .writeAll ("</span>" );
847855 }
0 commit comments