@@ -10,7 +10,7 @@ impl<T: fmt::Debug> fmt::Debug for Escape<T> {
1010 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1111 let mut escaping_writer = EscapingWriter {
1212 inner : f,
13- skip_control_chars : false ,
13+ skip_csi_codes : false ,
1414 } ;
1515 write ! ( escaping_writer, "{:?}" , self . 0 )
1616 }
@@ -24,7 +24,7 @@ impl<T: fmt::Debug> fmt::Debug for EscapeSkip<T> {
2424 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2525 let mut escaping_writer = EscapingWriter {
2626 inner : f,
27- skip_control_chars : true ,
27+ skip_csi_codes : true ,
2828 } ;
2929 write ! ( escaping_writer, "{:?}" , self . 0 )
3030 }
@@ -33,21 +33,32 @@ impl<T: fmt::Debug> fmt::Debug for EscapeSkip<T> {
3333/// Helper struct that escapes ANSI sequences as characters are written
3434struct EscapingWriter < ' a , ' b > {
3535 inner : & ' a mut fmt:: Formatter < ' b > ,
36- skip_control_chars : bool ,
36+ skip_csi_codes : bool ,
3737}
3838
3939impl < ' a , ' b > fmt:: Write for EscapingWriter < ' a , ' b > {
4040 fn write_str ( & mut self , s : & str ) -> fmt:: Result {
4141 // Stream the string character by character, escaping all control sequences
42- for ch in s. chars ( ) {
42+ let mut chars = s. chars ( ) . peekable ( ) ;
43+ while let Some ( ch) = chars. next ( ) {
44+ // Recognize and remove ECMA-48 CSI codes
45+ // This is a best effort to clean up colour codes in the message field
46+ if ch == '\x1b' && self . skip_csi_codes {
47+ if chars. next_if_eq ( & '[' ) . is_some ( ) {
48+ // Remove parameter and intermediate bytes
49+ while chars. next_if ( |x| matches ! ( x, '\x20' ..='\x3f' ) ) . is_some ( ) { }
50+ // Remove final byte
51+ chars. next_if ( |x| matches ! ( x, '\x40' ..='\x7E' ) ) ;
52+ continue ;
53+ }
54+ }
55+
4356 // ESC BEL BS FF DEL
4457 if matches ! ( ch, '\x1b' | '\x07' | '\x08' | '\x0c' | '\x7f' ..='\u{9f}' ) {
45- if !self . skip_control_chars {
46- if ch. is_ascii ( ) {
47- write ! ( self . inner, "\\ x{:02x}" , ch as u32 ) ?
48- } else {
49- write ! ( self . inner, "\\ u{{{:x}}}" , ch as u32 ) ?
50- }
58+ if ch. is_ascii ( ) {
59+ write ! ( self . inner, "\\ x{:02x}" , ch as u32 ) ?
60+ } else {
61+ write ! ( self . inner, "\\ u{{{:x}}}" , ch as u32 ) ?
5162 }
5263 } else {
5364 self . inner . write_char ( ch) ?;
0 commit comments