8
8
* published by the Free Software Foundation.
9
9
*/
10
10
11
- #include "git-compat-util .h"
11
+ #include "cache .h"
12
12
#include "gettext.h"
13
13
#include "progress.h"
14
14
#include "strbuf.h"
15
15
#include "trace.h"
16
+ #include "utf8.h"
16
17
17
18
#define TP_IDX_MAX 8
18
19
@@ -37,6 +38,9 @@ struct progress {
37
38
unsigned sparse ;
38
39
struct throughput * throughput ;
39
40
uint64_t start_ns ;
41
+ struct strbuf counters_sb ;
42
+ int title_len ;
43
+ int split ;
40
44
};
41
45
42
46
static volatile sig_atomic_t progress_update ;
@@ -79,41 +83,64 @@ static int is_foreground_fd(int fd)
79
83
return tpgrp < 0 || tpgrp == getpgid (0 );
80
84
}
81
85
82
- static int display (struct progress * progress , uint64_t n , const char * done )
86
+ static void display (struct progress * progress , uint64_t n , const char * done )
83
87
{
84
- const char * eol , * tp ;
88
+ const char * tp ;
89
+ struct strbuf * counters_sb = & progress -> counters_sb ;
90
+ int show_update = 0 ;
91
+ int last_count_len = counters_sb -> len ;
85
92
86
93
if (progress -> delay && (!progress_update || -- progress -> delay ))
87
- return 0 ;
94
+ return ;
88
95
89
96
progress -> last_value = n ;
90
97
tp = (progress -> throughput ) ? progress -> throughput -> display .buf : "" ;
91
- eol = done ? done : " \r" ;
92
98
if (progress -> total ) {
93
99
unsigned percent = n * 100 / progress -> total ;
94
100
if (percent != progress -> last_percent || progress_update ) {
95
101
progress -> last_percent = percent ;
96
- if (is_foreground_fd (fileno (stderr )) || done ) {
97
- fprintf (stderr , "%s: %3u%% (%" PRIuMAX "/%" PRIuMAX ")%s%s" ,
98
- progress -> title , percent ,
99
- (uintmax_t )n , (uintmax_t )progress -> total ,
100
- tp , eol );
101
- fflush (stderr );
102
- }
103
- progress_update = 0 ;
104
- return 1 ;
102
+
103
+ strbuf_reset (counters_sb );
104
+ strbuf_addf (counters_sb ,
105
+ "%3u%% (%" PRIuMAX "/%" PRIuMAX ")%s" , percent ,
106
+ (uintmax_t )n , (uintmax_t )progress -> total ,
107
+ tp );
108
+ show_update = 1 ;
105
109
}
106
110
} else if (progress_update ) {
111
+ strbuf_reset (counters_sb );
112
+ strbuf_addf (counters_sb , "%" PRIuMAX "%s" , (uintmax_t )n , tp );
113
+ show_update = 1 ;
114
+ }
115
+
116
+ if (show_update ) {
107
117
if (is_foreground_fd (fileno (stderr )) || done ) {
108
- fprintf (stderr , "%s: %" PRIuMAX "%s%s" ,
109
- progress -> title , (uintmax_t )n , tp , eol );
118
+ const char * eol = done ? done : "\r" ;
119
+ size_t clear_len = counters_sb -> len < last_count_len ?
120
+ last_count_len - counters_sb -> len + 1 :
121
+ 0 ;
122
+ size_t progress_line_len = progress -> title_len +
123
+ counters_sb -> len + 2 ;
124
+ int cols = term_columns ();
125
+
126
+ if (progress -> split ) {
127
+ fprintf (stderr , " %s%*s" , counters_sb -> buf ,
128
+ (int ) clear_len , eol );
129
+ } else if (!done && cols < progress_line_len ) {
130
+ clear_len = progress -> title_len + 1 < cols ?
131
+ cols - progress -> title_len : 0 ;
132
+ fprintf (stderr , "%s:%*s\n %s%s" ,
133
+ progress -> title , (int ) clear_len , "" ,
134
+ counters_sb -> buf , eol );
135
+ progress -> split = 1 ;
136
+ } else {
137
+ fprintf (stderr , "%s: %s%*s" , progress -> title ,
138
+ counters_sb -> buf , (int ) clear_len , eol );
139
+ }
110
140
fflush (stderr );
111
141
}
112
142
progress_update = 0 ;
113
- return 1 ;
114
143
}
115
-
116
- return 0 ;
117
144
}
118
145
119
146
static void throughput_string (struct strbuf * buf , uint64_t total ,
@@ -189,9 +216,10 @@ void display_throughput(struct progress *progress, uint64_t total)
189
216
display (progress , progress -> last_value , NULL );
190
217
}
191
218
192
- int display_progress (struct progress * progress , uint64_t n )
219
+ void display_progress (struct progress * progress , uint64_t n )
193
220
{
194
- return progress ? display (progress , n , NULL ) : 0 ;
221
+ if (progress )
222
+ display (progress , n , NULL );
195
223
}
196
224
197
225
static struct progress * start_progress_delay (const char * title , uint64_t total ,
@@ -212,6 +240,9 @@ static struct progress *start_progress_delay(const char *title, uint64_t total,
212
240
progress -> sparse = sparse ;
213
241
progress -> throughput = NULL ;
214
242
progress -> start_ns = getnanotime ();
243
+ strbuf_init (& progress -> counters_sb , 0 );
244
+ progress -> title_len = utf8_strwidth (title );
245
+ progress -> split = 0 ;
215
246
set_progress_signal ();
216
247
return progress ;
217
248
}
@@ -285,6 +316,7 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
285
316
free (buf );
286
317
}
287
318
clear_progress_signal ();
319
+ strbuf_release (& progress -> counters_sb );
288
320
if (progress -> throughput )
289
321
strbuf_release (& progress -> throughput -> display );
290
322
free (progress -> throughput );
0 commit comments