@@ -12,7 +12,7 @@ use console::Term;
12
12
use instant:: Instant ;
13
13
14
14
use crate :: multi:: { MultiProgressAlignment , MultiState } ;
15
- use crate :: TermLike ;
15
+ use crate :: { term_like , TermLike } ;
16
16
17
17
/// Target for draw operations
18
18
///
@@ -71,9 +71,12 @@ impl ProgressDrawTarget {
71
71
///
72
72
/// Will panic if `refresh_rate` is `0`.
73
73
pub fn term ( term : Term , refresh_rate : u8 ) -> Self {
74
+ let supports_ansi_codes = term. supports_ansi_codes ( ) ;
75
+
74
76
Self {
75
77
kind : TargetKind :: Term {
76
78
term,
79
+ supports_ansi_codes,
77
80
last_line_count : VisualLines :: default ( ) ,
78
81
rate_limiter : RateLimiter :: new ( refresh_rate) ,
79
82
draw_state : DrawState :: default ( ) ,
@@ -83,9 +86,12 @@ impl ProgressDrawTarget {
83
86
84
87
/// Draw to a boxed object that implements the [`TermLike`] trait.
85
88
pub fn term_like ( term_like : Box < dyn TermLike > ) -> Self {
89
+ let supports_ansi_codes = term_like. supports_ansi_codes ( ) ;
90
+
86
91
Self {
87
92
kind : TargetKind :: TermLike {
88
93
inner : term_like,
94
+ supports_ansi_codes,
89
95
last_line_count : VisualLines :: default ( ) ,
90
96
rate_limiter : None ,
91
97
draw_state : DrawState :: default ( ) ,
@@ -96,9 +102,12 @@ impl ProgressDrawTarget {
96
102
/// Draw to a boxed object that implements the [`TermLike`] trait,
97
103
/// with a specific refresh rate.
98
104
pub fn term_like_with_hz ( term_like : Box < dyn TermLike > , refresh_rate : u8 ) -> Self {
105
+ let supports_ansi_codes = term_like. supports_ansi_codes ( ) ;
106
+
99
107
Self {
100
108
kind : TargetKind :: TermLike {
101
109
inner : term_like,
110
+ supports_ansi_codes,
102
111
last_line_count : VisualLines :: default ( ) ,
103
112
rate_limiter : Option :: from ( RateLimiter :: new ( refresh_rate) ) ,
104
113
draw_state : DrawState :: default ( ) ,
@@ -151,6 +160,7 @@ impl ProgressDrawTarget {
151
160
match & mut self . kind {
152
161
TargetKind :: Term {
153
162
term,
163
+ supports_ansi_codes,
154
164
last_line_count,
155
165
rate_limiter,
156
166
draw_state,
@@ -162,6 +172,7 @@ impl ProgressDrawTarget {
162
172
match force_draw || rate_limiter. allow ( now) {
163
173
true => Some ( Drawable :: Term {
164
174
term,
175
+ supports_ansi_codes : * supports_ansi_codes,
165
176
last_line_count,
166
177
draw_state,
167
178
} ) ,
@@ -179,12 +190,14 @@ impl ProgressDrawTarget {
179
190
}
180
191
TargetKind :: TermLike {
181
192
inner,
193
+ supports_ansi_codes,
182
194
last_line_count,
183
195
rate_limiter,
184
196
draw_state,
185
197
} => match force_draw || rate_limiter. as_mut ( ) . map_or ( true , |r| r. allow ( now) ) {
186
198
true => Some ( Drawable :: TermLike {
187
199
term_like : & * * inner,
200
+ supports_ansi_codes : * supports_ansi_codes,
188
201
last_line_count,
189
202
draw_state,
190
203
} ) ,
@@ -230,6 +243,7 @@ impl ProgressDrawTarget {
230
243
enum TargetKind {
231
244
Term {
232
245
term : Term ,
246
+ supports_ansi_codes : bool ,
233
247
last_line_count : VisualLines ,
234
248
rate_limiter : RateLimiter ,
235
249
draw_state : DrawState ,
@@ -241,6 +255,7 @@ enum TargetKind {
241
255
Hidden ,
242
256
TermLike {
243
257
inner : Box < dyn TermLike > ,
258
+ supports_ansi_codes : bool ,
244
259
last_line_count : VisualLines ,
245
260
rate_limiter : Option < RateLimiter > ,
246
261
draw_state : DrawState ,
@@ -270,6 +285,7 @@ impl TargetKind {
270
285
pub ( crate ) enum Drawable < ' a > {
271
286
Term {
272
287
term : & ' a Term ,
288
+ supports_ansi_codes : bool ,
273
289
last_line_count : & ' a mut VisualLines ,
274
290
draw_state : & ' a mut DrawState ,
275
291
} ,
@@ -281,6 +297,7 @@ pub(crate) enum Drawable<'a> {
281
297
} ,
282
298
TermLike {
283
299
term_like : & ' a dyn TermLike ,
300
+ supports_ansi_codes : bool ,
284
301
last_line_count : & ' a mut VisualLines ,
285
302
draw_state : & ' a mut DrawState ,
286
303
} ,
@@ -326,9 +343,10 @@ impl<'a> Drawable<'a> {
326
343
match self {
327
344
Drawable :: Term {
328
345
term,
346
+ supports_ansi_codes,
329
347
last_line_count,
330
348
draw_state,
331
- } => draw_state. draw_to_term ( term, last_line_count) ,
349
+ } => draw_state. draw_to_term ( term, supports_ansi_codes , last_line_count) ,
332
350
Drawable :: Multi {
333
351
mut state,
334
352
force_draw,
@@ -337,9 +355,10 @@ impl<'a> Drawable<'a> {
337
355
} => state. draw ( force_draw, None , now) ,
338
356
Drawable :: TermLike {
339
357
term_like,
358
+ supports_ansi_codes,
340
359
last_line_count,
341
360
draw_state,
342
- } => draw_state. draw_to_term ( term_like, last_line_count) ,
361
+ } => draw_state. draw_to_term ( term_like, supports_ansi_codes , last_line_count) ,
343
362
}
344
363
}
345
364
}
@@ -466,12 +485,20 @@ impl DrawState {
466
485
fn draw_to_term (
467
486
& mut self ,
468
487
term : & ( impl TermLike + ?Sized ) ,
488
+ supports_ansi_codes : bool ,
469
489
last_line_count : & mut VisualLines ,
470
490
) -> io:: Result < ( ) > {
471
491
if panicking ( ) {
472
492
return Ok ( ( ) ) ;
473
493
}
474
494
495
+ // Begin synchronized update
496
+ let sync_guard = if supports_ansi_codes {
497
+ Some ( term_like:: SyncGuard :: begin_sync ( term) ?)
498
+ } else {
499
+ None
500
+ } ;
501
+
475
502
if !self . lines . is_empty ( ) && self . move_cursor {
476
503
term. move_cursor_up ( last_line_count. as_usize ( ) ) ?;
477
504
} else {
@@ -547,6 +574,11 @@ impl DrawState {
547
574
}
548
575
term. write_str ( & " " . repeat ( last_line_filler) ) ?;
549
576
577
+ // End synchronized update
578
+ if let Some ( sync_guard) = sync_guard {
579
+ sync_guard. finish_sync ( ) ?;
580
+ }
581
+
550
582
term. flush ( ) ?;
551
583
* last_line_count = real_len - orphan_visual_line_count + shift;
552
584
Ok ( ( ) )
0 commit comments