@@ -10,7 +10,7 @@ use console::Term;
1010use instant:: Instant ;
1111
1212use crate :: multi:: { MultiProgressAlignment , MultiState } ;
13- use crate :: TermLike ;
13+ use crate :: { term_like , TermLike } ;
1414
1515/// Target for draw operations
1616///
@@ -69,9 +69,12 @@ impl ProgressDrawTarget {
6969 ///
7070 /// Will panic if `refresh_rate` is `0`.
7171 pub fn term ( term : Term , refresh_rate : u8 ) -> Self {
72+ let supports_ansi_codes = term. supports_ansi_codes ( ) ;
73+
7274 Self {
7375 kind : TargetKind :: Term {
7476 term,
77+ supports_ansi_codes,
7578 last_line_count : 0 ,
7679 rate_limiter : RateLimiter :: new ( refresh_rate) ,
7780 draw_state : DrawState :: default ( ) ,
@@ -81,9 +84,12 @@ impl ProgressDrawTarget {
8184
8285 /// Draw to a boxed object that implements the [`TermLike`] trait.
8386 pub fn term_like ( term_like : Box < dyn TermLike > ) -> Self {
87+ let supports_ansi_codes = term_like. supports_ansi_codes ( ) ;
88+
8489 Self {
8590 kind : TargetKind :: TermLike {
8691 inner : term_like,
92+ supports_ansi_codes,
8793 last_line_count : 0 ,
8894 rate_limiter : None ,
8995 draw_state : DrawState :: default ( ) ,
@@ -94,9 +100,12 @@ impl ProgressDrawTarget {
94100 /// Draw to a boxed object that implements the [`TermLike`] trait,
95101 /// with a specific refresh rate.
96102 pub fn term_like_with_hz ( term_like : Box < dyn TermLike > , refresh_rate : u8 ) -> Self {
103+ let supports_ansi_codes = term_like. supports_ansi_codes ( ) ;
104+
97105 Self {
98106 kind : TargetKind :: TermLike {
99107 inner : term_like,
108+ supports_ansi_codes,
100109 last_line_count : 0 ,
101110 rate_limiter : Option :: from ( RateLimiter :: new ( refresh_rate) ) ,
102111 draw_state : DrawState :: default ( ) ,
@@ -149,6 +158,7 @@ impl ProgressDrawTarget {
149158 match & mut self . kind {
150159 TargetKind :: Term {
151160 term,
161+ supports_ansi_codes,
152162 last_line_count,
153163 rate_limiter,
154164 draw_state,
@@ -160,6 +170,7 @@ impl ProgressDrawTarget {
160170 match force_draw || rate_limiter. allow ( now) {
161171 true => Some ( Drawable :: Term {
162172 term,
173+ supports_ansi_codes : * supports_ansi_codes,
163174 last_line_count,
164175 draw_state,
165176 } ) ,
@@ -177,12 +188,14 @@ impl ProgressDrawTarget {
177188 }
178189 TargetKind :: TermLike {
179190 inner,
191+ supports_ansi_codes,
180192 last_line_count,
181193 rate_limiter,
182194 draw_state,
183195 } => match force_draw || rate_limiter. as_mut ( ) . map_or ( true , |r| r. allow ( now) ) {
184196 true => Some ( Drawable :: TermLike {
185197 term_like : & * * inner,
198+ supports_ansi_codes : * supports_ansi_codes,
186199 last_line_count,
187200 draw_state,
188201 } ) ,
@@ -228,6 +241,7 @@ impl ProgressDrawTarget {
228241enum TargetKind {
229242 Term {
230243 term : Term ,
244+ supports_ansi_codes : bool ,
231245 last_line_count : usize ,
232246 rate_limiter : RateLimiter ,
233247 draw_state : DrawState ,
@@ -239,6 +253,7 @@ enum TargetKind {
239253 Hidden ,
240254 TermLike {
241255 inner : Box < dyn TermLike > ,
256+ supports_ansi_codes : bool ,
242257 last_line_count : usize ,
243258 rate_limiter : Option < RateLimiter > ,
244259 draw_state : DrawState ,
@@ -268,6 +283,7 @@ impl TargetKind {
268283pub ( crate ) enum Drawable < ' a > {
269284 Term {
270285 term : & ' a Term ,
286+ supports_ansi_codes : bool ,
271287 last_line_count : & ' a mut usize ,
272288 draw_state : & ' a mut DrawState ,
273289 } ,
@@ -279,6 +295,7 @@ pub(crate) enum Drawable<'a> {
279295 } ,
280296 TermLike {
281297 term_like : & ' a dyn TermLike ,
298+ supports_ansi_codes : bool ,
282299 last_line_count : & ' a mut usize ,
283300 draw_state : & ' a mut DrawState ,
284301 } ,
@@ -324,9 +341,10 @@ impl<'a> Drawable<'a> {
324341 match self {
325342 Drawable :: Term {
326343 term,
344+ supports_ansi_codes,
327345 last_line_count,
328346 draw_state,
329- } => draw_state. draw_to_term ( term, last_line_count) ,
347+ } => draw_state. draw_to_term ( term, supports_ansi_codes , last_line_count) ,
330348 Drawable :: Multi {
331349 mut state,
332350 force_draw,
@@ -335,9 +353,10 @@ impl<'a> Drawable<'a> {
335353 } => state. draw ( force_draw, None , now) ,
336354 Drawable :: TermLike {
337355 term_like,
356+ supports_ansi_codes,
338357 last_line_count,
339358 draw_state,
340- } => draw_state. draw_to_term ( term_like, last_line_count) ,
359+ } => draw_state. draw_to_term ( term_like, supports_ansi_codes , last_line_count) ,
341360 }
342361 }
343362}
@@ -464,12 +483,20 @@ impl DrawState {
464483 fn draw_to_term (
465484 & mut self ,
466485 term : & ( impl TermLike + ?Sized ) ,
486+ supports_ansi_codes : bool ,
467487 last_line_count : & mut usize ,
468488 ) -> io:: Result < ( ) > {
469489 if panicking ( ) {
470490 return Ok ( ( ) ) ;
471491 }
472492
493+ // Begin synchronized update
494+ let sync_guard = if supports_ansi_codes {
495+ Some ( term_like:: SyncGuard :: begin_sync ( term) ?)
496+ } else {
497+ None
498+ } ;
499+
473500 if !self . lines . is_empty ( ) && self . move_cursor {
474501 term. move_cursor_up ( * last_line_count) ?;
475502 } else {
@@ -542,6 +569,11 @@ impl DrawState {
542569 }
543570 term. write_str ( & " " . repeat ( last_line_filler) ) ?;
544571
572+ // End synchronized update
573+ if let Some ( sync_guard) = sync_guard {
574+ sync_guard. finish_sync ( ) ?;
575+ }
576+
545577 term. flush ( ) ?;
546578 * last_line_count = real_len - orphan_visual_line_count + shift;
547579 Ok ( ( ) )
0 commit comments