@@ -10,7 +10,7 @@ use console::Term;
10
10
use instant:: Instant ;
11
11
12
12
use crate :: multi:: { MultiProgressAlignment , MultiState } ;
13
- use crate :: TermLike ;
13
+ use crate :: { term_like , TermLike } ;
14
14
15
15
/// Target for draw operations
16
16
///
@@ -69,9 +69,12 @@ impl ProgressDrawTarget {
69
69
///
70
70
/// Will panic if `refresh_rate` is `0`.
71
71
pub fn term ( term : Term , refresh_rate : u8 ) -> Self {
72
+ let supports_ansi_codes = term. supports_ansi_codes ( ) ;
73
+
72
74
Self {
73
75
kind : TargetKind :: Term {
74
76
term,
77
+ supports_ansi_codes,
75
78
last_line_count : 0 ,
76
79
rate_limiter : RateLimiter :: new ( refresh_rate) ,
77
80
draw_state : DrawState :: default ( ) ,
@@ -81,9 +84,12 @@ impl ProgressDrawTarget {
81
84
82
85
/// Draw to a boxed object that implements the [`TermLike`] trait.
83
86
pub fn term_like ( term_like : Box < dyn TermLike > ) -> Self {
87
+ let supports_ansi_codes = term_like. supports_ansi_codes ( ) ;
88
+
84
89
Self {
85
90
kind : TargetKind :: TermLike {
86
91
inner : term_like,
92
+ supports_ansi_codes,
87
93
last_line_count : 0 ,
88
94
rate_limiter : None ,
89
95
draw_state : DrawState :: default ( ) ,
@@ -94,9 +100,12 @@ impl ProgressDrawTarget {
94
100
/// Draw to a boxed object that implements the [`TermLike`] trait,
95
101
/// with a specific refresh rate.
96
102
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
+
97
105
Self {
98
106
kind : TargetKind :: TermLike {
99
107
inner : term_like,
108
+ supports_ansi_codes,
100
109
last_line_count : 0 ,
101
110
rate_limiter : Option :: from ( RateLimiter :: new ( refresh_rate) ) ,
102
111
draw_state : DrawState :: default ( ) ,
@@ -149,6 +158,7 @@ impl ProgressDrawTarget {
149
158
match & mut self . kind {
150
159
TargetKind :: Term {
151
160
term,
161
+ supports_ansi_codes,
152
162
last_line_count,
153
163
rate_limiter,
154
164
draw_state,
@@ -160,6 +170,7 @@ impl ProgressDrawTarget {
160
170
match force_draw || rate_limiter. allow ( now) {
161
171
true => Some ( Drawable :: Term {
162
172
term,
173
+ supports_ansi_codes : * supports_ansi_codes,
163
174
last_line_count,
164
175
draw_state,
165
176
} ) ,
@@ -177,12 +188,14 @@ impl ProgressDrawTarget {
177
188
}
178
189
TargetKind :: TermLike {
179
190
inner,
191
+ supports_ansi_codes,
180
192
last_line_count,
181
193
rate_limiter,
182
194
draw_state,
183
195
} => match force_draw || rate_limiter. as_mut ( ) . map_or ( true , |r| r. allow ( now) ) {
184
196
true => Some ( Drawable :: TermLike {
185
197
term_like : & * * inner,
198
+ supports_ansi_codes : * supports_ansi_codes,
186
199
last_line_count,
187
200
draw_state,
188
201
} ) ,
@@ -228,6 +241,7 @@ impl ProgressDrawTarget {
228
241
enum TargetKind {
229
242
Term {
230
243
term : Term ,
244
+ supports_ansi_codes : bool ,
231
245
last_line_count : usize ,
232
246
rate_limiter : RateLimiter ,
233
247
draw_state : DrawState ,
@@ -239,6 +253,7 @@ enum TargetKind {
239
253
Hidden ,
240
254
TermLike {
241
255
inner : Box < dyn TermLike > ,
256
+ supports_ansi_codes : bool ,
242
257
last_line_count : usize ,
243
258
rate_limiter : Option < RateLimiter > ,
244
259
draw_state : DrawState ,
@@ -268,6 +283,7 @@ impl TargetKind {
268
283
pub ( crate ) enum Drawable < ' a > {
269
284
Term {
270
285
term : & ' a Term ,
286
+ supports_ansi_codes : bool ,
271
287
last_line_count : & ' a mut usize ,
272
288
draw_state : & ' a mut DrawState ,
273
289
} ,
@@ -279,6 +295,7 @@ pub(crate) enum Drawable<'a> {
279
295
} ,
280
296
TermLike {
281
297
term_like : & ' a dyn TermLike ,
298
+ supports_ansi_codes : bool ,
282
299
last_line_count : & ' a mut usize ,
283
300
draw_state : & ' a mut DrawState ,
284
301
} ,
@@ -324,9 +341,10 @@ impl<'a> Drawable<'a> {
324
341
match self {
325
342
Drawable :: Term {
326
343
term,
344
+ supports_ansi_codes,
327
345
last_line_count,
328
346
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) ,
330
348
Drawable :: Multi {
331
349
mut state,
332
350
force_draw,
@@ -335,9 +353,10 @@ impl<'a> Drawable<'a> {
335
353
} => state. draw ( force_draw, None , now) ,
336
354
Drawable :: TermLike {
337
355
term_like,
356
+ supports_ansi_codes,
338
357
last_line_count,
339
358
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) ,
341
360
}
342
361
}
343
362
}
@@ -464,12 +483,20 @@ impl DrawState {
464
483
fn draw_to_term (
465
484
& mut self ,
466
485
term : & ( impl TermLike + ?Sized ) ,
486
+ supports_ansi_codes : bool ,
467
487
last_line_count : & mut usize ,
468
488
) -> io:: Result < ( ) > {
469
489
if panicking ( ) {
470
490
return Ok ( ( ) ) ;
471
491
}
472
492
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
+
473
500
if !self . lines . is_empty ( ) && self . move_cursor {
474
501
term. move_cursor_up ( * last_line_count) ?;
475
502
} else {
@@ -542,6 +569,11 @@ impl DrawState {
542
569
}
543
570
term. write_str ( & " " . repeat ( last_line_filler) ) ?;
544
571
572
+ // End synchronized update
573
+ if let Some ( sync_guard) = sync_guard {
574
+ sync_guard. finish_sync ( ) ?;
575
+ }
576
+
545
577
term. flush ( ) ?;
546
578
* last_line_count = real_len - orphan_visual_line_count + shift;
547
579
Ok ( ( ) )
0 commit comments